Using RMT to read 433Mhz signal

nozomiman
Posts: 3
Joined: Sat Aug 12, 2023 10:17 am

Using RMT to read 433Mhz signal

Postby nozomiman » Sat Aug 12, 2023 10:42 am

I want to read 433MhZ binary data using ESP32 RMT peripheral. The wave form can be seen here https://imgur.com/a/4vqZOHZ.

using RTL_433 with rtl_433 -R 0 -X 'n=name,m=OOK_PCM, s=800, l=800, g=2000,r=6000'

time : 2023-08-12 20:08:07
model : name count : 2 num_rows : 2 rows :
len : 65 data : aaaaaaaaaaaaaaaa0,
len : 82 data : aa5999a5a699965666950
codes : {65}aaaaaaaaaaaaaaaa0, {82}aa5999a5a69996566695

I have been using the Arduino code here - https://www.espboards.dev/blog/esp32-433-rmt-ev1527/ as basis for what Ive done.

The data which I am reading with the following ESP-IDF code does not match.

I am new to RMT peripheral and how to use it.

Could I get some guidance on how to read the wave form using RMT?

Do I need to define a carrier wave so I can read? Like the example in the Arduino code? Would my carrier frequency be? 1/800 Mhz?

Are there any references I could read to learn how to turn the timings to binary data?

The timings appear to match the wave form? Is converting these my issue?
  • Frame start 47---
    {1:735},{0:914}
    {1:758},{0:905}
    {1:771},{0:897}
    {1:809},{0:840}
    {1:837},{0:859}
    {1:797},{0:868}
    {1:803},{0:862}
    {1:815},{0:861}
    {1:812},{0:840}
    {1:850},{0:815}
    {1:867},{0:815}
    {1:834},{0:847}
    {1:841},{0:832}
    {1:843},{0:818}
    {1:839},{0:834}
    {1:846},{0:817}
    {1:854},{0:818}
    {1:843},{0:840}
    {1:857},{0:4978}
    {1:845},{0:915}
    {1:832},{0:935}
    {1:823},{0:949}
    {1:840},{0:1817}
    {1:992},{0:837}
    {1:1850},{0:1876}
    {1:1777},{0:1768}
    {1:1759},{0:1793}
    {1:1791},{0:990}
    {1:841},{0:1859}
    {1:1026},{0:825}
    {1:1805},{0:918}
    {1:843},{0:1747}
    {1:1791},{0:966}
    {1:845},{0:1843}
    {1:1832},{0:1870}
    {1:1809},{0:1748}
    {1:939},{0:814}
    {1:1800},{0:1796}
    {1:1003},{0:824}
    {1:1014},{0:836}
    {1:1870},{0:1790}
    {1:1745},{0:1775}
    {1:1793},{0:968}
    {1:843},{0:1823}
    {1:1010},{0:836}
    {1:1040},{0:817}
    {1:886},{0:0}
    ---Frame end:
    3 3 3 3 2 1 0 0 0 3 3 2 2 2 2 1 1 2 0 0 1 1 0
The code I have tried

Code: Select all

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "esp_log.h"
#include "driver/rmt_rx.h"


// Set the RMT channel number
#define RMT_CHANNEL 0

static const char *TAG ="RMTExample";

static void parse_frame(rmt_symbol_word_t *items, size_t numItems)
{
    uint8_t data[numItems / 2];
    printf("Frame start %d---\r\n", numItems);
    for (size_t i = 0; i < numItems; i++) {
        printf("{%d:%d},{%d:%d}\r\n", items[i].level0, items[i].duration0, items[i].level1, items[i].duration1);
        uint8_t high = items[i * 2].duration1 > items[i * 2].duration0 ? 1 : 0;
        uint8_t low = items[i * 2 + 1].duration1 > items[i * 2 + 1].duration0 ? 1 : 0;
        data[i] = (high << 1) | low;
    }
    printf("---Frame end: \r\n");
    for (int i = 0; i < numItems / 2; i++) {
        printf("%x ", data[i]);
    }
    printf ("\r\n");

}

static bool example_rmt_rx_done_callback(rmt_channel_handle_t channel, const rmt_rx_done_event_data_t *edata, void *user_data)
{
    BaseType_t high_task_wakeup = pdFALSE;
    QueueHandle_t receive_queue = (QueueHandle_t)user_data;
    // send the received RMT symbols to the parser task
    xQueueSendFromISR(receive_queue, edata, &high_task_wakeup);
    return high_task_wakeup == pdTRUE;
}


void app_main(void)
{
    rmt_rx_channel_config_t rx_channel_cfg = {
        .clk_src = RMT_CLK_SRC_DEFAULT,
        .resolution_hz = 1000000, // 1MHz resolution, 1 tick = 1us,
        .mem_block_symbols = 256, // number of RMT symbols that the channel can store at a time
        .gpio_num = GPIO_NUM_4,
    };

    rmt_channel_handle_t rx_channel = NULL;
    ESP_ERROR_CHECK(rmt_new_rx_channel(&rx_channel_cfg, &rx_channel));

    ESP_LOGI(TAG, "register RX done callback");
    QueueHandle_t receive_queue = xQueueCreate(1, sizeof(rmt_rx_done_event_data_t));
    
    assert(receive_queue);

    rmt_rx_event_callbacks_t cbs = {
        .on_recv_done = example_rmt_rx_done_callback,
    };

    ESP_ERROR_CHECK(rmt_rx_register_event_callbacks(rx_channel, &cbs, receive_queue));

    // rmt_carrier_config_t rx_carrier_cfg = {
    //     .duty_cycle = 0.33,                 // duty cycle 33%
    //     .frequency_hz = 25000,              // 25 KHz carrier, should be smaller than the transmitter's carrier frequency
    //     .flags.polarity_active_low = false, // the carrier is modulated to high level
    // };
    // demodulate carrier from RX channel
    // ESP_ERROR_CHECK(rmt_apply_carrier(rx_channel, &rx_carrier_cfg));


    rmt_receive_config_t receive_config = {
        .signal_range_min_ns = 650000,     // 650-ms What should this be set to?
        .signal_range_max_ns = 20000000,   // 20s What should this be set to?
    };


    ESP_ERROR_CHECK(rmt_enable(rx_channel));

    rmt_symbol_word_t raw_symbols[256]; // 256 symbols should be sufficient 
    rmt_rx_done_event_data_t rx_data;
    // ready to receive

    ESP_ERROR_CHECK(rmt_receive(rx_channel, raw_symbols, sizeof(raw_symbols), &receive_config));
    while (1) {
        // wait for RX done signal
        if (xQueueReceive(receive_queue, &rx_data, pdMS_TO_TICKS(1000)) == pdPASS) {
            // parse the receive symbols and print the result
            parse_frame(rx_data.received_symbols, rx_data.num_symbols);
            // start receive again
            ESP_ERROR_CHECK(rmt_receive(rx_channel, raw_symbols, sizeof(raw_symbols), &receive_config));
        }
    }
}

MicroController
Posts: 1708
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: Using RMT to read 433Mhz signal

Postby MicroController » Sun Aug 13, 2023 10:13 am

Is converting these my issue?
It looks like it is.
For one,
data[numItems / 2];
...
for (size_t i = 0; i < numItems; i++) {
...
data[ i ] = ...
}

writes past the array's end; and items[i * 2] reads beyond the input's length.

Then, the pulses you receive are either ~900 or ~1800 long, so you should just compare the pulse length to (1800+900)/2 = 1350 to distinguish between '1' and '0'.
As there are two pulses in each rmt_symbol_word_t, you get two bits per symbol; i.e. you need to collect four symbols into one byte.

Who is online

Users browsing this forum: username and 137 guests