RMT peripheral clk_div how does it work?

Captain.Chode
Posts: 15
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

Hi,

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

4467,-4471,541,-1687,542,-1685,568,-1661,567,-546,569,-546,541,-573,540,-574,567,-547,542,-1685,568,-1660,568,-1660,542,-573,540,-573,568,-547,541,-572,542,-572,568,-546,542,-1685,569,-546,542,-572,540,-574,567,-547,542,-572,540,-574,567,-1661,566,-547,569,-1659,540,-1688,542,-1686,568,-1660,568,-1660,566,-1661,569,0
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

-4461,603,-526,599,-529,601,-526,601,-527,602,-525,603,-1627,602,-527,598,-530,599,-528,601,-526,602,-527,602,-1627,599,-529,598,-530,600,-528,601,-527,602,-525,627,-501,603,-525,603,-525,598,-530,601,-527,601,-527,600,-527,603,-1627,603,-1626,601,-1629,601,-1628,602,-1628,602,-1627,598,-1631,603,-1626,604
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

7193,-3571,482,-421,479,-423,478,-425,477,-425,497,-405,481,-1302,483,-420,479,-424,477,-425,478,-424,480,-422,481,-1302,483,-420,482,-421,478,-424,478,-424,480,-423,481,-421,481,-421,482,-421,481,-421,479,-423,479,-424,478,-424,478,-1305,481,-1303,478,-1306,478,-1305,480,-1304,481,-1303,477,-1306,478,-1306,479,0
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

3626,-3604,431,-1367,472,-1320,476,-1322,451,-465,455,-444,412,-486,412,-487,451,-447,456,-1320,476,-1322,452,-1344,430,-486,434,-464,456,-443,433,-464,455,-443,457,-442,412,-1366,474,-443,432,-465,434,-465,456,-443,433,-464,454,-444,456,-1322,473,-444,456,-1321,474,-1325,450,-1344,475,-1321,473,-1342,455,-1323,474,0
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_config(&rmt_rx);
        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_config(&rmt_tx);
        rmt_driver_install(_txChannel, 0, 0);
        rmt_rx_start(_txChannel, 1);

        _txInited = true;
    }
}

mauribr123
Posts: 6
Joined: Mon Mar 22, 2021 7:47 pm

Re: RMT peripheral clk_div how does it work?

Postby mauribr123 » Mon Mar 22, 2021 7:51 pm


Hi guys, I have exactly the same doubts as the author of the post and tried to reread the documents several times and there were some loose ends in relation to the clock_div with the reception timing being changed ... Could someone there at Espressif could give a hand ?

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

Re: RMT peripheral clk_div how does it work?

Postby ESP_Sprite » Tue Mar 23, 2021 4:19 am

Please state a question if you want to have an answer. We can't clear up 'loose ends' if we don't know what they are. Wrt the original post you are replying to: I did not see it at the time it was posted (more than a year ago) but I suspect that guy is interpreting the 16-bit returned values as signed integers, hence the negative numbers and the weirdness. In general, clk_div pre-divides the 80MHz APB clock by a certain number, and the resulting frequency is used as the timebase for the RMT results and values written.

Captain.Chode
Posts: 15
Joined: Mon Mar 11, 2019 4:23 pm

Re: RMT peripheral clk_div how does it work?

Postby Captain.Chode » Tue Mar 23, 2021 3:25 pm

Yes, I converted the 16-bit returned values to signed integers based on the level property in rmt_item32_t. But that doesn't explain the "weirdness". Which was the fact that with one clk_div setting it was working, but with another one it didn't. A you can see I had negative values both in the working, and non-working examples as well.

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

Re: RMT peripheral clk_div how does it work?

Postby ESP_Sprite » Wed Mar 24, 2021 9:43 am

Ah. In that case, it gets harder to say. One of the things is that the idle_treshold is in ticks and is set to a relatively low number in your code. If somehow the remote sends out something with a longer duration than that, the RMT thinks the transmission is done. By increasing the RMT divider, you also increase the (actual wall-clock) time that timeout is. Possibly that allows the 2nd remote controller to be processed correctly.

Who is online

Users browsing this forum: Google [Bot] and 48 guests