1

I receive byte data from a RS-232 device with Serial.read();. Now I need to slice this down in bit-pieces:

  • value1: 15bits
  • value2: 7bits
  • value3: 9bits
  • value4: 12bits
  • and so on

Data from the stream (switch them around for better understanding):

  • Byte 1: 00101100 => 00110100 (least significant byte first)
  • Byte 2: 10011011 => 11011001
  • Byte 3: 00110011 => 11001100
  • Byte 4: 11101000 => 00010111
  • Byte 5: 01001100 => 00110010
  • Byte 6: 01100111 => 11100110

Now the least significant is first.

  • value1: 00110100.1101100[1] => 6956
    Need to cut of the last bit of the second byte
  • value2: 1.110011[00] => 103
    Add the last bit of the second byte and cut off the last two bits of the third byte
  • value3: 00.0001011[1] => 416
    Add the last two bits of the third byte and cut off the last bit of the fourth byte
  • value4: 1.00110010.111[00110] => 3737
    Add the last bit of the fourth byte and cut off the last 5 bits of the fifth byte

Now the question: How do I realize this from programming side. I'm lost.

4
  • 1
    If the records are byte aligned you could use a struct with bit-fields and let the compiler do the work. tutorialspoint.com/cprogramming/c_bit_fields.htm – Mikael Patel May 22 '16 at 10:11
  • Another alternative is to define a BitStream class that operates on a Stream (Serial). Typical member function would be uint16_t read(uint8_t bits). The class would have to buffer any remaining bits for the next read, etc. drdobbs.com/bitstream-parsing-in-c/184402014 – Mikael Patel May 22 '16 at 10:13
  • 1
    I'm voting to close this question as off-topic because it's a year old question with no answers. – user31481 Oct 24 '17 at 14:51
  • @LookAlterno But this one has an answer. It is/was edited into the question. I have now put that as an answer. – gre_gor Oct 25 '17 at 13:19
3

Note: This is an answer that OP originally edited into his question.


I gather the data into an array of bytes data[125].

Then I gather the relevant bytes per value and stack them together:

long var = (data[4]<<8) + (data[3]);

I shift them so the relevant bytes start first

var=var>>3;

Afterwards I mask them with the RIGHT mask

var=var & 0xFF;

For the example in my question:

long var = (data[1]<<8) + (data[0]); // I need two bytes  
var=var>>1; // shift them to the right one bit  
var=var & 0x7FFF; // mask it with "0111 1111 1111 1111"
1
  • 1
    Good work gre_gor! – sa_leinad Oct 25 '17 at 14:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.