Simple Interrupt Handler

phando
Posts: 14
Joined: Wed Dec 14, 2016 5:30 am

Simple Interrupt Handler

Postby phando » Wed Dec 21, 2016 6:43 am

Welcome to the brave new world of ESP32 development.

There is very little native (non arduino) code available for the ESP32. I have been having a lot of trouble setting up an interrupt to handle buttons and sensors. In order to interact with buttons and sensors correctly, you need to take action when they are triggered. Don't fall victim to checking pin status on a loop. Checking status at a given time instead of based on events means you might miss something.

First you need to declare a function to handle the interrupt:

Code: Select all

   void gpioHandler(void* arg)


Next you have to set up a pin that is interrupt friendly:

Code: Select all

   gpio_pad_select_gpio(GPIO_INTR);
   gpio_set_direction(GPIO_INTR, GPIO_MODE_INPUT);
   gpio_set_pull_mode(GPIO_INTR, GPIO_PULLUP_ONLY);
   gpio_set_intr_type(GPIO_INTR, GPIO_INTR_NEGEDGE);
   gpio_intr_enable(GPIO_INTR);


The final step is registering the events with the function from step one:

Code: Select all

   esp_intr_alloc( ETS_GPIO_INTR_SOURCE, 0, gpioHandler, "Test", NULL);
   //gpio_isr_register(gpioHandler, "Test", 0, NULL);


Note1: Both esp_intr_alloc and gpio_isr_register work, but I am unsure which is the right one to use.

Note2: When you see the parameter 0 in my example, it is the default setting. I would rather use ESP_INTR_FLAG_EDGE or ESP_INTR_FLAG_HIGH. I was never able to get the EDGE or HIGH flags working.

The full main.c is below.

Happy coding.

Code: Select all

#include "freertos/FreeRTOS.h"
#include "esp_wifi.h"
#include "esp_system.h"
#include "esp_event.h"
#include "esp_event_loop.h"
#include "nvs_flash.h"
#include "driver/gpio.h"

#define GPIO_LED GPIO_NUM_27
#define GPIO_INTR GPIO_NUM_17

void gpioHandler(void* arg)
{
   printf("Interrupt\n");
   gpio_set_level(GPIO_LED, 1);
}

void app_main(void)
{
   nvs_flash_init();
   tcpip_adapter_init();

       gpio_pad_select_gpio(GPIO_LED);
   gpio_set_direction(GPIO_LED, GPIO_MODE_OUTPUT);
   gpio_set_level(GPIO_LED, 0);

   gpio_pad_select_gpio(GPIO_INTR);
   gpio_set_direction(GPIO_INTR, GPIO_MODE_INPUT);
   gpio_set_pull_mode(GPIO_INTR, GPIO_PULLUP_ONLY);
   gpio_set_intr_type(GPIO_INTR, GPIO_INTR_NEGEDGE);
   gpio_intr_enable(GPIO_INTR);
   esp_intr_alloc( ETS_GPIO_INTR_SOURCE, 0, gpioHandler, "Test", NULL);
   //gpio_isr_register(gpioHandler, "Test", 0, NULL);
}

ESP_Sprite
Posts: 635
Joined: Thu Nov 26, 2015 4:08 am

Re: Simple Interrupt Handler

Postby ESP_Sprite » Wed Dec 21, 2016 6:58 am

Fyi, ESP_INTR_FLAG_HIGH does not work because you can't write interrupt handlers for high-level interrupts in C. I'm not entirely sure why edge interrupts do not work with the GPIO, but my guess would be that the GPIO hardware only does level interrupts.

Ah, reading your other topic I think you were under the impression that the ESP_INTR_FLAG_EDGE/HIGH flags would generate an interrupt when the GPIO itself has an edge or is high. This is not true: the HIGH flag selects an interrupt with a high priority (which does not work herebecause you can't write a handler for that in C) and the EDGE flag governs the interrupt line *between the CPU core and the GPIO peripheral*. To do what you want, please leave the flags as they are and use gpio_set_intr_type instead,

Also, esp_intr_alloc and gpio_isr_register are basically equivalent (gpio_isr_register actually directly calls esp_intr_alloc) but if you use the gpio driver, it's usually better to register your interrupt through that: it may in the future do some gpio-specific underlying magic that esp_intr_alloc does not.

ricardoquesada
Posts: 1
Joined: Tue Sep 27, 2016 4:25 am

Re: Simple Interrupt Handler

Postby ricardoquesada » Fri Jan 06, 2017 3:45 pm

thanks.

is gpio_pad_select_gpio() needed if you use the "driver" API?
it seems that gpio_pad_select_gpio() belongs to the "rom" API and I guess it is needed if you use that set of APIs.

BTW, why what's the difference between the "driver" and the "rom" APIs ? Which one should we use ?


Also, were you able to use printf() from the interrupt handler? Everytime that I do a printf() or similar it crashes.

rom API:
https://github.com/espressif/esp-idf/bl ... rom/gpio.h

driver API:
https://github.com/espressif/esp-idf/bl ... ver/gpio.h

User avatar
kolban
Posts: 680
Joined: Mon Nov 16, 2015 4:43 pm
Location: Texas, USA

Re: Simple Interrupt Handler

Postby kolban » Mon Jan 16, 2017 9:20 pm

I'm not sure that this sample still holds true. I think there was some re-architecture in the APIs and methods relating to interrupt service routines. This is the code fragment/sample I have been using:

https://github.com/nkolban/esp32-snippe ... est_intr.c
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32

Who is online

Users browsing this forum: No registered users and 2 guests