본문 바로가기

라즈베리파이 5

인터럽트가 있는 Raspberry Pi Pico

반응형

 

인터럽트가 있는 Raspberry Pi Pico: 외부 및 타이머 인터럽트(MicroPython) 

 

이 가이드에서는 MicroPython을 사용하여 Raspberry Pi Pico에서 인터럽트를 처리하는 방법을 알아보고, 푸시 버튼과 PIR 모션 센서를 사용하여 몇 가지 프로젝트 예제를 만들어 보겠습니다. 외부 인터럽트와 시간 인터럽트도 다룹니다. 

 

 

https://randomnerdtutorials.com/raspberry-pi-pico-interrupts-micropython/

 

 

목차 이 가이드에서는 다음 주제를 다룹니다.

인터럽트 소개

MicroPython의 외부 인터럽트

예제 1: 푸시 버튼 누름 감지

예제 2: 버튼 누름 횟수 세기

예제 3: 버튼을 누를 때마다 LED 토글

MicroPython의 타이머 인터럽트

예제 1: 타이머를 사용하여 LED 깜박임

예제 2: 서로 다른 주파수로 여러 개의 LED 깜박임

예제 3: 타이머를 사용하여 푸시 버튼의 바운싱 해제

예제 4: PIR 모션 센서를 사용한 인터럽트 및 타이머 

 

필수 구성 요소 – MicroPython 펌웨어 

 

이 튜토리얼을 따라 하려면 Raspberry Pi Pico 보드에 MicroPython 펌웨어가 설치되어 있어야 합니다. 또한 코드를 작성하고 보드에 업로드할 IDE가 필요합니다.

 

Raspberry Pi Pico에 권장되는 MicroPython IDE는 Thonny IDE입니다. 다음 튜토리얼을 따라 Thonny IDE를 설치하고, MicroPython 펌웨어를 플래시 하고, 보드에 코드를 업로드하는 방법을 알아보세요.

 

MicroPython을 사용하여 Raspberry Pi Pico 프로그래밍

 

인터럽트 소개

 

인터럽트는 마이크로컨트롤러 프로그램에서 자동으로 작업을 처리하는 데 유용하며, 타이밍 문제를 해결하는 데 도움이 될 수 있습니다. 인터럽트와 이벤트 처리는 외부 이벤트에 응답하는 메커니즘을 제공하여 Raspberry Pi Pico가 지속적인 폴링(핀이나 변수의 현재 값을 지속적으로 확인) 없이도 변경 사항에 신속하게 대응할 수 있도록 합니다.

 

인터럽트란 무엇인가요?

 

인터럽트는 특정 이벤트를 처리하기 위해 프로그램의 정상적인 실행 흐름을 일시 정지하는 신호입니다. 인터럽트가 발생하면 프로세서는 메인 프로그램의 실행을 중단하고 작업을 수행한 후 메인 프로그램으로 돌아갑니다. 이 작업은 아래 그림과 같이 인터럽트 처리 루틴 이라고도 합니다.

 

인터럽트의 작동 방식

 

인터럽트를 사용하면 상태를 지속적으로 확인할 필요 없이 동작이 감지되거나 푸시 버튼이 눌릴 때마다 동작을 트리거하거나, 시간을 지속적으로 확인할 필요 없이 주기적으로 어떤 일이 발생하도록 할 때 특히 유용합니다.

 

인터럽트 유형

 

인터럽트에는 외부 인터럽트와 타이밍 인터럽트 등 여러 유형이 있습니다.

 

1. 외부 인터럽트 : 버튼 눌림이나 센서 감지와 같은 외부 신호에 의해 트리거됩니다. 하드웨어 기반이며 특정 GPIO 핀과 연결됩니다. 핀의 상태가 변경되면 작업이 트리거 됩니다.

 

2. 시간 간격에 따라 시작되는 인터럽트(타이머) : 주기적 작업을 활성화합니다. 이 기능은 RP2040(또는 Raspberry Pi Pico 버전에 따라서는 RP2350)의 하드웨어 타이머를 사용하여 정기적인 간격으로 콜백을 트리거합니다.

 

MicroPython의 외부 인터럽트

 

MicroPython에서 인터럽트를 설정하려면 다음 단계를 따라야 합니다.

 

1. 인터럽트 처리 함수를 정의합니다.

 

인터럽트 처리 함수는 프로세서가 메인 프로그램 실행으로 빠르게 돌아갈 수 있도록 최대한 간단해야 합니다. 가장 좋은 방법은 전역 변수를 사용하여 메인 코드에 인터럽트가 발생했음을 알리는 것입니다.

 

인터럽트 처리 기능은 다음 유형의 매개변수를 허용해야 합니다. 핀이 매개변수는 콜백 함수로 반환되며, 인터럽트를 발생시킨 GPIO를 참조합니다. 몇 가지 예제를 테스트해 보면 이러한 개념을 더 잘 이해할 수 있을 것입니다.

 

def handle_interrupt(pin):

 

2. 인터럽트 핀을 입력으로 설정합니다. 예:

 

interrupt_pin = Pin(21, Pin.IN)

 

3. 해당 핀에 인터럽트를 연결하려면 다음을 호출합니다. irq() 방법:

 

interrupt_pin.irq(trigger=Pin.IRQ_RISING, handler=handle_interrupt)

 

그만큼 irq()이 메서드는 다음 인수를 허용합니다.

 

트리거 : 트리거 모드를 정의합니다. 3가지 조건이 있습니다.

 

핀. IRQ_FALLING: 핀이 다음 위치에서 이동할 때마다 인터럽트를 트리거합니다. 높은에게 낮은;

핀. IRQ_RISING: 핀이 다음 위치에서 이동할 때마다 인터럽트를 트리거합니다. 낮은에게 높은.

핀. IRQ_LOW_LEVEL: 핀이 있을 때 인터럽트를 트리거하려면 낮은.

핀. IRQ_HIGH_LEVEL: 핀이 있을 때 인터럽트를 트리거하려면 높은.

 

핸들러 : 이것은 인터럽트가 감지될 때 호출되는 함수입니다. 이 경우에는 핸들_인터럽트() 기능.

 

다음 그림은 다양한 트리거 모드를 더 잘 이해하는 데 도움이 될 것입니다.

 

인터럽트 모드

 

푸시 버튼을 사용한 외부 인터럽트(예)

 

인터럽트 처리 방법을 보여주기 위해 푸시 버튼과 LED를 사용하여 간단한 프로젝트를 만들어 보겠습니다. 푸시 버튼을 GPIO 21에 연결하고 LED를 GPIO 20에 연결합니다.

 

다음은 이러한 예제에 필요한 부품 목록입니다.

 

라즈베리파이 피코 또는 라즈베리파이 피코 2

5mm LED

220Ω 저항기

푸시버튼

브레드보드

점퍼 와이어

 

위의 링크를 이용하거나 MakerAdvisor.com/tools로 직접 접속하여 프로젝트에 필요한 모든 부품을 최고의 가격으로 찾아보세요!

 

회로도

 

이 섹션의 예제에서는 LED를 GPIO20에 연결하고 푸시 버튼을 GPIO21에 연결합니다. 다음 다이어그램을 참고할 수 있습니다.

 

라즈베리파이 피코 푸시버튼 LED 회로

 

추천 자료 : Raspberry Pi Pico 및 Pico W 핀아웃 가이드: GPIO 설명

 

예제 1: 푸시 버튼 누름 감지

 

인터럽트 작동 방식을 보여주는 가장 간단한 예제 중 하나입니다. 다음 코드를 Thonny IDE에 복사하세요.

 

# Rui Santos & Sara Santos - Random Nerd Tutorials
# Complete project details at https://RandomNerdTutorials.com/raspberry-pi-pico-interrupts-micropython/

from machine import Pin

button = Pin(21, Pin.IN, Pin.PULL_DOWN)

def button_pressed(pin):
    print("Button Pressed!")

# Attach the interrupt to the button's rising edge
button.irq(trigger=Pin.IRQ_RISING, handler=button_pressed)

 

이 예에서는 다음과 같은 입력 객체를 생성합니다. 단추. [ RPi Pico 입력에 대해 자세히 알아보세요 ]

 

button = Pin(21, Pin.IN, Pin.PULL_DOWN)

 

그런 다음, 다음과 같이 해당 핀에 인터럽트를 추가합니다.

 

button.irq(trigger=Pin.IRQ_RISING, handler=button_pressed)

 

이 라인은 버튼 신호가 입력될 때를 의미합니다. 상승모드(에서 낮은 에게 높은), 그 버튼_누름함수가 호출됩니다.

 

그만큼 버튼_누름이 함수는 단순히 버튼이 눌렸다는 것을 Shell에 출력합니다.

 

def button_pressed(pin):

    print("Button Pressed!")

 

함수 정의는 인터럽트 생성 전에 이루어진다는 점에 유의하세요. MicroPython에서는 모든 사용자 정의 함수는 호출되기 전에 정의되어야 합니다.

 

코드 테스트

 

Raspberry Pi Pico 보드에서 이전 코드를 실행해 보세요. 푸시 버튼을 누를 때마다 Shell에 메시지가 표시됩니다.

 

Raspberry Pi Pico에서 푸시 버튼 누름 감지

 

Raspberry Pi Pico에서 푸시 버튼 눌림 감지 - Micropython Shell Thonny IDE

 

예제 2: 버튼 누름 횟수 세기

 

이 예제에서는 전역 변수를 사용하여 버튼 눌림 횟수를 계산해 보겠습니다. 이를 통해 전역 변수의 작동 방식을 더 잘 이해할 수 있습니다.

 

# Rui Santos & Sara Santos - Random Nerd Tutorials
# Complete project details at https://RandomNerdTutorials.com/raspberry-pi-pico-interrupts-micropython/

from machine import Pin

button = Pin(21, Pin.IN, Pin.PULL_DOWN)
counter = 0  # Initialize the button press count

def button_pressed(pin):
    global counter # Declare variable as global
    counter +=1
    print("Button Pressed! Count: ", counter)

# Attach the interrupt to the button's rising edge
button.irq(trigger=Pin.IRQ_RISING, handler=button_pressed)

 

이 예에서 우리는 라는 전역 변수를 생성합니다. 계수기— 외부에서 선언되고 초기화됩니다. 버튼_누름기능.

 

counter = 0 # Initialize the button press count

 

함수 내부에서 해당 변수를 사용하려면 키워드를 사용해야 합니다. 글로벌함수 내에서—이렇게 하면 변수계수기전역적으로 정의되어 있으므로 함수 내부와 외부 모두에서 접근하고 수정할 수 있습니다.

 

버튼을 누르면 버튼_누름함수가 호출되면 전역계수기변수가 증가되고, 업데이트된 값이 인쇄됩니다.

 

global counter # Declare variable as global
counter +=1
print("Button Pressed! Count: ", counter)

 

참고: counter +=1은 counter = counter +1의 약자입니다.

 

코드 테스트

 

Raspberry Pi Pico에서 이전 코드를 실행해 보세요. 버튼을 누른 횟수가 Shell에 출력되는 것을 확인할 수 있습니다.

 

푸시버튼 카운터 라즈베리파이 피코 마이크로파이썬 토니 IDE

 

예제 3: 버튼을 누를 때마다 LED 토글

 

이는 이전 예와 비슷하지만, 푸시 버튼을 누르면 LED가 켜집니다.

 

# Rui Santos & Sara Santos - Random Nerd Tutorials
# Complete project details at https://RandomNerdTutorials.com/raspberry-pi-pico-interrupts-micropython/

from machine import Pin

led = Pin(20, Pin.OUT)
button = Pin(21, Pin.IN, Pin.PULL_DOWN)
counter = 0   # Initialize the button press count

def button_pressed(pin):
    global counter # Declare variable as global
    counter +=1
    print("Button Pressed! Count: ", counter)
    
    # Toggle the LED on each button press
    led.value(not led.value())

# Attach the interrupt to the button's rising edge
button.irq(trigger=Pin.IRQ_RISING, handler=button_pressed)

 

 

이 예에서 우리는 단지 새로운 것을 선언해야 합니다. 핀이 경우 GPIO 20에서 LED에 대한 객체입니다.

 

led = Pin(20, Pin.OUT)

 

그런 다음 LED를 내부에서 토글 하는 명령을 추가합니다.버튼_누름기능.

 

led.value(not led.value())

 

라즈베리파이 피코 푸시버튼 LED 켜짐

 

버튼 바운싱

 

푸시 버튼이 실제로는 한 번 눌렀는데도 두 번 이상 눌렸다고 계산되는 경우가 종종 있습니다. 이를 기계적 바운싱이라고 하며, 푸시 버튼과 같은 기계식 버튼에서 매우 흔히 발생합니다.

 

푸시버튼 디바운스

 

이런 현상은 버튼 내부의 전기 접점이 안정 상태에 도달하기 전에 매우 빠르게 연결되고 분리되기 때문에 발생하는데, 이로 인해 시스템이 여러 번 눌림 이벤트를 등록하여 계산이 부정확해질 수 있습니다.

 

이 문제를 방지하기 위해 지연이나 타이머 인터럽트를 사용하여 디바운싱 기법을 추가할 수 있습니다. 다음 섹션에서는 타이머 인터럽트와 이벤트에 대해 살펴보고, 버튼 디바운싱 방법을 알아보겠습니다.

 

기타 응용 프로그램

 

Raspberry Pi Pico에서는 버튼 외에도 센서 입력, 회전 인코더, 기타 실시간 이벤트 기반 시나리오를 포함한 다양한 애플리케이션에 외부 인터럽트를 사용할 수 있습니다.

 

가장 일반적인 응용 분야 중 하나는 PIR 모션 센서입니다. 이 센서는 트리거 상태로 전환됩니다(높은) 움직임이 감지된 후 몇 초 동안은 인터럽트가 작동하지 않습니다. 따라서 상승 모드에서 인터럽트를 사용하면 센서가 움직임을 감지했을 때 이를 감지하는 좋은 방법입니다.

 

추천 자료 : Raspberry Pi Pico: PIR 센서를 사용하여 동작 감지(MicroPython )

 

PIR 모션 센서가 있는 Raspberry Pi Pico

 

연기 센서, 강우 센서, 수위 센서, 소리 센서 등 특정 임계값을 초과하면 디지털 신호를 보내는 다른 센서도 있습니다. 센서가 이러한 신호를 보내는 시점을 감지하는 것은 인터럽트를 통해서도 가능합니다. 특정 GPIO에서 값을 지속적으로 폴링하지 않고도 해당 상태를 감지할 수 있기 때문입니다.

 

타이머 인터럽트

 

타이머 인터럽트를 사용하면 경과 시간을 지속적으로 확인하지 않고도 주기적으로 또는 미리 정의된 기간 후에 어떤 일이 발생하도록 하는 데 특히 유용합니다.

 

타이머 인터럽트

 

MicroPython 클래스 Timer

 

마이크로파이썬기계모듈에는 다음과 같은 클래스가 포함되어 있습니다.시간제 노동자지정된 기간 내에 또는 미리 정의된 지연 시간 후에 콜백 함수를 주기적으로 실행하는 메서드를 제공합니다. 이는 경과 시간을 지속적으로 확인할 필요 없이 이벤트를 예약하거나 주기적인 작업을 실행하는 데 유용합니다.

 

잠깐 살펴보겠습니다.시간제 노동자건설자.

 

타이머 만들기

 

타이머를 생성하려면 다음을 호출하세요.시간제 노동자()생성자는 다음과 같습니다.

 

my_timer = Timer()

 

그런 다음 다음을 사용하여 타이머를 초기화합니다.초기화()방법에 대한시간제 노동자()객체를 만들고 타이머 모드, 기간, 콜백 함수를 인수로 전달합니다. 예를 들어 다음과 같습니다.

 

my_timer.init(mode=Timer.PERIODIC, period=1000, callback=timer_callback)

 

이는 다음을 실행할 주기 타이머를 초기화합니다.타이머 콜백1000밀리초(1초)마다 함수를 실행합니다. 기간 매개변수를 원하는 기간으로 변경할 수 있습니다.

 

콜백 함수를 주기적으로 호출하는 대신, 미리 정의된 시간 후에 한 번만 실행하고 싶을 수도 있습니다. 이를 위해 다음을 사용할 수 있습니다.타이머.ONE_SHOT모드는 다음과 같습니다.

 

my_timer.init(mode=Timer.ONE_SHOT, period=1000, callback=timer_callback)

 

이 코드 줄은 타이머를 구성합니다(마이_타이머) 일회성 모드로 실행하여 지정된 콜백 함수를 트리거합니다.타이머 콜백) 1000밀리초 후.

 

예제 1: 타이머를 사용하여 LED 깜박임

 

이 예제에서는 타이머를 사용하여 LED를 깜빡이는 방법을 알아봅니다. 이를 통해 주기 타이머의 작동 방식을 이해하는 데 도움이 될 것입니다.

 

회로도

 

GPIO 20에 연결된 LED를 깜빡이겠습니다. Raspberry Pi Pico의 GPIO에 LED를 연결하세요. 다음 다이어그램을 참고하시면 됩니다.

 

LED에 연결된 RPi Pico - 회로도

 

코드

 

다음 예에서는 다음을 사용합니다.시간제 노동자0.5초마다 LED를 깜박이는 클래스입니다.

 

# Rui Santos & Sara Santos - Random Nerd Tutorials
# Complete project details at https://RandomNerdTutorials.com/raspberry-pi-pico-interrupts-micropython/

from machine import Pin, Timer
from time import sleep

# LED pin
led_pin = 20
led = Pin(led_pin, Pin.OUT)

# Callback function for the timer
def toggle_led(timer):
    led.value(not led.value())  # Toggle the LED state (ON/OFF)

# Create a periodic timer
blink_timer = Timer()
blink_timer.init(mode=Timer.PERIODIC, period=500, callback=toggle_led)  # Timer repeats every half second

# Main loop (optional)
while True:
    print('Main Loop is running')
    sleep(2)

 

이 코드에서는 다음과 같은 타이머를 생성합니다.블링크 타이머:

 

blink_timer = Timer()

 

그런 다음, 다음 매개변수를 사용하여 타이머를 초기화합니다.

 

blink_timer.init(mode=Timer.PERIODIC, period=500, callback=toggle_led)

 

이는 이 타이머가 다음을 호출한다는 것을 의미합니다.토글_LED500밀리초마다 영원히(또는 프로그램을 멈출 때까지) 함수가 실행됩니다.

 

그만큼토글_LED이름에서 알 수 있듯이 이 기능은 LED 상태를 전환합니다.

 

# Callback function for the timer
def toggle_led(timer):
    led.value(not led.value())  # Toggle the LED state (ON/OFF)

 

타이머 이벤트에 대한 콜백 함수는 하나의 인수를 가져야 합니다.def toggle_led( 타이머 ):). 그시간제 노동자이벤트가 트리거되면 객체가 해당 함수에 자동으로 인수로 전달됩니다. 해당 인수를 사용하지 않더라도 반드시 전달해야 합니다.

 

타이머를 사용하면 메인 루프에서 다른 작업을 서로 방해하지 않고 실행할 수 있습니다. 예를 들어, 메인 루프에서 2초마다 메시지를 출력하겠습니다.

 

while True:
    print('Main Loop is running')
    sleep(2)

 

 

코드 테스트

 

GPIO 20에 LED를 연결한 후 보드에서 이전 코드를 실행합니다.

 

셸에서 2초마다 "메인 루프가 실행 중입니다"라는 메시지가 표시되고, 동시에 LED가 반초마다 깜박입니다.

 

Thonny IDE에서 실행되는 RPi Pico 메인 루프

 

RPi Pico 깜박이는 LED 1

 

RPi Pico 깜박이는 LED 1

 

예제 2: 서로 다른 주파수로 여러 개의 LED 깜박임

 

이전 예제를 테스트해 보니, 타이머를 여러 개 만들면 여러 작업을 서로 다른 빈도로 실행할 수 있다는 것을 쉽게 이해할 수 있습니다. 이 예제에서는 두 개의 LED를 각각 0.5초마다, 그리고 2초마다 깜박이도록 설정해 보겠습니다.

 

회로도

 

Raspberry Pi Pico에 두 개의 LED를 연결합니다(각 LED를 구분하기 위해 서로 다른 색상을 사용합니다).

 

파란색 LED: GPIO 19 >가 0.5초마다 깜박입니다.

녹색 LED: GPIO 20 > 2초마다 깜박입니다.

 

다음 다이어그램을 참고하여 회로를 배선할 수 있습니다.

 

라즈베리파이 피코 LED 2개 연결

 

코드

 

다음 코드는 타이머를 사용하여 두 개의 서로 다른 LED를 서로 다른 주파수로 깜박입니다.

 

# Rui Santos & Sara Santos - Random Nerd Tutorials
# Complete project details at https://RandomNerdTutorials.com/raspberry-pi-pico-interrupts-micropython/

from machine import Pin, Timer
from time import sleep

# LEDs
green_led_pin = 19
green_led = Pin(green_led_pin, Pin.OUT)
blue_led_pin = 20
blue_led = Pin(blue_led_pin, Pin.OUT)

# Callback function for the green timer
def toggle_green_led(timer):
    green_led.toggle()  # Toggle the LED state (ON/OFF)
    print('Green LED is: ', green_led.value())

# Callback function for the blue timer
def toggle_blue_led(timer):
    blue_led.toggle()  # Toggle the LED state (ON/OFF)
    print('Blue LED is: ', blue_led.value())

# Create periodic timers
green_timer = Timer()
blue_timer = Timer()

# Init the timers
green_timer.init(mode=Timer.PERIODIC, period=500, callback=toggle_green_led)  # Timer repeats every 0.5 second
blue_timer.init(mode=Timer.PERIODIC, period=2000, callback=toggle_blue_led)  # Timer repeats every 2 seconds

# Main loop (optional)
while True:
    print('Main Loop is running')
    sleep(2)

 

이 코드에서는 각 LED에 대해 하나씩 두 개의 서로 다른 타이머를 생성합니다.

 

green_timer = Timer()

blue_timer = Timer()

 

그런 다음, 서로 다른 간격으로 해당 콜백 함수를 호출합니다.

 

# Timer repeats every 0.5 second
green_timer.init(mode=Timer.PERIODIC, period=500, callback=toggle_green_led)
# Timer repeats every 2 seconds
blue_timer.init(mode=Timer.PERIODIC, period=2000, callback=toggle_blue_led)

 

콜백 함수는 단순히 현재 LED 값을 전환합니다.

 

# Callback function for the green timer
def toggle_green_led(timer):
    green_led.toggle()  # Toggle the LED state (ON/OFF)
    print('Green LED is: ', green_led.value())

# Callback function for the blue timer
def toggle_blue_led(timer):
    blue_led.toggle()  # Toggle the LED state (ON/OFF)
    print('Blue LED is: ', blue_led.value())

 

그만큼비녀장()함수: MicroPython에는 다음과 같은 메서드가 있습니다.비녀장()예를 들어 LED와 같은 출력 핀 객체에 사용할 수 있습니다. 이를 통해 디지털 핀의 상태를 현재 상태에서 반대 상태로 변경할 수 있습니다.

 

코드 테스트

 

이전 코드를 Raspberry Pi Pico에서 실행해 보세요. 두 개의 LED가 서로 다른 빈도로 깜박이는 것을 볼 수 있습니다.

 

RPi Pico LED가 다른 주파수로 깜박임

 

동시에, 당신은 메시지를 받게 될 것입니다~하는 동안2초마다 루프가 실행됩니다. 이는 다른 작업이 루프에 영향을 주지 않는다는 것을 보여줍니다.

 

RPi Pico 다중 타이머 및 루프 실행

 

예제 3: 타이머를 사용하여 푸시 버튼의 바운싱 해제

 

앞서 언급했듯이, 타이머를 사용하면 푸시 버튼의 디바운싱을 통해 잘못된 버튼 눌림을 방지할 수 있습니다. 푸시 버튼을 디바운싱하는 방법은 여러 가지가 있으며, 아래 예시는 그 중 하나일 뿐입니다.

 

# Rui Santos & Sara Santos - Random Nerd Tutorials
# Complete project details at https://RandomNerdTutorials.com/raspberry-pi-pico-interrupts-micropython/

from machine import Pin, Timer

led = Pin(20, Pin.OUT)
button = Pin(21, Pin.IN, Pin.PULL_DOWN)
counter = 0  # Initialize the button press count
debounce_timer = None

def button_pressed(pin):
    global counter, debounce_timer  # Declare variables as global

    if debounce_timer is None:
        counter += 1
        print("Button Pressed! Count: ", counter)
        
        # Toggle the LED on each button press
        led.toggle()

        # Start a timer for debounce period (e.g., 200 milliseconds)
        debounce_timer = Timer()
        debounce_timer.init(mode=Timer.ONE_SHOT, period=200, callback=debounce_callback)

def debounce_callback(timer):
    global debounce_timer
    debounce_timer = None

# Attach the interrupt to the button's rising edge
button.irq(trigger=Pin.IRQ_RISING, handler=button_pressed)

 

 

대부분의 코드는 이미 알고 계실 테니, 이 예제와 관련된 부분만 살펴보겠습니다.

 

이 예제에서는 원샷 타이머를 사용합니다(디바운스 타이머) 각 버튼을 누를 때마다 지정된 디바운스 기간(이 예에서는 200밀리초)이 시작됩니다.

 

debounce_timer.init(mode=Timer.ONE_SHOT, period=200, callback=debounce_callback)

 

이전 예제와 마찬가지로 푸시 버튼 핀에 인터럽트를 연결하여 트리거합니다.버튼_누름상승 모드(버튼을 눌렀을 때)에서 작동합니다.

 

button.irq(trigger=Pin.IRQ_RISING, handler=button_pressed)

 

버튼을 누르면,버튼_누름함수가 호출되어 카운터가 증가하고, LED가 켜지고, 디바운스를 위한 원샷 타이머가 시작됩니다.

 

counter += 1
print("Button Pressed! Count: ", counter)
# Toggle the LED on each button press
led.toggle()
# Start a timer for debounce period (e.g., 200 milliseconds)
debounce_timer = Timer()
debounce_timer.init(mode=Timer.ONE_SHOT, period=200, callback=debounce_callback)

 

그만큼디바운스 콜백타이머의 기능은 원샷 타이머가 만료되면 호출되어 재설정됩니다.디바운스 타이머에게 없음.

 

def debounce_callback(timer):
    global debounce_timer
    debounce_timer = None

 

타이머가 아직 만료되지 않은 경우 다른 버튼 누름이 감지되면 이는 계산되지 않습니다.디바운스 타이머재설정되지 않았습니다없음:

 

if debounce_timer is None:

 

모든 코드 부분, 특히 함수 내부에서 접근할 수 있도록 전역 변수를 활용한다는 점에 유의하세요.

 

global counter, debounce_timer # Declare variables as global

 

이것은 푸시버튼의 바운스를 해소하는 여러 방법 중 하나일 뿐입니다.

 

None 의 사용

 

Python/MicroPython에서없음는 의미 있는 값이 없음을 나타내는 자리 표시자 또는 기본값으로 자주 사용됩니다. 이전 예에서없음우리가 상태를 관리하는 데 도움이 됩니다디바운스 타이머변하기 쉬운.

 

그만큼디바운스 타이머처음에는 다음으로 설정됩니다없음현재 디바운스 타이머가 활성화되어 있지 않음을 나타냅니다.

 

debounce_timer = None

 

에서버튼_누름함수의 경우 다음 조건은 활성화된 디바운스 타이머가 없는지 확인합니다.

 

if debounce_timer is None:

 

활성 타이머가 없는 경우 (없음), 버튼 누름 동작이 수행되고 새로운 원샷 타이머가 있습니다.디바운스 타이머시작됩니다.

 

debounce_timer = Timer()

debounce_timer.init(mode=Timer.ONE_SHOT, period=200, callback=debounce_callback)

 

원샷 타이머가 만료되면디바운스 콜백함수가 호출되고 설정됩니다.디바운스 타이머돌아가다없음이는 디바운스 기간이 끝났음을 나타냅니다.

 

def debounce_callback(timer):
    global debounce_timer
    debounce_timer = None

 

 

코드 테스트

 

Raspberry Pi Pico에서 코드를 실행하세요. 푸시 버튼을 여러 번 누르세요. 더 이상 오탐(false positive)이 발생하지 않는 것을 확인할 수 있습니다. 만약 오탐(false positive)이 발생한다면, 200밀리초 디바운스 기간을 늘려야 합니다.디바운스 타이머.

 

debounce_timer.init(mode=Timer.ONE_SHOT, period=200, callback=debounce_callback)

 

라즈베리파이 피코 푸시버튼 LED 켜짐

 

타이머가 있는 RPi Pico 푸시버튼 디바운스

 

예제 4: PIR 모션 센서를 사용한 인터럽트 및 타이머

 

이 예제에서는 PIR 모션 센서와 함께 싱글샷 타이머를 사용하는 방법을 살펴보겠습니다. PIR 모션 센서를 사용하여 간단한 프로젝트를 만들어 보겠습니다. 움직임이 감지될 때마다 LED가 20초 동안 켜지고, 그 후 LED가 꺼집니다.

 

PIR 모션 센서를 이용한 LED 제어

 

PIR 모션 센서

 

수동 적외선(PIR) 모션 센서는 시야 내 물체에서 방출되는 적외선을 감지하도록 설계되었습니다. PIR 센서는 주로 생물에서 방출되는 적외선의 변화를 감지합니다. 센서 범위 내에 움직임이 있으면 감지되는 적외선의 세기가 변합니다. 아래 그림은 널리 사용되는 HC-SR501 모션 센서입니다.

 

HC-SR501 PIR 모션 센서

 

 

Raspberry Pi Pico의 PIR 모션 센서에 대한 자세한 가이드를 보려면 다음 가이드를 읽어보세요.

 

Raspberry Pi Pico: PIR 센서를 사용하여 동작 감지(MicroPython)

 

센서는 움직임을 감지하면 HIGH 신호를, 감지하지 못하면 LOW 신호를 출력합니다. PIR 센서의 디지털 출력은 Raspberry Pi Pico GPIO 핀으로 읽을 수 있으며, 이를 통해 감지된 움직임 상태에 따라 특정 동작을 프로그래밍할 수 있습니다. 이 예시에서는 단순히 LED를 켜지만, 이메일 전송, 알람 발생 등과 같은 유용한 용도로도 사용할 수 있습니다.

 

PIR 모션 센서에 대한 중요한 개념은 유지 시간 (재설정 시간 또는 센서 지연)입니다. 이는 PIR 모션 센서의 출력이 모션을 감지한 후 LOW 상태로 돌아가기 전에 HIGH를 유지하는 기간입니다.

 

PIR 모션 센서 작동 원리

 

필요한 부품

 

이 예에서는 다음 부분을 사용합니다.

 

라즈베리파이 피코 또는 라즈베리파이 피코 2

5mm LED

220Ω 저항기

PIR 모션 센서 ( Mini AM312)

브레드보드

점퍼 와이어

 

참고: 이 프로젝트에서 사용하는 Mini AM312 PIR 모션 센서는 3.3V에서 작동합니다. 하지만 HC-SR501과 같은 다른 PIR 모션 센서를 사용하는 경우 5V 에서 작동 합니다. 3.3V에서 작동하도록 수정 하거나 , USB를 통해 Raspberry Pi Pico에 5V 전원을 공급하는 경우 VBUS 핀을 통해 5V를 출력하도록 전원을 공급할 수 있습니다.

 

이 예는 푸시 버튼으로도 구현할 수 있습니다.

 

아래 그림은 Mini AM312 PIR 모션 센서의 핀아웃을 보여줍니다. 다른 모션 센서를 사용하는 경우, 회로를 조립하기 전에 해당 센서의 핀아웃을 확인하세요.

 

미니 피르 모션 센서 핀아웃

 

다음 표는 PIR 모션 센서와 Raspberry Pi Pico 간의 연결을 보여줍니다.

 

PIR 모션 센서 라즈베리파이 피코
접지 접지
데이터 모든 디지털 핀(예: GPIO 21)
3.3V 3V3(아웃)

 

회로도

 

PIR 모션 센서 데이터 핀을 GPIO 21에 연결하고 LED를 GPIO 20에 연결합니다.

 

RPi Pico LED 푸시버튼 회로

 

 

다음 코드는 PIR 모션 센서를 인터럽트로 설정합니다. 움직임이 감지되면 마지막으로 감지된 움직임 이후 20초 동안 LED가 켜집니다. 20초가 지나면 LED가 꺼지고 모션 센서가 다시 움직임을 감지할 수 있게 됩니다.

 

이 예제에서는 PIR 센서를 사용하여 움직임을 감지하는 방법을 배우는 동시에 원샷 타이머의 또 다른 응용 프로그램을 볼 수 있습니다.

 

# Rui Santos & Sara Santos - Random Nerd Tutorials
# Complete project details at https://RandomNerdTutorials.com/raspberry-pi-pico-interrupts-micropython/

from machine import Pin, Timer
import time

# PIR sensor pin
pir_pin = 21
# LED pin 
led_pin = 20

# Set up LED and PIR sensor
led = Pin(led_pin, Pin.OUT)
pir = Pin(pir_pin, Pin.IN)

# Create timer
motion_timer = Timer()

# Create timer
motion = False
motion_printed = False

def handle_motion(pin):
    global motion
    motion = True
    motion_timer.init(mode=Timer.ONE_SHOT, period=20000, callback=turn_off_led)

def turn_off_led(timer):
    global motion, motion_printed
    led.off()  # Turn off the LED
    print('Motion stopped!')
    motion = False
    motion_printed = False

# Attach interrupt to the PIR motion sensor
pir.irq(trigger=Pin.IRQ_RISING, handler=handle_motion)

while True:
    if motion and not motion_printed:
        print('Motion detected!')
        led.on()  # Turn on the LED
        motion_printed = True
    elif not motion:
        time.sleep(0.1)
        # Other tasks that you might need to do in the loop

 

코드 작동 방식

 

먼저, 각각의 GPIO 핀에 연결된 LED와 PIR 모션 센서를 선언합니다.

 

# PIR sensor pin
pir_pin = 21
# LED pin
led_pin = 20
# Set up LED and PIR sensor
led = Pin(led_pin, Pin.OUT)
pir = Pin(pir_pin, Pin.IN)

 

움직임이 감지된 후 20초가 지나면 LED가 꺼지는 타이머를 만듭니다.

 

# Create timer

motion_timer = Timer()

 

우리는 두 개의 전역 변수를 생성합니다운동, 그리고모션 프린트. 그운동변수는 코드 전체에 걸쳐 동작이 감지되었는지 여부를 알리는 것입니다.모션 프린트변수를 사용하면 '움직임이 감지되었습니다!' 메시지가 셸에 이미 인쇄되었는지 확인할 수 있습니다.

 

# Create global variables

motion = False

motion_printed = False

 

PIR 모션 센서에 상승 모드 인터럽트를 연결합니다. 즉, 움직임이 감지되면핸들_모션함수가 실행됩니다.

 

pir.irq(trigger=Pin.IRQ_RISING, handler=handle_motion)

 

ISR 작성 시 고려해야 할 사항

 

인터럽트는 인터럽트가 발생할 때 실행되는 함수인 인터럽트 서비스 루틴(ISR)에서 처리됩니다(예에서는 다음과 같습니다).핸들_모션기능). 인터럽트가 발생하면 프로세서는 하던 작업을 멈추고 일시적으로 ISR에서 작업한 후 이전에 하던 작업(메인 코드)으로 돌아갑니다.

 

ISR을 최대한 작게 구축하여 프로세서가 메인 프로그램 실행으로 빠르게 돌아갈 수 있도록 하는 것이 좋습니다. 가장 좋은 방법은 플래그나 카운터 등을 사용하여 메인 코드에 인터럽트가 발생했음을 알리는 것입니다. 여기서는운동변수는 움직임이 감지되었음을 나타내는 플래그로 사용됩니다. 그러면 메인 코드에는 움직임이 감지되었을 때 실행되기를 원하는 모든 동작(예: LED 켜기, 셸에 메시지 출력)이 포함되어야 합니다.

 

ISR 작성에 대한 자세한 내용은 여기에서 확인할 수 있습니다 .

 

코드를 진행해 보겠습니다.handle_motion 함수, 우리는 전역 변수 motion을 다음과 같이 설정합니다.진실, 코드의 모든 부분에서 동작이 감지되었음을 알 수 있도록 20초 후에 LED를 끄는 원샷 타이머를 초기화합니다.led_끄기()기능.

 

def handle_motion(pin):
    global motion
    motion = True
    motion_timer.init(mode=Timer.ONE_SHOT, period=20000, callback=turn_off_led)

 

에서하는 동안루프에서 움직임이 감지되었는지 확인합니다. 움직임이 감지되었고 아직 Shell에 메시지가 출력되지 않았다면 메시지를 출력하고 LED를 켜고모션 프린트변수에진실.

 

while True:
    if motion and not motion_printed:
        print('Motion detected!')
        led.on()  # Turn on the LED
        motion_printed = True

 

 

20000밀리초 후에LED 끄기기능이 실행되어 LED가 꺼지고 설정됩니다.운동그리고모션 프린트전역 변수거짓.

 

def turn_off_led(timer):
    global motion, motion_printed
    led.off()  # Turn off the LED
    print('Motion stopped!')
    motion = False
    motion_printed = False

 

그만큼운동변수는 다음과 같이 될 수 있습니다.진실다시 만약운동감지되고핸들_모션함수가 호출됩니다.

 

동일한 결과를 얻는 방법은 여러 가지가 있습니다. 이는 코드에서 싱글샷 타이머를 사용하는 방법을 보여주는 여러 예시 중 하나일 뿐입니다.

 

코드 테스트

 

Raspberry Pi Pico에서 이전 코드를 실행하세요. PIR 모션 센서 앞에서 손을 흔들어 보세요.

 

RPi Pico, PIR 모션 센서 테스트

 

Shell에 메시지를 인쇄하고 20초 동안 LED를 켭니다.

 

RPi Pico - PIR 모션 센서 테스트 - Thonny IDE Shell

 

20초 후에 LED가 꺼집니다.

 

RPi Pico, PIR 모션 센서 테스트

 

마무리하기

 

이 가이드에서는 MicroPython으로 프로그래밍된 Raspberry Pi Pico의 인터럽트에 대해 알아보았습니다. 외부 인터럽트와 타이머 인터럽트도 다루었습니다.

 

이 가이드와 예시가 유용했기를 바라며, 학습한 개념을 여러분의 프로젝트에 적용할 수 있기를 바랍니다.

 

MicroPython을 사용하여 Raspberry Pi Pico를 프로그래밍하고 제어하는 ​​방법에 대해 자세히 알아보려면 다음 리소스를 확인하세요.

 

MicroPython으로 Raspberry Pi Pico/Pico W 배우기 (eBook) - 책 구조와 설명을 확인할

무료 Raspberry Pi Pico 프로젝트 및 튜토리얼 

 

 

* 다음 문서 참고하고 Raspberry Pi Pico 학습 항목 리스트를 참고한다. 

 

반응형

더욱 좋은 정보를 제공하겠습니다.~ ^^