Pages: 1 [2] 3   Go Down
Author Topic: Ard <--> Pi serial data transfer(unsolved)  (Read 4574 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Full Member
***
Karma: 1
Posts: 131
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

cant believe i missed that long day lol.
ard sending
Code:
  Serial3.print('<');
    Serial3.write((byte *)&sendBuff,sizeof(sendBuff));
    Serial3.print('>');

pi recieveing ( chopped up the triggers but still not triggering)
Code:
#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)
Logged

0
Offline Offline
Full Member
***
Karma: 1
Posts: 131
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

changed some code on the linux(RPI) side.

Code:
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.
Logged

0
Offline Offline
Full Member
***
Karma: 1
Posts: 131
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 617
Posts: 49463
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

0
Offline Offline
Full Member
***
Karma: 1
Posts: 131
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Miramar Beach, Florida
Offline Offline
Faraday Member
**
Karma: 147
Posts: 6040
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 617
Posts: 49463
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

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

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

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

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

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

Quote
2. 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.

Logged

0
Offline Offline
Full Member
***
Karma: 1
Posts: 131
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Code:
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
Code:
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
Code:
#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
Logged

Miramar Beach, Florida
Offline Offline
Faraday Member
**
Karma: 147
Posts: 6040
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Code:
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.
« Last Edit: September 16, 2013, 05:46:13 am by SurferTim » Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 617
Posts: 49463
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
    MyStruct.yaw = 87.96;
    MyStruct.pitch = -114.58;
    MyStruct.roll = 100.50;
Yaw, pitch and roll are defined as ints.

Code:
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.

Code:
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.

Code:
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 '>'.
Logged

Miramar Beach, Florida
Offline Offline
Faraday Member
**
Karma: 147
Posts: 6040
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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.
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 617
Posts: 49463
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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.
Logged

0
Offline Offline
Full Member
***
Karma: 1
Posts: 131
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Code:

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.
Code:
#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-twist

Logged

0
Offline Offline
Full Member
***
Karma: 1
Posts: 131
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

new rpi code. getting odd result on printing the buff.
Code:
#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
Code:
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  smiley-cry
output from minicom
Code:
<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.
Logged

0
Offline Offline
Full Member
***
Karma: 1
Posts: 131
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

"""think""" the sscanf is ok but i dont seem to be grabbing the serial data ok.
Code:
#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");
}
Logged

Pages: 1 [2] 3   Go Up
Jump to: