Serial data corrupted after six bytes

Hello group:

I'm communicating with another target over TTL-level serial bus at 57600 baud. Sending only 8 bytes ending in two bytes of CRC.

Example:

Sending (HEX): 05 1B 00 02 1C 00 1C 38

Received at Target: 05 1B 00 02 1C 00 9C 8E

Last two byte data seems to be shifted (maybe).

Target receives data from other targets correctly.

Any thoughts on why only last two byte corrupted? THANKS!

void loop() 
{

  // Modbus server accept incoming connections
  EthernetClient client = EthServer.available();

  if (client.connected()) 
  {
    modbusTCPServer.accept(client);
    // poll for Modbus TCP requests, while client connected
    modbusTCPServer.poll();
    

    digitalWrite(3, LOW);    // set BiBuffer Low to begin transfer
    delay (1);

    Serial.print("poll");
  }

        

        AdjustBuf[0]= 0x05;     //magic number
        AdjustBuf[1]= 0x1B;     //op code LSB
        AdjustBuf[2]= 0x00;     //op code MSB
        AdjustBuf[3]= 0x02;     //body length
        AdjustBuf[4]= 0x1C;     //body LSB (byte 1)
        AdjustBuf[5]= 0x00;     //body MSB (byte 2)
        AdjustBuf[6]= 0x1C;     //cksum LSB
        AdjustBuf[7]= 0x38;     //body MSB
       
        
                
        Serial1.write (AdjustBuf,8);   //Send request to target to change value
        delay(30);
        digitalWrite(3, HIGH);    // set BiBuffer Low to begin transfer
        delay(3000);

}

Please post ALL the code. If you are using SoftwareSerial, that is the problem.

What's the distance and what's the cable? Any drivers used?
It sounds too ambitious to me using that baudrate.

Complete code:

#include <Ethernet.h>
#include <ArduinoModbus.h>

bool _5s;
unsigned long TimeAct, TimePrev, HoldingResult, InputResult, HeartBeat, i, StartingAddr;
long Cmd, Cmd2;




EthernetServer EthServer(502);
ModbusTCPServer modbusTCPServer;

char Param;
char NewValue;

byte AdjustBuf[4];

const int BUFFER_SIZE = 66;
byte DataBufOut[BUFFER_SIZE];        //holds data going out to Modbus connection
byte DataBufIn[BUFFER_SIZE];      //holdds data coming in from Modbus connection
bool DataDirection= false;          //data in/out flag from Modbus
unsigned int seed;
unsigned int ckSum;


void setup() {
  // Ethernet Settings
  byte mac[] = { 0x4E, 0xA0, 0xBE, 0x3F, 0xFE, 0x0F };  // Define MAc address
  byte ip[] = { 192, 168, 1, 100 };                      // Define IP address
  byte subnet[] = { 255, 255, 255, 0 };                 // Define SubNEt mask

  //UART Settings
  pinMode(3, OUTPUT);      // set BiBuffer as output pin
  digitalWrite(3, HIGH);    // set BiBuffer High to start
  Serial1.begin(57600);       // initialize UART with baud rate of 57600 bps
  Serial.begin(9600);
  

  // initialize the ethernet device
  Ethernet.begin(mac, ip, subnet);                      // Assign MAC, IP, and subnet mask
  
  EthServer.begin();          // start listening for clients
  modbusTCPServer.begin();    // start listening for clients

  // Define Holding register:
  HoldingResult = modbusTCPServer.configureHoldingRegisters(0, 100);
  InputResult = modbusTCPServer.configureInputRegisters(0, 100);

  //Serial.print("Holding Reg init result =");
  //Serial.print(HoldingResult);
  //Serial.print("\n");

  //Serial.print("Input Reg init result =");
  //Serial.print(InputResult);
  //Serial.print("\n");

  //Serial.print("Modbus server address=");
  //Serial.println(Ethernet.localIP());
  //Serial.print("\n");
}

unsigned int Fletcher16(unsigned int val, unsigned int seed)
{
     unsigned int high = seed >> 8;
     unsigned int low = seed & 0xFFL;
     unsigned int ret = 0;

    low = low + val;
    high = high + low;
    low = low & 0xFF;
    high = high & 0xFF;
    ret = high << 8;
    ret = ret | low;

    return ret;

}
//================================================================================================
//Main Loop
//================================================================================================
void loop() 
{

  // Modbus server accept incoming connections
  EthernetClient client = EthServer.available();

  if (client.connected()) 
  {
    modbusTCPServer.accept(client);
    // poll for Modbus TCP requests, while client connected
    modbusTCPServer.poll();
    

    digitalWrite(3, LOW);    // set BiBuffer Low to begin transfer
    delay (1);

    Serial.print("poll");
  }

        

        AdjustBuf[0]= 0x05;     //magic number
        AdjustBuf[1]= 0x1B;     //op code LSB
        AdjustBuf[2]= 0x00;     //op code MSB
        AdjustBuf[3]= 0x02;     //body length
        AdjustBuf[4]= 0x1C;     //body LSB (byte 1)
        AdjustBuf[5]= 0x00;     //body MSB (byte 2)
        AdjustBuf[6]= 0x1C;     //cksum LSB
        AdjustBuf[7]= 0x38;     //body MSB
       
        
                
        Serial1.write (AdjustBuf,8);   //Send request to AGC-7 to change value
        delay(30);
        digitalWrite(3, HIGH);    // set BiBuffer Low to begin transfer
        delay(3000);

}

Good point if it didn't just go through a 1 inch header. On oscilloscope data looks virtually noiseless and square.

Thanks,

What is receiving the data, and what does the receive code look like?

Okey.
TTL level and Ethernet sounds new. Are special drivers/receivers used?
You understand I'm outside my comfort zone now....

Group: THANKS for your help

Target uses a Microchip 8 bit device. Code was compiled using the CCS compiler and is extremely complex and proprietary so I can't post it. Do know that the Microchip-based target receives the same 8 bit sequence correctly and that combination has been working well for years.

Additional information:

If I "pack" 0xFF and 0xFF into the last two buffer locations, communication is correct. If I "pack" 0x00 and 0x00 into the last two buffer locations, I get 0x80 0x80. Pretty crazy.

No, TTL level for serial communications, Ethernet works correctly and uses traditional driver and magnetics.

Thanks

ā€œUnbalancedā€™ TTL comms is only reliable for about 60-100cm in a fairly clean environment.

Stray capacitance, voltage drop can bring problemsā€¦. If you can, try running at a lower bit rate to test. I expect youā€™ll be surprised

Factors like ā€˜energy density lin the continuous setiial signal can cause unexpected reception.

TYPOS FIXED :hugs::scream:

Yes, I suspect some type of baud rate mismatch issue between the Arduino and the other target. That accumulated mismatch might be affecting the latter bytes.

Donā€™t know how to skew the baud rate slightly on either target.

Iā€™ll keep the group posted

Itā€™s not a slight mismatch, they could perfectā€¦ judging by the ā€˜correctā€™ messages.
More likely signal distortion on that length of wire.
Thatā€™s why I mentioned energy density ā€¦
Try the code sending a string of ā€œU5U5U5ā€ā€¦ the hex for that is 0x35 and 0x55,
which provides continuous alternating data bits.

Sending combinations of 0x00 and 0xFF sequentially does a similar thing, with sequential blocks of 000000 and 1111111 to test the link integrity,

1 Like

Iā€™ll give that a try. BTW- only one inch header between the boards, no no real distance. Iā€™ve successfully communicated 57600 TTL over several inches without drivers during tests.

Thanks

byte AdjustBuf[4];
...
AdjustBuf[4]= 0x1C;     //body LSB (byte 1)
AdjustBuf[5]= 0x00;     //body MSB (byte 2)
AdjustBuf[6]= 0x1C;     //cksum LSB
AdjustBuf[7]= 0x38;     //body MSB

Don't write outside of an array, it will corrupt your program.

4 Likes

Can you set the sender to 8N2? If so, does that fix the problem?

The problem there is I canā€™t change the targets code. Good suggestion
though

Please fix the egregious error noted in post #16 and let us know if the problem is solved.

1 Like

A Pox upon me! Great catch guix! A stupid copy and paste error. Fixed!

However, issue still exists

Changed bytes sent to: 0x05 0x1B 0x00 0x02 0x18 0x00 0x35 ox55
Get at target: 0x05 0x1B 0x00 0x02 0x18 0x00 0x9A oxAA

Last two bytes are shifted. All other bytes are fine. Strange!

Yeah, it's a baud rate mismatch between the two ends, or the start/stop bits aren't being handled correctly. There's a one-bit shift when it goes wrong:

0x35 is 0b 00110101
0x9A is 0b 10011010

And I believe it's sent LS bit first. So maybe the receiver is reading the end of the start bit as the first data bit. So unless my thinking is backwards, the transmitter is slow. Edit: Or, you know, the receiver is fast.

Similarly for 0x55 (01010101) and 0xAA (10101010).

Looking at your code it appears you are using a hardware serial port for Serial1. Which Arduino are you using?

Is it a MEGA2560 based board or something else?

Is it a custom designed board or an off the shelf board?