joan2937 / pigpio

pigpio is a C library for the Raspberry which allows control of the General Purpose Input Outputs (GPIO).
The Unlicense
1.47k stars 410 forks source link

DMA polling for interrupt only partially detects 50us pulses #525

Closed pcdangio closed 2 months ago

pcdangio commented 2 years ago

I'm using the pigpio interrupt feature to detect 50us pulses from an IMU that signals when data is ready to read. From the pigpio documentation, it seems that the default DMA sampling frequency for detecting edges is set to 5us. In my testing, however, the interrupt is unable to catch many of the 50us-wide interrupt pulses being generated.

I set the IMU to push data out at 1000Hz, 500Hz, and then 100Hz over three separate tests. On my RPi3B+ running the latest version of pigpio, I had the interrupt print out a timestamp each time an interrupt was detected. At 1000Hz, i got ~70% of the interrupts. at 100Hz, i got only ~25% of the interrupts.

Afterwards, I configured the IMU to instead hold the interrupt line high until data was read from it. When I implemented this, I was able to catch every single interrupt at 100Hz, 500Hz, and even 1000Hz. This is what leads me to believe that somehow the DMA polling is unable to reliably catch the 50us width that the IMU was generating originally.

EDIT: I love pigpio!!

joan2937 commented 2 years ago

The DMA polling defaults to 5µs. It will capture all edges 5µs or longer.

gpioSetISRFunc is a wrapper around Linux interrupts. Linux on the Pi can not handle multiple GPIO interrupts in close succession (although the /dev/gpiochip interace is an improvement over sysfs which gpioSetISRFunc currently uses).

Have you tried using gpioSetAlertFunc?

pcdangio commented 2 years ago

Thanks for the reply! I have not tried gpioSetAlertFunc... out of curiosity what makes the alerts work better than the ISRs in this scenario?

joan2937 commented 2 years ago

Alerts are fed from the DMA sampling stream. They should see everyting longer than the sampling period. They are also delivered in time order. The downside is the roughly half a millisecond latency as they are processed every millisecond.

ISR is fed from the Linux interrupt system. They may have less latency (around 50 µs potentially) but on sysfs (which pigpio uses) only a couple can be queued and short edges are not picked up. If we ever change to /devgpiozero more may be queued but short edges are still missed.