Movatterモバイル変換


[0]ホーム

URL:


Skip to content
HOMEESP32ESP8266ESP32-CAMRASPBERRY PIMICROPYTHONRPi PICOARDUINOREVIEWS

MicroPython: Interrupts with ESP32 and ESP8266

Learn how to configure and handle interrupts using MicroPython firmware with ESP32 and ESP8266 boards. You’ll also build a project example with a PIR Motion Sensor.

Prerequisites

To follow this tutorial you need MicroPython firmware flashed in your ESP32 or ESP8266. You also need an IDE to write and upload the code to your board. We suggest using Thonny IDE or uPyCraft IDE:

Introducing Interrupts

Interrupts are useful for making things happen automatically in microcontroller programs and can help solve timing problems. With interrupts you don’t need to constantly check the current pin value. When a change is detected, an event is triggered (a function is called).

When an interrupt happens, the processor stops the execution of the main program to execute a task, and then gets back to the main program as shown in the figure below.

This is especially useful to trigger an action whenever motion is detected or whenever a pushbutton is pressed without the need for constantly checking its state.

ESP32 interrupt pins: you can use all GPIOs as interrupts, except GPIO 6 to GPIO 11.

ESP8266 interrupt pins: you can use all GPIOs, except GPIO 16.

Set Up an Interrupt in MicroPython

To setup an interrupt in MicroPython, you need to follow the next steps:

1. Define an interrupt handling function. The interrupt handling function should be as simple as possible, so the processor gets back to the execution of the main program quickly. The best approach is to signal the main code that the interrupt has happened by using a global variable, for example. The interrupt handling function should accept a parameter of typePin. This parameter is returned to the callback function and it refers to the GPIO that caused the interrupt.

def handle_interrupt(pin):

2. Setup the GPIO that will act as an interrupt pin as an input. For example:

pir = Pin(14, Pin.IN)

3.Attach an interrupt to that pin by calling theirq() method:

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

Theirq() method accepts the following arguments:

  • trigger: this defines the trigger mode. There are 3 different conditions:
    • Pin.IRQ_FALLING: to trigger the interrupt whenever the pin goes from HIGH to LOW;
    • Pin.IRQ_RISING: to trigger the interrupt whenever the pin goes from LOW to HIGH.
    • 3: to trigger the interrupt in both edges (this means, when any change is detected)
  • handler: this is a function that will be called when an interrupt is detected, in this case thehandle_interrupt() function.

Project Example with PIR Motion Sensor

To demonstrate how to handle interrupts, we’ll build a simple project with a PIR motion sensor. Whenever motion is detected we’ll light up an LED for 20 seconds.

pir motion sensor micropython esp32 esp8266

Parts required

Here’s a list of the parts you need to build the circuit:

You can use the preceding links or go directly toMakerAdvisor.com/tools to find all the parts for your projects at the best price!

Schematic – ESP32

Follow the next schematic diagram if you’re using an ESP32 board:

Schematic – ESP8266

Follow the next schematic diagram if you’re using an ESP8266 board:

Important: theMini AM312 PIR Motion Sensor we’re using in this project operates at 3.3V. However, if you’re using another PIR motion sensor like theHC-SR501, it operates at 5V. You can eithermodify it to operate at 3.3V or simply power it using the Vin pin.

In the figure below, we provide the pinout for the Mini AM312 PIR motion sensor. If you’re using another motion sensor, please check its pinout before assembling the circuit.

mini-pir-pinout-am312

Code

Here’s the script that detects motion and lights up an LED whenever motion is detected. This code is compatible with both the ESP32 and ESP8266.

# Complete project details at https://RandomNerdTutorials.comfrom machine import Pinfrom time import sleepmotion = Falsedef handle_interrupt(pin):  global motion  motion = True  global interrupt_pin  interrupt_pin = pin led = Pin(12, Pin.OUT)pir = Pin(14, Pin.IN)pir.irq(trigger=Pin.IRQ_RISING, handler=handle_interrupt)while True:  if motion:    print('Motion detected! Interrupt caused by:', interrupt_pin)    led.value(1)    sleep(20)    led.value(0)    print('Motion stopped!')    motion = False

View raw code

How the code Works

To use interrupts, import thePin class from themachine module. We also import thesleep method from thetime module to add a delay in our script.

from machine import Pinfrom time import sleep

Create a variable calledmotion that can be either True of False. This variable will indicate whether motion was detected or not (this is the global variable that will be changed on the interrupt handling function).

motion = False

Then, create a function calledhandle_interrupt.

def handle_interrupt(pin):  global motion  motion = True  global interrupt_pin  interrupt_pin = pin

This function will be called every time motion is detected. Thehandle_interrupt function has an input parameter (pin) in which an object of classPin will be passed when the interrupt happens (it indicates which pin caused the interrupt).

Here we’re saving the pin that caused the interrupt in theinterrupt_pin variable. In this case, it is not very useful because we only have one interrupt pin. However, this can be useful if we have several interrupts that trigger the same interrupt handling function and we want to know which GPIO caused the interrupt.

In our example, thehandle_interrupt function simply changes themotion variable toTrue and saves the interrupt pin. You should keep your handling interrupt functions as short as possible and avoid using theprint() function inside. Then, the main code should have all the things we want to happen when the interrupt happens.

Note: as you wantmotionto be usable both inside the function and throughout the code, it needs to be declared as global. Otherwise, when motion is detected nothing would happen, because themotion variable would be changing inside the function and not in the main body of the code.

Proceeding with the code, we need to create two Pin objects. One for the LED onGPIO 12, and another for the PIR motion sensor onGPIO 14.

led = Pin(12, Pin.OUT)pir = Pin(14, Pin.IN)

Then, set an interrupt on thepir by calling theirq() method.

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

In theloop(), when themotionvariable is True, we turn the LED on for 20 seconds and print a message that indicates that motion was detected and which pin caused the interrupt.

if motion:  print('Motion detected! Interrupt caused by:', interrupt_pin)  led.value(1)  sleep(20)

After 20 seconds, turn the LED off, and print a message to indicate that motion stopped.

led.value(0)print('Motion stopped!')

Finally, set themotion variable to False:

motion = False

Themotion variable can only become True again, if motion is detected and thehandle_interrupt function is called.

For simplicity, in this example we use a delay to keep the LED on for 20 seconds. Ideally, you should use timers.

Demonstration

Upload the code to your ESP32/ESP8266 board. The LED should turn on for 20 seconds when motion is detected, and a message should be printed in the Shell.

After 20 seconds the LED turns off.

Note: the AM312 PIR motion sensor has a default delay time of 8 seconds. This means that it won’t be triggered before 8 seconds have passed since the last trigger.

Wrapping Up

We hope you’ve found this article interesting. We’ve learned how to:

  • setup a pin as an interrupt
  • handle that interrupt in your code
  • detect which GPIO pin caused the interrupt

In our example, we’ve used a PIR motion sensor to trigger the interrupt. But the example presented can also be used to detect a button press, for example.

If you like programming the ESP32 and ESP8266 boards with MicroPython, and you want to learn more, please take a look at the following resources:



SMART HOME with Raspberry Pi ESP32 and ESP8266 Node-RED InfluxDB eBook
Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »
Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »

Enjoyed this project? Stay updated by subscribing our newsletter!

9 thoughts on “MicroPython: Interrupts with ESP32 and ESP8266”

  1. Would it be possible to wake the esp32 from deepsleep with these interrupts?

    Reply
    • Hi Seth.
      Yes, I think you can, but I haven’t tried it yet.
      It seems that you can pass a wake parameter when defining the interrupt and it can be:
      – machine.IDLE
      – machine.SLEEP
      – machine.DEEPSLEEP

      See more information here:
      docs.micropython.org/en/v1.8.7/esp8266/library/machine.Pin.html?highlight=pin#machine.Pin.irq

      Regards,
      Sara

      Reply
  2. On a somewhat related topic, has anyone (else) had issues with debounce on the ESP32 with reed switches? I’m using an anemometer with a reed switch to fire an interrupt, and for some reason every time I get a falling edge interrupt (I’ve got the GPIO pin held high), it triggers between 1 and 4 interrupts. I’m using an adafruit HUZZAH32, and GPIO21.

    Reply
  3. Does Micro-Python support interrupt on ‘both’ rising and falling edge? I am sensing a damper in my HVAC system to monitor blower on off. Rising edge = timestamp start of blower cycle, falling edge = timestamp end of blower cycle. Can I do this with one input or do I need to use two inputs one for rising one for falling?

    Reply
    • Hi Brian.
      There are 3 different conditions:
      Pin.IRQ_FALLING: to trigger the interrupt whenever the pin goes from HIGH to LOW;
      Pin.IRQ_RISING: to trigger the interrupt whenever the pin goes from LOW to HIGH.
      3: to trigger the interrupt in both edges (this means, when any change is detected)

      So, yes. It supports both at the same time.
      Regards,
      Sara

      Reply
  4. you can add 200 ms of delay in ISR function before enabling using machine.enable_irq(state)
    that will prevent interrupt to occur again and again.

    Reply
  5. Hi people. Can NodeMcu 32 work with UART interrupts ??? May I use UART.IRQ (…)???
    I can’t find how to do that..
    Thanks .. !

    Reply

Leave a CommentCancel reply

Learn MicroPython

MicroPython Introduction

Thonny IDE Install

VS Code Install

Flash Firmware esptool.py

MicroPython Programming

MicroPython GPIOs

ESP32 Pinout

MicroPython Inputs Outputs

MicroPython PWM

MicroPython Analog Inputs

MicroPython Interrupts

ESP32 Deep Sleep

ESP8266 Deep Sleep

Web Servers

MicroPython Output Web Server

MicroPython Relay Web Server

MicroPython DHT Web Server

MicroPython BME280 Web Server

MicroPython BME680 Web Server

MicroPython DS18B20 Web Server

Sensors and Modules

MicroPython Relay Module

MicroPython PIR

MicroPython DHT11/DHT22

MicroPython BME280

MicroPython BME680

MicroPython DS18B20

MicroPython Multiple DS18B20

Weather Station Datalogger

MicroPython OLED

MicroPython OLED Draw Shapes

MicroPython WS2812B LEDs

MicroPython HC-SR04

MQTT

MicroPython MQTT Introduction

MQTT DHT11/DHT22

MQTT BME280

MQTT BME680

MQTT DS18B20

Useful Guides

MicroPython Access Point

MicroPython WiFiManager

uPyCraft IDE Windows

uPyCraft IDE Mac OS X

uPyCraft IDE Linux

Flash MicroPython Firmware

Learn More

Learn ESP32

Learn ESP8266

Learn ESP32-CAM

Learn MicroPython

Learn Arduino

MicroPython eBook »

Affiliate Disclosure:Random Nerd Tutorials is a participant in affiliate advertising programs designed to provide a means for us to earn fees by linking to Amazon, eBay, AliExpress, and other sites. We might be compensated for referring traffic and business to these companies.



Learn ESP32 with Arduino IDE eBook » Complete guide to program the ESP32 with Arduino IDE!



SMART HOME with Raspberry Pi, ESP32, and ESP8266 » learn how to build a complete home automation system.



Learn Raspberry Pi Pico/Pico W with MicroPython​ » The complete getting started guide to get the most out of the the Raspberry Pi Pico/Pico W (RP2040) microcontroller board using MicroPython programming language.



🔥 Learn LVGL: Build GUIs for ESP32 Projects​ » Learn how to build Graphical User Interfaces (GUIs) for ESP32 Projects using LVGL (Light Versatile Graphics Library) with the Arduino IDE.

Download Our Free eBooks and Resources

Get instant access to our FREE eBooks, Resources, and Exclusive Electronics Projects by entering your email address below.


[8]ページ先頭

©2009-2025 Movatter.jp