Electronics > Microcontrollers

Counting pulses on ESP32 with ESP-IDF

(1/2) > >>

reyntjensm:
I want to measure incoming GPIO pulses and the time between each pulse. Max pulse rate is 15000 pulses/min so it's relatively slow. I already made the code for this with another micro controller and this is working fine with a simple polling strategy and interrupts. Right now i would like to use an ESP32 with freertos. As i don't have much experience with freertos i can't figure out what would be the best solution for this.

I'm using the PCNT functionalities on the ESP32 to count the pulses. But i still need to give every pulse a timestamp. I guess using timers would be a better solution to this?

What is the best way to signal my task (this task prints data to the terminal) for a new pulse/data available?

PlainName:
Are you triggering an interrupt with the GPIO? If so I think your best option in the ISR handler is to use xTaskNotifyFromISR() to let your task know there's something happening, and xTaskNotifyWait() in the task to wait for the signal.

The time when you hit the ISR is more important than when the task runs, so these functions allow you to pass a 32-bit value, which can be the time offset in whatever scale you want to use. You can do stuff like reserve a bit in the notification value (so use 31-bits for the time) and use that to notify either end if the logging task missed a notify call.

Timing: the standard FreeRTOS clock might not have enough resolution for your purposes, but if it does then the built-in TickType_t has useful functions and is reasonable slim. I though there was a higher-res clock source but I don't have access to the dox at the moment, so might be thinking of a different processor! Either way, you might need to trim the top bits to get everything into the 32-bit notify value. Also note that the task tick is pretty slow on the ESP-IDF, and that might affect how quickly the log task can deal with the ISR notify, although at 40ms between interrupts it should manage.

reyntjensm:

--- Quote from: PlainName on October 02, 2023, 09:40:56 pm ---Are you triggering an interrupt with the GPIO? If so I think your best option in the ISR handler is to use xTaskNotifyFromISR() to let your task know there's something happening, and xTaskNotifyWait() in the task to wait for the signal.

The time when you hit the ISR is more important than when the task runs, so these functions allow you to pass a 32-bit value, which can be the time offset in whatever scale you want to use. You can do stuff like reserve a bit in the notification value (so use 31-bits for the time) and use that to notify either end if the logging task missed a notify call.

Timing: the standard FreeRTOS clock might not have enough resolution for your purposes, but if it does then the built-in TickType_t has useful functions and is reasonable slim. I though there was a higher-res clock source but I don't have access to the dox at the moment, so might be thinking of a different processor! Either way, you might need to trim the top bits to get everything into the 32-bit notify value. Also note that the task tick is pretty slow on the ESP-IDF, and that might affect how quickly the log task can deal with the ISR notify, although at 40ms between interrupts it should manage.

--- End quote ---

I'm not using interrupts right now. The PCNT module is some specific hardware used for counting pulses... It increments a certain register without interrupting the whole system. It's pretty useful for my application as it has glitch filters built in.
https://docs.espressif.com/projects/esp-idf/en/v4.3/esp32/api-reference/peripherals/pcnt.html#

nctnico:
If the PCNT has a driver that can create a callback when an event happens, you can use esp_timer_impl_get_counter_reg() to get a 64 bit monotonic timestamp (you have to divide by 16000 to get milli-seconds on the ESP32S3).

Another option is to use a timer interrupt callback and do polling from there: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/gptimer.html

PlainName:

--- Quote ---I'm not using interrupts right now. The PCNT module is some specific hardware used for counting pulses...
--- End quote ---

Not used it but had a quick look at your link. Your problem isn't the counting but timestamping, and the reason you want to do that determines how you could use this. For instance, if you don't need to log every transition but could go with an average, you could get the PCNT to interrrupt after, say, 5 transitions to trigger your log task. The interrupt times would then have a better average accuracy than doing them individually (actually, it would remove jitter caused by capture resolution), but the downside is it would be an average over 200ms.

Re interrupts: I don't think you will be able to timestamp usefully unless you use interrupts but, again, it depends on why you want the timestamps. Perhaps you could expand on that?

Navigation

[0] Message Index

[#] Next page

There was an error while thanking
Thanking...
Go to full version
Powered by SMFPacks Advanced Attachments Uploader Mod