2022-08-09 11:48 PM
Hello. I am trying to implement my own MODBUS write registers and read registers commands. I have connected serial analyzer to A and B pins of the transceiver and can monitor what I send and what I receive.
The stm32 that I am programming is acting as a master and I use modbus slave simulator on my pc to simulate slave device:
https://www.modbustools.com/modbus_slave.html
I have connect RS485 -> USB converter from my A B pins to PC via the USB cable.
uint8_t MODBUS_write_holding(uint8_t slave_id,uint16_t start_address,uint16_t value){
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_15, 1); // ENABLE THE TRANSCEIVER
uint8_t message_buffer[20];
message_buffer[0] = slave_id;
message_buffer[1] = WRITE_SINGLE_HOLDING;
message_buffer[2] = ((uint16_t)start_address >> 8) & 0xFF;
message_buffer[3] = ((uint16_t)start_address >> 0) & 0xFF;
message_buffer[4] = ((uint16_t)value >> 8) & 0xFF;
message_buffer[5] = ((uint16_t)value >> 0) & 0xFF;
uint16_t crc = MODBUS_CRC16_v3(message_buffer,6);
message_buffer[6] = ((uint16_t)crc >> 0) & 0xFF;
message_buffer[7] = ((uint16_t)crc >> 8) & 0xFF;
HAL_UART_Transmit(&huart4, message_buffer, 8, 10);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_15, 0); // DISABLE THE TRANSCEIVER
return 0;
}
and I call it as following:
MODBUS_write_holding(1,4,0x1234);
The function is supposed to write value 0x1234 to holding register with an offset of 4.
Serial analyzer:
Modbus slave simulator:
As you can see from above, the value on the modbus simulator has been updated to 4660 when I have executed the command so everything seems to be working fine.
However, I have issues when I try to read back the register. I use the following command:
uint8_t MODBUS_read_multiple_holding(uint8_t slave_id,uint16_t start_address,uint16_t number_of_registers){
//printf("Reading multiple holding register \n");
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_15, 1); // PULL LCD CS PIN HIGH
uint8_t message_buffer[20];
message_buffer[0] = slave_id;
message_buffer[1] = READ_MULTIPLE_HOLDING;
message_buffer[2] = ((uint16_t)start_address >> 8) & 0xFF;
message_buffer[3] = ((uint16_t)start_address >> 0) & 0xFF;
message_buffer[4] = ((uint16_t)number_of_registers >> 8) & 0xFF;
message_buffer[5] = ((uint16_t)number_of_registers >> 0) & 0xFF;
uint16_t crc = MODBUS_CRC16_v3(message_buffer,6);
message_buffer[6] = ((uint16_t)crc >> 0) & 0xFF;
message_buffer[7] = ((uint16_t)crc >> 8) & 0xFF;
HAL_UART_Transmit(&huart4, message_buffer, 8, 10);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_15, 0); // PULL LCD CS PIN HIGH
return 0;
}
and I call it my main as following:
MODBUS_read_multiple_holding(1,4,1);
If I implemented the command correctly, this command should read 1 register at offset 4 from the slave ID = 1.
The serial analyzer output:
As you can see from above, the serial analyzer picked up signal and received a response after 50ms.
If I zoom in to modbus request to read register:
This is modbus response 50ms after the request:
The response does not seem to be correct. I would like to understanding what is happening here and what could be the issue. I would appreciate a lot if someone could help me out here thanks in advance.