rmt reciever problem (items is very large number)

AlbertH
Posts: 5
Joined: Wed Feb 03, 2021 3:54 pm

rmt reciever problem (items is very large number)

Postby AlbertH » Sat Feb 06, 2021 3:21 pm

I am using an ESP32 and I am trying to capture a continues low frequent signal (150 - 300Hz) which is coming from a tacho (In this test phase I am using a waveform generator from my scope). I took an example from the internet, which seems to work, but I can't get it working. When I feed it with about 200Hz nothing is working and get an RMT error 0x13000040. When I lower the frequency to 10 Hz, I get an "items" number that is very high while the "rx_size" is always 0. Going to 15Hz the "rx_size" becomes 4 and the "items" number is still extremely high.
I have to admit that I have only very little knowledge about software, I am more a hardware designer (FPGA's). So that could also be the problem here.
Could someone help me with my problem?

Code: Select all

// test for rmt RX

#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "freertos/semphr.h"
#include "esp_err.h"
#include "esp_log.h"
#include "driver/rmt.h"
#include "driver/periph_ctrl.h"
#include "soc/rmt_reg.h"
#include "LiquidCrystal.h"


//define pinnumbers
const int pin_Tacho = 13;
const int pin_Vsync = 23;

// Initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to
const int pin_RS = 5, pin_EN = 19, pin_d4 = 15, pin_d5 = 2, pin_d6 = 0, pin_d7 = 4;
//
LiquidCrystal lcd(pin_RS, pin_EN, pin_d4, pin_d5, pin_d6, pin_d7);

//
// FreeRTOS function
#define INCLUDE_vTaskDelay 1

#define rrmt_item32_tIMEOUT_US  10000   /*!< RMT receiver timeout value */

// LED on board
const int led_buildin = 22;
const int pin_rxflag = 23;

// structure used to initialize RMT inputs
// NOTE: tag is used on the monitor outputs to distinguish between channels
struct rmt_rx_inits {
  rmt_channel_t  channel;
  gpio_num_t     gpio_num;
  uint8_t        clk_div;
  uint8_t        mem_block_num;
  bool           config_filter_en;
  uint8_t        config_filter_tics_thresh;
  uint16_t       config_idle_threshold;
  char           tag[10];
};

rmt_rx_inits rx_inputs[2] = {
  // channel,          gpio_num,         clk_div, mem_block, filter_en, filter_tics, config_idle_threshold,   tag
  { RMT_CHANNEL_0, (gpio_num_t)pin_Tacho,     64,         1,      true,          10,                 50000, "Tacho" },
  { RMT_CHANNEL_1, (gpio_num_t)pin_Vsync,     64,         1,      true,          10,                 50000, "Vsync" }
};


// initialize RMT receive channels
void rx_channels_init() 
{
    rmt_config_t rmt_rx;
    size_t i;
    size_t len = sizeof(rx_inputs) / sizeof( rx_inputs[0] ); // number of channels

    for ( i=0; i<len; i++ ) {
//    i=0;
    rmt_rx.channel       = rx_inputs[i].channel;
    rmt_rx.gpio_num      = rx_inputs[i].gpio_num;
    rmt_rx.clk_div       = rx_inputs[i].clk_div;
    rmt_rx.mem_block_num = rx_inputs[i].mem_block_num;
    rmt_rx.rmt_mode      = RMT_MODE_RX;

    rmt_rx.rx_config.filter_en           = rx_inputs[i].config_filter_en;
    rmt_rx.rx_config.filter_ticks_thresh = rx_inputs[i].config_filter_tics_thresh;
    rmt_rx.rx_config.idle_threshold      = rx_inputs[i].config_idle_threshold;

    rmt_config(&rmt_rx);
    // buffer size = 16; interrupt handler = 0
    rmt_driver_install(rx_inputs[i].channel, 1000, 0); 
  }
}


// initialize visible LED on ESP32 board
static void visible_led_init() 
{
  gpio_pad_select_gpio(LED_BUILTIN);
  gpio_set_direction(gpio_num_t(LED_BUILTIN), GPIO_MODE_OUTPUT);
}

/* Converts the RMT level, duration into a positive or negative integer
 * Compatible with the ESP32-RMT-server application
 * Note: most IR receivers have active-low outputs, where the
 *   ESP32-RMT-server application has active-high oututs
 * This function inverts the RMT receive level so the text output is
 *   compatible with ESP32-RMT-server application
 */
int dur( uint32_t level, uint32_t duration ) 
{
  if ( level == 0 ) 
  { 
    return duration; 
  }
  else 
  { 
    return -1.0 * duration; 
  }
}


static void rmt_example_tacho_rx_task(void * parmas) 
{
  size_t num_channels = sizeof(rx_inputs) / sizeof( rx_inputs[0] ); // 2 channels used here
  size_t c, i;
  size_t rx_size = 0;
  int level0, level1, duration0, duration1;
  rmt_item32_t* items = NULL;

  // define ringbuffer handle
  RingbufHandle_t rb;

  // start receiving Tacho & Vsync signals
  for ( c=0; c<num_channels; c++ ) 
  {
    rmt_rx_start(rx_inputs[c].channel, 1); // start the rx channel
  }

    // loop forever
    while (1) 
    {
    // check each receive channel
    for ( c=0; c<num_channels; c++ ) 
    {
      // get the ring buffer handle
      rmt_get_ringbuf_handle(rx_inputs[c].channel, &rb);

      // get items, if there are any
      items = (rmt_item32_t*) xRingbufferReceive(rb, &rx_size, 10);
      if(items) 
      {
      printf( "items %i \n", items );
      printf ("rx_size %i \n", rx_size);
        // turn on visible led
//        gpio_set_level(gpio_num_t(LED_BUILTIN), 1);
        digitalWrite(pin_rxflag, HIGH);

        // print the RMT received durations to the monitor
//        printf( "  %s received %i items\n", rx_inputs[c].tag, rx_size/4 );

        for ( i=0; i<rx_size/4; i++ ) 
        {
          if ( i>0 ) { printf(","); }
//          printf("Tacho" ",%i", dur( items[i].level0, items[i].duration0 ) );
//          printf(",%i", dur( items[i].level1, items[i].duration1 ) );
//            level0 = items[0].level0;
//            duration0 = items[0].duration0;
//            level1 = items[0].level1;
//            duration1 = items[0].duration1;
            duration0 = dur( items[i].level0, items[i].duration0 );
            duration1 = dur( items[i].level1, items[i].duration1 );
//         printf ("durations ,%i, %i", duration0, duration1);   
        }
//        printf("\n");

        // turn off visible led
//        gpio_set_level(gpio_num_t(LED_BUILTIN), 0);
        digitalWrite(pin_rxflag, LOW);

        // free up data space, remove from buffer
        vRingbufferReturnItem(rb, (void*) items);
      }
    }
  }
}


void setup() 
{
/////////////////////////////////
// Define input/output pins
/////////////////////////////////
  pinMode (pin_Tacho, INPUT);
  pinMode (pin_rxflag, OUTPUT);

  visible_led_init();

  rx_channels_init();
  //
  lcd.setCursor(0, 0); // first position, first line
  lcd.print("Init done");
  //
}

void loop() 
{

//
  lcd.setCursor(0, 1); // first position, second line
  lcd.print("TaskCreate");


  // start receive processing task
  // xTaskCreate(Taskname,               "rmt_tacho_rx_task", Stackdepth, Parameters, Priority, Taskhandler);
  xTaskCreate(rmt_example_tacho_rx_task, "rmt_example_tacho_rx_task",       2048,       NULL,       10,        NULL);


  // delay 10 milliseconds. No need to overheat the processor
 //vTaskDelay( 1000 / portTICK_PERIOD_MS );


}
  • text on the COM port

    16:18:08.283 -> rx_size 4
    16:18:08.383 -> items 1073448444
    16:18:08.383 -> rx_size 4
    16:18:08.430 -> items 1073448456
    16:18:08.430 -> rx_size 4
    16:18:08.483 -> items 1073448468
    16:18:08.483 -> rx_size 4
    16:18:08.583 -> items 1073448480
    16:18:08.583 -> rx_size 4
    16:18:08.630 -> items 1073448492
    16:18:08.630 -> rx_size 4
    16:18:08.730 -> items 1073448504
    16:18:08.730 -> rx_size 4
    16:18:08.783 -> items 1073448516
    16:18:08.783 -> rx_size 4
    16:18:08.884 -> items 1073448528
    16:18:08.884 -> rx_size 4
    16:18:08.931 -> items 1073448540

ESP_Minatel
Posts: 364
Joined: Mon Jan 04, 2021 2:06 pm

Re: rmt reciever problem (items is very large number)

Postby ESP_Minatel » Mon Feb 08, 2021 9:17 am

Hi,

Any update on this issue? Have you tried the example in the ESP-IDF GitHub?

https://github.com/espressif/esp-idf/tr ... _protocols

AlbertH
Posts: 5
Joined: Wed Feb 03, 2021 3:54 pm

Re: rmt reciever problem (items is very large number)

Postby AlbertH » Mon Feb 08, 2021 9:32 am

Hi ESP_Minatel,

thanks for your post. Yesterday I decreased the "config_idle_threshold" to 50 and suddenly I had a some output signals indicating that values were received. But I don't understand this, because the "config_idle_threshold" is kind of time-out. But when I changed my input frequency(tacho) from 5 to 500Hz I got output pulses. With the higher value of "config_idle_threshold" I only got pulses with an input tacho below 12Hz.

No, I did not tried that example, because I have a continues signal, tacho pulses from a motor of a projector.

At this moment I don't know how to continue my project.

Best Regards

AlbertH

ESP_Minatel
Posts: 364
Joined: Mon Jan 04, 2021 2:06 pm

Re: rmt reciever problem (items is very large number)

Postby ESP_Minatel » Mon Feb 08, 2021 10:16 am

Hi,

If you are trying to measure the frequency itself and not decoding, take a look at this project and the PCNT peripheral. You can find a lot of examples about measuring frequency using PCNT.

viewtopic.php?f=19&p=71613#p71613

AlbertH
Posts: 5
Joined: Wed Feb 03, 2021 3:54 pm

Re: rmt reciever problem (items is very large number)

Postby AlbertH » Mon Feb 08, 2021 10:21 am

I checked that topic. I did not find a download of that code. Where can I find it?

AlbertH


AlbertH
Posts: 5
Joined: Wed Feb 03, 2021 3:54 pm

Re: rmt reciever problem (items is very large number)

Postby AlbertH » Mon Feb 08, 2021 10:35 am

Hi ESP_Minatel,

thanks for the link. I will download the code and give it a try.

Best Regards

Albert H

User avatar
nvtby_espf
Posts: 15
Joined: Wed Mar 03, 2021 1:11 pm
Location: Belarus
Contact:

Re: rmt reciever problem (items is very large number)

Postby nvtby_espf » Sun Apr 25, 2021 5:34 pm

Hi, Just my 5 cents: I looks like "config_idle_threshold" is measured in divided ticks. I found this during my low level tests with RMT registers I/O. I mean, take active clock (APB or REF), apply divider in use, and you will get a frequency ticks to use with this parameter.

Who is online

Users browsing this forum: No registered users and 96 guests