ESP32 RMT - rmt_fill_tx_items() does not work

nocsspecop123
Posts: 3
Joined: Thu Mar 07, 2024 8:09 am

ESP32 RMT - rmt_fill_tx_items() does not work

Postby nocsspecop123 » Thu Mar 07, 2024 8:17 am

Hello all,

I am trying to use the RMT peripheral of the ESP32 with a very simple example to send a signal-sequence in infinite loop.
If I use rmt_write_items() to activate the RMT peripheral everything works fine.
But I need to change the signal-sequence at run-time. According to the ESP32 RMT documentation, rmt_fill_tx_items() should be used to change the signal-sequence at runtime. But once I use rmt_fill_tx_items() (instead of rmt_write_items()), the RMT peripheral does not work anymore and sends just random stuff.
Here is my code:

Code: Select all

#include <Arduino.h>
#include "driver/rmt.h"

rmt_config_t config;
rmt_item32_t items[1];

void setup()
{
  Serial.begin(115200);

  config.rmt_mode = RMT_MODE_TX;
  config.channel = RMT_CHANNEL_0;
  config.gpio_num = GPIO_NUM_4;
  config.mem_block_num = 1;
  config.tx_config.loop_en = 1;
  config.tx_config.carrier_en = 0;
  config.tx_config.idle_output_en = 1;
  config.tx_config.idle_level = RMT_IDLE_LEVEL_LOW;
  config.tx_config.carrier_level = RMT_CARRIER_LEVEL_HIGH;
  config.clk_div = 80; // 80MHx / 80 = 1MHz 0r 1uS per count
 
  ESP_ERROR_CHECK(rmt_config(&config));
  ESP_ERROR_CHECK(rmt_driver_install(config.channel, 0, 0));
   
  items[0].duration0 = 3;
  items[0].level0 = 1;
  items[0].duration1 = 10;
  items[0].level1 = 0;
  items[1].duration0 = 5;
  items[1].level0 = 1;
  items[1].duration1 = 5;
  items[1].level1 = 0;

  ESP_ERROR_CHECK(rmt_fill_tx_items(config.channel, items, 2, 0));
  ESP_ERROR_CHECK(rmt_tx_start(config.channel, false));
}

void loop()
{

}
I really would appreciate any help! I have tried a lot of code-variants and searched in the internet but it seems that rmt_fill_tx_items() is rarely used. I couldn't find any examples.

Thank you very much!

nocsspecop123
Posts: 3
Joined: Thu Mar 07, 2024 8:09 am

Re: ESP32 RMT - rmt_fill_tx_items() does not work

Postby nocsspecop123 » Thu Mar 07, 2024 1:32 pm

Hello all,

it seems I found the problem related to the use of rmt_fill_tx_items():
the rtm_items array that is passed to the rmt_fill_tx_items() functions seems to need the last element of the array to be set to 0 (duration0 and duration1) so that it is recognized as some sort of "end-marker". With such last element set to 0, the RMT module works in the loop as expected.

Unfortunately now I have a new issue: the period of the generated signal is much higher than expected.
I set the RMT-clock divisor to 1. When setting duration0 and duration1 to 1 tick respectively and level0 to 1 and level1 to 0 I expected a square wave with frequency of 40Mhz and period of 25ns. Instead I got a signal with a frequency of 500kHz (period of 2us):
signal.jpg
signal.jpg (815.21 KiB) Viewed 1703 times
This is the code I used:

Code: Select all

#include <Arduino.h>
#include <driver/rmt.h>

#define PACKET_LENGTH 	18
#define PAUSE			50

rmt_item32_t rmt_items[PACKET_LENGTH]; 

void setup()
{
    rmt_config_t config;
    config.rmt_mode = RMT_MODE_TX;
    config.mem_block_num = 1;
    config.tx_config.loop_en = 1;
    config.tx_config.carrier_en = 0;
    config.tx_config.idle_output_en = 1;
    config.tx_config.idle_level = RMT_IDLE_LEVEL_LOW;
    config.clk_div = 1;
 
    config.channel = RMT_CHANNEL_0;
    config.gpio_num = GPIO_NUM_4;
 
    ESP_ERROR_CHECK(rmt_config(&config));
    ESP_ERROR_CHECK(rmt_driver_install(config.channel, 0, 0));

    for (int i = 0; i < PACKET_LENGTH-2; i++, val <<= 1)
    {
        rmt_items[i].duration0 = 1;
        rmt_items[i].level0 = 0;
        rmt_items[i].duration1 = 1;
        rmt_items[i].level1 = 1;
    }

    // pause
    rmt_items[16].duration0 = PAUSE;
    rmt_items[16].level0 = 1;
    rmt_items[16].duration1 = 0;
    rmt_items[16].level1 = 0;

    // zero
    rmt_items[17].duration0 = 0;
    rmt_items[17].level0 = 0;
    rmt_items[17].duration1 = 0;
    rmt_items[17].level1 = 0;    

    rmt_fill_tx_items(RMT_CHANNEL_0, rmt_items, sizeof(rmt_items)/sizeof(rmt_items[0]), 0);
    rmt_tx_start(RMT_CHANNEL_0, true);
}


void loop() {
  // put your main code here, to run repeatedly:
}
Any idea why the frequency of the square-wave is so low?

ESP_Sprite
Posts: 9727
Joined: Thu Nov 26, 2015 4:08 am

Re: ESP32 RMT - rmt_fill_tx_items() does not work

Postby ESP_Sprite » Fri Mar 08, 2024 4:02 am

First of all, try zero-initializing your stack-allocated variables, otherwise they may have garbage in them:

Code: Select all

rmt_config_t config={};

nocsspecop123
Posts: 3
Joined: Thu Mar 07, 2024 8:09 am

Re: ESP32 RMT - rmt_fill_tx_items() does not work

Postby nocsspecop123 » Mon Mar 11, 2024 1:47 pm

Zeroeing the rmt_config_t structure did the trick, thank you!

Who is online

Users browsing this forum: ahuar88 and 90 guests