RMT for DALI in ESP32-C3 not filtering correctly

0

I use RMT in ESP32-C3 with ESP-IDF 5.3 to receive DALI 2 commands.

DALI uses Manchester encoding to send the signals using 1200bps. 1200bps means each bit is 833us, and each half bit is 416us. I tried using this data in the min_ns and max_ns but always got the "value too big" error. The values I'm using now are from the ESP-IDF example, which is similar to the DALI Manchester encoding timing.

The problem is that I'm expecting 32 symbols, which would be 16 bits. And the duration is in the 400us range, but the logs show something way different. This is the log when I send an OFF command 0xFD00 from the DALI software.

I (4590788) DALI: Received DALI frame (18 symbols)
I (4590788) DALI: Symbol[0]: Level0=1, Duration0=357, Level1=0, Duration1=480
I (4590788) DALI: Symbol[1]: Level0=1, Duration0=353, Level1=0, Duration1=468
I (4590798) DALI: Symbol[2]: Level0=1, Duration0=365, Level1=0, Duration1=474
I (4590798) DALI: Symbol[3]: Level0=1, Duration0=357, Level1=0, Duration1=470
I (4590798) DALI: Symbol[4]: Level0=1, Duration0=2, Level1=0, Duration1=6
I (4590808) DALI: Symbol[5]: Level0=1, Duration0=354, Level1=0, Duration1=469
I (4590808) DALI: Symbol[6]: Level0=1, Duration0=365, Level1=0, Duration1=474
I (4590808) DALI: Symbol[7]: Level0=1, Duration0=358, Level1=0, Duration1=882
I (4590818) DALI: Symbol[8]: Level0=1, Duration0=787, Level1=0, Duration1=886
I (4590818) DALI: Symbol[9]: Level0=1, Duration0=359, Level1=0, Duration1=465
I (4590828) DALI: Symbol[10]: Level0=1, Duration0=367, Level1=0, Duration1=470
I (4590828) DALI: Symbol[11]: Level0=1, Duration0=362, Level1=0, Duration1=475
I (4590828) DALI: Symbol[12]: Level0=1, Duration0=357, Level1=0, Duration1=466
I (4590838) DALI: Symbol[13]: Level0=1, Duration0=367, Level1=0, Duration1=469
I (4590838) DALI: Symbol[14]: Level0=1, Duration0=363, Level1=0, Duration1=474
I (4590848) DALI: Symbol[15]: Level0=1, Duration0=357, Level1=0, Duration1=467
I (4590848) DALI: Symbol[16]: Level0=1, Duration0=7, Level1=0, Duration1=3
I (4590848) DALI: Symbol[17]: Level0=1, Duration0=356, Level1=0, Duration1=0
I (4590858) DALI: Invalid DALI  0x1FFF

This is the config code for RMT

    rmt_rx_channel_config_t rx_config = {
    .gpio_num = DALI_RX_GPIO,
    .clk_src = RMT_CLK_SRC_DEFAULT,
    .resolution_hz = RMT_CLK_RES, // 1 MHz tick resolution, i.e., 1 tick = 1 µs
    .mem_block_symbols = DALI_SYMBOL_BUFFER_SIZE,
    .flags.with_dma = false,
};

ESP_ERROR_CHECK(rmt_new_rx_channel(&rx_config, &dali_rx_channel));
ESP_ERROR_CHECK(rmt_rx_register_event_callbacks(dali_rx_channel, &cbs, dali_rx_queue));

receive_config.signal_range_min_ns = 1250;    // shortest duration of DALI bit should be 416us. 1250ns < 416 µs (safe minimum)
receive_config.signal_range_max_ns = 1200000; // longest duration of DALI bit should be 832us, 1200000 ns > 832 us(upper limit)

ESP_ERROR_CHECK(rmt_enable(dali_rx_channel));
ESP_ERROR_CHECK(rmt_receive(dali_rx_channel, raw_symbols, sizeof(raw_symbols), &receive_config));

This is how I decode the pulses:

    for (int i = 0; i < num_symbols; i++)
{
    uint32_t duration0 = symbols[i].duration0;
    uint32_t duration1 = symbols[i].duration1;
    int level0 = symbols[i].level0;
    int level1 = symbols[i].level1;

    // Each Manchester bit-pair should be around 416µs
    if ((duration0 >= 350 && duration0 <= 500) && (duration1 >= 350 && duration1 <= 500))
    {
        if (level0 == 1 && level1 == 0)
        {
            dali_data = (dali_data << 1) | 1; // 1 → HIGH-LOW
        }
        else if (level0 == 0 && level1 == 1)
        {
            dali_data = (dali_data << 1) | 0; // 0 → LOW-HIGH
        }
    }
}

As far as I understand, RMT could be used to receive this type of signal, but it seems kinda tricky. I would appreciate any help in understanding this. Thanks a lot in advance :slight_smile:

Are you still working on this? I have been looking at ESP32 RMT for DALI reception but I get errors on some commands. If I have the bus master send 0xff06 everything works but if 0xff05 is sent, I get an error. I'm pretty sure is due to a half symbol being received like in your data above "Symbol[17]: Level0=1, Duration0=356, Level1=0, Duration1=0" there is no level 0 duration to match the level 1.

I faced some similar errors.
I would recommend you to print all the bits and durations.
Then, decode it manually.

Sometimes you will see some bits are double the duration. You'll need to split them.

But, its easier to understand if you decode the bits manually after printing them