Possible bug: ESP32 remote control peripheral works when uploaded with idf.py but not PlatformIO [Closed]

In my continuing experimentation with the ESP32 Remote Control peripheral I have found that, regardless of what I do, any call to it to actually write a pulse stream to the output pin results in the program hanging. The call to rmt_write_items or rmt_write_sample never returns to the calling program.
However, I discovered yesterday that the function does work, if it is compiled using Espressif’s idf.py tool. I tried uploading my program with it and found that it did work as expected, and the write functions did return to the calling program. However when the same program is compiled and uploaded using PlatformIO, the calls do not return. This happened using PIO’s espidf framework and arduinio framework.

Thanks.

Is it possible that this uses ESP-IDF of a different version? What version is it using?

PIO uses ESP-IDF v4.0.1.

Just for reference, does it also not work with the latest Arduino IDE ESP32 platform version?

Hi @maxgerhardt, thanks for the reply.
I followed the instructions here to install esp-idf. It installs v4.0.1.

I must apologise, I retested my programs again, and the ESP-IDF version actually didn’t work, it hung on the second iteration of the rmt_write_items as did the PlatformIO run, and Arduino IDE did the same thing. So not a PIO problem.

I’ve been on an issue discussion about this problem related to Micropython, details here. I tried the recommendations of JonathanHogg, and using that structure the functions work in Arduino and PlatformIO as well as ESP-IDF. This is the latest program, note the code in between the “Jonathan Hogg mods” comment lines. This version works as expected, generating a correct pulse train and continuously cycling around the loop() function (i.e. not hanging). The issue is still being worked on, and is still being treated as a bug as far as I understand, so it remains to be seen where this thing ends up.

/* RMT Example
 *
 */
#include <Arduino.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "driver/rmt.h"

static const char *TAG = "ppmGenerator";

static rmt_item32_t channelItems[] = {
    {{{ 3000, 1, 300, 0 }}}, // channel 1 - variable pulse high followed by 300us pulse low.
    {{{ 1000, 1, 300, 0 }}}, // channel 2
    {{{ 1500, 1, 300, 0 }}}, // channel 3
    {{{ 2000, 1, 300, 0 }}}, // channel 4
    {{{ 1000, 1, 300, 0 }}}, // channel 5
    {{{ 1500, 1, 300, 0 }}}, // channel 6
    {{{ 2000, 1, 300, 0 }}}, // channel 7
    {{{ 1000, 1, 300, 0 }}}, // channel 8
    {{{ 7100, 1, 300, 0 }}} // sync pulse (22500 - sum of all channel pulses
};
uint16_t item_count = sizeof(channelItems) / sizeof(channelItems[0]); // 9
uint16_t channels[] = {1000, 1100, 1200, 1400, 1500, 1700, 1900, 2000};
/*
 * Initialize the RMT Tx channel
 */
void setup()
{
    Serial.begin(115200);
    Serial.println(">>> Configuring transmitter");
    ESP_LOGI(TAG, "Configuring transmitter");
    
    rmt_config_t config;
    config.rmt_mode = RMT_MODE_TX;
    config.channel = RMT_CHANNEL_0;
    config.gpio_num = GPIO_NUM_18;
    config.mem_block_num = 1;
    config.tx_config.loop_en = false;
    config.tx_config.carrier_en = false;
    /*--- set clock divider ------------------------------------------*/
    config.clk_div = 80; // gives 1us tick size (for 80MHz processor)

    ESP_ERROR_CHECK(rmt_driver_install(RMT_CHANNEL_0, 0, 0)); 
    ESP_ERROR_CHECK(rmt_config(&config)); // rmt_driver_install MUST be before this
   /*** Jonathan Hogg mods ********************************************/
    rmt_set_tx_intr_en(RMT_CHANNEL_0, false); // turn off Tx interrupt
    
    // ESP_LOGI(TAG, "setting loop enable false for this write");
    // Serial.println(">>> setting loop enable false for this write");
    // rmt_set_tx_loop_mode(RMT_CHANNEL_0, false); // set loop mode off for this write

    ESP_LOGI(TAG, "starting first write items");
    Serial.println(">>> starting first write items");
    rmt_write_items(RMT_CHANNEL_0, channelItems, item_count, false); //write train
    ESP_LOGI(TAG, "finished first write items");
    Serial.println(">>> fomosjed first write items");
    rmt_set_tx_loop_mode(RMT_CHANNEL_0, true); //
   /*** end of Jonathan Hogg mods *************************************/ 
}

void loop()
{
    Serial.println(">>> loop entered");
    ESP_LOGI(TAG, "loop entered");
    uint16_t sync_pulse = 22500;
    for (int i = 0; i < 8; i++) {
        channelItems[i].duration0 = channels[i];
        sync_pulse = sync_pulse - (channels[i] + 300);
    }
    channelItems[8].duration0 = sync_pulse;
    ESP_LOGI(TAG, "start rmt_write_items");
    Serial.println(">>> start rmt_write_items");
    /*** Jonathan Hogg mods ********************************************/
    rmt_set_tx_intr_en(RMT_CHANNEL_0, true);    // turn on Tx interrupt
    rmt_set_tx_loop_mode(RMT_CHANNEL_0, false); // disable looping
    rmt_wait_tx_done(RMT_CHANNEL_0, 22500);     // wait for train to complete, timeout fixed train length
    rmt_set_tx_intr_en(RMT_CHANNEL_0, false);   // disable Tx interrupt again
    /*** end of Jonathan Hogg mods *************************************/
    rmt_write_items(RMT_CHANNEL_0, channelItems, item_count, false); // write train. "wait" must be false
    /*** Jonathan Hogg mods ********************************************/
    rmt_set_tx_loop_mode(RMT_CHANNEL_0, true);  // enable Tx looping again
    /*** end of Jonathan Hogg mods *************************************/
    Serial.println(">>> Finished rmt_write_items");
    ESP_LOGI(TAG, "Finish rmt_write_items");
    // vTaskDelay(1000 / portTICK_PERIOD_MS);
}

// void app_main()
// {
//     setup();
//     while(true)
//     {
//         loop();
//     }
// }

Dunno why but the ESP_LOGI function doesn’t work in Arduino or PlatformIO (in fact PIO gives a warning message about an unused variable TAG, which is used in the ESP_LOGI macro). Corrupted by Arduino.h maybe?.. Needless to say Serial.print doesn’t work in the ESP-IDF world, but ESP_LOGI does.

Anyway I think this thread can be closed. Again, thanks for your help.

:wink: Ian