이 블로그는 Web 환경을 이용한 원격 제어 기술에 필요한 지식을 공유 하기 위한 블로그 입니다.
실제 개발과 프로그램 예를 위하여 WiFi Module과 Raspberry Pi, Raspberry Pi Pico, ATmega128 보드, Arduino Mega 보드(ATmega2560)를 사용 합니다.

python-gpio-interrupt

ESP32 GPIO control - MicroPython
ESP8266/ESP32 GPIO Port와 Interrupt - MicroPython


  • ESP8266/ESP32 GPIO Port
    • Pin object(class Pin)
      • Pin 개체는 I/O Pin을 제어하는 데 사용된다. Pin 클래스에는 Pin 모드(IN, OUT 등)를 설정하는 메서드와 디지털 값을 가져오고(Input) 설정(Output)하는 메서드가 있다.

        여기에서는 자주시용하는 항목과 Methods만 요약하여 설명한다. 전체 자료는 아래 참고자료를 참고하기 바람.

      • Pin object 생성자(Constructors): class machine.Pin(id, mode=- 1, pull=- 1, *, value, drive, alt)
        • id: Pin 식별자로 필수 인수(다른 인수는 선택 사항)이다. 가능한 값 유형은 int(핀을 식별하는 정수), str(핀 이름), tuple([port, pin]) 이다.
        • mode: 핀 모드 설정 값으로 Pin.IN, Pin.OUT, Pin.OPEN_DRAIN 등으로 설정할 수 있다.
        • pull: pull up 저항의 시용여부를 설정한다. None, Pin.PULL_UP,Pin.PULL_DOWN 중 하나로 설정한다.
        • value: Pin.OUT 과 Pin.OPEN_DRAIN 모드에서만 유효하다.
        • GPIO2를 Output Pin으로 설정하는 예
        • from machine import Pin

          p2 = Pin(2, Pin.OUT)

      • Methods
        • Pin.init(mode=- 1, pull=- 1, *, value, drive, alt): 주어진 매개 변수를 사용하여 핀을 다시 초기화한다. 지정된 인수 만 설정된다. 나머지 핀 주변 장치 상태는 변경되지 않는다.
        • Pin.value([x]): 핀 값을 설정(Pin.OUT 모드)하거나 갖어(Pin.IN 모드) 오는 경우에 시용한다. 만약 인수가 샹략된 경우 핀의 디지털 값을 갖어 온다.
        • Pin.on(): 핀을 디지털 값 "1"로 설정한다.
        • Pin.off(): 핀을 디지털 값 "0"로 설정한다.
        • Pin.mode([mode]): 핀 모드를 설정하거나 갖어(인수가 없는 경우) 온다.
        • Pin.pull([pull]): 핀 상태를 설정하거나 갖어(인수가 없는 경우) 온다.
        • Pin.irq(handler=None, trigger=Pin.IRQ_FALLING | Pin.IRQ_RISING, *, priority=1, wake=None, hard=False)
          • 핀의 트리거 소스가 활성화 될 때 호출 할 인터럽트 핸들러를 구성한다. 핀 모드가 Pin.IN 이면 트리거 소스는 핀의 외부 값 이다. 핀 모드가 Pin.OUT 이면 트리거 소스는 핀의 출력 버퍼이다.

          • handler: 인터럽트가 트리거 될 때 호출되는 함수(생략될 수도 있음)이다.
          • trigger: 인터럽트가 발생하는 조건을 설정한다. 가능한 값은 Pin.IRQ_FALLING, Pin.IRQ_RISING, Pin.IRQ_LOW_LEVEL, Pin.IRQ_HIGH_LEVEL 이다. 이 값은 OR'ed 되기 때문에 하나 이상의 조건에서 인터럽트가 트리거 되게 설정할 수 있다.
          • priority: 인터럽트의 우선 순위를 설정한다. 취할 수있는 값은 포트 별로 다르지만 더 높은 값이 더 높은 우선 순위를 갖는다.
      • 핀 설정에 서용하는 상수(Constants)
        • 핀 모드를 설정하는 데 사용하는 상수: Pin.IN, Pin.OUT, Pin.OPEN_DRAIN
        • Pull up 저항을 설정하는 데 사용하는 상수: Pin.PULL_UP, Pin.PULL_DOWN, Pin.PULL_HOLD
        • 인터럽트(IRQ) 트리거 타입을 설정하는 데 사용하는 상수: Pin.IRQ_FALLING, Pin.IRQ_RISING, Pin.IRQ_LOW_LEVEL, Pin.IRQ_HIGH_LEVEL

        참고자료: MicroPython libraries(class Pin – control I/O pins)

    • ESP32 개발보드에 내장된 Switch(Push button)와 LED
      • ESP32 개발보드에 내장된 SW(GPIO0)와 LED(GPIO2) 위치

    • 프로그램 예: Switch(Push button)와 LED
      • 이 프로그램은 Pin object를 생성하고 Method를 사용하는 가장 기본이 되는 예 이다.

        Switch의 상태를 LED에 출력하는 프로그램 예: sw_status_led.py

        
        from machine import Pin
        from time import sleep_ms
        
        # NodeMCU 보드는 GPIO0을 SW input pin으로 사용한다.
        button = Pin(0, Pin.IN, Pin.PULL_UP)
        # NodeMCU 보드는 GPIO2를 LED Pin으로 사용한다.
        led = Pin(2, Pin.OUT)
        
        # Switch의 상태를 LED에 출력하는 무한 Loop
        while True:
          # NodeMCU ESP8266 보드는 LED Pin이 High일 때 Off 되고 Low일 때 On 됨.
          # NodeMCU ESP32 보드는 LED Pin이 High일 때 On 되고 Low일 때 Off 됨.
          # 기타 보드는 다른 GPIO Pin을 LED Pin으로 사용할 수 있으니 확인이 필요하다.
          # 만약 button(GPIO0)가 눌린 상태이면 LED를 On 하고
          if button.value() == 0:
            led.value(1) # LED(pin2)-> High. ESP8266 -> Off, ESP32 -> On
          # 아니면 LED를 Off 한다.
          else:
            led.value(0) # LED(pin2)-> Low. ESP8266 -> On, ESP32 -> Off
          sleep_ms(50)   # Sleep for 50 milliseconds
                  
      • 실험을 위한 준비
        • LED: 개발보드에 내장(GPIO2)되어 있기 때문에 별도의 회로를 필요로 하지 않는다.
        • Button switch: 개발보드에 내장(GPIO0)되어 있기 때문에 별도의 회로를 필요로 하지 않는다.
      • 실험 방법
        • Thonny IDE를 실행하고 Thonny IDE의 사용 환경(Thonny 실행에 사용할 장치와 COM Port 선택)이 바르게 되어 있는지 확인한다.
        • 참고자료: "Thonny IDE 개발보드 사용 환경 설정하기"

        • Thonny IDE의 Python shell 창에 prompt( >>> )가 출력되었는 확인한다.
        • 위 프로그램을 복사하여 Thonny IDE의 Script 편집 창에 복사한다.
        • Script 편집 창의 프로그램을 File name "sw_status_led.py"로 저장 한다.
        • 실험
          • "실행 -> 현재 스크립트 실행"을 실행하거나 Toolbar의 "실행" Icon을 클릭하면 스크립트가 개발보드에 전송되고 프로그램이 실행된다.
          • 개발보드의 BOOT 버튼(GPIO0 Pin을 사용함)을 누르면 ESP32 보드인 경우 LED(GPIO2)가 On 되고 누르지 않으면 Off 상태가 된다. ESP8266 보드는 누르면 LED(GPIO2)가 Off 되고 누르지 않으면 On 상태가 된다.

  • 외부 인터럽트(External interrupt)
    • ESP8266/ESP32의 GPIO Pin은 외부 신호를 받아 이 신호에 대응하는 인터럽트(External interrupt)를 발생 시키는 목적으로 사용 할 수 있다.

    • 프로그램 예: Switch Counter(Bouncing 현상 이해)
      • Switch를 누른 회수를 카운트(External interrupt를 이용)하여 콘솔창에 출력하는 프로그램 예 이다.

        프로그램 예: "switch_counter_interrupt.py

        
        from machine import Pin
        from time import sleep_ms
        
        # NodeMCU 보드는 GPIO0을 SW input pin으로 사용한다.
        button = Pin(0, Pin.IN, Pin.PULL_UP)
        swCounter = 0
        
        # Switch를 누르면 발생하는  external interrupt handler
        def button_callback(pin):
            global swCounter
            swCounter += 1
            print("Counter: " + str(swCounter))
        
        # Pin object의 irq Method를 사용하여 External interrupt에 필요한 설정을 한다.
        # 아래 설정은 버튼을 Push 할 때(Falling edge) Interrupt가 발생하게하고,
        # Interrupt handler의 이름을 button_callback으로 설정한다.
        button.irq(trigger=Pin.IRQ_FALLING, handler=button_callback)
                  
      • 실험을 위한 준비
        • LED: 개발보드에 내장(GPIO2)되어 있기 때문에 별도의 회로를 필요로 하지 않는다.
        • Button switch: 개발보드에 내장(GPIO0)되어 있기 때문에 별도의 회로를 필요로 하지 않는다.
      • 실험 방법
        • Thonny IDE를 실행하고 Thonny IDE의 사용 환경(Thonny 실행에 사용할 장치와 COM Port 선택)이 바르게 되어 있는지 확인한다.
        • Thonny IDE의 Python shell 창에 prompt( >>> )가 출력되었는 확인한다.
        • 위 프로그램을 복사하여 Thonny IDE의 Script 편집 창에 복사한다.
        • Script 편집 창의 프로그램을 File name "switch_counter_interrupt.py"로 저장 한다.
        • 실험
          • "실행 -> 현재 스크립트 실행"을 실행하거나 Toolbar의 "실행" Icon을 클릭하면 스크립트가 개발보드에 전송되고 프로그램이 실행된다.
          • 개발보드의 BOOT 버튼(GPIO0 Pin을 사용함)을 누르면 콘솔창에 버튼을 누른 회수가 출력된다. 이 실험에서 버튼을 한번 눌러도 경우에 따라 카운터 값이 1 이상 증가 할 수(Bouncing 현상 때문) 있다.

        주: 스위치의 물리적인 결함 때문에 스위치를 누르거나 뗄 때 Bouncing 현상이 발생할 수 있다.

        참고자료: Switch의 Bouncing 현상과 Debouncing 기술

        참고자료: Timer를 이용한 Debouncing - MicroPython

    • 프로그램 예: External Interrupt(SW)를 이용한 LED 제어
      • Switch를 누르면 LED의 상태가 Toggle(현재 상태가 On 이면 Off 상태로, Off 상태인 경우는 On 상태로 됨)되는 프로그램 예 이다.

        프로그램 예: "switch_toggle_led_interrupt.py

        
        from machine import Pin
        from time import sleep_ms
        
        # NodeMCU 보드는 GPIO2를 LED Pin으로 사용한다.
        led = Pin(2, Pin.OUT)
        # NodeMCU 보드는 GPIO0을 SW input pin으로 사용한다.
        button = Pin(0, Pin.IN, Pin.PULL_UP)
        
        # LED를 Turn on 한다.
        # LED(pin2)-> High. ESP8266 -> Off, ESP32 -> On
        led.value(1)
        
        # Switch를 누르면 발생하는  external interrupt handler
        def button_callback(pin):
          led.value(not led.value()) # LED Toggle
        
        # Pin object의 irq Method를 사용하여 External interrupt에 필요한 설정을 한다.
        # 아래 설정은 버튼을 Push 할 때(Falling edge) Interrupt가 발생하게하고,
        # Interrupt handler의 이름을 button_callback으로 설정한다.
        button.irq(trigger=Pin.IRQ_FALLING, handler=button_callback)
                  
      • 실험을 위한 준비
        • LED: 개발보드에 내장(GPIO2)되어 있기 때문에 별도의 회로를 필요로 하지 않는다.
        • Button switch: 개발보드에 내장(GPIO0)되어 있기 때문에 별도의 회로를 필요로 하지 않는다.
      • 실험 방법
        • Thonny IDE를 실행하고 Thonny IDE의 사용 환경(Thonny 실행에 사용할 장치와 COM Port 선택)이 바르게 되어 있는지 확인한다.
        • Thonny IDE의 Python shell 창에 prompt( >>> )가 출력되었는 확인한다.
        • 위 프로그램을 복사하여 Thonny IDE의 Script 편집 창에 복사한다.
        • Script 편집 창의 프로그램을 File name "switch_toggle_led_interrupt.py"로 저장 한다.
        • 실험
          • "실행 -> 현재 스크립트 실행"을 실행하거나 Toolbar의 "실행" Icon을 클릭하면 스크립트가 개발보드에 전송되고 프로그램이 실행된다.
          • 개발보드의 BOOT 버튼(GPIO0 Pin을 사용함)을 누르면 LED의 상태가 Toggle 된다.

  • ESP8266/ESP32 GPIO Port와 Interrupt 관련 페이지 보기