cesp32uart

Getting garbled data from UART on ESP32 from DSMR5 meter


I'm trying to read out my DSMR5 electricity meter on an ESP-WROOM-32. I've connected the 3.3v from the ESP to the RTS on the meter, and connected the ground and TXD from the meter to the ground and RX2 (GPIO 16) on the ESP.

I've taken the simple UART echo example in the ESP-IDF and slightly modified it (no need to echo anything back). I'm getting data every second, as expected (that's what the DSMR5 spec says), but the data is garbled. I cannot figure out why.

I've checked that the baud rate is set to 115200, parity is disabled, 1 stop bit, 8 bit data. I've also tried setting the XTAL frequency. When it's set to anything but 40 I get random data coming in even when the cable is unplugged.

I'm quite at a loss as to what it could be, I have the following code:

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/uart.h"
#include "driver/gpio.h"
#include "sdkconfig.h"
#include "esp_log.h"

#define ECHO_TASK_STACK_SIZE    (CONFIG_EXAMPLE_TASK_STACK_SIZE)

static const char *TAG = "UART TEST";

#define BUF_SIZE (1024)

static void echo_task(void *arg)
{
    /* Configure parameters of an UART driver,
     * communication pins and install the driver */
    uart_config_t uart_config = {
        .baud_rate = 115200,
        .data_bits = UART_DATA_8_BITS,
        .parity    = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
        .source_clk = UART_SCLK_DEFAULT,
    };
    int intr_alloc_flags = 0;

#if CONFIG_UART_ISR_IN_IRAM
    intr_alloc_flags = ESP_INTR_FLAG_IRAM;
#endif

    ESP_ERROR_CHECK(uart_driver_install(2, BUF_SIZE * 2, 0, 0, NULL, intr_alloc_flags));
    ESP_ERROR_CHECK(uart_param_config(2, &uart_config));
    ESP_ERROR_CHECK(uart_set_pin(2, 17, 16, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));

    // Configure a temporary buffer for the incoming data
    uint8_t *data = (uint8_t *) malloc(BUF_SIZE);

    while (1) {
        // Read data from the UART
        int len = uart_read_bytes(2, data, (BUF_SIZE - 1), 20 / portTICK_PERIOD_MS);
        if (len) {
            data[len] = '\0';
            ESP_LOGI(TAG, "Recv str: %s", (char *) data);
        }
    }
}

void app_main(void)
{
    gpio_config_t io_conf = {
        .intr_type = GPIO_INTR_DISABLE,
        .mode = GPIO_MODE_INPUT,
        .pin_bit_mask = (1ULL << 16),
        .pull_down_en = GPIO_PULLDOWN_DISABLE,
        .pull_up_en = GPIO_PULLUP_ENABLE,
    };

    gpio_config(&io_conf);

    xTaskCreate(echo_task, "uart_echo_task", ECHO_TASK_STACK_SIZE, NULL, 10, NULL);
}

The output I am getting is things like this:

I (28996) UART TEST: Recv str: 
JTky=��fL�ff�������2ky=��fL�ff�^>>>>2Z��=gifLL��"F>^2Z^>J>��ffӦL�ͦ�f�&���&�fVk�������ff&fM��ͦ�f&��&&&&���������&ff5Fkͦ�f�&��&�&�&���������L�fM�M=gifLff�34�������M������M�=gifLff�ff������M�=��fL�f�&f��MM=gifLfff�����f3fͥM=gifL�34d4��&ff�V�Z��O��fLfff����fsfͥM=gifL��f���ffMiS�:J>*:F"F>^����MiS�:J>":F"F>^>>�fMiS�:J>6:F"F>^>>F6���5JTky=gif̙f
I (29976) UART TEST: Recv str: 3f���34g&fMI�M�=gif̦ff���f�f��MIky=gif�ffd4���f���fMI�M�=gif�34d4���f��fMI�M�=gi��fff����4��fMI���=o�2]��
--- Warning: Failed to decode multiple lines in a row. Try checking the baud rate and XTAL frequency setting in menuconfig
--- Warning: Failed to decode multiple lines in a row. Try checking the baud rate and XTAL frequency setting in menuconfig&f&�M�=gifLf�������&�&f�&ff
����M�=gifLff�ff������M�=gifL�34f24������M�=gifLff�ff�����F�M�=��fL�f�&f��MM�=gifLfff�����f�V�Z��:@�fL�34d4��&&f�fͥM�=gifLfff����f�fͥM�=gifL�ff����ffMiS�:J>�1eg4d4����MiS�:J>":F"F>^>>>V@iS�~J>6:F"F>^>>F6*:�5JTky=gif
                                                     �ff���
--- Warning: Failed to decode multiple lines in a row. Try checking the baud rate and XTAL frequency setting in menuconfig
y=��fL�f�f������&�&&fcf&�&�&�&&&�&�L�&�&ef3f�M�=gifLf�F:^>>>��&f�&ffMI�IM�=gifLf��43���&�L̳fffMI�IM�=gif�f�F:^>>|:*F>2:VR@�IM�=gif�f�F6^>>>6&2�4g&fMI�IM=��fL�f��f����f�M�=gifLff���f4�3�MI�M�=gif�ff���f���fMI�M�=��fL�ff�g����f�M�=��fL�ff�^����&�M�=gifLL��"F>^2��ͦ�fL�ff��L͍3ef�&ge&�f&���������ff&fMkͦ�f�&��&&&F��������&fffM��ͦ�f�&��&�&eVk��������L�fM�M�=gifLff�ff��������M�=gi1e34f34�����f�M�=gif
                                                                      d34f34������M�=gifL34f24������M�=gifL��4f24�����gky=gifLff�ff������ky=��fL�f�&f��MM�=gi1f3_ky=gifL�ff�����fMiy=gif̦ff����f���fM1d34Tky=gif̙ff���ff��4d4���ffM�S�:J>*@ff������
--- Warning: Failed to decode multiple lines in a row. Try checking the baud rate and XTAL frequency setting in menuconfig
I (32036) UART TEST: Recv str: 
                               5JTky=gif̦ff����f�2�5JTky=gif�fff���f���fMI�M�=gif̙34d4��f���fMI�M�=gif�ff4���f���fMI�M�=o.�&��=hZ.YeZ_[._iY]��+y=y=gif1f�f�^*>Z��>J>:F>F��ͦ�f����L�&�L�M�=��1c24g4g͙��&�&&&�L�&&�&�F&&�&�L�&�&�&f&�ky=gifLf�F:^>>>2.2F>�ffMI�IM�=gifLf�F6^>>���L��f&fMI�IM�=gif�f�������L�4&�fMI�IM�=gif�f�F6^>>>6&2JTky=gif�34d4���f���5JTky=��fL�ff������f�M�=��fL�ff�^>>>>2�M�=gifLL��"F>^2Z^>J>�1c24d4gckͦ�f�&���&�3Vk�������ff&fM��ͦ�2&��&&&&���������&f35Fkͦ�f�&��&�&�&���������L�fM�M=gifLfff34������M�=gifL�34f34�����f�M�=gifLff�f4�������M�=gifLff�ff������M�=gifL�34f24�����F�M�=gifLff�ff�������M�=�fL�f�&f��MM�=gifLff4����f�V�Z��:J>*6F"�4��&&f3fͥM�=gifLff4����f�V�Z��:J>2:F"�4���ffMiS�:J|*:F"F>�����MiS�:��fL�ff�����fMiS�:J>�13g4d4���f���fMI�M�=gif̙ff���ffӦffMI�M
I (33016) UART TEST: Recv str: =gif̦ff����f�f�fMIky=gif�ffd4���f���5JTky=gif̙34d4���f��fMI�M�=gif�fff����4��fMI�M�=of.23y=hZ.YeZ_[._iY]��+y=y=gif1434�M��M�=��fLf�f���ef����L�&�L�M�=��fL�4g4g͙��&�&&&�L�&�&�f&&&�&�L�f�&�&f&�M�=gifLf�F:^>>>2.2F>"6V�I�IM�=gi�Lf�F6^>>>2@̳f&fMI�IM�=gif�f�F:�����L�4&�fMI�IM�=gi134̳����ff&f��&fMI�k--- Warning: Failed to decode multiple lines in a row. Try checking the baud rate and XTAL frequency setting in menuconfig

Interestingly, certain patterns seem to be recurring, I keep seeing the string gif in the output. It doesn't seem to be completely random. Any idea what the issue could be here? I've tried both using the internal pullup (as you can see in the code) as well as putting a 10kOhm resistor between the 3.3v and RXD.


Solution

  • DSMR5 serial output uses inverted polarity comparing to UART. You should invert signal back before applying it to RX pin.