Serial.read() Why can't I sync data?

Hello,

I have a problem that I can not solve alone,
I do not understand where there is error, I ask for help to frum :confused:

I have a PC that communicates data via serial (USB) with Arduino UNO, communication is at regular intervals of 1 seconds (polling), PC transmits every 1seconds 20 bytes, fixed length.

I would like to store the received data on the serial in a variable structure (TgrPak_RX).

To do this I developed the following code

typedef struct
{
  int ID;
  int Mod;
  int Brig;
  int Dec;
  int Ord;
  int Pet;
  unsigned long Time;
  byte Err;
  byte Rif;
  int CRC;
}
TelegrDef_RX;
TelegrDef_RX TgrPak_RX;

int index=0;
byte b[sizeof(TgrPak_RX)];


void setup() {
Serial.begin(115200); 
}


void loop() {
delay(1); //This just simulates time spent elsewhere in a big program

if (Serial.available() >= sizeof(b)) {
    for (index=0;index<sizeof(b);index++) b[index] = Serial.read();
    memcpy(&TgrPak_RX, b, sizeof(b));
    }

}

Data arrives regularly to the arduino,
I see the RX led flashing every 1s.
I also checked the data sent over a serial Analyzer and are correct and in the right quantity (20 bytes).

Oddly enough happens that data are not synchronous than the structure that I created (TgrPak_RX),
it looks like the serial function serial.read() does not point the serial buffer from the starting point than the previous reading;
in practice the data inside the structure (TgrPak_RX) are never consistent but continue to vary,
according to what I understand are not synchronous than the PC sends.

Is there anything I can do or change?
Because the serial buffer does not behave properly?
He has a breadth of 64 bytes so if I send them 20 bytes should not overflow!
Thanks in advance for those who want to help me :slight_smile:

Have a look at the 2nd and 3rd examples in Serial Input Basics. They will provide a more robust way of receiving data. The system in the 3rd example will be most reliable. When it signals newData = true then you can copy the data to your struct.

...R

Hi Robin, thankyou for the answer :slight_smile:
I have read and enjoyed your work you've posted,
I initially thought that StartEndMarker was good for me but then I changed my mind because my telegram has fixed length of 20 bytes and then if the FIFO buffer of Arduino working properly shouldn't need this.

Just now I discovered something more!
I failed to mention that my original program includes some libraries including:

#include <SPI.h>
#include <DMD.h>
#include <TimerOne.h>

I not indicated why I didn't absolutely could create problems!
I tried to exclude the code and libraries and magically it works perfectly, my structure is filled by the data coming from the serial, properly!

So there is something that "crash" the serial buffer pointer of Arduino,
my suspicion falls on the time interrupt:

void setup() {
....
Timer1.initialize( 5000 );
Timer1.attachInterrupt( ScanDMD ); 
}

it's possible that the function interrupt (Timer1) influence the read pointer serial function?

Sorry. I have never used the TimerOne library. I just use millis() for my timing as in Several Things at a Time

My guess is that if the library is the problem it is more likely the way you are using it rather than an intrinsic problem with the library. But that's just a guess.

...R

Hi Robin, I answer myself ...
TimerOne library function interrupt conflicts with the FIFO buffer pointer of the serial!!!
I just proved this by making a change to my program ...
I disabled the function for TimerOne and I implemented in its place a simple logic of calling time.
Is not as precise as the interrupt but okay ...
Did this I tested communication and I found that the serial communication works perfectly.

Anyway I'm planning to implement your function StartEndMarkers, though in that case I am forced to circulate ASCII characters and not hexadecimal data as I wanted in the beginning.
This for the reason that if I use the hex data with delimiters, there is a risk that if inside the DataPack, lies a byte with a same code as the value of the delimiter, I can create a situation of failure.
So if I use the delimiters do I have to send only ASCII characters, despite this increases the length of bytes.

I try and let you know, thank you and congratulations for the post of the serial communication (y) :wink:

It is perfectly possible, with a little effort, to build a system that allows the use of start and end markers with binary data. In the system I used I set aside the three bytes 253, 254 and 255 for a special purpose. IIRC 254 and 255 were the start- and end-markers and 253 was used as a marker that preceded any of the three bytes if it should be treated as data rather than as a marker.

See the initial Posts in this Thread.

However sending binary data makes debugging much more difficult and I avoid it if I can.

Recently I have been using a system that converts numbers into 2 or 3 (or 4) characters by first converting the number to base 64 and then adding 48 to the resulting byte values to bring them in the character range '0' to 'o' (lowercase O). This means that a number up to 4160 can be represented in 2 charcters and up to 266304 in 3 characters. The code to turn those characters back into numbers is about 10 times faster than atoi().

...R