RS485 serial comms failing using different ports on Mega2560

Hi All,
I've been searching for a solution to this problem on the net and this forum, but can't find anything about what I'm experiencing.

I'm using a Mega2560 and SN75176 (RS485) chip to talk to a digital AC meter, as shown below:
image

Everything works fine if I connect the D/R lines (Sn75176) to TX0/RX0 (Mega), respectively, and run the following code:

int RS485EnablePin = 3;  //1 to send, 0 to receive
byte DigMeterAddr = 0x01; //RS485 address of the digital AC meter (used to measure V,I,P, etc. of the variac secondary)
byte Modbus_GetVIDataCmd_Meter[] = {DigMeterAddr, 0x04, 0x00, 0x00, 0x00, 0x03, 0xb0, 0x0b}; //Command to be sent to the AC digital meter in order to get just the V,I electrical data returned
byte ReturnedModbusDat_Meter[25];  //Setup a byte array to receive the Modbus data from digital AC meter
String ReturnedModbusDat_Str = ""; //Setup a String to convert the ReturnedModbusDat into a String
unsigned long StartTime;

void setup() {
  Serial.begin(9600); 
  pinMode(RS485EnablePin, OUTPUT);
}

void loop() {
  digitalWrite(RS485EnablePin, HIGH); //Enable high, RS485 shield waiting to transmit data*/
  Serial.write(Modbus_GetVIDataCmd_Meter, 8); //Send the modbus command to receive data to AC meter
  Serial.flush();  //Ensure serial buffer has been sent before putting RS485 shield into receive mode (otherwise sending data is truncated & terminated and the full message is not received by the listening device)
  digitalWrite(RS485EnablePin, LOW); //Enable low, RS485 shield waiting to receive data
  StartTime = millis(); //Set the start time before waiting on a Serial.available response from the RS485 devices
  while ((Serial.available() == 0) && (millis() - StartTime < 50)) {}
  if (Serial.available() == 0) {
    Serial.println("Meter unavailable");
  }
  else {
    Serial.readBytes(ReturnedModbusDat_Meter, 11);
    ReturnedModbusDat_Str=ByteArr2ASCIIHexString(ReturnedModbusDat_Meter,11);
    Serial.println("ReturnedModbusDat_Str= "+ReturnedModbusDat_Str);
  }
  delay(1000);
}

//Function ByteArr2ASCIIHexString to convert a byte array to an ASCII Hex string (for printing)
String ByteArr2ASCIIHexString(byte dat[], int lngth) {
  String HexString = "";

  for (int i = 0; i < lngth; i++) {
    if (dat[i] < 0x10) {
      HexString += '0';
    }
    HexString += String(dat[i], HEX);
  }
  return HexString;
}

The output on the Serial Monitor shows the correct response coming back from the AC Meter every time (except for the 5 characters of garbage preceding each data line - not sure why this appears):

The hex strings are the correct format and contain the correct data (I've checked by converting the register bytes to their corresponding float values, and they are showing the right values as read by the AC meter).

However, instead of using RX0/TX0, I want to use one of the hardware serial ports on the Mega, say, RX1/TX1.
So, I rewire the circuit as follows (change RX0/TX0 to RX1/TX1):

and run the following code:

int RS485EnablePin = 3;  //1 to send, 0 to receive
byte DigMeterAddr = 0x01; //RS485 address of the digital AC meter (used to measure V,I,P, etc. of the variac secondary)
byte Modbus_GetVIDataCmd_Meter[] = {DigMeterAddr, 0x04, 0x00, 0x00, 0x00, 0x03, 0xb0, 0x0b}; //Command to be sent to the AC digital meter in order to get V,I electrical data returned
byte ReturnedModbusDat_Meter[25];  //Setup a byte array to receive the Modbus data from digital AC meter
String ReturnedModbusDat_Str = ""; //Setup a String to convert the ReturnedModbusDat into a String
unsigned long StartTime;

void setup() {
  Serial.begin(9600); 
  Serial1.begin(9600);
  pinMode(RS485EnablePin, OUTPUT);
}

void loop() {
  digitalWrite(RS485EnablePin, HIGH); //Enable high, SN75176 waiting to transmit data*/
  Serial1.write(Modbus_GetVIDataCmd_Meter, 8); //Send the modbus command to receive data to AC meter
  Serial1.flush();  //Ensure serial buffer has been sent before putting RS485 shield into receive mode (otherwise sending data is truncated & terminated and the full message is not received by the listening device)
  digitalWrite(RS485EnablePin, LOW); //Enable low, SN75176 waiting to receive data
  StartTime = millis(); //Set the start time before waiting on a Serial.available response from the RS485 devices
  while ((Serial1.available() == 0) && (millis() - StartTime < 50)) {}
  if (Serial1.available() == 0) {
    Serial.println("Meter unavailable");
  }
  else {
    Serial1.readBytes(ReturnedModbusDat_Meter, 11);
    ReturnedModbusDat_Str=ByteArr2ASCIIHexString(ReturnedModbusDat_Meter,11);
    Serial.println("ReturnedModbusDat_Str= "+ReturnedModbusDat_Str);
  }
  delay(1000);
}

//Function ByteArr2ASCIIHexString to convert a byte array to an ASCII Hex string (for printing)
String ByteArr2ASCIIHexString(byte dat[], int lngth) {
  String HexString = "";

  for (int i = 0; i < lngth; i++) {
    if (dat[i] < 0x10) {
      HexString += '0';
    }
    HexString += String(dat[i], HEX);
  }
  return HexString;
}

But now, the Serial Monitor reports the following:

The returned Modbus data shows that the stream appears to be 'walking' off by sometimes, 0, 1 or 2 bytes each time the data is read.
At least the garbage preceding the printed line is gone, but I can't figure out what is causing the hex stream to walk about the way it is.

Any thoughts/suggestions would be much appreciated.
Many thanks...

not sure why Serial and Serial1 should be different but it looks like you are missing the odd byte and the receiver gets out of synch
could the meter be sending more than 11 bytes? the odd characters at the start of Serial output may be a problem
try removing the delay(1000) - any effect?

avoid image of a screen output - copy and upload the text, e.g. have a look at how-to-get-the-best-out-of-this-forum

Pretty sure the issue is here :

while ((Serial1.available() == 0) && (millis() - StartTime < 50)) {}
  if (Serial1.available() == 0) {
    Serial.println("Meter unavailable");
  }
  else {
    Serial1.readBytes(ReturnedModbusDat_Meter, 11);
    ReturnedModbusDat_Str=ByteArr2ASCIIHexString(ReturnedModbusDat_Meter,11);
    Serial.println("ReturnedModbusDat_Str= "+ReturnedModbusDat_Str);
  }

You are waiting for a single byte to be in the RX buffer, and when there is you read 11 of them ! Chances are those 11 bytes haven't all arrived as yet.

Those are the bytes coming back from your sensor. Because you were piggybacking onto Serial (which is used for comms through the serial-USB interface to the IDE), the IDE serial monitor also sees the response. But the response is in binary (rather than ASCII) and the IDE serial monitor attempts to print them, resulting in what you see.

It's why you don't see them when using Serial1.

I thought that too. It seems that readBytes will wait for up to 1 second (if you've not changed the default timeout) for the 11 bytes to arrive.

I would have structured the while loop a little differently myself. If I get to my desktop PC shortly, i'll post an example of how I do it.

Thanks for the suggestions.
Removing the delay(1000); doesn't change the results: bytes still 'walk'...

Thanks Deva-Rishi,
If the bytes haven't all arrived when I read them on RX1/TX1, then shouldn't the same problem occur when connected to RX0/TX0?
Why do the bytes get read correctly on RX0/TX0 but somehow get missed on RX1/TX1?

Thanks markd833,
That explanantion (of the garbage printed before the main hex stream) makes sense.

I put a delay of up to 1000mS before the Serial1.readBytes(ReturnedModbusDat_Meter, 11); line, in order to allow time for all 11 bytes to be secured in the RX buffer, but the results don't change: hex stream still walking around...

This is a little confusing to me as well,

I never use readBytes, prefer to be fully in control.

It actually looks like some leading zeroes are added, Serial0 is also connected to USB and the RX-pin is also pulled up, this may have something to do with it.

You could try flushing the receive buffer. At the top of loop() just before starting the transmission, insert:

while (Serial1.available() ) Serial1.read();

Hope i've got that right!

And i'm of the same opinion as @Deva_Rishi. I don't use readBytes either. I sit in a while loop reading bytes until either I have the bytes I want, or the loop times out.

@glen104 , just a thought, but do you get the same issue if you print out the received bytes without using your String function ByteArr2ASCIIHexString?

to test the basic communications I ran a simple simulation of the meter by connecting a couple of Mega Serial1 back to back
ran your Serial1 code on one of them
and this on the other - if I press a key it transmits { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };

// Arduino Mega serial1 test

// mega pin 18 is Tx
//      pin 19 is Rx
// for loopback test connect pin 18 to pin 19

// for RS232 shield connect pin 18 to Tx and pin 19 to Rx
// for loopback test connect 9 pin D connector pins 2 and 3

unsigned long time;

void setup() {
  Serial.begin(115200);   // initialise serial monitor port
  Serial1.begin(115200);  // initialise Serial1
  Serial.write("Arduino Mega Serial1 test -  for loopback test connect pin 18 to pin 19\n");
}

void loop() {
  if (Serial1.available()) {  // read from Serial1 output to Serial
    Serial.print((int)Serial1.read(), HEX);
    Serial.print(' ');
  }
  if (Serial.available()) {  // read from Serial outut to Serial1
    byte data[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
    int inByte = Serial.read();
    //Serial.print('>');
    //Serial.write(inByte);     // local echo if required
    //Serial1.write(inByte);
    if (inByte >= ' ') {
      Serial.println("\ntransmitting");
      Serial1.write(data, 11);
    }
  }
}

my program displays

Arduino Mega Serial1 test -  for loopback test connect pin 18 to pin 19
1 4 0 0 0 3 B0 B 1 4 0 0 0 3 B0 B 1 4 0 0 0 3 B0 B 
transmitting
1 4 0 0 0 3 B0 B 1 4 0 0 0 3 B0 B 1 4 0 0 0 3 B0 B 
transmitting
1 4 0 0 0 3 B0 B 1 4 0 0 0 3 B0 B 1 4 0 0 0 3 B0 B 1 4 0 0 0 3 B0 B 1 4 0 0 0 3 B0 B 
transmitting

transmitting

transmitting
1 4 0 0 0 3 B0 B 1 4 0 0 0 3 B0 B 1 4 0 0 0 3 B0 B 1 4 0 0 0 3 B0 B

your program displays

Meter unavailable
Meter unavailable
Meter unavailable
ReturnedModbusDat_Str= 0102030405060708090a0b
Meter unavailable
Meter unavailable
ReturnedModbusDat_Str= 0102030405060708090a0b
Meter unavailable
Meter unavailable
Meter unavailable
ReturnedModbusDat_Str= 0102030405060708090a0b
ReturnedModbusDat_Str= 0102030405060708090a0b
ReturnedModbusDat_Str= 0102030405060708090a0b
Meter unavailable
Meter unavailable
Meter unavailable

shows the basic receive of 11 bytes is OK
can you upload a schematic of the wiring?

Hi Horace,
Looks interesting.
The wiring schematic was included in my first post, but included (using RX1/TX1) as follows:

does the data from the meter have bytes to detect start and end of a frame?

Now that is what i was wondering as well since now the code just listens for 11 bytes, maybe a good idea would be to flush the RX buffer before transmitting the request. Still that does not explain the difference between Serial0 & Serial1

It looks like the meter uses the Modbus protocol. From memory Modbus detects a gap between bytes as it's way of detecting a new message. I think the Modbus spec says the gap has to be at least the time taken to send 3.5 bytes at the selected baud rate, but that's off the top of my head.

But the reception is done using Serial without break. So these zeroes could be trailing the 11 bytes. Still doesn't explain the difference between Serial0 & Serial1 unless the cause is electro-static. How about adding a 10K pullup on the RX-pin ?

don't know if this will help
I have modified my meter emulator to use RS485
when it receives a 0x0b (end of your request for data) it will transmit { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
the transmission can be switched on/of by entering a character

// RS485 using arduino mega Seial1 pins 18 and 19 - also works on the arduino DUE

#define RS485Serial Serial1  // hardware serial port on Mega

// connect RS485 DI and RO to Mega Serial1
//  Mega Serial Receive  pin 19 to RO
//  Mega Serial Transmit pin 18 to DI
// RS485 DE and RE to Mega pins 2 and 3
#define DE 2  //RS485 Direction control pin
#define RE 3  //RS485 Direction control pin

#define RS485Transmit HIGH
#define RS485Receive LOW

void setup() {
  while (!Serial)
    ;
  delay(1000);
  // Start the built-in serial port, probably to Serial Monitor
  Serial.begin(115200);
  Serial.println("Use Serial Monitor, type in upper window, ENTER");
  pinMode(DE, OUTPUT);
  pinMode(RE, OUTPUT);
  digitalWrite(DE, RS485Receive);  // Disable RS485 Transmit
  digitalWrite(RE, RS485Receive);  // Disable RS485 Transmit
  RS485Serial.begin(9600);       // set the RS485 data rate
}

void RS485sendData(void) {
  static byte data[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
  digitalWrite(DE, RS485Transmit);  // Enable RS485 Transmit
  digitalWrite(RE, RS485Transmit);  // Enable RS485 Transmit                                    //RS485Serial.write(Serial.read());  // Send byte to Remote Arduino
  Serial.println("\ntransmitting");
  delay(5);
  Serial1.write(data, 11);
  delay(5);
  RS485Serial.flush();             // wait for byte to be transmitted
  digitalWrite(DE, RS485Receive);  // Disable RS485 Transmit
  digitalWrite(RE, RS485Receive);  // Disable RS485 Transmit
  data[1]++;
}
// loop sending data from Mega to RS485 and receiving data
void loop() {
  static int senddata=1;
  if (Serial.available()) {      // Arduino Serial data avaliable?
    int inByte = Serial.read();
    if (inByte >= ' ') senddata=!senddata;    // invert sending
  }

  if (RS485Serial.available())  // RS485 serial data available?
  {
    int inByte = RS485Serial.read();
    Serial.print((int)inByte, HEX);  // read character and display it
    Serial.print(' ');
    if (senddata && inByte == 0x0b) RS485sendData();  // send data???
  }
}

modified your loop() to flush the Serial1 input

int RS485EnablePin = 3;                                                                         //1 to send, 0 to receive
int RS485EnablePin2 = 2;                                                                        //1 to send, 0 to receive
byte DigMeterAddr = 0x01;                                                                       //RS485 address of the digital AC meter (used to measure V,I,P, etc. of the variac secondary)
byte Modbus_GetVIDataCmd_Meter[] = { DigMeterAddr, 0x04, 0x00, 0x00, 0x00, 0x03, 0xb0, 0x0b };  //Command to be sent to the AC digital meter in order to get V,I electrical data returned
byte ReturnedModbusDat_Meter[25];                                                               //Setup a byte array to receive the Modbus data from digital AC meter
String ReturnedModbusDat_Str = "";                                                              //Setup a String to convert the ReturnedModbusDat into a String
unsigned long StartTime;

void setup() {
  Serial.begin(115200);
  Serial1.begin(9600);
  pinMode(RS485EnablePin, OUTPUT);
  pinMode(RS485EnablePin2, OUTPUT);
}

void loop() {
  digitalWrite(RS485EnablePin, HIGH);           //Enable high, SN75176 waiting to transmit data*/
  digitalWrite(RS485EnablePin2, HIGH);          //Enable high, SN75176 waiting to transmit data*/
  Serial1.write(Modbus_GetVIDataCmd_Meter, 8);  //Send the modbus command to receive data to AC meter
  Serial1.flush();                              //Ensure serial buffer has been sent before putting RS485 shield into receive mode (otherwise sending data is truncated & terminated and the full message is not received by the listening device)
  digitalWrite(RS485EnablePin, LOW);            //Enable low, SN75176 waiting to receive data
  digitalWrite(RS485EnablePin2, LOW);           //Enable low, SN75176 waiting to receive data
  delay(1);
  while (Serial1.available()) Serial1.read();   // clear input buffer
  StartTime = millis();  //Set the start time before waiting on a Serial.available response from the RS485 devices
  while ((Serial1.available() == 0) && (millis() - StartTime < 50)) {}
  if (Serial1.available() == 0) {
    Serial.println("Meter unavailable");
  } else {
    byte ReturnedModbusDat_Meter[25] = { 0xff };
    //Setup a byte array to receive the Modbus data from digital AC meter
    if (Serial1.readBytes(ReturnedModbusDat_Meter, 11) == 11) {
      ReturnedModbusDat_Str = ByteArr2ASCIIHexString(ReturnedModbusDat_Meter, 11);
      Serial.println("ReturnedModbusDat_Str= " + ReturnedModbusDat_Str);
    }
  }
  delay(1000);
}

//Function ByteArr2ASCIIHexString to convert a byte array to an ASCII Hex string (for printing)
String ByteArr2ASCIIHexString(byte dat[], int lngth) {
  String HexString = "";

  for (int i = 0; i < lngth; i++) {
    if (dat[i] < 0x10) {
      HexString += '0';
    }
    HexString += String(dat[i], HEX);
  }
  return HexString;
}

the meter emulator displays

1 4 0 0 0 3 B0 B 
transmitting
1 4 0 0 0 3 B0 B 
transmitting
1 4 0 0 0 3 B0 B 1 4 0 0 0 3 B0 B 1 4 0 0 0 3 B0 B 1 4 0 0 0 3 B0 B 1 4 0 0 0 3 B0 B 1 4 0 0 0 3 B0 B 1 4 0 0 0 3 B0 B 1 4 0 0 0 3 B0 B 
transmitting
1 4 0 0 0 3 B0 B 
transmitting
1 4 0 0 0 3 B0 B 
transmitting
1 4 0 0 0 3 B0 B 
transmitting
1 4 0 0 0 3 B0 B 
transmitting
1 4 0 0 0 3 B0 B 
transmitting
1 4 0 0 0 3 B0 B 
transmitting

and your program displays

ReturnedModbusDat_Str= 0102030405060708090a0b
ReturnedModbusDat_Str= 0103030405060708090a0b
ReturnedModbusDat_Str= 0104030405060708090a0b
ReturnedModbusDat_Str= 0105030405060708090a0b
ReturnedModbusDat_Str= 0106030405060708090a0b
ReturnedModbusDat_Str= 0107030405060708090a0b
ReturnedModbusDat_Str= 0108030405060708090a0b
Meter unavailable
Meter unavailable
Meter unavailable
Meter unavailable
Meter unavailable
Meter unavailable
Meter unavailable
ReturnedModbusDat_Str= 0109030405060708090a0b
ReturnedModbusDat_Str= 010a030405060708090a0b
ReturnedModbusDat_Str= 010b030405060708090a0b
ReturnedModbusDat_Str= 010c030405060708090a0b
ReturnedModbusDat_Str= 010d030405060708090a0b
ReturnedModbusDat_Str= 010e030405060708090a0b
ReturnedModbusDat_Str= 010f030405060708090a0b
Meter unavailable
Meter unavailable
Meter unavailable
Meter unavailable
Meter unavailable
Meter unavailable

you can see where I switched off/on the sending of the sample data

will it work with the meter? depends up how like the real meter my emulator timing works

Hi All,
There's some really intensive and extensive work being done here, and I'm very impressed and appreciative.
FYI, the comms is Modbus RTU, 9600 8N1.
After tossing over all the suggestions and ideas raised, I thought it may be useful to dump the Serial.readBytes() function, and, as suggested, write a while loop that reads each byte sequentially, eg:

int RS485EnablePin = 3;  //1 to send, 0 to receive
byte DigMeterAddr = 0x01; //RS485 address of the digital AC meter (used to measure V,I,P, etc. of the variac secondary)
byte Modbus_GetVIDataCmd_Meter[] = {DigMeterAddr, 0x04, 0x00, 0x00, 0x00, 0x03, 0xb0, 0x0b}; //Command to be sent to the AC digital meter in order to get V,I electrical data returned
byte ReturnedModbusDat_Meter[25];  //Setup a byte array to receive the Modbus data from digital AC meter
String ReturnedModbusDat_Str = ""; //Setup a String to convert the ReturnedModbusDat into a String
unsigned long StartTime;

void setup() {
  Serial.begin(9600); 
  Serial1.begin(9600);
  pinMode(RS485EnablePin, OUTPUT);
}

void loop() {
  digitalWrite(RS485EnablePin, HIGH); //Enable high, SN75176 waiting to transmit data*/
  Serial1.write(Modbus_GetVIDataCmd_Meter, 8); //Send the modbus command to receive data to AC meter
  Serial1.flush();  //Ensure serial buffer has been sent before putting RS485 shield into receive mode (otherwise sending data is truncated & terminated and the full message is not received by the listening device)
  digitalWrite(RS485EnablePin, LOW); //Enable low, SN75176 waiting to receive data
  StartTime = millis(); //Set the start time before waiting on a Serial.available response from the RS485 devices
  while ((Serial1.available() == 0) && (millis() - StartTime < 50)) {}
  if (Serial1.available() == 0) {
    Serial.println("Meter unavailable");
  }
  else {
  //Replace readBytes with the following loop:
    int n=0;
    while (Serial1.available()) {
      ReturnedModbusDat_Meter[n]=Serial1.read();
      n++;
    } //End of new loop
    ReturnedModbusDat_Str=ByteArr2ASCIIHexString(ReturnedModbusDat_Meter,11);
    Serial.println("ReturnedModbusDat_Str= "+ReturnedModbusDat_Str);
  }
  delay(100);
}

//Function ByteArr2ASCIIHexString to convert a byte array to an ASCII Hex string (for printing)
String ByteArr2ASCIIHexString(byte dat[], int lngth) {
  String HexString = "";

  for (int i = 0; i < lngth; i++) {
    if (dat[i] < 0x10) {
      HexString += '0';
    }
    HexString += String(dat[i], HEX);
  }
  return HexString;
}

And, wonder of wonders, it now seems to work (mostly):

ReturnedModbusDat_Str= 01040609940000000051d7
ReturnedModbusDat_Str= 0104060995000000006c17
ReturnedModbusDat_Str= 0104060995000000006c17
ReturnedModbusDat_Str= 0104060995000000006c17
ReturnedModbusDat_Str= 0104060995000000006c17
ReturnedModbusDat_Str= 0104060995000000006c17
ReturnedModbusDat_Str= 0104060995000000006c17
ReturnedModbusDat_Str= c10104060995000000006c
ReturnedModbusDat_Str= f80104060995000000006c
ReturnedModbusDat_Str= 0104060995000000006c17
ReturnedModbusDat_Str= 0104060995000000006c17
ReturnedModbusDat_Str= 0104060995000000006c17
ReturnedModbusDat_Str= 0104060995000000006c17
ReturnedModbusDat_Str= 0104060995000000006c17
ReturnedModbusDat_Str= 0104060995000000006c17
ReturnedModbusDat_Str= 0104060995000000006c17
ReturnedModbusDat_Str= 0104060995000000006c17
ReturnedModbusDat_Str= 0104060995000000006c17
ReturnedModbusDat_Str= 0104060995000000006c17
ReturnedModbusDat_Str= 0104060995000000006c17
ReturnedModbusDat_Str= 0104060995000000006c17
ReturnedModbusDat_Str= 0104060995000000006c17
ReturnedModbusDat_Str= 0104060995000000006c17
ReturnedModbusDat_Str= 01040609940000000051d7
ReturnedModbusDat_Str= 01040609940000000051d7
ReturnedModbusDat_Str= e101040609940000000051
ReturnedModbusDat_Str= 01040609940000000051d7
ReturnedModbusDat_Str= 01040609940000000051d7
ReturnedModbusDat_Str= 01040609940000000051d7
ReturnedModbusDat_Str= 01040609940000000051d7
ReturnedModbusDat_Str= 01040609940000000051d7

Except for some 'misdeameanours' every now and again.
So, to address the 'misdeamenors', and thinking about the suggestion that Modbus protocol requires 3.5 bytes space between messages (3.5/(9600/8)=2.9mS), I introduced a 5mS delay just before the int n=0; line, just to add some time for the complete stream to come in prior to reading it.
And now there's no 'misdeamenours'!

ReturnedModbusDat_Str= 01040609940000000051d7
ReturnedModbusDat_Str= 01040609940000000051d7
ReturnedModbusDat_Str= 01040609940000000051d7
ReturnedModbusDat_Str= 01040609940000000051d7
ReturnedModbusDat_Str= 010406099200000000d9d7
ReturnedModbusDat_Str= 010406099200000000d9d7
ReturnedModbusDat_Str= 010406099200000000d9d7
ReturnedModbusDat_Str= 010406099200000000d9d7
ReturnedModbusDat_Str= 010406099200000000d9d7
ReturnedModbusDat_Str= 010406099200000000d9d7
ReturnedModbusDat_Str= 010406099200000000d9d7
ReturnedModbusDat_Str= 010406099200000000d9d7
ReturnedModbusDat_Str= 010406099200000000d9d7
ReturnedModbusDat_Str= 010406099200000000d9d7
ReturnedModbusDat_Str= 010406099200000000d9d7
ReturnedModbusDat_Str= 010406099200000000d9d7
ReturnedModbusDat_Str= 010406099300000000e417
ReturnedModbusDat_Str= 010406099300000000e417
ReturnedModbusDat_Str= 010406099300000000e417
ReturnedModbusDat_Str= 010406099300000000e417
ReturnedModbusDat_Str= 010406099300000000e417
ReturnedModbusDat_Str= 010406099300000000e417
ReturnedModbusDat_Str= 010406099300000000e417
ReturnedModbusDat_Str= 010406099300000000e417
ReturnedModbusDat_Str= 010406099300000000e417
ReturnedModbusDat_Str= 010406099300000000e417
ReturnedModbusDat_Str= 010406099300000000e417
ReturnedModbusDat_Str= 010406099300000000e417
ReturnedModbusDat_Str= 010406099300000000e417
ReturnedModbusDat_Str= 010406099300000000e417
ReturnedModbusDat_Str= 010406099300000000e417
ReturnedModbusDat_Str= 010406099300000000e417

So, folks, it looks like this is now working the way it should, and I can only thank everyone for their very helpful ideas that eventually funnelled down the range of options to a solution!
Cheers & many thanks...

1 Like

this is just a checksum as defined in Modbus.

I just wonder why you aren't using a Modbus Library. I like Modbus Master from Doc Walker: