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.
Ian