Using union to return a range of bits from a data frame: wrong approach?
You are using a union so you have to specify which part of the union you want. Your function should read:

 signed long DJ_ED()
{
  pack5 ED;
  ED.ints[0] = (DJ_buf[3] &gt;&gt; 5) &amp; 1;
  ED.ints[1] = (DJ_buf[3] &gt;&gt; 6) &amp; 1;
  ED.ints[2] = (DJ_buf[3] &gt;&gt; 7) &amp; 1;
  ED.ints[3] = (DJ_buf[2] &gt;&gt; 5) &amp; 1;
  ED.ints[4] = (DJ_buf[2] &gt;&gt; 6) &amp; 1;

  return ED.value;
}


It still looks wrong because you are only putting a single bit into those 5 bytes (because of the &amp; 1). And 5 x int will be a lot longer than one signed long.



The code below seems to match the data structure you posted an image of:

struct packedFields
{
  // byte 0
  unsigned int sx      : 5;
  unsigned int rtt_4_3 : 3;

  // byte 1
  unsigned int sy      : 5;
  unsigned int rtt_2_1 : 3;

  // byte 2
  unsigned int rtt_5   : 1;
  unsigned int cs      : 4;
  unsigned int ed_4_3  : 2;  
  unsigned int rtt_0   : 1;

  // byte 3
  unsigned int ltt_4_0  : 5;
  unsigned int ed       : 3;

  // byte 4
  unsigned int ltt_5    : 1;
  unsigned int rbr      : 1;
  unsigned int b_plus   : 1;
  unsigned int filler_2 : 1;
  unsigned int b_minus  : 1;
  unsigned int lbr      : 1;
  unsigned int filler_1 : 2;

  // byte 5
  unsigned int filler_4 : 2;
  unsigned int rbb      : 1;
  unsigned int lbg      : 1;
  unsigned int be       : 1;
  unsigned int rbg      : 1;
  unsigned int filler_3 : 1;
  unsigned int lbb      : 1;

};

union packedFieldsUnion
  {
  packedFields a;
  byte b [6];
  };

void doSomethingWithTheFields (packedFieldsUnion &amp; theFields);  // prototype
void doSomethingWithTheFields (packedFieldsUnion &amp; theFields)
  {
  theFields.a.rtt_4_3 = 3;
  theFields.a.ltt_4_0 = 2;
  }  // end of doSomethingWithTheFields

void setup ()
  {
  Serial.begin (115200);
  Serial.println ();
  Serial.print (F("packedFields sized = "));
  Serial.println (sizeof (packedFields));

  packedFieldsUnion foo;
  memset (&amp;foo, 0, sizeof foo);

  doSomethingWithTheFields (foo);

  Serial.println (F("-- packedFields bytes --"));
  for (int i = 0; i &lt; sizeof foo; i++)
    Serial.println ((int) foo.b [i], HEX);

  }  // end of setup

void loop ()
  {
  }  // end of loop


I have a bitwise struct, as Ignacio Vazquez-Abrams suggested. Testing indicates you put the low-order bits first. Then I made a union of this struct and 6 bytes. You can't fit the whole thing into a signed long anyway (a long is 4 bytes) so that part of your code was doomed to fail.

A small bit of test code proves that the bits are being accessed in the correct way. You still need to fiddle around with things like RTT which has individual bits scattered in different places.



If you look at the data format you posted there are 6 bytes, not 5. They are numbered 0, 1, 2, 3, 4, 5. A total of six of them.