Serial1 read- bytes shifting randomly

Note: I've posted the same question/info at Stackoverflow.
Not sure if there is a "fix" but was curious if anyone had any ideas.

What I'm doing - Reading a 3d party device that sends 4bytes(there are no delimiters) at 9600 TTL 8N1 using an Industrial Shield(but equivalent to Mega).

What I'm seeing- Datawise- Bits come in but then "shift" left inconsistently(1,2,3 positions). Oscilloscope(s) - Owon DS8102- I can see the signal jumping/trigger shifting, looks like bad timing for the output. Picoscope - Locks on to the data bytes and can read correctly. It's better at "holding" position on the screen.

I've tried interrupts and various ideas for getting consistent clean data but no luck. One of the major factors is the 3d party unit will be shut down power-wise and restarted. 9 times out of 10 the data comes back shifted or just wrong.

Here's two versions of code that get the same results.
Simple:

void setup() {
  Serial1.begin(9600);  // Initialize Serial1 with a baud rate of 9600
  Serial.begin(9600);   // Initialize the Serial Monitor with a baud rate of 9600
}

void loop() {
  if (Serial1.available() >= 4) {  // Check if there are at least 4 bytes available to read from Serial1
    byte data[4];  // Create an array to store the received data
    Serial1.readBytes(data, 4);  // Read 4 bytes from Serial1 into the data array
    for (int i = 0; i < 4; i++) {  // Print out the received data in hexadecimal format
      Serial.print("0x");
      Serial.print(data[i], HEX);
      Serial.print(" ");
    }
    Serial.println();  // Print a new line
  }
}

Interrupt and struct:

// Define the struct for the communication packet
struct CommunicationPacket {
  uint8_t Source;
  uint8_t Function;
  uint8_t InfoA;
  uint8_t InfoB;
};

// Create an instance of the communication packet struct
CommunicationPacket com;

// Define a flag to indicate when new data has been received
volatile bool newData = false;

// Define the interrupt service routine to read incoming data
void serialEvent1() {
  // Check if there are at least 4 bytes available to read
  while (Serial1.available() >= 4) {
    // Read the 4 bytes into the communication packet struct// have tried readBytes, loops, etc also
    com.Source = Serial1.read();
    com.Function = Serial1.read();
    com.InfoA = Serial1.read();
    com.InfoB = Serial1.read();

    // Set the new data flag to indicate that new data has been received
    newData = true;
  }
}
const byte interruptPin = 19;
void setup() {
  // Initialize Serial1 at 9600 baud
  Serial1.begin(9600);
    Serial.begin(9600);

  // Enable interrupts for Serial1
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), serialEvent1, FALLING);

}

void loop() {
  // Check if new data has been received
  if (newData) {
    // Process the new data here...
  Serial.print("Source: ");
  Serial.println(com.Source, HEX);
  Serial.print("Function: ");
  Serial.println(com.Function, HEX);
  Serial.print("InfoA: ");
  Serial.println(com.InfoA, HEX);
  Serial.print("InfoB: ");
  Serial.println(com.InfoB, HEX);
  Serial.println(" ");
    // Reset the new data flag
    newData = false;
  }
}

Thanks for looking at this and open to any ideas.

In that case how do you know where each series of 4 bytes starts ?

I do in the sense of the Picoscope showing the start of the 4bytes, but the serial timing from the source seems a bit sketchy. Thus the shifting issue.

Do you know the order because there's a gap between transmissions of 4, perhaps?

Yes.

I was wondering if using something like a timer to check but the data timing changes. I did try an eventFuse idea. Same result.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.