Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Discussion options

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.

You must be logged in to vote

Replies: 31 comments

Comment options

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 Logging.h source file to emphasize errors and warnings. Your serial output seems to be directed to a terminal that is in non-ANSI mode and hence will print visible characters instead.

You must be logged in to vote
0 replies
Comment options

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
entry 0x403c98d0
ModbusServerRTU example
[D] 98| ModbusServer.cpp [ 16] registerWorker: Registered worker for CA/00
[V] 99| RTUutils.cpp [ 111] calculateInterval: Calc interval(9600)=3645
[D] 109| ModbusServerRTU.cpp [ 99] doBegin: Server task 1070522396 started. Interval=3645
[V] 113| RTUutils.cpp [ 261] receive: S/3651us without data after 1
[V] 119| RTUutils.cpp [ 271] receive: S/[V] Raw buffer received: @3FCEE184/1:
| 0000: FC |. |
[D] 140| RTUutils.cpp [ 436] receive: S/[D] Received packet: @3FCEE394/1:
| 0000: E5 |. |
␛[1;33m[E] 150| ModbusServerRTU.cpp [ 265] serve: RTU receive: E5 - Packet length error
␛[0mrunning[V] 4867| RTUutils.cpp [ 261] receive: S/3652us without data after 8
[V] 4867| RTUutils.cpp [ 271] receive: S/[V] Raw buffer received: @3FCEE3A8/8:
| 0000: CA 03 00 01 00 01 C5 B1 |........ |
[D] 4877| RTUutils.cpp [ 436] receive: S/[D] Received packet: @3FCEE260/6:
| 0000: CA 03 00 01 00 01 |...... |
[D] 4898| ModbusServerRTU.cpp [ 184] serve: Request received.
[D] 4898| ModbusServer.cpp [ 22] getWorker: Need worker for CA-03 : Worker found for CA/03
[D] 4908| ModbusServerRTU.cpp [ 207] serve: Callback found.
[D] 4918| ModbusServerRTU.cpp [ 214] serve: Callback called.
CA 03 00 01 00 01

request.getError(): 00 - Success

srv=202 fnc=3 addr=1 wrds=1

addr. OK
wrds. OK
response: ABCD
[V] Callback response: @3FCEE36C/5:
| 0000: CA 83 00 AB CD |..... |
[D] Sent packet: @3FCEE384/5:
| 0000: CA 83 00 AB CD |..... |
[D] 4957| ModbusServerRTU.cpp [ 251] serve: Response sent.
..[D] 24969| RTUutils.cpp [ 436] receive: S/[D] Received packet: @3FCEE358/1:
| 0000: E0 |. |
..[D] 44981| RTUutils.cpp [ 436] receive: S/[D] Received packet: @3FCEE24C/1:
| 0000: E0 |. |
..[D] 64993| RTUutils.cpp [ 436] receive: S/[D] Received packet: @3FCEE358/1:
| 0000: E0 |. |

You must be logged in to vote
0 replies
Comment options

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.

You must be logged in to vote
0 replies
Comment options

There is something out of sync on your RS485 bus:

V] 113| RTUutils.cpp [ 261] receive: S/3651us without data after 1
[V] 119| RTUutils.cpp [ 271] receive: S/[V] Raw buffer received: @3FCEE184/1:
| 0000: FC |. |
[D] 140| RTUutils.cpp [ 436] receive: S/[D] Received packet: @3FCEE394/1:
| 0000: E5 |. |

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:

[V] 4867| RTUutils.cpp [ 261] receive: S/3652us without data after 8
[V] 4867| RTUutils.cpp [ 271] receive: S/[V] Raw buffer received: @3FCEE3A8/8:
| 0000: CA 03 00 01 00 01 C5 B1 |........ |
[D] 4877| RTUutils.cpp [ 436] receive: S/[D] Received packet: @3FCEE260/6:
| 0000: CA 03 00 01 00 01 |...... |
[D] 4898| ModbusServerRTU.cpp [ 184] serve: Request received.
[D] 4898| ModbusServer.cpp [ 22] getWorker: Need worker for CA-03 : Worker found for CA/03
[D] 4908| ModbusServerRTU.cpp [ 207] serve: Callback found.
[D] 4918| ModbusServerRTU.cpp [ 214] serve: Callback called.

Yor callback function is returning a response, that in turn is sent:

[V] Callback response: @3FCEE36C/5:
| 0000: CA 83 00 AB CD |..... |
[D] Sent packet: @3FCEE384/5:
| 0000: CA 83 00 AB CD |..... |
[D] 4957| ModbusServerRTU.cpp [ 251] serve: Response 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.

You must be logged in to vote
0 replies
Comment options

Disregard this - rubbish 😜

[Wait a second, forgot to mention: [V] Callback response: @3FCEE36C/5:| 0000: CA 83 00 AB CD |..... | means there still is the (unresponded to) error condition set - you did not respond to the error and you are not able to overwrite the function code in your response for good reasons.]

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.

You must be logged in to vote
0 replies
Comment options

The respective code

      // Get the user's response
          LOG_D("Callback called.\n");
          m = callBack(request);
          HEXDUMP_V("Callback response", m.data(), m.size());

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?

You must be logged in to vote
0 replies
Comment options

packet length error. This should be handled in your error handler callback.
onErrorHandler seems to exist for clients only, right?
the code ist almost the provided example:

#include <Arduino.h>

#define LOG_LEVEL LOG_LEVEL_DEBUG
#include "Logging.h"

#include "ModbusServerRTU.h"
/* R485A01 High-Speed Half-Duplex Transceiver Auto Master-Slave Networking Module RS485 to TTL 
  expects TX --> RX and RX --> TX
  see https://www.facebook.com/photo/?fbid=824274743047003&set=pcb.824275263046951
*/

#define PIN_RS485_EN -1
#define PIN_MODBUS_RX 47
#define PIN_MODBUS_TX 21
#define MODBUS_SPEED 9600

const uint8_t server_address(202);  // Modbus server ID/address
const uint32_t MODBUS_TIMEOUT(20000);// after what time/ms of inactivity the server should loop around and re-initialize some working data
const unsigned int register_address = 0;
const unsigned int token = 0x12345678;
const unsigned int count = 1;


uint16_t data[128] = {0xabcd, 0xbcde, 0xcdef, 0x0123, 0x1234};                 // Test server memory

ModbusServerRTU RS485(MODBUS_TIMEOUT, PIN_RS485_EN);  // use rtsPin PIN_RS485_EN to toggle DE/RE in half-duplex RS485();          // for auto half-duplex

// Worker function for serverID=server_address, function code 0x03 or 0x04
ModbusMessage on_request(ModbusMessage request) {
 
  uint8_t srv = 0; // server ID from data packet
  uint8_t fnc = 0; // function code from data packet
  
  uint16_t addr = 0;        // Start address to read
  uint16_t wrds = 0;        // Number of words to read
  uint16_t crc = 0;       
  
  ModbusMessage response;

  request.get(0, srv);
  request.get(1, fnc);
  request.get(2, addr);
  request.get(4, wrds);

  if (!addr || addr > 128) {  // address valid?
    // No. Return error response
    response.setError(request.getServerID(), request.getFunctionCode(), ILLEGAL_DATA_ADDRESS);
    return response;
  }

  addr--;  // Modbus address is 1..n, memory address 0..n-1

  if (!wrds || (addr + wrds) > 127) {  // Number of words valid?
    // No. Return error response
    response.setError(request.getServerID(), request.getFunctionCode(), ILLEGAL_DATA_ADDRESS);
    return response;
  }

  // Prepare response
  uint8_t serverID = request.getServerID();
  uint8_t functionCode = request.getFunctionCode();
  uint8_t dataLength = (uint8_t)(wrds * 2);
  response.add(request.getServerID(), 3 /*request.getFunctionCode()*/, (uint8_t)(wrds * 2));
  response.setError(request.getServerID(), request.getFunctionCode(), SUCCESS);

  for (uint16_t i = 0; i < wrds; i++) {  // Loop over all words to be sent
    // Add word MSB-first to response buffer
    response.add(data[addr + i]);
  }

  return response;  // Return the data response
}

void setup() {
    Serial.begin(115200);
    Serial.println("ModbusServerRTU example");
    Serial.flush();

  // Set up Serial2 connected to Modbus RTU
    RTUutils::prepareHardwareSerial(Serial2);
    Serial2.begin(MODBUS_SPEED, SERIAL_8N1, PIN_MODBUS_RX, PIN_MODBUS_TX);

    // Register the worker function with the Modbus server
    RS485.registerWorker(server_address, ANY_FUNCTION_CODE, &on_request);
    RS485.begin(Serial2); // server will create its background task and start listening to the Modbus
    delay(1000); Serial.printf("running");
  }
 
  void loop() {
    static uint32_t statusTime = millis();
    const uint32_t statusInterval(10000);
  
    // We will be idling around here - all is done in subtasks :D
    if (millis() - statusTime > statusInterval) {
      Serial.print(".");Serial.flush(); 
      statusTime = millis();
    }
    delay(100);
  }
You must be logged in to vote
0 replies
Comment options

This is the culprit:

response.setError(request.getServerID(), request.getFunctionCode(), SUCCESS);

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.

You must be logged in to vote
0 replies
Comment options

removed the response.setError(request.getServerID(), request.getFunctionCode(), SUCCESS); and CA 83 is no longer in the response. Yet the PC/Python persists in NoResponse

[V] Callback response: @3FCEE2A8/6:
  | 0000: CA 03 00 01 AB CD                                 |......          |
[D] Sent packet: @3FCEE290/6:
  | 0000: CA 03 00 01 AB CD                                 |......          |
[D] 36036| ModbusServerRTU.cpp  [ 251] serve: Response sent.
You must be logged in to vote
0 replies
Comment options

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?

You must be logged in to vote
0 replies
Comment options

> Did the Python code ever receive anything from the ESP
sorry no. It will always complain about NoResponse. Looking at the debug output at ESP:

[V] 5575| RTUutils.cpp         [ 271] receive: S/[V] Raw buffer received: @3FCEE3A8/8: 
  | 0000: CA 03 00 01 00 01 C5 B1  
...
[D] Sent packet: @3FCEE2A8/6:
  | 0000: CA 03 00 02 AB CD  

Could it be the CRC is missing?
> Could it be the RE/DE toggle setting or wiring is not correct?
as mentioned before everything works when using
https://github.com/emelianov/modbus-esp8266/blob/master/examples/RTU/slave/slave.ino
(but this approach does not offer callbacks)
Can timing be the issue (are you responding to fast?

You must be logged in to vote
0 replies
Comment options

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

You must be logged in to vote
0 replies
Comment options

https://snipboard.io/AmIbVf.jpg
serial port is COM3
MinimalModbus debug mode. Will write to instrument (expecting 7 bytes back): CA 03 00 01 00 01 C5 B1 (8 bytes)
MinimalModbus debug mode. Clearing serial buffers for port COM3
MinimalModbus debug mode. No sleep required before write. Time since previous read: 1422114859.00 ms, minimum silent period: 4.01 ms.
MinimalModbus debug mode. Response from instrument: F6 7E 00 (3 bytes), roundtrip time: 0.1 ms. Timeout for reading: 50.0 ms.

client 202 InvalidResponseError

You must be logged in to vote
0 replies
Comment options

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.
Thank you for supporting me.

You must be logged in to vote
0 replies
Comment options

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)?

You must be logged in to vote
0 replies
Comment options

@wspeth Have a look here for a explanation of "nice" RS485 signals: Chipkin

You must be logged in to vote
0 replies
Comment options

@wspeth Any news on this?

You must be logged in to vote
0 replies
Comment options

Closing - seems to have been resolved otherwise.

You must be logged in to vote
0 replies
Comment options

Michael, I am sorry I did not reply when having a week's sick leave (sudden impact from the carnival season).
The other day I took everything apart and started from scratch.

a) PC/Python to modbus sensor (R46CA01 from eletechsup) works fine again. Signals on Osci are not pretty but Osci can successfully decode the signals (though not always)

b) emodbus on ESP32 as a client adressing same sensor via RS485 transceiver (Image)works like a charm.

c) repeating a) but also addressing ESP32 (now in server mode) still has issues.

c1) ESP having modbus address 0xCA again responds CA-83 to function read (03). I just put the complete sequence CA-03-00-00-00-01-AB-CD into data buffer which then is successfully sent out.

c2) PC/Python still comes up "No response error". Always. When checking the signal on Osci I see many times response at all after the read command issued by PC/Python. If there is a response, it follows only 65ms if not 835ms after the end of the read command.
I reduced log level to NONE which was no cure.

The setup is for educational purpose only so not critical in any sense.

You must be logged in to vote
0 replies
Comment options

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.

You must be logged in to vote
0 replies
Comment options

in the PC/Python code I increased the wait time for response to 100ms:
instrument.serial.timeout = 0.1
getting the prepared array from emodbus which must not exceed the expected number (7 bytes).
Termination may be still an issue, however wiring is 10cm lengths only.
but why does it take ESP/modbus so long to respond? I am no aware of blocking any timers. Possibly the UART is buffering.
And using the ModbusMessage response I don't get the API do what I expect:

  1. uint8_t data[128] = {0xca, 0x03, 0x02, 0xab, 0xcd}; response.add( data, 5); return response;
    CRC appended, the PC/Python gets 7 bytes
  2. response.add(request.getServerID(), uint8_t{3}, uint8_t{2}, uint8_t{0xab}, uint8_t{0xcd});
    sends 5 bytes, the last two are CRC but uint8_t{0xab}, uint8_t{0xcd} are missing
  3. same result (5 bytes instead of 7) when stuffing bytewise:
    response.add(request.getServerID());
    response.add(uint8_t{3});
    response.add(uint8_t{2});
    response.add(uint8_t{0xab});
    response.add(uint8_t{0xcd});
You must be logged in to vote
0 replies
Comment options

Some quick calculations.
You are running the bus at 9600 baud. That is - give or take some - 1000 bytes per second. A 7-byte message will take 7ms plus another 3.5 for the quiet time. Thus the ESP should be ready again after 20ms.

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.

You must be logged in to vote
0 replies
Comment options

/* 
platformio // VSCode
*/
#include <Arduino.h>

#define LOG_LEVEL LOG_LEVEL_VERBOSE
#include "Logging.h"

#include "ModbusServerRTU.h"
/* R485A01 High-Speed Half-Duplex Transceiver Auto Master-Slave Networking Module RS485 to TTL 
  expects TX --> RX and RX --> TX
  see https://www.facebook.com/photo/?fbid=824274743047003&set=pcb.824275263046951
*/

#define PIN_RS485_EN -1
#define PIN_MODBUS_RX 47
#define PIN_MODBUS_TX 21
#define MODBUS_SPEED 9600

const uint8_t server_address(202);  // Modbus server ID/address
const uint32_t MODBUS_TIMEOUT(20000);// after what time/ms of inactivity the server should loop around and re-initialize some working data
const unsigned int register_address = 0;
const unsigned int token = 0x12345678;
const unsigned int count = 1;


// select one of the RESPONSE building modes
#define RESPONSE_ARRAY  // MinimalModbus debug mode. Response from instrument: CA 03 02 AB CD A3 31 (7 bytes)
//#define RESPONSE_ONE_BYTE_EACH // MinimalModbus debug mode. Response from instrument: CA 83 02 B1 0F (5 bytes)
//#define RESPONSE_SOME_CALLS // MinimalModbus debug mode. Response from instrument: CA 83 02 B1 0F (5 bytes)


uint8_t data8[128] = {0xca, 0x03, 0x02, 0xab, 0xcd};                 // Test server memory
uint16_t data16[128] = {0xabcd, 0xcdef, 0x1234};      // Test server memory
ModbusServerRTU RS485(MODBUS_TIMEOUT, PIN_RS485_EN);  // use rtsPin PIN_RS485_EN to toggle DE/RE in half-duplex RS485();          // for auto half-duplex

uint8_t srv = 0; // server ID from data packet
uint8_t fnc = 0; // function code from data packet
uint16_t addr = 0;        // Start address to read
uint16_t wrds = 0;        // Number of words to read
uint16_t crc = 0;       
uint8_t semaphore = 0;

// Worker function for serverID=server_address, function code 0x03 or 0x04
ModbusMessage on_request(ModbusMessage request) {


  ModbusMessage response;
  request.get(0, srv);
  request.get(1, fnc);
  request.get(2, addr);  //addr--;  // Modbus address is 1..n, memory address 0..n-1
  request.get(4, wrds);
  semaphore = 1; // we can later report


#ifdef RESPONSE_ARRAY
  response.add( data8, 5);  // Copy data to response buffer
  return response;  // Return the data response
#endif


  if (!addr || addr > 128) {  // address valid?
    // No. Return error response
    response.setError(request.getServerID(), request.getFunctionCode(), ILLEGAL_DATA_ADDRESS);
    return response;
  }

  if (!wrds || (addr + wrds) > 127) {  // Number of words valid?
    // No. Return error response
    response.setError(request.getServerID(), request.getFunctionCode(), ILLEGAL_DATA_ADDRESS);
    return response;
  }

  // Prepare response
  uint8_t serverID = request.getServerID();
  uint8_t functionCode = request.getFunctionCode();
  uint8_t dataLength = (uint8_t)(wrds * 2);
  // response.begin();
  
#ifdef RESPONSE_ONE_BYTE_EACH
  response.add(srv);
  response.add(fnc);
  response.add(uint8_t{2});
  response.add(uint8_t{0xab});
  response.add(uint8_t{0xcd});
#endif


#ifdef RESPONSE_SOME_CALLS
  response.add(srv,  fnc, (uint8_t)(wrds*2));
#endif

for (uint16_t i = 0; i < wrds; i++) {  // Loop over all words to be sent
  // Add word MSB-first to response buffer // <<== not yet done
  response.add( (uint16_t) *(data16 + 2*(addr + i) ));
}
//response.setError(request.getServerID(), request.getFunctionCode(), SUCCESS);
//delay(20);
  return response;  // Return the data response


}



void setup() {
    Serial.begin(115200);
    Serial.println("ModbusServerRTU example");
    Serial.flush();

  // Set up Serial2 connected to Modbus RTU
    RTUutils::prepareHardwareSerial(Serial2);
    Serial2.begin(MODBUS_SPEED, SERIAL_8N1, PIN_MODBUS_RX, PIN_MODBUS_TX);

    // Register the worker function with the Modbus server
    RS485.registerWorker(server_address, ANY_FUNCTION_CODE, &on_request);
    RS485.begin(Serial2); // server will create its background task and start listening to the Modbus
    delay(1000); Serial.printf("running");
  }
 
  void loop() {
    static uint32_t statusTime = millis();
    const uint32_t statusInterval(10000);
  
    // We will be idling around here - all is done in subtasks :D
    if (millis() - statusTime > statusInterval) {
      Serial.print(".");Serial.flush(); 
      statusTime = millis();
    }
    if (semaphore) {
      Serial.printf("\t\t\trequest: srv:%02x, fnc:%02x, addr:%04x, wrds:%04x\n", srv, fnc, addr, wrds);
      semaphore = 0;
    }
  }
You must be logged in to vote
0 replies
Comment options

This:

response.add(uint8_t{2});
  response.add(uint8_t{0xab});
  response.add(uint8_t{0xcd});

may be problematic, as a construct like uint8_t{2} attempts top create a uint8_t type object and initialize it with 2. That may lead to padding issues. The easiest way would be to instead write (uint8_t)2 (C-style casting), uint8_t(2) (forced type) or even static_cast<uint8_t>(2) (C++-style casting).

This again:

  // Add word MSB-first to response buffer // <<== not yet done
  response.add( (uint16_t) *(data16 + 2*(addr + i) ));

is not necessary, as the add() method will always add values MSB first. So when you add any data16 value of type uint16_t it will be added as the standard requires it - MSB first.

I would ask you to add a line

HEXDUMP_N("Response is", response.data(), response,size());

immediately before the return response; statement to see what the response looks like when leaving your code.

You must be logged in to vote
0 replies
Comment options

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 |..... |

You must be logged in to vote
0 replies
Comment options

You must be logged in to vote
0 replies
Comment options

about the strange timing: did I mention my controller is ESP32-S3? Maybe this has some impact.
Switching to SoftwareSerial, result is the same (recent value: 87.22ms to respond)

You must be logged in to vote
0 replies
Comment options

about the strange timing: did I mention my controller is ESP32-S3? Maybe this has some impact. Switching to SoftwareSerial, result is the same (recent value: 87.22ms to respond)

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.

You must be logged in to vote
0 replies
Comment options

not C3 but S3, in particular ESP32-S3 wroom n16r8 cam devkit.
I removed all output (LOG_LEVEL_NONE). Same situation.
Don't bother and feel free to close the issue.
thank you for all support and assistance

You must be logged in to vote
0 replies
Comment options

No worries, feel free to share again whatever you will find out for others to learn.

You must be logged in to vote
0 replies
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
3 participants
Converted from issue

This discussion was converted from issue #391 on March 14, 2025 09:54.

Morty Proxy This is a proxified and sanitized view of the page, visit original site.