Pulse counter controlled by hardware timing for frequency measurement

meowsqueak
Posts: 151
Joined: Thu Jun 15, 2017 4:54 am
Location: New Zealand

Re: Pulse counter controlled by hardware timing for frequency measurement

Postby meowsqueak » Thu Nov 09, 2017 8:34 pm

rohit269 wrote: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)?
Try this, however I stress that I haven't tidied this up in any way - use at your own risk:

https://github.com/DavidAntliff/esp32-freqcount

Questions welcome.

rohit269
Posts: 24
Joined: Mon Sep 11, 2017 4:22 am

Re: Pulse counter controlled by hardware timing for frequency measurement

Postby rohit269 » Sun Nov 12, 2017 3:03 am

Hi,
I have been trying to test the code in: https://github.com/DavidAntliff/esp32-freqcount

I have understood the logic and this is exactly what I need. I have routed the RMT to an external GPIO which I can probe. However I can't seem to generate an RMT signal (can't detect on the oscilloscope probe).

I have tried isolating the RMT code from the PCNT part just to test the RMT signal. However, I can't seem to generate a simple toggle waveform.

Do you have any advice on how to proceed?
Thanks.

I have pasted the code below through which I am trying to test to generate the RMT signal (the code should produce pulses of 0.5 seconds) :

Code: Select all

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "driver/gpio.h"
#include "driver/pcnt.h"
#include "soc/rtc.h"
#include "driver/rmt.h"

#include "esp_log.h"
#include "sdkconfig.h"

#define RMT_TX_CHANNEL RMT_CHANNEL_0
//#define RMT_CLK_DIV          20   // results in 0.25us steps (80MHz / 20 = 4 MHz
#define RMT_CLK_DIV            160   // results in 2us steps (80MHz / 160 = 0.5 MHz
//#define RMT_CLK_DIV          1  // results in 25ns steps (80MHz / 2 / 1 = 40 MHz)

// The counter is signed 16-bit, so maximum positive value is 32767
// The filter is unsigned 10-bit, maximum value is 1023. Use full period of maximum frequency.
// For higher expected frequencies, the sample period and filter must be reduced.

// suitable up to 16,383.5 kHz
#define SAMPLE_PERIOD 1.0  // seconds
#define FILTER_LENGTH 1023  // APB @ 80MHz, limits to < 39,100 Hz


typedef struct
{
    double period;
} rmt_tx_task_args_t;


void rmt_tx_task(void * arg)
{
    rmt_tx_task_args_t * rmt_tx_task_args = arg;
  
    while (1)
    {
        rmt_item32_t items[100] = { 0 };
        int num_items = 0;
         // toggle:
        /*for (num_items = 0; num_items < 500; ++num_items)
        {
            items[num_items].level0 = 1;
            items[num_items].duration0 = 1000000;
            items[num_items].level1 = 0;
            items[num_items].duration1 = 100000;
        }*/

        // enable counter for exactly x seconds:
        double sample_period = SAMPLE_PERIOD;
        int32_t total_duration = (uint32_t)(sample_period / rmt_tx_task_args->period);
        //ESP_LOGI(TAG, "total_duration %d periods", total_duration);

        // max duration per item is 2^15-1 = 32767
        while (total_duration > 0)
        {
            uint32_t duration = total_duration > 32767 ? 32767 : total_duration;
            items[num_items].level0 = 1;
            items[num_items].duration0 = duration;
            total_duration -= duration;
            //ESP_LOGI(TAG, "duration %d", duration);

            if (total_duration > 0)
            {
                uint32_t duration = total_duration > 32767 ? 32767 : total_duration;
                items[num_items].level1 = 1;
                items[num_items].duration1 = duration;
                total_duration -= duration;
            }
            else
            {
                items[num_items].level1 = 0;
                items[num_items].duration1 = 0;
            }
            //ESP_LOGI(TAG, "[%d].level0 %d", num_items, items[num_items].level0);
            //ESP_LOGI(TAG, "[%d].duration0 %d", num_items, items[num_items].duration0);
            //ESP_LOGI(TAG, "[%d].level1 %d", num_items, items[num_items].level1);
            //ESP_LOGI(TAG, "[%d].duration1 %d", num_items, items[num_items].duration1);

            ++num_items;
        }
 
        rmt_write_items(RMT_TX_CHANNEL, items, num_items, false);
        rmt_wait_tx_done(RMT_TX_CHANNEL, portTICK_PERIOD_MS);
       

        vTaskDelay(1000 / portTICK_PERIOD_MS);
      
    }
} 
 
void app_main() {
  // put your setup code here, to run once:
rmt_config_t rmt_tx = {
        .rmt_mode = RMT_MODE_TX,
        .channel = RMT_CHANNEL_0,
        .gpio_num = 12,
        .mem_block_num = 1,  // single block
        .clk_div = RMT_CLK_DIV,
        .tx_config.loop_en = false,
        .tx_config.carrier_en = false,
        .tx_config.idle_level = RMT_IDLE_LEVEL_LOW,
        .tx_config.idle_output_en = true,
    };
    rmt_config(&rmt_tx);
  rmt_driver_install(rmt_tx.channel, 0, 0);  //  rmt_driver_install(rmt_channel_t channel, size_t rx_buf_size, int rmt_intr_num)
  const double rmt_period = (double)(RMT_CLK_DIV) / 80000000.0;
  rmt_tx_task_args_t rmt_tx_task_args = {
        .period = rmt_period,};
  
  xTaskCreate(rmt_tx_task, "rmt_tx_task", 4096, &rmt_tx_task_args, 10, NULL);


 }

meowsqueak
Posts: 151
Joined: Thu Jun 15, 2017 4:54 am
Location: New Zealand

Re: Pulse counter controlled by hardware timing for frequency measurement

Postby meowsqueak » Sun Nov 12, 2017 3:10 am

Hmmm, not sure, your version of the code looks OK to me on the face of it. Unfortunately I don't have my hardware in a state where I can try it out just now.

Can you try this project and see if you can get any output on your selected GPIO?

https://github.com/DavidAntliff/esp32-dco

This just uses the RMT to generate a square wave of a certain frequency.

rohit269
Posts: 24
Joined: Mon Sep 11, 2017 4:22 am

Re: Pulse counter controlled by hardware timing for frequency measurement

Postby rohit269 » Sun Nov 12, 2017 4:57 am

Thanks, I can generate a 51 Hz RMT signal on the GPIO using the code above.

I noticed that we enable the loop functionality of the RMT module for continuous pulse generation, and perform some additional memory allocation for items. We don't do this for the Frequency counting code.

Is that the main difference?

meowsqueak
Posts: 151
Joined: Thu Jun 15, 2017 4:54 am
Location: New Zealand

Re: Pulse counter controlled by hardware timing for frequency measurement

Postby meowsqueak » Sun Nov 12, 2017 8:03 am

Yeah, the DCO code is supposed to set up a cycling pulse, perhaps suitable as a clock signal or test waveform, whereas the Frequency Measurement code is just a one-shot (for each measurement). Hopefully you can compare the set-up code for the DCO vs the set-up code for the FreqCounter and work out why you're not seeing anything on the shared GPIO.

rohit269
Posts: 24
Joined: Mon Sep 11, 2017 4:22 am

Re: Pulse counter controlled by hardware timing for frequency measurement

Postby rohit269 » Mon Nov 13, 2017 4:55 am

Hi,
so I have managed to generate the RMT signal.

Now coming to the 2nd part to link it with the PCNT module, I notice that when I configure the PCNT-CTRL-in as RMT-out, the RMT signal disappears. I am initialising PCNT after installing the RMT driver.

I tried to configure the RMT GPIO as floating(if by chance the PCNT was pulling it up) but that did not help.

Any advice?
Thanks.

meowsqueak
Posts: 151
Joined: Thu Jun 15, 2017 4:54 am
Location: New Zealand

Re: Pulse counter controlled by hardware timing for frequency measurement

Postby meowsqueak » Mon Nov 13, 2017 5:50 am

Can you post your latest code on pastebin.com or github or somewhere?

rohit269
Posts: 24
Joined: Mon Sep 11, 2017 4:22 am

Re: Pulse counter controlled by hardware timing for frequency measurement

Postby rohit269 » Mon Nov 13, 2017 6:26 am

I have pasted it here: https://pastebin.com/thWGsq9H

Titled as: ESP32_freq_count

meowsqueak
Posts: 151
Joined: Thu Jun 15, 2017 4:54 am
Location: New Zealand

Re: Pulse counter controlled by hardware timing for frequency measurement

Postby meowsqueak » Mon Nov 13, 2017 6:33 am

Hmm, obviously your code is pretty similar to my original, and I can't see anything obviously wrong. Have you tried using different GPIO pins? I use GPIO 5 for my RMT-out/PCNT-in pin, and GPIO 4 for my external signal (to measure frequency).

It might be worth gradually commenting out the PCNT init code to work out where exactly it causes the RMT signal to disappear. Is it the call to `pcnt_unit_config()`?

rohit269
Posts: 24
Joined: Mon Sep 11, 2017 4:22 am

Re: Pulse counter controlled by hardware timing for frequency measurement

Postby rohit269 » Mon Nov 13, 2017 6:44 am

Yes, it's the call to `pcnt_unit_config()` which causes the RMT signal to disappear.

I wanted to use the GPIO's on my board to which I can connect an external probe (12,13,14,15) for the RMT. It didn't work for 12 and 13.

Who is online

Users browsing this forum: No registered users and 63 guests