Bitwise operators and conversion of int to 2 bytes and vice versa

first user Hello guys!

So I hope someone can help .. My php background therefore introduces the word lowend, for example, char are bytes that are bits .. which are binary values ​​.. etc. It takes some time to get stuck;)

What I'm trying to do here sends some values ​​from the Ardunio board to openFrameWorks (both are C ++).

That this script is currently working (and works well for one sensor, which I can add) when asked that the data will be sent ..

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); 

This is apparently the most reliable way to get data through. So, now when it is sent via the serial port, bytes are added to the char string and converted back ..

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

So, to understand, I'm trying to get 4 data values ​​with sensors (which, suppose, will be 8 of these consecutive graphs?) And have int num_01 - num_04 ... at the end of everything.

I suggest that this (like most things) can be quite easy for someone who has experience in these concepts.

Any help would be greatly appreciated. Thanks

+6
c ++ bit-manipulation arduino openframeworks
source share
4 answers

Write a function for abstract data sending (I got rid of your temporary variables because they do not add a lot of 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)); ... 
+7
source share

Just send them one by one.

Note that the serial driver allows you to send one byte (8 bits) at a time. A value from 0 to 1023 inclusive (which is similar to what you get) fits in 10 bits. So 1 byte is not enough. 2 bytes i.e. 16 bits is enough (there is extra space, but if the transmission speed is not a problem, you do not need to worry about this wasted space).

So, the first two bytes can carry data for your first sensor. The next two bytes contain 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 I hope you can decide what you need to do on the receiving side.

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

This code will not do what you expect.

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

 11111111 << 3 == 11111000 11111111 << 8 == 00000000 

i.e. any unsigned char when shifting 8 bits should be equal to zero.

You need something more:

 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 can get the same result:

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

If the byte order is ok. It should work on Little Endian (x86 or x64), but not on Big Endian (PPC, Sparc, Alpha, etc.).

0
source share

To summarize the submit 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)); } 
0
source share

All Articles