Page 1 of 1

Need Working Example for MCPWM Capture (or RMT) to Measure Frequency on GPIO36 – ESP32-WROOM32 / ESP-IDF v5.2.5

Posted: Tue Jun 03, 2025 12:59 am
by williankleber
Hi everyone,

I’m stuck trying to measure the frequency of a digital pulse signal on GPIO36 of an ESP32-WROOM32 (ESP-IDF v5.2.5). I hoped to use the MCPWM capture mode, but after days with the official docs and scattered snippets I still don’t have a working solution—and I haven’t found any up-to-date example code.
What I need
  • Signal: square-wave on GPIO36
  • Frequency range: 10 Hz – 1 kHz
  • Edge: rising edge is fine (falling or both would also work)
  • Task context: runs every 500 ms (void taskCalcFlowmetterPulses(void *pvParameters))
  • Output: update a global volatile float frequency with at least two decimal places of precision
  • Project constraints: no other timers or peripherals compete for GPIO36; I’m free to pick MCPWM capture channel, timer, etc.
Why PCNT isn’t enough
I first tried the PCNT peripheral: every 500 ms I read the pulse count and divide by the window. That’s too coarse at low frequencies (e.g. at 10 Hz I see only ≈5 pulses in 0.5 s, giving ±10–20 % error). I need sub-1 % accuracy across the range, so I’d rather measure the period between edges in hardware—hence MCPWM capture (or RMT if that’s simpler).

What I tried (and where it fails)
1 - MCPWM capture
  • Routed GPIO36 to MCPWM_UNIT_0, MCPWM_CAP_0.
  • Configured .cap_edge = MCPWM_POS_EDGE, .cap_prescale = 1.
  • ISR collects timestamps, task averages periods.
  • Result: driver throws ESP_ERR_INVALID_ARG on mcpwm_new_capture_channel() if I follow examples for older IDF versions, or the callback never fires if I adapt to new struct names. I suspect I’m still mis-configuring something.
2 -Looked at RMT RX examples, but most focus on IR or ultrasonic pulses, not continuous frequency. Before I dive deep there, I’d like to know if someone already has a clean solution.

What I’m asking for
1 - A minimal, self-contained code snippet that
  • configures MCPWM (or RMT, if that’s preferred) to capture rising edges on GPIO36,
  • runs inside a FreeRTOS task every 500 ms,
  • updates float frequency with real-time frequency (≥2 decimals).
2 - Any gotchas in ESP-IDF v5.2.x (new field names, timer resolution calls, etc.).
3 - If MCPWM capture simply isn’t the right tool, I’m open to an RMT-based approach—just need a working example.

Thank you in advance! Any pointers, code, or even partial examples would be greatly appreciated.

Re: Need Working Example for MCPWM Capture (or RMT) to Measure Frequency on GPIO36 – ESP32-WROOM32 / ESP-IDF v5.2.5

Posted: Tue Jun 03, 2025 2:15 am
by ok-home
Hi
What's wrong with the official esp example?
https://github.com/espressif/esp-idf/bl ... _hc_sr04.c
after small modifications will give the counter values every period of the measured signal ( 1-100 milliseconds )

Re: Need Working Example for MCPWM Capture (or RMT) to Measure Frequency on GPIO36 – ESP32-WROOM32 / ESP-IDF v5.2.5

Posted: Tue Jun 03, 2025 9:57 am
by MicroController
You can also set the PCNT to notify you once every, say, 5 pulses. Measure the time between two notifications, calculate 5/time, and Bob's your uncle.
You'll have to decide what "the" frequency of the signal is in your case. You can define it as the frequency of the latest pulse seen in your 500ms window, or the number of pulses during that time, or something else. The result of each approach will be different when the signal's frequency changes.