I'm using a custom board where there are a microprocessor that collects informations and the Esp32 reads that informations via modBus.
Now my problem is that sometimes (i have no clue when or why that happends) i see an extra byte in the response and is always the first byte and always at 0x00.
I checked with the oscilloscope and the response length of the micro is correct
It usually works correctly, but once it gives a wrong answer of that type it corrupts all the readings
This is how I initialize the uart:
Code: Select all
// *****************
// UART CONFIGURATION (modbus)
// *****************
uart_config_t uart_config;
uart_config.baud_rate = BAUDRATE_DEFAULT;
uart_config.data_bits = UART_DATA_8_BITS;
uart_config.parity = UART_PARITY_DISABLE;
uart_config.stop_bits = UART_STOP_BITS_1;
uart_config.flow_ctrl = UART_HW_FLOWCTRL_DISABLE;
uart_config.rx_flow_ctrl_thresh = 122;
uart_param_config(UART_NUM_1, &uart_config);
uart_set_pin(UART_NUM_1, TXD_PIN, RXD_PIN, TX_EN_PIN, UART_PIN_NO_CHANGE);
uart_driver_install(UART_NUM_1, RX_BUF_SIZE * 2, 0, 0, NULL, 0);
SET_PERI_REG_MASK(UART_MEM_CONF_REG(UART_NUM_1), 0X10);
CLEAR_PERI_REG_MASK(UART_MEM_CONF_REG(UART_NUM_1), 0X08);
// Set RS485 half duplex mode
uart_set_mode(UART_NUM_1, UART_MODE_RS485_HALF_DUPLEX);
And these are the functions to read the data from the micro:
Code: Select all
unsigned char TX_UARTBuffer[280]
unsigned char bufferricezione1[512];
int send_pkt_sngl_and_rcv_answer(unsigned char bytes_to_send, int responseLenght)
{
static TickType_t timer_timeout = 0;
unsigned long timeout_variable = 500;
int len, lenghtTX = 0;
switch (MB_master_FSM)
{
case TXing:
{
if (GET_PERI_REG_MASK(UART_STATUS_REG(UART_NUM_1), (UART_ST_UTX_OUT_M | UART_ST_URX_OUT_M)) == 0)
{
memset(bufferricezione1, 0, responseLenght);
lenghtTX = uart_write_bytes(UART_NUM_1, (const char*)TX_UARTBuffer, bytes_to_send);
MB_master_FSM = TX_ENABLE_RESETTING;
}
else
{
vTaskDelay(pdMS_TO_TICKS(50));
}
}
break;
case TX_ENABLE_RESETTING:
{
if (isModbusPacketSent())
{
MB_master_FSM = START_TIMER;
}
}
break;
case START_TIMER:
{
timer_timeout = xTaskGetTickCount(); // timeout timer
MB_master_FSM = RX_WAITING;
}
break;
case RX_WAITING:
{
len = uart_read_bytes(UART_NUM_1, bufferricezione1, BUF_SIZE, pdMS_TO_TICKS(1 + 40000 / QBO_memory.serial_data.baudrate));
if (len >= responseLenght)
{
if (len > responseLenght)
{
for (int i = 0; i < len; i++)
{
printf(" TX_UARTBuffer %d: 0x%.2X | ", i, (uint8_t)TX_UARTBuffer[i]);
printf(" i %d val %x", i, bufferricezione1[i]);
}
}
MB_master_FSM = NEXT_MSG_SET;
}
else if (len == 5)
{
MB_master_FSM = TXing;
return EXCEPTION;
}
else if ((xTaskGetTickCount() - timer_timeout) < timeout_variable)
{
}
else
{
MB_master_FSM = TXing;
exception = 1;
return NO_RESPONSE;
}
}
break;
case NEXT_MSG_SET:
{
MB_master_FSM = TXing;
return MB_OK;
}
break;
default:
break;
}
return WAITING;
}
signed long readSingleRegister(int zone, int index)
{
unsigned short crc;
unsigned char j = 0;
int response = 0;
int responseLenght = 7;
TX_UARTBuffer[0] = zone;
TX_UARTBuffer[1] = READ_HOLDING;
TX_UARTBuffer[2] = ((index & 0xFFFF) >> 8);
TX_UARTBuffer[3] = index & 0x00FF;
TX_UARTBuffer[4] = 0x00;
TX_UARTBuffer[5] = 0x01;
j = 6;
crc = modbusCRC(TX_UARTBuffer, j);
TX_UARTBuffer[j++] = crc & 0xff;
TX_UARTBuffer[j++] = (crc >> 8) & 0xff;
MB_master_FSM = TXing;
do
{
vTaskDelay(5);
response = send_pkt_sngl_and_rcv_answer(j, responseLenght);
} while (response < MB_OK);
if (exception == 0)
{
memset(TX_UARTBuffer, 0, 8);
uint32_t val = WORD(bufferricezione1[3], bufferricezione1[4]);
return val;
}
else
{
return response;
}
}
Code: Select all
TX_UARTBuffer 0: 0xF0 | i 0 val 0
TX_UARTBuffer 1: 0x03 | i 1 val f0
TX_UARTBuffer 2: 0x00 | i 2 val 3
TX_UARTBuffer 3: 0x88 | i 3 val 2
TX_UARTBuffer 4: 0x00 | i 4 val 0
TX_UARTBuffer 5: 0x01 | i 5 val 0
TX_UARTBuffer 6: 0x11 | i 6 val c5
TX_UARTBuffer 7: 0x01 | i 7 val 91