How to detect a cause of interrupt on GPIO (rise or fall) ?

zanzara
Posts: 4
Joined: Sat Jun 25, 2022 10:31 am

How to detect a cause of interrupt on GPIO (rise or fall) ?

Postby zanzara » Sat Jun 25, 2022 11:14 am

Hi there!

I work with ESP 32 (ESP-IDF) and try to detect a cause of interrupt - rising or falling edge. I know some ways to accomplish. So:
1. Use one GPIO configured as an interrupt emitter (rise and fall), after it we need to measure a voltage on GPIO (of course by ADC) - is not bad method, but needs some CPU time;
2. Use two GPIO pin tied each other by external jumper. These GPIO (configured with interrupt) have individual interrupt handlers - one for rising edge, other for falling. This way is more quickly, but needs 1 additional GPIO.

Is there a way use one GPIO to separate the cause of interrupt?

Best wishes:)

straubm
Posts: 7
Joined: Thu Jan 27, 2022 5:09 pm

Re: How to detect a cause of interrupt on GPIO (rise or fall) ?

Postby straubm » Mon Jun 27, 2022 9:09 am

I use method 1.
There is no need to read the GPIO via ADC. Simply use gpio_get_level(gpio_num_t gpio_num).
HTH

username
Posts: 537
Joined: Thu May 03, 2018 1:18 pm

Re: How to detect a cause of interrupt on GPIO (rise or fall) ?

Postby username » Mon Jun 27, 2022 10:18 am

If I understand what your asking, I believe this example does what you want.
https://github.com/espressif/esp-idf/bl ... ple_main.c

When the IRQ fires for the pin, it reads the pin level and sends that value via xQueueSendFromISR.

zanzara
Posts: 4
Joined: Sat Jun 25, 2022 10:31 am

Re: How to detect a cause of interrupt on GPIO (rise or fall) ?

Postby zanzara » Wed Jun 29, 2022 7:41 pm

straubm wrote:
Mon Jun 27, 2022 9:09 am
I use method 1.
There is no need to read the GPIO via ADC. Simply use gpio_get_level(gpio_num_t gpio_num).
HTH
Thanks a lot for the advice!
I made some tests.

Code: Select all

/* snippet 1 */
/* SOME_GPIO_ISR configured for [b]any edge[/b] interrupt firing, the pulses has active level LOW. */

    static bool wait_begin_pulse = true;

    if (!gpio_get_level(SOME_GPIO_ISR)) // is it begin of pulse?
    {
        if (wait_begin_pulse) // are we waiting for begin of pulse?
        {
            // now we are waiting end of pulse
            wait_begin_pulse = false;
            
	    	// for measuring
            gpio_set_level(ANOTHER_GPIO, 1);
            gpio_set_level(ANOTHER_GPIO, 0);
        }
        else    // previous end of pulse is missed
                // it's possible if the pulse is too short
        {
            // some code for handle this error
        }      
    }
    else    // no, it's end of pulse
    {
        if (wait_begin_pulse == false) // are we waiting for end of pulse?
        {
            // now we are waiting for begin next pulse
            wait_begin_pulse = true;
	    	// for measuring
            gpio_set_level(ANOTHER_GPIO, 1);
            gpio_set_level(ANOTHER_GPIO, 0);
        }
        else    // previous begin of pulse is missed
                // it's possible if the interval between pulses is too short
        {
            // some code for handle this error
        } 
    }
In code in snippet 2 i have to reconfigure input interrupt trigger on GPIO every interrupt event.

Code: Select all

/* snippet 2 */
/* SOME_GPIO_ISR first configured for [b]negative edge[/b] interrupt firing, the pulses has active level LOW. */
   static bool wait_begin_pulse = true;

    if (wait_begin_pulse)	// are we waiting for begin of pulse?
    {
        // reconfigure interrupt trigger for positive edge
        gpio_set_intr_type(SOME_GPIO_ISR, GPIO_INTR_POSEDGE);
	// now we are waiting for end of pulse
        wait_begin_pulse = false;
	// for measuring
        gpio_set_level(ANOTHER_GPIO, 1);
        gpio_set_level(ANOTHER_GPIO, 0);
    }
    else
    {
        // reconfigure interrupt trigger for negative edge
        gpio_set_intr_type(SOME_GPIO_ISR, GPIO_INTR_NEGEDGE);
	// now we are waiting for begin of pulse
        wait_begin_pulse = true;
	// for measuring
        gpio_set_level(ANOTHER_GPIO, 1);
        gpio_set_level(ANOTHER_GPIO, 0);
    }
    /* NOTE: In this variant missing the pulses is possible... */
 
The code in snippet 1 is more effective - about 20%.

zanzara
Posts: 4
Joined: Sat Jun 25, 2022 10:31 am

Re: How to detect a cause of interrupt on GPIO (rise or fall) ?

Postby zanzara » Wed Jun 29, 2022 7:48 pm

username wrote:
Mon Jun 27, 2022 10:18 am
If I understand what your asking, I believe this example does what you want.
https://github.com/espressif/esp-idf/bl ... ple_main.c

When the IRQ fires for the pin, it reads the pin level and sends that value via xQueueSendFromISR.
Thanks a lot! I thought there are some register with information about of the source of interrupt as in another MCUs.

Who is online

Users browsing this forum: No registered users and 45 guests