rmt reciever problem (items is very large number)
Posted: 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?
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