RMT, 1-Wire Slave and timing woes in general

pmckeon
Posts: 9
Joined: Sat Aug 18, 2018 9:18 am

RMT, 1-Wire Slave and timing woes in general

Postby pmckeon » Wed Aug 12, 2020 10:40 am

I have a project that requires me to emulate a simple 1-Wire Slave device.

HoHo, no problem pmckeon! I hear you say, just use https://github.com/orgua/OneWireHub

Except it's part of an existing project I've mostly completed in the native Espressif IDF and that library was made to work with the Arduino framework. I did try compiling it under the IDF tools but there were far too many compiler errors and warnings than I want to deal with right now in trying to port it over, plus it's a bit heavy for my needs anyway.

Fortunately 1-Wire protocol is relatively simple, the timing as I have discovered not so much.

I had something that sort of worked using a pin interrupt and high resolution timers but I found overheads of some functions and calls were causing me to miss the 60μs time-slot required by the Master device.

So, similar to the above library and it's initial discussion here:
viewtopic.php?t=3655

I'm trying to use the RMT peripheral and have setup a test case to read the 1-Wire bus but I either get an initial burst of random data or simply no data at all instead of the expected Reset pulse of about 480-500μs.

I have no idea if it's the way I've setup the RMT configuration or something else entirely.

Code: Select all

static void gun_owbrmt_task(void *pvParameter)
{
    uint32_t length = 0;
    RingbufHandle_t rb = NULL;
    rmt_item32_t *items = NULL;

    rmt_config_t rmt_conf;
    rmt_conf.channel = RMT_CHANNEL_0;
    rmt_conf.rmt_mode = RMT_MODE_RX;
    rmt_conf.gpio_num = GPIO_OWBSLAVE_INPUT;
    rmt_conf.mem_block_num = 1;
    rmt_conf.flags = 0;
    rmt_conf.clk_div = 80;

    rmt_rx_config_t rx_conf;
    rx_conf.filter_en = true;
    rx_conf.filter_ticks_thresh = 30;
    rx_conf.idle_threshold = 77;
    rmt_conf.rx_config = rx_conf;
    rmt_config(&rmt_conf);
    rmt_driver_install(RMT_CHANNEL_0, 1000, 0);

    rmt_get_ringbuf_handle(RMT_CHANNEL_0, &rb);
    rmt_rx_start(RMT_CHANNEL_0, true);

    while(rb)
    {
        items = (rmt_item32_t *) xRingbufferReceive(rb, &length, portMAX_DELAY);
        length /= 4;

        for(int i=0; i < length; i++)
        {
            ESP_LOGI(TAG, "[%d]Pulse (%d), [%d]Pulse (%d)\n", items[i].level0, items[i].duration0, items[i].level1, items[i].duration1);
        }

        vRingbufferReturnItem(rb, (void *) items);
    }

    ESP_LOGE(TAG, "gun_owbrmt_task quit unexpectedly!");
    rmt_driver_uninstall(RMT_CHANNEL_0);
    vTaskDelete(NULL);
}

pmckeon
Posts: 9
Joined: Sat Aug 18, 2018 9:18 am

Re: RMT, 1-Wire Slave and timing woes in general

Postby pmckeon » Thu Aug 13, 2020 7:45 am

After a break and a bit of a rethink I finally got it working, though slightly puzzled why it didn't in previous tests.

I didn't initially fully understand the relationship between rmt_conf.clk_div and tick rate and now I do, I was never sure on the correct values to set for rx_conf.filter_ticks_thresh and rx_conf.idle_threshold, I mostly just copied values from other similar projects.

I now under stand that with APB Clock of 80MHz and Clock Divider of 80MHz = tick rate of 1μs so exact values can be used for the two threshold parameters. I got confused because elsewhere on this forum someone said it was 1ms not 1μs.

The second area of confusion was that I assumed based on the documentation that rx_conf.filter_en applied to both threshold values, now it seems in testing that it only effects rx_conf.filter_ticks_thresh. So disabling it didn't yield any different result.

The final solution was to set rx_conf.idle_threshold to > 500 and it started working, but I'm fairly certain in some of my early tests I had it set at 1000 and I still didn't receive any pulses.

Either way it's working and I'm happy.

volandir
Posts: 1
Joined: Sun Feb 09, 2025 12:54 pm

Re: RMT, 1-Wire Slave and timing woes in general

Postby volandir » Sun Feb 09, 2025 1:56 pm

I'm using the orgua/OneWireHub library to emulate a few DS18B20 sensors, getting their data on the analog inputs. Now I decided to go wireless and get the data from an MQTT server. As soon as I enable the WiFi functionality of my Arduino Nano ESP32, I start getting CRC8 errors (tested with OneWireViewer/DS9190A master). Using RMT was the only thing that came to my mind, that's how I ended up finding your post.
You wrote that you managed to solve the timing issues, maybe you can share that part of your code?

Who is online

Users browsing this forum: ChatGPT-User, Qwantbot, YisouSpider and 5 guests