Page 1 of 1

Unable to Send RS485 data from esp32-s3 to custom keypad with MAX3483

Posted: Sun Apr 06, 2025 5:17 am
by devhari
Hi
I'm working on RS485 MAX485 communication from esp32s3 idf to silicon labs zigbee keypad(contains MAX3483 chip).
Connections:
keypad(MAX3483 ) -> TTL - RS485 Module
A -> A
B -> B
3.3V -> VCC
GND -> GND

TTL - RS485 Module -> ESP32-S3
DI -> GPIO-4
DE -> GPIO-42
RE -> GPIO-2
RO -> GPIO-5

when I try to send data from esp to zigbee side, data reception is not happening at zigbee side. I'm suspecting issue is from esp coding side.
Kindly check my configurations and let me know if any modifications required.

----------esp32-s3 idf code---------

Code: Select all

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

#define TAG "RS485_APP"

#define UART_NUM UART_NUM_1        // Use UART1
#define TXD_PIN GPIO_NUM_4         // TX pin
#define RXD_PIN GPIO_NUM_5         // RX pin
#define BAUD_RATE 9600             // Baud rate
#define RS485_DE_PIN GPIO_NUM_42    // DE pin (Drive Enable)
#define RS485_RE_PIN GPIO_NUM_2    // RE pin (Receive Enable)

uint8_t rxBuff_from_device[254];

// UART initialization
void init_uart() {
    uart_config_t uart_config = {
        .baud_rate = BAUD_RATE,
        .data_bits = UART_DATA_8_BITS,
        .parity = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE
    };

    uart_driver_install(UART_NUM, 256, 256, 0, NULL, 0);
    uart_param_config(UART_NUM, &uart_config);
    uart_set_pin(UART_NUM, TXD_PIN, RXD_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);

    // Initialize direction control pins
    gpio_set_direction(RS485_DE_PIN, GPIO_MODE_OUTPUT);
    gpio_set_direction(RS485_RE_PIN, GPIO_MODE_OUTPUT);
    
    // Default to receive mode
    gpio_set_level(RS485_DE_PIN, 1);  // DE low
    gpio_set_level(RS485_RE_PIN, 0);  // ~RE high (disabled)
}

// Function to send RS485 data to devices
void send_rs485_to_device(uint8_t *data, size_t length) {

    // Small delay to ensure mode switch before transmission
    vTaskDelay(pdMS_TO_TICKS(10));
    
    // Send data
    uart_write_bytes(UART_NUM, (const char *)data, length);
    
    // Wait for transmission to complete (1ms per byte + margin)
    vTaskDelay(pdMS_TO_TICKS(20));

    vTaskDelay(pdMS_TO_TICKS(1));
}

// Receiving data task
void get_data_from_device(void *pvParameters) {
    while (1) {
        int len = uart_read_bytes(UART_NUM, rxBuff_from_device, sizeof(rxBuff_from_device), pdMS_TO_TICKS(50));

        if (len > 0) {
            ESP_LOGI(TAG, "Received %d bytes:", len);
            for (int k = 0; k < len; k++) {
                printf("%02X ", rxBuff_from_device[k]);
            }
            printf("\n");
        }
        vTaskDelay(pdMS_TO_TICKS(1));
    }
}

// Periodic send task
void periodic_send_task(void *pvParameters) {
    // Example message to send
    uint8_t buftx[] = {0x84, 0xBA, 0x20, 0xFF, 0xFE, 0x92, 0x5E, 0x5F, 0x04, 0x01, 0x00, 0xB3, 0x11};
    
    while(1) {
        ESP_LOGI(TAG, "Sending RS485 data...");
        send_rs485_to_device(buftx, 13);
        
        // Wait before next transmission
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
}

void app_main(void) {
    init_uart();
    xTaskCreate(periodic_send_task, "periodic_send_task", 4096, NULL, 4, NULL);
}
why data not receiving at silabs side, check issue is whether esp or silabs side for transmitting from esp to zigbee side

Re: Unable to Send RS485 data from esp32-s3 to custom keypad with MAX3483

Posted: Sun Apr 06, 2025 5:18 am
by devhari

Code: Select all

----------silicon labs zigbee code---------

[code]#define RX_BUFF_LEN 64
volatile uint16_t txFrameLength;
uint8_t txSum = 0;
volatile uint16_t Rx_Buff[RX_BUFF_LEN] = {0};
static uint16_t Rx_Buff_Len = 0;
#define RX_BUFF_SIZE 128



void USART2_RX_IRQHandler(void)
{

    uint32_t flags;
    flags = USART_IntGet(USART2);
    USART_IntClear(USART2, flags);

    uint32_t data;

    // Start a timer (HW timer)
    TIMER_CounterSet(TIMER1, 1);
    TIMER_Enable(TIMER1, true);

    data = (uint32_t)USART_Rx(USART2);
    if (Rx_Buff_Len < RX_BUFF_SIZE) // Ensure no overflow
    {
        Rx_Buff[Rx_Buff_Len++] = data;
       // emberAfCorePrintln("%02X ", data);
    }
    else
    {
        emberAfCorePrintln("Rx_Buff overflow");
    }
}

void TIMER1_IRQHandler(void)
{

  uint32_t flags = TIMER_IntGet(TIMER1);
  TIMER_IntClear(TIMER1, flags);

  TIMER_Enable(TIMER1,false);
  processReceivedData();
  Rx_Buff_Len = 0;
}

void USART1_TX_IRQHandler(void) {

    uint32_t flags;
    flags = USART_IntGet(USART1);
    USART_IntClear(USART1, flags);

    if (flags & USART_IF_TXC)
    {
       // emberAfCorePrintln("Transmission complete");
    }

    GPIO_PinOutClear(WRITE_PORT, WRITE_PIN);
    GPIO_PinOutClear(READ_PORT, READ_PIN);
}

void Init_Hw_Timer()
{
    emberAfCorePrintln("====Init_Hw_Timer");

    CMU_ClockEnable(cmuClock_TIMER1, true);

    TIMER_InitCC_TypeDef timerCCInit = TIMER_INITCC_DEFAULT;
    timerCCInit.mode = timerCCModeCompare;
    TIMER_InitCC(TIMER1, 0, &timerCCInit);

    TIMER_Init_TypeDef timerInit = TIMER_INIT_DEFAULT;
    timerInit.prescale = timerPrescale4;
    timerInit.enable = false;

    TIMER_Init(TIMER1, &timerInit);
    TIMER_TopSet(TIMER1, 0xFFFF);

    TIMER_IntEnable(TIMER1, TIMER_IEN_CC0);
    NVIC_EnableIRQ(TIMER1_IRQn);
}

void Serial_Init()
{
    // Enable clocks for USART1 (TX) and USART2 (RX)
    CMU_ClockEnable(cmuClock_USART1, true);
    CMU_ClockEnable(cmuClock_USART2, true);

    // Initialize USART1 for TX
    USART_InitAsync_TypeDef initTX = USART_INITASYNC_DEFAULT;
    initTX.baudrate = 9600;

    // Set pin modes for USART1 TX pin
    GPIO_PinModeSet(SERIAL_TX_PORT, SERIAL_TX_PIN, gpioModePushPull, 1);  // Tx
    GPIO_PinModeSet(READ_PORT, READ_PIN, gpioModePushPull, 0);  // Control GPIO
    GPIO_PinModeSet(WRITE_PORT, WRITE_PIN, gpioModePushPull, 0); // Control GPIO

    GPIO_PinOutClear(READ_PORT, READ_PIN);
    GPIO_PinOutClear(WRITE_PORT, WRITE_PIN);

    // Route USART1 TX pin
    GPIO->USARTROUTE[1].TXROUTE = (SERIAL_TX_PORT << _GPIO_USART_TXROUTE_PORT_SHIFT)
                                | (SERIAL_TX_PIN << _GPIO_USART_TXROUTE_PIN_SHIFT);
    GPIO->USARTROUTE[1].ROUTEEN = GPIO_USART_ROUTEEN_TXPEN;

    // Initialize USART1 in asynchronous mode
    USART_InitAsync(USART1, &initTX);

    // Initialize USART2 for RX
    USART_InitAsync_TypeDef initRX = USART_INITASYNC_DEFAULT;
    initRX.baudrate = 9600;

    // Set pin modes for USART2 RX pin
    GPIO_PinModeSet(SERIAL_RX_PORT, SERIAL_RX_PIN, gpioModeInput, 0);   // Rx
    GPIO->USARTROUTE[2].RXROUTE = (SERIAL_RX_PORT << _GPIO_USART_RXROUTE_PORT_SHIFT)
                                | (SERIAL_RX_PIN << _GPIO_USART_RXROUTE_PIN_SHIFT);
    GPIO->USARTROUTE[2].ROUTEEN = GPIO_USART_ROUTEEN_RXPEN;

    // Initialize USART2 in asynchronous mode
    USART_InitAsync(USART2, &initRX);

    // Enable RX and TX interrupts for USART2 and USART1
    USART_IntEnable(USART2, USART_IEN_RXDATAV);
    NVIC_ClearPendingIRQ(USART2_RX_IRQn);
    NVIC_EnableIRQ(USART2_RX_IRQn);

    USART_IntEnable(USART1, USART_IEN_TXC);
    NVIC_ClearPendingIRQ(USART1_TX_IRQn);
    NVIC_EnableIRQ(USART1_TX_IRQn);

    // Initialize the hardware timer
    Init_Hw_Timer();
}
[/code]