views:

190

answers:

4

first time user, Hi guys!

So hopefully someone can help.. My background is php so entering the word of lowend stuff like, char is bytes, which are bits.. which is binary values.. etc is taking some time to get the hang of ;)

What im trying to do here is sent some values from an Ardunio board to openFrameWorks (both are c++).

What this script currently does (and works well for one sensor i might add) when asked for the data to be sent is..

int value_01 = analogRead(0);  // which outputs between 0-1024

 unsigned char val1;
 unsigned char val2;

//some Complicated bitshift operation           
    val1 = value_01 &0xFF;
    val2 = (value_01 >> 8) &0xFF;  

    //send both bytes
    Serial.print(val1, BYTE);
    Serial.print(val2, BYTE);

Apparently this is the most reliable way of getting the data across.. So now that it is send via serial port, the bytes are added to a char string and converted back by..

int num = ( (unsigned char)bytesReadString[1] << 8 | (unsigned char)bytesReadString[0] );

So to recap, im trying to get 4 sensors worth of data (which im assuming will be 8 of those serialprints?) and to have int num_01 - num_04... at the end of it all.

Im assuming this (as with most things) might be quite easy for someone with experience in these concepts..

Any help would be greatly appreciated. Thanks

+3  A: 

Write a function to abstract sending the data (I've gotten rid of your temporary variables because they don't add much value):

void send16(int value)
{
    //send both bytes
    Serial.print(value & 0xFF, BYTE);
    Serial.print((value >> 8) & 0xFF, BYTE);
}

Now you can easily send any data you want:

send16(analogRead(0));
send16(analogRead(1));
...
R Samuel Klatchko
Wow, that cleans thing up rather nicely.. Its working perfectly now, thanks guys!Compared to what i had before (when it wasnt working) im really not sure why it wasnt working (i think i might have been sending bad data, which was mucking me around).. If this is the result of using stackoverflow, ill be back!
aKiwi
@aKiwi: best way to thank the author of the answer that fits your need, is to mark the answer as accepted :)
AOI Karasu
ah was wondering what to do. thanks, was trying to vote him up (need some more reputation apparently ;)
aKiwi
+1  A: 

Just send them one after the other.

Note that the serial driver lets you send one byte (8 bits) at a time. A value between 0 and 1023 inclusive (which looks like what you're getting) fits in 10 bits. So 1 byte is not enough. 2 bytes, i.e. 16 bits, are enough (there is some extra space, but unless transfer speed is an issue, you don't need to worry about this wasted space).

So, the first two bytes can carry the data for your first sensor. The next two bytes carry the data for the second sensor, the next two bytes for the third sensor, and the last two bytes for the last sensor.

I suggest you use the function that R Samuel Klatchko suggested on the sending side, and hopefully you can work out what you need to do on the receiving side.

Artelius
Thanks alot for the information on the serial side of things, clears somethings up in my head. Thanks
aKiwi
A: 
   int num = ( (unsigned char)bytesReadString[1] << 8 | 
               (unsigned char)bytesReadString[0] );

That code will not do what you expect.

When you shift an 8-bit unsigned char, you lose the extra bits.

11111111 << 3 == 11111000

11111111 << 8 == 00000000

i.e. any unsigned char, when shifted 8 bits, must be zero.

You need something more like this:

typedef unsigned uint;
typedef unsigned char uchar;

uint num = (static_cast<uint>(static_cast<uchar>(bytesReadString[1])) << 8 ) |
           static_cast<uint>(static_cast<uchar>(bytesReadString[0]));

You might get the same result from:

typedef unsigned short ushort;
uint num = *reinterpret_cast<ushort *>(bytesReadString);

If the byte ordering is OK. Should work on Little Endian (x86 or x64), but not on Big Endian (PPC, Sparc, Alpha, etc.)

Michael J
A: 

To generalise the "Send" code a bit --

void SendBuff(const void *pBuff, size_t nBytes)
{
    const char *p = reinterpret_cast<const char *>(pBuff);
    for (size_t i=0; i<nBytes; i++)
        Serial.print(p[i], BYTE);
}

template <typename T>
void Send(const T &t)
{
    SendBuff(&t, sizeof(T));
}
Michael J