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

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!.

I've used serial with a Mega and a Linux PC. I convert all binary data to text using CSV with cr/lf as the terminator on the transmit end, and reconvert to the correct data types on the receive end. Slower but effective.

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?

Yes and yes.

would I2C be better?

No. The problem you are having is that the two sides do not agree on how big the packet is. Using a different transport mechanism is not going to change that.

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!!!

See above for why that won't work, either.

waste of equipment but for $2.35 i am asking my self why not.

See above.

i would how ever look at it each time and go why?!?

No. You'd remove them when they didn't work. For why, see above.

  1. is it possible to send Structs to the Pi over serial

Yes, but given the issues you are having, sending strings seems a much better option.

  1. Exactly how would "you" send it and receive it (code please).

You had the right idea above. Use types that are the same size on each end.

great and now i have some progress

getting this on the pi side now (should be got < Getting data! Got > now buff null and memcpy) and then print the struct members to the cons

got <
 Getting data!
 got <
 Getting data!
 got <
 Getting data!
 got <
 Getting data!
 got <
 Getting data!
 got <
 Getting data!
 got <
 Getting data!
 got <
 Getting data!
 got <

still not completing tho. here is the 2 codes as they stand.
Arduino

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

    memcpy(sendBuff, &MyStruct, sizeof(MyStruct));
    sBuff();
    localSerial();
}

void sBuff(){
   Serial3.write("<");
   Serial3.write((uint8_t *)&sendBuff,sizeof(sendBuff));
   Serial3.write(">");
}
void localSerial(){
    Serial.print("<");
    Serial.write((uint8_t *)&sendBuff,sizeof(sendBuff));
    Serial.print(">");
    Serial.println(""); 
}

RPI

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

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

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

int fd;
int i, x, sDA, cChar;
int recBuff[13];

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

 for (;;)
        {

         serialRead();
 }
}

void serialRead(){
    cChar = serialGetchar(fd);
    sDA = serialDataAvail(fd);
        if (sDA > 0 ) {
        x=0;
        if (cChar == '<'){
        printf("got <\n ");
        gStart();
        }
      }
    }
void gStart(){
        cChar = serialGetchar(fd);
         if (cChar != '>'){
         printf("Getting data!\n ");
         recBuff[x] = cChar;
         x++;}
        else{
        gEnd();
        }
}
void gEnd(){
        cChar = serialGetchar(fd);
  if(cChar =='>'){
        printf("Got > now buff null and memcpy\n");
    recBuff[x] = '\0';
    memcpy(&MyStruct, recBuff, sizeof(MyStruct));
    printf("Yaw :%d\n", MyStruct.yaw);
    printf("Pitch: %d\n", MyStruct.pitch);
    printf("Roll: %d\n", MyStruct.roll);
    }
     serialFlush(fd);
     return;
   }

so i guess since it is getting the < but not getting to > prob somtthing to do with the get char function yes?
BTW the RPI code uses the serial lib from WiringPi.com if that helps any

This is how I would do it on the Arduino end. I would use sscanf on the RPI side. I added a 1 second delay so I could see it work.

char sendBuf[48];
char tBuf[16];

double yaw = 87.96;
double pitch = -114.58;
double roll = 100.50;

void setup(){
 Serial.begin(57600); 
 Serial3.begin(57600); 
}

void loop() {
    dtostrf(yaw,2,2,sendBuf);
    
    dtostrf(pitch,2,2,tBuf);
    strcat(sendBuf,",");
    strcat(sendBuf,tBuf);
    
    dtostrf(roll,2,2,tBuf);
    strcat(sendBuf,",");
    strcat(sendBuf,tBuf);

    sBuff();
    localSerial();

    delay(1000);
}

void sBuff(){
   Serial3.println(sendBuf);
}
void localSerial(){
    Serial.println(sendBuf);
}

edit: I moved yaw, pitch, and roll to global so you can load them up in another function.

    MyStruct.yaw = 87.96;
    MyStruct.pitch = -114.58;
    MyStruct.roll = 100.50;

Yaw, pitch and roll are defined as ints.

void serialRead(){
    cChar = serialGetchar(fd);
    sDA = serialDataAvail(fd);
        if (sDA > 0 ) {
        x=0;
        if (cChar == '<'){
        printf("got <\n ");
        gStart();
        }
      }
    }

Read a character. Then, see if there is anything to read. Generally, it works better if the horse is in front of the cart.

void gStart(){
        cChar = serialGetchar(fd);
         if (cChar != '>'){
         printf("Getting data!\n ");
         recBuff[x] = cChar;
         x++;}
        else{
        gEnd();
        }
}

Keep reading data until the '>' arrives. When it does, call gEnd(). Sounds reasonable. Almost.

void gEnd(){
        cChar = serialGetchar(fd);
  if(cChar =='>'){
        printf("Got > now buff null and memcpy\n");

Oops. You've already read the '>'. There should now be nothing left to read. If there is, it certainly won't be another '>'.

If there is, it certainly won't be another '>'.

That is an incorrect presumption. When sending bytes, any of them could be a '<' or a '>' (0x03C or 0x03E) embedded in the raw data bytes.

That is an incorrect presumption. When sending bytes, any of them could be a '<' or a '>' (0x03C or 0x03E) embedded in the raw data bytes.

Hmmm. So it is.

Surf: so funny i ended up mostly doing the same thing very very early this morning here is what it ended up looking like this

struct MyStruct_t {
    float yaw;
    float pitch;
    float roll;
    }MyStruct;
void setup(){
 Serial.begin(57600); 
 Serial3.begin(57600); 
}
char sendBuff[23], tmpbuff[6];
void loop() {
    fillStruct();
    makeString();
    sendStr();
}

void sendStr(){
   for (int i = 0; i < sizeof(sendBuff); i++){
   Serial.print(sendBuff[i]);
   Serial3.print(sendBuff[i]);
   }  
   Serial.println("");
   Serial3.println("");   
 }
void fillStruct(){
    MyStruct.yaw = 111.456;
    MyStruct.pitch = -222.679;
    MyStruct.roll = 333.012; 
}
void makeString(){
  strcpy(sendBuff, "<");
  dtostrf(MyStruct.yaw, 4,2, tmpbuff);
  strcat(sendBuff, tmpbuff);
  strcat(sendBuff, ",");
  dtostrf(MyStruct.pitch, 4,2, tmpbuff);
  strcat(sendBuff, tmpbuff);
  strcat(sendBuff, ",");
  dtostrf(MyStruct.roll, 4,2, tmpbuff);
  strcat(sendBuff, tmpbuff);
  strcat(sendBuff, ">");
  sendBuff[23] = '\0';
}

ill look at the sscanf right now.

Pauls: thanks for pointing those out. been driving me soooo nuts.
i will work in it now the way i have it just for the heck of it and then try and figure out the sscanf Surf mentions. here is what i looks like as of very very early this morning now that i got some sleep i prob can bang
some code out from both your help.

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

void serialRead();
void parseBuff();

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

int fd, i, b, C, x, z, sDA, gChar;

char recBuff[23], tmpBuff[6];

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

 for (;;)
        {

         serialRead();
 }
}

void serialRead(){
        gChar = serialGetchar(fd);
        sDA = serialDataAvail(fd);
        x = 0;
        if (sDA > 0 ) {
        if (x < sizeof(recBuff)){
         recBuff[x] = gChar;
        x++;
        }
//       printf("%s\n",(char *)&recBuff);
         parseBuff();
         }
}
void parseBuff(){
     b = 0;
     C = recBuff[b];
     if (b < sizeof(recBuff)){
     if (C == '>'){
      recBuff[b] = '\0';
//      printf("%s\n", (char *)&recBuff);
        b++;
        }
    }
        for (z = 0; z < sizeof(recBuff); z++){
        printf("%c",recBuff[z]);
        }
        printf("\n");
    serialFlush(fd);
     return;
}

Surf/Paul: good call on the hex, thinking that's why i saw a lot of hex parsing out there when looking up how to get this done.

well time to get cracking. still would know how to send the dang struct maybe eth shield and tcp?.

Pauls: defined as ints as the uint32_t's i used or the MS.y = 87.96 <- that = the real data that comes off the IMU.

wonder what is going to hold out the longest. the code or my sanity? ]:smiley:

new rpi code. getting odd result on printing the buff.

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

void serialRead();
void prntBuff();

int fd, z, x, sDA, cChar, recBuff[23];

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

 for (;;)
        {
         x = 0;
         cChar = serialGetchar(fd);
         if(cChar == '<') serialRead();
         serialRead();
 }
}

void serialRead(){
        sDA = serialDataAvail(fd);
         while (cChar != '>' ){
           if (sDA > 0){
             printf("Getting data!\n ");
             cChar = serialGetchar(fd);
             recBuff[x] = cChar;
             x++;
             }
          else if(sDA == 0){
             printf("Got no Data\n");
             }
            break;
            }

        if(cChar == '>'){
        printf("End of data");
        recBuff[x] = '\0';
        serialFlush(fd);
        prntBuff();

    }
 }
void prntBuff(){
        for (z = 0; z < sizeof(recBuff); z++){
            printf("%c",recBuff[z]);
            }
        printf("\n");
}

result

 End of data>
Getting data!
 Getting data!
 End of data>>
Getting data!
 Getting data!
 Getting data!
 Getting data!
 Getting data!
 Getting data!PuTTY
 Getting data!
 Getting data!
 Getting data!
 Getting data!
 End of data>
Getting data!
 Getting data!
 Getting data!
 End of data>>
Getting data!
 Getting data!
 Getting data!
 Getting data!
 Getting data!
 Getting data!
 Getting data!
 Getting data!
 Getting data!
 Getting data!
 Getting data!
 Getting data!
 End of data>>
Getting data!

where in the world is Putty coming from and why >>'s? and where is my precious data =(
output from minicom

<111.46,-222.68,333.01>
<111.46,-222.68,333.01>
<111.46,-222.68,333.01>
<111.46,-222.68,333.01>
<111.46,-222.68,333.01>
<111.46,-222.68,333.01>
<111.46,-222.68,333.01>
<111.46,-222.68,333.01>
<111.46,-222.68,333.01>
<111.46,-222.68,333.01>
<111.46,-222.68,333.01>
<111.46,-222.68,333.01>
<111.46,-222.68,333.01>
<111.46,-222.68,333.01>
<111.46,-222.68,333.01>

so dev/ttyAMA0 is geting the right format coming in.

"""think""" the sscanf is ok but i dont seem to be grabbing the serial data ok.

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

void serialRead();
void prntBuff();

float yaw, pitch, roll;
int fd, z, x, sDA, recBuff[23];
char cChar;
int main ()
{
  if ((fd = serialOpen ("/dev/ttyAMA0", 57600)) < 0)
  {
   fprintf (stderr, "Unable to open serial device: %s\n", strerror $
    return 1 ;
  }

 for (;;)
        {
         x = 0;
         cChar = serialGetchar(fd);
         if(cChar == '<') serialRead();
         serialRead();
 }
}

void serialRead(){
        sDA = serialDataAvail(fd);
         while (cChar != '>' ){
           if (sDA > 0){
             printf("Getting data!\n ");
             cChar = serialGetchar(fd);
             recBuff[x] = cChar;
             x++;
             }
          else if(sDA == 0){
             printf("Got no Data\n");
             }
            break;
            }

        if(cChar == '>'){
        printf("End of data\n");
        recBuff[x] = '\0';
        sscanf((char *)recBuff,"%f %f %f", &yaw, &pitch, &roll );
        printf("Yaw:%lf  :Pitch:%lf :Roll:%lf\n", yaw, pitch, roll);
//      serialFlush(fd);
//      prntBuff();

    }
 }
void prntBuff(){
        for (z = 0; z < sizeof(recBuff); z++){
            printf("%c",recBuff[z]);
            }
        printf("\n");
}
        sDA = serialDataAvail(fd);
         while (cChar != '>' ){
           if (sDA > 0){
             printf("Getting data!\n ");
             cChar = serialGetchar(fd);
             recBuff[x] = cChar;
             x++;
             }
          else if(sDA == 0){
             printf("Got no Data\n");
             }
            break;
            }

So, suppose 3 bytes arrive before this function gets called. It just keeps reading and reading - most likely getting garbage, until finally the > trickles in. No! No! No!

You know how many bytes are available to read. Do NOT read more than than without updating the count of bytes available to be read.

i understand the words you used i however do not see where exactly you want the count. should it be like

sDA = serialDataAvail(fd);
         while (cChar != '>' ){
           if (x <= sizeof(recBuff)-1){ // read only 22 then pass to end and get the \0 null for 23?
             printf("Getting data!\n ");
             cChar = serialGetchar(fd);
             recBuff[x] = cChar;
             x++;
             }
          else if(sDA == 0){
             printf("Got no Data\n");
             }
            break;
            }

i still have my doubts on this being the best way to send data to the Pi for processing and back and in time for the bot not to drive off a cliff or into traffic or a wall.
but i guess ill try and see what the speed of data is this way.

FYI here is a sample of the REAL struct. it occurred to me you might be thinking to small

struct StructBuff_t {
  float imuRoll;  //MinIMU-9 data 
  float imuPitch;//MinIMU-9 data 
  float imuYaw; //MinIMU-9 data
  long flAt;  // GPS latitude
  long flOn; // GPS Longitude
  unsigned long Speed; //GPS speed
  unsigned long Date;  //GPS date
  unsigned long Course; //GPS curent course
  unsigned long Time;   //GPS Time
  unsigned long Fix_age; //GPS age of signal fix  
  unsigned int FC_AP;     //Front Center Ultrasonic Avrage Ping
  unsigned int FL_AP;     //Front Left Ultrasonic Avrage Ping
  unsigned int FR_AP;     //Front Rgith Ultrasonic Avrage Ping
  unsigned int RC_AP;     //Rear Center Ultrasonic Avrage Ping
  int FCir;       //Front Center Infrared sen
  int FLir;       //Front Left Infrared sen
  int FRir;       //Front Right Infrared sen
  int RCir;       //Rear  Center Infrared sen
  int BSTempature;       //Barometric sen tempature
  int BSPressure;      //Barometric sen pressure
  int Heading;         //LM303 mag heading
}
StructBuff;

so that is the struct as it stands there most certainly will be more data being processed back and forth i assure you.
BUT i do want to see this buffed and send over serial and parse it just to see how it's done. so lead on! :smiley:

ok so one has even a little clue on sending structs that size to a Linux ARM system?

(missedskipped a lot of the discussion)
To reduce size you could create 2 or more structs with an identifier as extra field to divide the 21 fields in e.g. 5 groups.

Each struct has another update frequency (if you split them well)

ultimate you send the fields per field (+ identifier) only when they are changed.

just an idea...