Pulse counter controlled by hardware timing for frequency measurement
-
- Posts: 151
- Joined: Thu Jun 15, 2017 4:54 am
- Location: New Zealand
Pulse counter controlled by hardware timing for frequency measurement
Is there a way to connect the output of one of the general purpose timers to the control signal of the Pulse Counter?
What I want to do is count incoming pulses for a precise amount of time, then generate an interrupt so that my application can read the result from the counter. This is in order to get an accurate frequency measurement from an external signal. Although I can enable the pulse counter in software, wait for some time, then poll the value, if I can remove software from the loop I can make it more reliable and more accurate.
Another option might be to use the timer to generate an interrupt, and read the pulse counter in the interrupt handler.
I've seen the ULP example (for counting during sleep) - I could use this if there's no better way to do it.
What I want to do is count incoming pulses for a precise amount of time, then generate an interrupt so that my application can read the result from the counter. This is in order to get an accurate frequency measurement from an external signal. Although I can enable the pulse counter in software, wait for some time, then poll the value, if I can remove software from the loop I can make it more reliable and more accurate.
Another option might be to use the timer to generate an interrupt, and read the pulse counter in the interrupt handler.
I've seen the ULP example (for counting during sleep) - I could use this if there's no better way to do it.
Re: Pulse counter controlled by hardware timing for frequency measurement
One way would be to:
1. use RMT to generate a pulse of a precise length
2. connect RMT channel to an IO
3. connect PCNT control input to the same IO as input
4. configure PCNT to inhibit counting when control input is low, and perform counting when control input is high.
You may also configure a software interrupt on the RMT (tx complete interrupt) to get the value of PCNT after counting is done.
As for GPIO, if you are not using pSRAM, you can use GPIO20 (which is not wired to external pad, but exists in the chip).
Take a look at https://github.com/espressif/esp-idf/bl ... ef_clock.c which uses similar idea to connect RMT and PCNT.
1. use RMT to generate a pulse of a precise length
2. connect RMT channel to an IO
3. connect PCNT control input to the same IO as input
4. configure PCNT to inhibit counting when control input is low, and perform counting when control input is high.
You may also configure a software interrupt on the RMT (tx complete interrupt) to get the value of PCNT after counting is done.
As for GPIO, if you are not using pSRAM, you can use GPIO20 (which is not wired to external pad, but exists in the chip).
Take a look at https://github.com/espressif/esp-idf/bl ... ef_clock.c which uses similar idea to connect RMT and PCNT.
-
- Posts: 151
- Joined: Thu Jun 15, 2017 4:54 am
- Location: New Zealand
Re: Pulse counter controlled by hardware timing for frequency measurement
Thanks Ivan, that sounds like a good way to do it - I'll try it out. I assume I can use an externally wired GPIO, rather than GPIO20, for testing purposes via scope?
Re: Pulse counter controlled by hardware timing for frequency measurement
Yes, externally wired GPIO will also work fine.
-
- Posts: 151
- Joined: Thu Jun 15, 2017 4:54 am
- Location: New Zealand
Re: Pulse counter controlled by hardware timing for frequency measurement
I'm finding the docs a little unclear on this point. They are clear that I should not call rmt_isr_register() if I've also called rmt_driver_install(), but what is not clear is how to set things up if I don't call rmt_driver_install(). I think I've worked out that if I use rmt_driver_install() then I lose the ability to set my own Tx Complete interrupt handler - is that correct? But if I'm using just a single memory block I probably don't need that feature. EDIT: after reading the driver code, I see that it hooks the channel interrupt to keep the device fed with data - is this required for single-mem-block operation, or just for joining multiple mem blocks into one? I tried simply not calling rmt_driver_install() but didn't get any output at all.ESP_igrr wrote:You may also configure a software interrupt on the RMT (tx complete interrupt) to get the value of PCNT after counting is done.
So to implement my own tx complete handler, I think this means I'll need to manually set up the RMT (and presumably lose the driver's ability to "refresh" the TX buffer automatically for long sequences).
I can find a couple of examples of RMT interrupts prior to the recent addition of the RMT driver, however examples that use custom interrupt handlers alongside the new API seem very rare (i.e. I haven't found any yet).
Re: Pulse counter controlled by hardware timing for frequency measurement
Yes, that is correct, sorry that i didn't consider this when offering advice above. In case you are generating a single high pulse using RMT, auto-refresh may not be an issue, so you can call "rmt_write_items" and then "rmt_uart_tx_done". When that function returns, it means that the pulse was sent and you can retrieve the value from PCNT.if I use rmt_driver_install() then I lose the ability to set my own Tx Complete interrupt handler - is that correct
-
- Posts: 151
- Joined: Thu Jun 15, 2017 4:54 am
- Location: New Zealand
Re: Pulse counter controlled by hardware timing for frequency measurement
Just to report back on this. I got something useful working (thank you) with a simple rmt_write_items()/rmt_wait_tx_done() task, but there were some notes I'd like to share when using the same GPIO for RMT-out, PCNT-CTRL-in:
- The PCNT initialisation needed to happen after the RMT otherwise the RMT config seems to affect the GPIO in a way that stops it working. This might be as simple as affecting the GPIO mode - not sure.
- The pcnt_unit_config() function sets the GPIO to pull-up, when I actually need it high-impedance. I mentioned this in another thread. The workaround is simply a subsequent call to gpio_set_pull_mode().
- The gpio_matrix_in() call in the linked ref_clock example didn't seem useful and I didn't seem to need it.
- GPIO_NUM_20 isn't a valid enum value and using int 20 doesn't work with the newer API functions - both PCNT and RMT config complain about it being an invalid GPIO. The ref_clock example doesn't use the new API so handles it directly.
Re: Pulse counter controlled by hardware timing for frequency measurement
Is there a way to count the frequency of an externally generated pulse (without using RMT as source) using the PCNT module?
-
- Posts: 151
- Joined: Thu Jun 15, 2017 4:54 am
- Location: New Zealand
Re: Pulse counter controlled by hardware timing for frequency measurement
As long as you can provide an enable signal that is a precise and known duration, you can use this to enable the PCNT and determine the frequency. That enable could be externally generated or perhaps sourced from another counter connected to a known clock.rohit269 wrote:Is there a way to count the frequency of an externally generated pulse (without using RMT as source) using the PCNT module?
EDIT: I suppose if you don't have a way of generating a precise duration enable, you could use a "rough" enable and use interrupts to determine the duration of the enable relative to, say, the CPU clock. It might not be quite as accurate but may be sufficient for many applications.
Re: Pulse counter controlled by hardware timing for frequency measurement
Thanks.
Also, what RMT settings do you suggest if I need to measure the frequency of an external signal (i.e. count the number of pulses in one seccond with RMT as the PCNT control signal)?
Also, what RMT settings do you suggest if I need to measure the frequency of an external signal (i.e. count the number of pulses in one seccond with RMT as the PCNT control signal)?
Who is online
Users browsing this forum: No registered users and 109 guests