Closed SuriyaMeras closed 3 years ago
Can you provide more details about your environment? For example microcontroller, type of modbus operation, length, steps to reproduce the issue, etc. Thanks
I am using STM32F429 on a custom board, It is configured as modbus master
{ ModbusH.uiModbusType = MASTER_RTU; ModbusH.port = &huart4; ModbusH.u8id = 0; //Master ID ModbusH.u16timeOut = 1000; ModbusH.EN_Port = RS485_EN_GPIO_Port; // RS485 Enable ModbusH.EN_Pin = RS485_EN_Pin; // RS485 Enable ModbusH.u32overTime = 0; ModbusH.au16regs = ModbusDATARX; ModbusH.u16regsize= sizeof(ModbusDATARX)/sizeof(ModbusDATARX[0]); ModbusInit(&ModbusH); ModbusStart(&ModbusH); }
`void StartDefaultTask(void const argument)
{
/ USER CODE BEGIN 5 */
modbus_t telegram;
uint32_t u32NotificationValue;
telegram.u8id = 1; // slave address telegram.u8fct = 3; // function code (this one is registers read) //telegram.u16RegAdd = 0x160; // start address in slave telegram.u16RegAdd = 0x0; // start address in slave telegram.u16CoilsNo = 10; // number of elements (coils or registers) to read telegram.au16reg = ModbusDATARX; // pointer to a memory array in the Arduino
for(;;) { ModbusQuery(&ModbusH, telegram); // make a query u32NotificationValue = ulTaskNotifyTake(pdTRUE, portMAX_DELAY); // block until query finishes if(u32NotificationValue) { //handle error // while(1); } osDelay(5000); } / Infinite loop / for(;;) { osDelay(1); } / USER CODE END 5 / }`
I have the same error on atmel SAMDJ17, where I write to 8 coils (sending 8 modbus write single coil frames via rs485) and then reading coils states (modbus read coil), when I receive a CRC error, the system has this unknown behaviour under FreeRTOS (the system gets a software reset from watchdog)
@SuriyaMeras I cannot reproduce your issue I tested exactly your same code for more than 1000 packages with zero error rate.
You should check the ModbusDATARX's length, if you read 10 registers you need at least an array of 10 elements, this is not controlled by the library. Also, double check the configuration of your heap and stack in FreeRTOS. Probably, you are having a buffer overflow. Check the example for F429 for more details.
@oussemagaied my answer is valid for you as well.
Do Transmission and reception use same au8Buffer buffer?
Yes, it is used but at different times. For RX the library uses first an independent ring buffer. This ring buffer is copied to au8Buffer when the whole frame was received. TX uses directly au8Buffer to send a frame. RX and TX occur at different times. As a master the only way to interrupt the TX process and corrupt the au8Buffer should be if you have another master running in the same bus, or having a very slow slave that responds too late to the master while the master is preparing a request.
I will close this issue, feel free to reopen it if you have more information about your issue.
So here's the problem explicitly: 1.1 - Plug the USB RS485 interface and run a modbus server script in PC side (uModbus "python") 1.2 - Request reading coils every 3 seconds (Freemodbus) 1.3 - Close the script and re-open it on the first read retry after the timeout
So what actually happens here : Script response is shifted on the ucMasterRTURcvBuf buffer so the response is always incorrect thus read coil timeout yet the response is not shifted on the USART circular fifo buffer.
@oussemagaied lets clarify something.
What do you mean by Freemodbus in 1.2?
I think you have a slave running in python with uModbus and a master running this library in a SAMDJ17, right?
I will try to reproduce your issue and see if something is happening on the library.
I tested using the following code , without any issue I close and reopen the script as you mentioned.
`#!/usr/bin/env python3 from serial import Serial from collections import defaultdict
from umodbus.server.serial import get_server from umodbus.server.serial.rtu import RTUServer
s = Serial('/dev/ttyACM0') s.timeout = 10 s.baudrate = 115200
data_store = defaultdict(int) app = get_server(RTUServer, s)
data_store[0] = 0
@app.route(slave_ids=[1], function_codes=[1, 2, 3], addresses=list(range(0, 10))) def read_data_store(slave_id, function_code, address): """" Return value of address. """ print("\nreading code:{}, addrr:{}, val:{}".format(function_code, address, data_store[address])) print(data_store) return data_store[address]
@app.route(slave_ids=[1], function_codes=[5, 6, 15], addresses=list(range(0, 10))) def write_data_store(slave_id, function_code, address, value): """" Set value for address. """ print("\nwriting code:{}, addrr:{}, val:{}".format(function_code, address, value)) print(data_store) data_store[address] = value
if name == 'main': try: app.serve_forever()
finally:
app.shutdown()`
I have received CRC failed error and while debugging the crc value for received frame is taken as transmitted frame crc value. because the last values in the au8Buffer were transmission frame. So the value of crc is miss interupted.