how to handle CRC check error? #397
Replies: 31 comments
|
First, the CRC handling is done completely within the worker to relieve the user from doing it. The user interface will provide the message body regardless of the protocol (RTU/TCP) used. The CRC calculation is standardized and known to be working. If the server will complain about a wrong CRC something is wrong with the message. In your excerpt from the log there are two E2 errors within 23ms - are you requesting that frequently? If so, the server may be unable to respond in time and the bus timing will be broken. Another reason could be the notorious "stray zero byte" happening with some RS485 adapters when switching from reading to writing mode. There are numerous issues and discussion threads on that you may find when doing a search here. To better tell what really is happening you should compile your code with "-DLOG_LEVEL=6" and post the output again here for us to analyze. The ANSI escape sequences are built into the |
|
Thank you for the quick reply, Michael. Meanwhile I employed different code (https://github.com/emelianov/modbus-esp8266) and it worked without any issue. switching back to eModbus the situation changed a bit. Applying the compiler flag you adviced and manually setting the response message*s error to success this is output while the PC/Python Client now always reports NoResponseError
srv=202 fnc=3 addr=1 wrds=1
|
|
I removed all Serial.print statements from the code, assuming they cause the response could not be delivered in time. Also manually setting function code to 03 in the response. Still the Debug output shows 0x83 and PC/Python a "no response" error. |
|
There is something out of sync on your RS485 bus: Here we can see a single 0xFC byte being received that can not be converted into any message, so the worker reports back a E5 packet length error. This should be handled in your error handler callback. Next a correct packet is received and forwarded to your callback: Yor callback function is returning a response, that in turn is sent: Do not care about the cyclic E0 timeout returns in the log - that is used internally every 20s to signal another receive loop has finished without any incoming data. So someone is not keeping quiet on the bus so it seems. |
|
Disregard this - rubbish 😜 [Wait a second, forgot to mention: I mixed client and server behaviour - sorry. The server will report the E5 packet length error internally only and put it in the log. So the interesting bit indeed is the 0x83 function code instead of the 0x03 to be expected. I will try to find why that may have happened. |
|
The respective code is doing nothing between the return of the callback and the dump line you see in the log. It really looks like your callback function is inducing the error state?!? Can you post the code here? |
|
|
This is the culprit: Why do you do that? The error code is SUCCESS (0x00) by default, by using this call you are setting the error flag. All else is senseless after that, the 0x00 "error code" will stamp out your data length etc. Delete that line and try again. |
|
removed the |
|
The response looks okay now. Did the Python code ever receive anything from the ESP? Could it be the RE/DE toggle setting or wiring is not correct? |
|
> Did the Python code ever receive anything from the ESP Could it be the CRC is missing? |
|
The CRC is added when physically sending the response. If it would be missing, none of the existing applications using eModbus RTU would be working. Also timing should be no issue, the library is strictly maintaining the required quiet time between messages - unless you deliberately will shorten it by hand. Do you have a spare ESP32 you could use as a bus sniffer? Or a logic level analyzer to see the data on the Serial lines? Or even a scope to visualize what is going on on the RS485 bus |
|
https://snipboard.io/AmIbVf.jpg client 202 InvalidResponseError |
|
let's have a break. Waht used to work (reading that modbus temperature sensor in parallel with the ESP-RS485) does no longer do so. Maybe PC needs a restart. I need a restart. Expect my new input in 2 or 3 days. |
|
I suppose the screenshot is from a scope connected to the A+ and B- wires of the RS485 bus? If so, it immediately springs to the eye that the signal is rather unbalanced. It seems to have a strong bias to the negative voltage. there is no clear polarity switch as well, I would expect steeper flanks and linear maxima on both sides of the scale. The strange data F6 7E 00 hints in the same direction, the signal is distorted. Do you have proper termination on all attached servers (120 Ohms between A+ and B-)? And biasing resistors on one end (B- to GND and A- to Vcc)? |
|
Closing - seems to have been resolved otherwise. |
|
If the ESP32 can talk to the sensor equally well as the PC, this at least tells us the sensor has a valid wiring. I still an suspecting an issue in the wires/termination/biasing on the ESP32 or the PC ends. I almost would sort out any software issues here. Since the scope showed a shifted signal my guess would be the biasing. |
|
in the PC/Python code I increased the wait time for response to 100ms:
|
|
Some quick calculations. If it needs almost five times that span something else must be blocking it. Your test results for 2. and 3. are incomprehensible for me. All three must result into the same 5 bytes in the message proper plus 2 bytes CRC appended to it. Do me a favour and post again your current, unmodified sketch for me to check again. |
|
|
This: may be problematic, as a construct like This again: is not necessary, as the I would ask you to add a line immediately before the |
#define RESPONSE_ARRAY ==> :) #define RESPONSE_ONE_BYTE_EACH ==> /* after editing to: [N] FIN Response is: @3FCEE290/5: #define RESPONSE_SOME_CALLS ==> |
|
Now it looks more consistent to me. "works as coded" :)
the 7-byte response is visibly done in your code, and the check for address
0 has to be removed.
spethwa ***@***.***> schrieb am Di., 11. März 2025, 22:01:
… All three must result into the same 5 bytes in the message proper plus 2
bytes CRC appended to it.
at last this is the case.
#define RESPONSE_ARRAY ==> :)
[N] Response is: @3FCEE290/5:
request: srv:ca, fnc:03, addr:0000, wrds:0001
| 0000: CA 03 02 AB CD |..... |
[V] Callback response: @3FCEE290/5:
| 0000: CA 03 02 AB CD |..... |
[D] Sent packet: @3FCEE2A8/5:
| 0000: CA 03 02 AB CD |..... |
[D] 6989| ModbusServerRTU.cpp [ 251] serve: Response sent.
#define RESPONSE_ONE_BYTE_EACH ==>
[N] ERR Response is: @3FCEE24C/3:
| 0000: CA 83 02 |... |
skipping the addr == 0 check (because we do use addr = 0):
[N] FIN Response is: @3FCEE290/7:
| 0000: CA 03 02 AB CD AB CD |....... |
/* after editing to:
response.add(srv);
response.add(fnc);
response.add(uint8_t(2));
response.add(uint8_t(0xab));
response.add(uint8_t(0xcd));
*/ ==> :)
[N] FIN Response is: @3FCEE290/5:
| 0000: CA 03 02 AB CD |..... |
[V] Callback response: @3FCEE290/5:
| 0000: CA 03 02 AB CD |..... |
[D] Sent packet: @3FCEE2A8/5:
| 0000: CA 03 02 AB CD |..... |
#define RESPONSE_SOME_CALLS ==>
[N] FIN Response is: @3FCEE290/5:
| 0000: CA 03 02 AB CD |..... |
[V] Callback response: @3FCEE290/5:
| 0000: CA 03 02 AB CD |..... |
—
Reply to this email directly, view it on GitHub
<#391 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AGFPLXCMMM2ZYL27WNDRRUT2T5FKDAVCNFSM6AAAAABYCA24BCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDOMJVGY4TQNZUGQ>
.
You are receiving this because you modified the open/close state.Message
ID: ***@***.***>
[image: spethwa]*spethwa* left a comment (eModbus/eModbus#391)
<#391 (comment)>
All three must result into the same 5 bytes in the message proper plus 2
bytes CRC appended to it.
at last this is the case.
#define RESPONSE_ARRAY ==> :)
[N] Response is: @3FCEE290/5:
request: srv:ca, fnc:03, addr:0000, wrds:0001
| 0000: CA 03 02 AB CD |..... |
[V] Callback response: @3FCEE290/5:
| 0000: CA 03 02 AB CD |..... |
[D] Sent packet: @3FCEE2A8/5:
| 0000: CA 03 02 AB CD |..... |
[D] 6989| ModbusServerRTU.cpp [ 251] serve: Response sent.
#define RESPONSE_ONE_BYTE_EACH ==>
[N] ERR Response is: @3FCEE24C/3:
| 0000: CA 83 02 |... |
skipping the addr == 0 check (because we do use addr = 0):
[N] FIN Response is: @3FCEE290/7:
| 0000: CA 03 02 AB CD AB CD |....... |
/* after editing to:
response.add(srv);
response.add(fnc);
response.add(uint8_t(2));
response.add(uint8_t(0xab));
response.add(uint8_t(0xcd));
*/ ==> :)
[N] FIN Response is: @3FCEE290/5:
| 0000: CA 03 02 AB CD |..... |
[V] Callback response: @3FCEE290/5:
| 0000: CA 03 02 AB CD |..... |
[D] Sent packet: @3FCEE2A8/5:
| 0000: CA 03 02 AB CD |..... |
#define RESPONSE_SOME_CALLS ==>
[N] FIN Response is: @3FCEE290/5:
| 0000: CA 03 02 AB CD |..... |
[V] Callback response: @3FCEE290/5:
| 0000: CA 03 02 AB CD |..... |
—
Reply to this email directly, view it on GitHub
<#391 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AGFPLXCMMM2ZYL27WNDRRUT2T5FKDAVCNFSM6AAAAABYCA24BCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDOMJVGY4TQNZUGQ>
.
You are receiving this because you modified the open/close state.Message
ID: ***@***.***>
|
|
about the strange timing: did I mention my controller is ESP32-S3? Maybe this has some impact. |
I honestly doubt that. with the exception of one less UART it should behave as the WROVER or WROOM MCUs. from the time stamps in your very first log you can see that about 40ms each are spent in the library routines and your callback function. the latter may be due to the Serial.print calls. |
|
not C3 but S3, in particular ESP32-S3 wroom n16r8 cam devkit. |
|
No worries, feel free to share again whatever you will find out for others to learn. |

Uh oh!
There was an error while loading. Please reload this page.
I run a PC program in Python (that for a test successfully reads a modbus sensor using MinimalModbus library) as a modbus client while esp32 is modbus server.
When PC sends CA 03 00 00 00 01 94 71 (8 bytes) it gets Response from instrument: CA 83 02 B1 0F (5 bytes) and reports client 202 SlaveReportedException
ESP32 outputs
␛[0mrunning.␛[1;33m[E] 16447| ModbusServerRTU.cpp [ 265] serve: RTU receive: E2 - CRC check error
␛[0m␛[1;33m[E] 16470| ModbusServerRTU.cpp [ 265] serve: RTU receive: E2 - CRC check error
and after that from my own code:
␛[0mCA 03 00 00 00 01
request.getError(): 00 - Success
a) how would you suppress those terminal escape sequences for coloring
b) how can I handle the CRC error myself before the registered worker is invoked
c) why does it not give access to the crc it complains about but replaces it by zero? or does it tell a zero crc did arrive?
please advice.
btw that other sensor will send response from instrument: C9 03 02 00 DC 58 0D (7 bytes) upon request from PC : C9 03 00 02 00 01 35 82 (8 bytes). So erything seems fine.
All reactions