문제

I need to send data from a microcontroller through a serial port and would like to minimize the data sent, because the data is a 10bit reading from an ADC. So I thought, I would use an union. This is what I got:

union fortybit
{
 struct
 {
  unsigned int a : 10;
  unsigned int b : 10;
  unsigned int c : 10;
  unsigned int d : 10;
 } tenbits;
 unsigned char bytes[5];
};

Now I'm sending the data like this:

fortybit fb;
for (int i = 0; i < 640; i++)
{
 fb.tenbits.a = 512;
 fb.tenbits.b = 512;
 fb.tenbits.c = 512;
 fb.tenbits.d = 512;
 Serial.write(fb.bytes, 5);
}

Which results in some strange readings, which are periodic and some of the values are right, but most of them are completely wrong.

What could I be doing wrong? What is the right way to do this?

도움이 되었습니까?

해결책

You should never use bitfields in any external representation. This becomes external since you send the raw bytes where the bitfields are stored, over a serial line.

There's no way to know that the computer in the receiving end of hte serial line interprets your struct the same way. It might have a different byte ordering, a different native integer size into which the bits are packed which might mean different padding, or whatever.

It's simply not portable.

You should do it in a more controlled fashion, perhaps by manually computing each byte of the desired external representation. This is called serialization, and it's a good thing.

다른 팁

Its not like its that hard to do the packing transform yourself. Something like this should do the trick:

int A[4] = { 0x1,0x1,0x1,0x1 };
int B[5];

long long x=0;
for(int i=0; i<4; i++) {
    x |= A[i] << (10*i);
}
for(int i=0; i<5; i++) {
    B[i] = x & 0xFF;
    x >>= 8;
}

printf("%02x %02x %02x %02x %02x\n",B[0],B[1],B[2],B[3],B[4]);
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top