Ard <--> Pi serial data transfer(unsolved)

Hello all, Why will arduino find '$' but not find '!' in my incoming data to trigger the print struct function?
TIA.
Arduino code.

void setup(){
  Serial.begin(57600); 
  Serial3.begin(57600); 
}  
struct MyStruct_t{
    float FloatValue01;
      int IntValue01;
 long int lIntValue01;
    char* CharValue01[15];
 }
MyStruct;

int PiData;

void loop()
{
  if (Serial3.available() > 0){
    PiData = Serial3.read();
    if (PiData == '

RPI (Raspberry Pi) code.

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <wiringSerial.h>
#include <stdlib.h>

void serialSend();
char *ChVal = "Hello World";

        struct MyStruct_t{
          float FloatValue01;
            int IntValue01;
       long int lIntValue01;
          char* CharValue01[15];
        }MyStruct;

int fd;

int main ()
{
  if ((fd = serialOpen ("/dev/ttyAMA0", 57600)) < 0)
  {
   fprintf (stderr, "Unable to open serial device: %s\n", strerror (errno)) ;
    return 1 ;
  }

 for (;;)
  {
          serialSend();
        }
 }//main

void serialSend(){

        serialPutchar(fd, '

it finds $ just fine and triggers the while loop bit never seems to find !.){
     Serial.println("SoS Found");      
     readSerial();
   }
 }
}

void readSerial(){

while (PiData != '!'){
   if (Serial3.available() > 0){
     Serial3.readBytes((char *)&MyStruct,sizeof(MyStruct));
   }
 }
     if (PiData == '!'){
     Serial.println("Found !, Now printing MyStuct");
     prnStruct();
   }

}

void prnStruct(){

Serial.print(MyStruct.FloatValue01);
 Serial.print(" : ");      
 Serial.print(MyStruct.IntValue01);
 Serial.print(" : ");      
 Serial.print(MyStruct.lIntValue01);
 Serial.print(" : ");            
 for (int i=0;i < sizeof(MyStruct.CharValue01);i++){
   Serial.print(MyStruct.CharValue01[i]);
 }
 Serial.println("");      
}


RPI (Raspberry Pi) code.

§DISCOURSE_HOISTED_CODE_1§


it finds $ just fine and triggers the while loop bit never seems to find !.);
        MyStruct.FloatValue01 = 33.999;
        MyStruct.IntValue01 = -37000;
        MyStruct.lIntValue01= 2000000000;
        MyStruct.CharValue01[0] = ChVal;
        serialPuts(fd,(char *)&MyStruct);
        serialPutchar(fd, '!');
        return;
}

it finds $ just fine and triggers the while loop bit never seems to find !.){
     Serial.println("SoS Found");      
     readSerial();
   }
 }
}

void readSerial(){

while (PiData != '!'){
   if (Serial3.available() > 0){
     Serial3.readBytes((char *)&MyStruct,sizeof(MyStruct));
   }
 }
     if (PiData == '!'){
     Serial.println("Found !, Now printing MyStuct");
     prnStruct();
   }

}

void prnStruct(){

Serial.print(MyStruct.FloatValue01);
 Serial.print(" : ");      
 Serial.print(MyStruct.IntValue01);
 Serial.print(" : ");      
 Serial.print(MyStruct.lIntValue01);
 Serial.print(" : ");            
 for (int i=0;i < sizeof(MyStruct.CharValue01);i++){
   Serial.print(MyStruct.CharValue01[i]);
 }
 Serial.println("");      
}


RPI (Raspberry Pi) code.

§DISCOURSE_HOISTED_CODE_1§


it finds $ just fine and triggers the while loop bit never seems to find !.
void readSerial(){

  while (PiData != '!'){
    if (Serial3.available() > 0){ 
      Serial3.readBytes((char *)&MyStruct,sizeof(MyStruct)); 
    }
  }
      if (PiData == '!'){
      Serial.println("Found !, Now printing MyStuct");
      prnStruct();
    }
 
  }

Where does PiData ever get a new value?

Errrm, good question seems as if once i parse $ out in main loop i never update Pidata huh?. Thanks for the answer as always PaulS.

Ok changed to this now.(still cant believe i missed that lol).

void readSerial(){
  while (PiData != '!'){
    PiData = Serial3.read();
    if (Serial3.available() > 0){ 
      Serial3.readBytes((char *)&MyStruct,sizeof(MyStruct)); 
    }
    if (PiData == '!'){
      Serial.println("Found !, Now printing MyStuct");
      prnStruct();
    }

  }
}

So now i get a bunch of spew from the terminal like this.

øøøøøøøøøøøøíøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøø
øøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøø
øøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøø
øøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøø
øøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøø
øøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøø
øøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøÿæÿOW™-ÎdtÓÏçO!NÁåáu
‘wí¾ñ‡ó¤ÕIÆ}ikÞ×À2úéOg^׿GÑ6õý½Çy…ïÔdÞv/øO½c
                                                 YÌ‘4!ÿ{Z)Æzö}ÕêTî!¯Î˜[¹r;Ÿ¾î
wþsºIÌJµ¯¼ï$î?¾Þý÷sÚÌÅP+¥sµ ÿг|Û:«î}Ú³Õi?ú[¥œåøøøøøøøøøøøøøøøøøøøøøøøøøøøøø
øøøøøøøøøøøøøøøøøøøøøøøøøîøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøø
øøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøø
øøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøø
øøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøíøøøøøøøøøøøøø
øøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøø
øøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøîøøøøøøøø
øøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøø
øøøøøøøøøøøøøøøøøøøøøîøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøø

so i rem out the array print part and got some odd data also.

Found !, Now printing MyStuct
ovf : 16903 : -37000 : 
SoS Found
Found !, Now printing MyStuct
ovf : 16903 : -37000 : 
SoS Found
Found !, Now printing MyStuct
ovf : 16903 : -37000 : 
SoS Found
Found !, Now printing MyStuct
ovf : 2046 : -9471934 : 
SoS Found
Found !, Now printing MyStuct
0.00 : -1500 : 2017593342 : 
SoS Found
Found !, Now printing MyStuct
ovf : 16903 : -37000 : 
SoS Found
Found !, Now printing MyStuct
ovf : 16903 : -37000 : 
SoS Found
Found !, Now printing MyStuct
ovf : 16903 : -37000 : 
SoS Found
Found !, Now printing MyStuct
ovf : 16903 : -37000 :

if you notice in the Pi code the values should be.

serialPutchar(fd, '

how/why are they getting changed?);
        MyStruct.FloatValue01 = 33.999;
        MyStruct.IntValue01 = -37000;
        MyStruct.lIntValue01= 2000000000;
        MyStruct.CharValue01[0] = ChVal;
        serialPuts(fd,(char *)&MyStruct);
        serialPutchar(fd, '!');


how/why are they getting changed?

how/why are they getting changed?

There are potentially several problems. First, you assume that the struct on the Pi and the Arduino are the same size. The only way that this could be true is if neither side pads the struct and floats, longs, ints, and chars on both sides are the same size. I don not know that either assumption is valid.

Second, you assume that both the Pi and the Arduino use the same endianness. I do not know that this is a valid assumption, either.

Third, you assume that all serial data is delivered without issue. This I do know about. It is NOT a valid assumption.

The readBytes() method reads the specified number of bytes IF that number of bytes arrives in a reasonable amount of time. Do you know that they do? It returns the number of bytes read. You discard that value. Why? Checking that the correct number of bytes was read would be useful.

Finally, you print stuff to the Serial instance without bothering to prefix the data with any sort of identification. That makes it difficult to see what part of the struct is not populated correctly.

did a little digging before i need to get some sleep and found that both are little endian but it seems the structs might be diff hard to tell tho. got any test code i can whip up and check on the pi ( linux) and ard?
yeah it could be issues with the data trans and other things. heck it could be 2 or 3 of them at once. i suspect the struct size could be derived with sizeof(mystuct) and some printing yes? if so could ya post the example im to tired to try and look for it :). anyhow thanks as usual PaulS you always seem to know what to look out for. maby some day ill grasp programming :).

nite nite all.

from your code

void readSerial(){
  while (PiData != '!'){
    PiData = Serial3.read();   <<<<<<<<<< you read before checking if there is something available...
    if (Serial3.available() > 0){ 
      Serial3.readBytes((char *)&MyStruct,sizeof(MyStruct)); 
    }
...

welp now that i got some rest i got the sizeof(MyStruct) on both systems and it's size is 12 on Pi and 6 on Arduino.
So endianness is same at littleE Pi has 2x the size struct that the Arduino has.

Serial.readBytesUntil('!', (char *)&Mystruct,sizeof(MyStruct)); returned this.

SoS Found
0
SoS Found
0
SoS Found
0
SoS Found
1
SoS Found
0
SoS Found
0
SoS Found
0
SoS Found
0

int bytesRead1 = Serial.readBytes('!', (char *)&Mystruct,sizeof(MyStruct)); returned this.

Found !, Now printing MyStuct
6
SoS Found
6
Found !, Now printing MyStuct
6
SoS Found
6
Found !, Now printing MyStuct
6
SoS Found
6
Found !, Now printing MyStuct

so it seems Pi is sending the 12 but the Arduino is only reading 6 in because Arduino is storing my int's at 2 byte val's? and pi is 12 because it's int's are 4? or am i missing the point?
so how do i down size the Pi data or get Arduino to use more memory for each Int? ( is this going to be the same with others like float long unsigned long there all going to be 2x the size as the Arduino?)

        struct MyStruct_t{
          float FloatValue01;
            int IntValue01;
       long int lIntValue01;
          char* CharValue01[15];
        }MyStruct;

4 + 2 + 4 + 30 = 40. Where did you get 6? or 12?

Are you actually sending an array of pointers? What are they supposed to point to?

6 and 12 is the byte size the returns form the serial.readBytes and on the Pi.. 6 on ard and 12 on pi. i guess i thought that is what the struct size was = to.
as far as sending it's just bogus data you can see in the first post where i stuff them to be sent from the Pi.

i know this is late for asking but there is no Arduino <-> Pi serial com lib or something that sends structured data back and forth?

The usual ratio of answers to questions is 1 to 1 or higher. Less than 1 to 1 does not encourage people to continue trying to help.

You know that you can print the value that sizeof() returns which may not be the same value that readBytes() returns. If, in fact, the two values are not the same, then you know what the problem is.

About the pointers?

sorry for the slow response day to day life is only giving me with a small amount of time for my project each day. anyhow i am sorry i am so stumped on this that my Q to A ratio is not up to par for the community. as for you question about the pointers unless i am not getting where your coming from they are pointed to static values being assigned on the Pi side for now in the for loop in main.

serialPutchar(fd, '

as for am i sending the array of pointers successfully well that is the $64,000 question i guess.
So maybe ill start from scratch. so let me ask you this. if you were trying to send a strut of data from an Arduino to a Linux based system and from the Linux system to the Arduino how would you go about it.you have the choice of I2C,SPI,Serial. thanks in advance.);
        MyStruct.FloatValue01 = 33.999;
        MyStruct.IntValue01 = -37000;
        MyStruct.lIntValue01= 2000000000;
        MyStruct.CharValue01[0] = ChVal;
        serialPuts(fd,(char *)&MyStruct);
        serialPutchar(fd, '!');


as for am i sending the array of pointers successfully well that is the $64,000 question i guess.
So maybe ill start from scratch. so let me ask you this. if you were trying to send a strut of data from an Arduino to a Linux based system and from the Linux system to the Arduino how would you go about it.you have the choice of I2C,SPI,Serial. thanks in advance.

Think of pointers as index card numbers. If I tell you that the answer to your question is on card number 12 in the third file cabinet from the left as you go into room 21B7, is that going to do you any good?

Sending pointers from one device to another makes no sense. The Arduino can't use that pointer to get the data from the PI.

the struct was filled with

void serialSend(){

        serialPutchar(fd, '

those on the pi side the the struct was suppose to be transmitted ( think it was but who knows at this point) so if the struct was sent like it was when i was using the Nrf24l01's befor it should have unpacked and populated it on the arduino side.

been looking at a god awful lot of examples on arduino and pi and c++ forums and i seen some memcpy stuff (also some struct packing, have not made to much sense of that yet)
but i have come up with this so far. tell me if i am heading in the right direction anyhow.
Arduino side (send only for now)

struct MyStruct_t {
    float yaw;
    float pitch;
    float roll;
}MyStruct;
void setup(){
 Serial.begin(57600); 
}
char sendBuff[sizeof(MyStruct)];
void loop() {
    MyStruct.yaw = 87.96;
    MyStruct.pitch = -114.58;
    MyStruct.roll = 100.50;

    //Sending Side
        memcpy(sendBuff, &MyStruct, sizeof(MyStruct));
    S3();//serial 3
    LS();// local serial
}

void S3(){
   Serial3.print("<");
    for(int x =0;x < sizeof(sendBuff);x++){
    Serial3.print(sendBuff[x]);
    }
    Serial3.print(">");
    Serial3.println(""); 
}
void LS(){
    Serial.print("<");
    for(int x =0;x < sizeof(sendBuff);x++){
    Serial.print(sendBuff[x]);
    }
    Serial.print(">");
    Serial.println(""); 
}

Pi side ( rec for now)

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <wiringSerial.h>
#include <stdlib.h>

void serialRead();

struct MyStruct_t {
    float yaw;
    float pitch;
    float roll;
}MyStruct;

int fd;
int i, x, sDA, cChar;
char recbuff[100];

int main ()
{
  if ((fd = serialOpen ("/dev/ttyAMA0", 57600)) < 0)
  {
   fprintf (stderr, "Unable to open serial device: %s\n", strerror (errno)) ;
    return 1 ;
  }

 for (;;)
        {

         serialRead();
 }//for
}//main

void serialRead(){

    sDA = serialDataAvail(fd); // is Serial avail?
    if (sDA > 0 )
    {
      x=0;
      for (i=0;i<sDA;i++)  // for as long as i is less than sDA get char
      {
        cChar = serialGetchar(fd); // get the char
        if ( cChar == '<')      // is it the start char?
        printf("got <\n");
        {
     for(;;)
     {
       cChar = serialGetchar(fd); // get char
       if (cChar == '>'){   // is it the end char?
        printf(" Got >\n");
         recbuff[x] = '\0'; // null term the buffer
         break;  // exit loop
       }
       else
        {
        //otherwise current buffer pos (x) = curent incoming char
        recbuff[x] = cChar;
         x++;  // add 1 to x
       }
     }
    memcpy(&MyStruct, recbuff, sizeof(MyStruct));
    printf("Yaw :%lf\n", MyStruct.yaw);
    printf("Pitch: %lf\n", MyStruct.pitch);
    printf("Roll: %lf\n", MyStruct.roll);
     }
     serialFlush(fd);
     break;
   }
      }
}

much earlier copy of the PI code would trigger -.- but now it does not and i cant recall what i had changed ( was having probs populating the stuct so i went messing around lol)

  1. am i filling and sending the struct correctly on the Arduino side?
  2. what is falling on the Pi side to trigger the start?

example of Arduino output throuhg local.

<…ë¯Bö(åÂÉB>
<…ë¯Bö(åÂÉB>
<…ë¯Bö(åÂÉB>
<…ë¯Bö(åÂÉB>
<…ë¯Bö(åÂÉB>
<…ë¯Bö(åÂÉB>
<…ë¯Bö(åÂÉB>
<…ë¯Bö(åÂÉB>

i am guessing it's good yes? ( i know it's a guess but i do not think i could know till i try and extract it on pi side);
but it does have the start and stop parts so i would think it would trigger fine.); // start char
        MyStruct.FloatValue01 = 33.999; // value for stuct
        MyStruct.IntValue01 = -37000;  //" "
        MyStruct.lIntValue01= 2000000000;// " "
        MyStruct.CharValue01[0] = ChVal;// " "
        serialPuts(fd,(char *)&MyStruct); // send struct
        serialPutchar(fd, '!'); // end char
        return;
}


those on the pi side the the struct was suppose to be transmitted ( think it was but who knows at this point) so if the struct was sent like it was when i was using the Nrf24l01's befor it should have unpacked and populated it on the arduino side.

been looking at a god awful lot of examples on arduino and pi and c++ forums and i seen some memcpy stuff (also some struct packing, have not made to much sense of that yet)
but i have come up with this so far. tell me if i am heading in the right direction anyhow.
Arduino side (send only for now)

§DISCOURSE_HOISTED_CODE_1§


Pi side ( rec for now)

§DISCOURSE_HOISTED_CODE_2§


much earlier copy of the PI code would trigger -.- but now it does not and i cant recall what i had changed ( was having probs populating the stuct so i went messing around lol) 
1. am i filling and sending the struct correctly on the Arduino side?
2. what is falling on the Pi side to trigger the start?

example of Arduino output throuhg local.

§DISCOURSE_HOISTED_CODE_3§


i am guessing it's good yes? ( i know it's a guess but i do not think i could know till i try and extract it on pi side); 
but it does have the start and stop parts so i would think it would trigger fine.

the struct was filled with

But that doesn't match the definition that the Arduino was using, for the struct.

The whole reason for sending and receiving a struct is so that BINARY data can be sent. The print() method on the Arduino does NOT send binary data. The write() method does. The print() method converts the data to strings. NOT what you want.

cant believe i missed that long day lol.
ard sending

  Serial3.print('<');
    Serial3.write((byte *)&sendBuff,sizeof(sendBuff));
    Serial3.print('>');

pi recieveing ( chopped up the triggers but still not triggering)

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <wiringSerial.h>
#include <stdlib.h>

void serialRead();
void gStart();
void gEnd();

struct MyStruct_t {
    float yaw;
    float pitch;
    float roll;
}MyStruct;

int fd;
int i, x, sDA, cChar;
char recbuff[100];

int main ()
{
  if ((fd = serialOpen ("/dev/ttyAMA0", 57600)) < 0)
  {
   fprintf (stderr, "Unable to open serial device: %s\n", strerror (errno)) ;
    return 1 ;
  }

 for (;;)
        {

         serialRead();
 }//for
}//main

void serialRead(){//*
    cChar = serialGetchar(fd);
    sDA = serialDataAvail(fd); // is Serial avail?
    if (sDA > 0 ) {//*
      x=0;
        if ( cChar == '<'){//*      // is it the start char?
        printf("got <\n");
        gStart();
        }// if cchar ==<
      }// sDA >0
    }//serialRead
void gStart(){//*
        cChar = serialGetchar(fd);
         if (cChar != '>'){//*
         recbuff[x] = cChar;
         x++;}// if cChar!= >
        else{//*
        gEnd();
        }//else
}//gStart
void gEnd(){
        cChar = serialGetchar(fd);
  if(cChar =='>'){//*
    recbuff[x] = '\0';
    memcpy(&MyStruct, recbuff, sizeof(MyStruct));
    printf("Yaw :%lf\n", MyStruct.yaw);
    printf("Pitch: %lf\n", MyStruct.pitch);
    printf("Roll: %lf\n", MyStruct.roll);
    } // if cchar == >
     serialFlush(fd);
     return;
   }//gEnd

thinking im going to have to use something other than serialGetchar because that's just going to grab gibberish from a binary stream? (yes my brain is officially fried by this point)

changed some code on the linux(RPI) side.

cChar = read(fd, &recBuff,sizeof(recBuff));

now i should be reading the stream from the serial and be able to see the binary bits.
still can not seem to parse the start and stop tho.

LOL welp i give. been at this for over a week, ill just have to put the bot to the side. kinda knew mixing ard with pi was not going to be as easy as i had read about. well i guess it could be for usb -> ard IDE on the pi parsing a few lines off the serial but that's not what i wanted out of it. does do a nice job on linux and running cams so maybe ill find something for it. thanks for the help Paul and if you do run across something along the lines of C with struct trans over serial for the pi/ard link it here. ill check back in ever now and then.

I guess I don't see how you can expect to send a struct from one device to another, when the members of the struct are different sizes. Send the data as strings, and let the Arduino convert the string to it's idea of what a float is.

would using like uint8_t 16_ 32_t on both fix that? my limited understanding these are of an exact size on ardino and linux yes?
i would have never imagined sending structs across serial being so bad. would I2C be better? because at this point i am also ready to put 2 NRF24L01's 2" apart on my bot to send the data back and forth LOL!!!
waste of equipment but for $2.35 i am asking my self why not. i would how ever look at it each time and go why?!? and be some what shameful at such a cheap workaround. so yes i guess at this point i am pleeding.

  1. is it possible to send Structs to the Pi over serial or at least I2C.
  2. Exactly how would "you" send it and receive it (code please).
  3. i promise to study it and learn each element of it.
    i just cant keep doing this. my brain is frying from reading forum posts,wikis,how-to docs and frankly find this overall not a good experience.
    if any or all of what i am asking bothers you i understand thanks for the trying you have done.
    if that's the case i will just go back to the 2560 and stay there till i get better, adding the PI and cam was a leap i guess LOL!.