Open Asanga-Viraj opened 11 months ago
Hi @Asanga-Viraj,
Thank you for the issue. I think more information from you is required to reproduce this issue. I just checked this functionality and can confirm this works as expected with esp-modbus v1.0.11 and latest esp-idf.
The application:
void app_main(void)
{
// Initialization of device peripheral and objects
ESP_ERROR_CHECK(master_init());
vTaskDelay(10);
esp_err_t err = 0;
// Write registers to predefined state
uint16_t register_data = 0x1111;
// write_modbus_parameter(CID_DEV_REG0, ®ister_data);
// register_data = 0x2222;
// write_modbus_parameter(CID_DEV_REG1, ®ister_data);
register_data = 0x3333;
mb_param_request_t req = {};
req.slave_addr = 1; // Set of the slave address is required here!!!
req.command = 6;
req.reg_start = 1;
req.reg_size = 1;
err = mbc_master_send_request(&req, (void *)®ister_data);
ESP_LOGI("TEST", "value:%x(%d)", (int)register_data, (int)err); //can check the value from here. It is automatically updated to previous value.
register_data = 0x4444;
req.command = 6;
req.reg_start = 2;
req.reg_size = 1;
err = mbc_master_send_request(&req, (void *)®ister_data); //still writes value 156
ESP_LOGI("TEST", "value:%x(%d)", (int)register_data, (int)err); //can check the value from here. It is automatically updated to previous value.
}
The log of test application:
D (818) MB_PORT_COMMON: 0:EV_MASTER_READY
I (868) MODBUS_MASTER: Modbus master stack initialized...
D (968) MB_PORT_COMMON: xMBMasterRunResTake:Take MB resource (500 ticks).
D (968) MB_PORT_COMMON: xMBMasterRunResTake:Take MB resource (500 ticks).
D (968) MB_PORT_COMMON: 325429:EV_MASTER_FRAME_TRANSMIT
D (968) POLL transmit buffer: 06 00 01 33 33
D (978) MB_PORT_COMMON: eMBMasterRTUSend: Port enter critical.
D (978) MB_PORT_COMMON: eMBMasterRTUSend: Port exit critical
D (988) MB_PORT_COMMON: xMBMasterPortSerialSendRequest default
D (998) MB_PORT_COMMON: vMBMasterPortTimersRespondTimeoutEnable Respond enable timeout.
D (998) MB_MASTER_SERIAL: MB_TX_buffer sent: (9) bytes.
D (1008) MB_PORT_COMMON: vMBMasterRxSemaRelease:RX semaphore is free.
D (1008) MB_PORT_COMMON: xMBPortSerialWaitEvent, UART event: 1
D (1018) MB_MASTER_SERIAL: MB_uart[2] event:
D (1028) MB_MASTER_SERIAL: uart rx break.
D (1028) MB_PORT_COMMON: xMBPortSerialWaitEvent, UART event: 1
D (1038) MB_MASTER_SERIAL: MB_uart[2] event:
D (1038) MB_MASTER_SERIAL: uart rx break.
D (1038) MB_PORT_COMMON: 325429:EV_MASTER_FRAME_SENT
D (1048) MB_PORT_COMMON: xMBPortSerialWaitEvent, UART event: 0
D (1048) MB_MASTER_SERIAL: MB_uart[2] event:
D (1058) MB_MASTER_SERIAL: Data event, len: 8.
D (1058) MB_MASTER_SERIAL: Received data: 9(bytes in buffer)
D (1068) MB_MASTER_SERIAL: Timeout occured, processed: 9 bytes
D (1078) POLL sent buffer: 06 00 01 33 33
D (1078) MB_PORT_COMMON: 325429:EV_MASTER_FRAME_RECEIVED
D (1078) MB_PORT_COMMON: xMBMasterPortSerialGetResponse default
D (1088) MB_PORT_COMMON: eMBMasterRTUReceive: Port enter critical.
D (1098) MB_PORT_COMMON: eMBMasterRTUReceive: Port exit critical
D (1098) MB_PORT_COMMON: 325429: Packet data received successfully (0).
D (1108) POLL receive buffer: 06 00 01 33 33
D (1108) MB_PORT_COMMON: 325429:EV_MASTER_EXECUTE
D (1118) MB_PORT_COMMON: 325429:set event EV_ERROR_OK
D (1118) MB_PORT_COMMON: 325429:EV_MASTER_ERROR_PROCESS
D (1128) MB_PORT_COMMON: vMBMasterCBRequestSuccess: Callback request success.
D (1138) MB_PORT_COMMON: Transaction (325429), processing time(us) = 156402
D (1138) MB_PORT_COMMON: eMBMasterWaitRequestFinish: returned event = 0x80
I (1148) TEST: value:3333(0)
D (1148) MB_PORT_COMMON: xMBMasterRunResTake:Take MB resource (500 ticks).
D (1158) MB_PORT_COMMON: xMBMasterRunResTake:Take MB resource (500 ticks).
D (1168) MB_PORT_COMMON: 525759:EV_MASTER_FRAME_TRANSMIT
D (1168) POLL transmit buffer: 06 00 02 44 44
D (1178) MB_PORT_COMMON: eMBMasterRTUSend: Port enter critical.
D (1178) MB_PORT_COMMON: eMBMasterRTUSend: Port exit critical
D (1188) MB_PORT_COMMON: xMBMasterPortSerialSendRequest default
D (1198) MB_PORT_COMMON: vMBMasterPortTimersRespondTimeoutEnable Respond enable timeout.
D (1198) MB_MASTER_SERIAL: MB_TX_buffer sent: (9) bytes.
D (1208) MB_PORT_COMMON: xMBPortSerialWaitEvent, UART event: 1
D (1218) MB_MASTER_SERIAL: MB_uart[2] event:
D (1218) MB_MASTER_SERIAL: uart rx break.
D (1218) MB_PORT_COMMON: 525759:EV_MASTER_FRAME_SENT
D (1228) POLL sent buffer: 06 00 02 44 44
D (1238) MB_PORT_COMMON: xMBPortSerialWaitEvent, UART event: 0
D (1238) MB_MASTER_SERIAL: MB_uart[2] event:
D (1238) MB_MASTER_SERIAL: Data event, len: 8.
D (1248) MB_MASTER_SERIAL: Received data: 9(bytes in buffer)
D (1248) MB_MASTER_SERIAL: Timeout occured, processed: 9 bytes
D (1258) MB_PORT_COMMON: 525759:EV_MASTER_FRAME_RECEIVED
D (1258) MB_PORT_COMMON: xMBMasterPortSerialGetResponse default
D (1268) MB_PORT_COMMON: eMBMasterRTUReceive: Port enter critical.
D (1278) MB_PORT_COMMON: eMBMasterRTUReceive: Port exit critical
D (1278) MB_PORT_COMMON: 525759: Packet data received successfully (0).
D (1288) POLL receive buffer: 06 00 02 44 44
D (1288) MB_PORT_COMMON: 525759:EV_MASTER_EXECUTE
D (1298) MB_PORT_COMMON: 525759:set event EV_ERROR_OK
D (1298) MB_PORT_COMMON: 525759:EV_MASTER_ERROR_PROCESS
D (1308) MB_PORT_COMMON: vMBMasterCBRequestSuccess: Callback request success.
D (1318) MB_PORT_COMMON: Transaction (525759), processing time(us) = 136105
D (1318) MB_PORT_COMMON: eMBMasterWaitRequestFinish: returned event = 0x80
I (1328) TEST: value:4444(0)
I (1328) main_task: Returned from app_main()
host software log (RS485 interface):
Rx:001949-11:41:09.766-01 06 00 01 33 33 8C EF
Tx:001950-11:41:09.766-01 06 00 01 33 33 8C EF
Rx:001951-11:41:09.939-01 06 00 02 44 44 1B 39
Tx:001952-11:41:09.940-01 06 00 02 44 44 1B 39
If you are sure that it works incorrectly please send your code to reproduce this issue, log of your application with debug verbosity enabled in kconfig and log of the host application (RS485 bus log).
Thank you.
@Asanga-Viraj,
Any update on this issue? Could you please let me know which version of esp-idf and esp-modbus component you are using?
Hi,
I am running complex system in ESP32 with idf 5.0.2 (release) and modbus 1.0.11 (latest) . I extracted what I did for ModBus write to replicate the issue in a single file. I couldn't replicate the issue. Tried many ways, I couldn't.
So, may be some fault in my side which I didn't recognized. Thank you for your help.
Hi @Asanga-Viraj,
Could you try to describe your complex system? For example: which active objects (tasks, interrupts) you have and how they dependent to each other and their priorities compare to Modbus priorities, Modbus settings in sdkconfig, etc. Do you have the tasks with priority >= 20 in your system.The modbus uses esp-timer and its task priority is 21, and higher priority tasks can apply to its functionality as well. Other components (wifi, bluethooth, lwip related) are also apply to the functionality of the whole system with their high priority tasks (prio up to 23). Does the issue exist only when you use the mbc_master_send_request
to write the registers or the regular write API functions work the same way?
I think the active objects dependencies is the important point to be investigated on high level design stage.
Try to add the task with priority like something like ~20 into your extracted code and check issue again.
Thanks.
Hi @alisitsyn ,
I will try to explain the system as much as I can.
Using IDF version 5.0.2
Using lateset esp_modbus 1.0.11
System consist of internet connectivity 3 interfaces such as WiFi, Ethernet and 4G PPP. Only one interface is running at a time.
Once internet is connected, the system is running MQTT (not SSL) to publish data.
Meanwhile RTU ModBus master is running.
ModBus reading and writing each 200ms
Read data comparison tasks and other several tasks are running.
two esp timers are running for data publishing and led indication.
gpio interrupts are running for digital inputs.
Let me know any more information you may want.
Thanks.
Hi @Asanga-Viraj,
Thank you for update. Could you share the sdkconfig file as well? Your logging information can also help to improve your system.
Read data comparison tasks and other several tasks are running.
Please include the tasks priority for most of your tasks including the tasks which do Modbus read data and comparison. This will help to find solutions for your case.
ModBus reading and writing each 200ms
I would suggest to increase the CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND
at least to 400 ms, even through your slave is able to process request during 200ms or less and increase the read/write period. The 200ms response timeout is to short response time for your baud rate and highly loaded system. How the modbus read/write is scheduled in your code?
Modbus task affinity = CPU0
My suggestion is to change affinity setting to CPU1. This is required because your LWIP related services (WIFI, ethernet, PPP) use high priority tasks and process data intensively. This allows to increase the reliability of Modbus data procesisng due to deterministic aspects of protocol. In this case it is recommended to move deterministic protocols to other CPU. This will significantly increase the reliability of data reading/writing in highly loaded system.
Modbus timer uses ISR dispatch method = unticked
I recommend to set CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD=y
. The esp-timer which is used by modbus by default use dispatch method ESP_TIMER_TASK
when the above setting is disabled. This may cause the decreased accuracy for response timeout event triggering in case of heavily loaded system. If this setting is enabled, the timeout is dispatched from ISR.
Please try the suggestions above and report the results. Thank you.
Hi,
Thank you for the support. I updated the values as requested and did testing. Still got the issue. It is not happening all the times, but randomly occurs. I updated the code to handle this ModBus mis-writing.
As a information, I added sdkconfig file here.
Hi @Asanga-Viraj ,
It is very strange. I need to reproduce this, but could not do it yet. Let me know if you have any update for this.
I am using ESP32 RTU ModBus master. The reading registers are working fine. But, writing register doesn't work properly. I am using mbc_master_send_request() function to write register. This function writes value of previous call each time for a specific reg_start address. An example code is below.
This issue can overcome by calling
mbc_master_send_request(&req, (void *)&temp);
with zero value before writing actual value. It seems to be calling this function release resources allocated for reg_start address.What should I do? Am I making invalid requests?