Skip to content

Multiple rising or falling edges detected in a row with gpio_set_irq_enabled_with_callback #141

@BenoitVII

Description

@BenoitVII

Hello guys,

I'm currently trying to use external pin interrupts with the pico. I try to detect both rising and falling edges, and my issue is that the result is not consistent. My goal is to read a rotary encoder input so I attached GPIO10 to pinA of my encoder.

I expect to have a perfect "rising / falling / rising / falling / ... " pattern, as the pin will be alternatively pulled either high or low while I turn the encoder (it should be the case with all kind of inputs, as the pin will always go from high to low and from low to high, not from high to high or from low to low, which doesn't make any sense).

However, i'm not getting that, and multiple rising or falling edges are detected in a row as you can see with the putty output:
image
(You can spot sometimes I have 2 or 3 "0"s or "1"s corresponding to falling or rising edges).

Bellow is the code producing this. I retrieved the gpio_event_string function from the pico-example repository, and adapted the output to make it clearer.

#include <stdio.h>
#include "pico/stdlib.h"

static char event_str[128];

void gpio_event_string(char *buf, uint32_t events);


//callback for rising/falling edge.
void gpio_callback(uint gpio, uint32_t events)
{
    //get a string of what happened during this callback
    gpio_event_string(event_str, events);
    printf("%s", event_str);
}


int main()
{
    //init serial for debug
    stdio_init_all();

    // use pull-up
    gpio_init(10);
    gpio_pull_up(10);
    // register callback on both rising and falling edges.
    gpio_set_irq_enabled_with_callback(10, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL, true, &gpio_callback);
    
    while(1){
        //do nothing.
    }
}


static const char *gpio_irq_str[] = {
    "LEVEL_LOW",  // 0x1
    "LEVEL_HIGH", // 0x2
    "0",  // 0x4 edge fall
    "1"   // 0x8 edge rise
};

//retrieved from pico-example
void gpio_event_string(char *buf, uint32_t events)
{
    for (uint i = 0; i < 4; i++)
    {
        uint mask = (1 << i);
        if (events & mask)
        {
            // Copy this event string into the user string
            const char *event_str = gpio_irq_str[i];
            while (*event_str != '\0')
            {
                *buf++ = *event_str++;
            }
            events &= ~mask;
        }
    }
    *buf++ = '\0';
}

Thank you!

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions