RMT peripheral clk_div how does it work?

Posts: 8
Joined: Mon Mar 11, 2019 4:23 pm

RMT peripheral clk_div how does it work?

Postby Captain.Chode » Mon Feb 17, 2020 7:34 am


I am trying to create an universal remote using the RMT peripheral based on this code: https://github.com/kimeckert/ESP32-RMT- ... t_rx_raw.c. It seems like it is working, however there is one thing that I can't quite get which is the clk_div parameter when initializing the peripheral.

If I set the clk_div to 80 then with a Samsung TV remote I get the following sequence for the Power button:

Code: Select all

I've looked up the the protocol Samsung uses and the timings are correct. It starts with 4.5 ms on and 4.5 ms off: https://www.techdesign.be/projects/011/011_waves.htm

Now with another remote (UPC set top box) if I set the clk_div to 80 I get the following sequence for its power button:

Code: Select all

It seems weird as the last element should be zero. And also if I transmit this sequence with the RMT, the device does not respond.

But if I set the clk_div to 100 I have this sequence:

Code: Select all

Transmitting this and the device responds to my ir blaster.

But with setting the clk_div to 100 the sequence of the Samsung turns to this:

Code: Select all

Transmitting this and my TV responds, so thats fine.

Now the question is that how that clk_div parameter should be set (based on what). What exactly does it mean? I would prefer it to set in a way that it would display the "correct" timings according to the Samsung remote, but that breaks other remotes which of course I don't like.

My methods to initialize the RX and TX part:

Code: Select all

void Esp32RmtRaw::InitReceive(uint8_t rxChannel, uint8_t rxPin)
    if (!_rxInited)
        _rxPin = static_cast<gpio_num_t>(rxPin);
        _rxChannel = static_cast<rmt_channel_t>(rxChannel);

        rmt_config_t rmt_rx;

        rmt_rx.channel = _rxChannel;
        rmt_rx.gpio_num = _rxPin;
        rmt_rx.clk_div = 80;//100|80
        rmt_rx.mem_block_num = 2;
        rmt_rx.rmt_mode = RMT_MODE_RX;

        rmt_rx.rx_config.filter_en = true;
        rmt_rx.rx_config.filter_ticks_thresh = 100;
        rmt_rx.rx_config.idle_threshold = 8000;

        rmt_driver_install(_rxChannel, 3000, 0);

        rmt_get_ringbuf_handle(_rxChannel, &_rb);
        rmt_rx_start(_rxChannel, 1);
        _rxInited = true;

void Esp32RmtRaw::InitTransmit(uint8_t txChannel, uint8_t txPin)
    if (!_txInited)
        _txPin = static_cast<gpio_num_t>(txPin);
        _txChannel = static_cast<rmt_channel_t>(txChannel);

        rmt_config_t rmt_tx;

        rmt_tx.channel = _txChannel;
        rmt_tx.gpio_num = _txPin;
        rmt_tx.clk_div = 80;//100|80
        rmt_tx.mem_block_num = 1;
        rmt_tx.rmt_mode = RMT_MODE_TX;

        rmt_tx.tx_config.loop_en = false;
        rmt_tx.tx_config.carrier_duty_percent = 30;
        rmt_tx.tx_config.carrier_freq_hz = 38381; //38000
        rmt_tx.tx_config.carrier_level = RMT_CARRIER_LEVEL_LOW;
        rmt_tx.tx_config.carrier_en = true;
        rmt_tx.tx_config.idle_level = RMT_IDLE_LEVEL_HIGH;
        rmt_tx.tx_config.idle_output_en = false;

        rmt_driver_install(_txChannel, 0, 0);
        rmt_rx_start(_txChannel, 1);

        _txInited = true;

Who is online

Users browsing this forum: ESP_Roland and 38 guests