Go Down

Topic: Assign each Byte of a long or int a value (Read 739 times) previous topic - next topic

Phyllomedusa

Hallo,
I have just ordered my Arduino and started to work on programming a bit. Well... I am quite new to Microprocessors and my c-experince is some years back. So sorry if I got something wrong (just tell me).

My problem is:
I get a datastream from a Sensor (Cloud Droplet Probe) as a 156byte hex stream via serial.read. The datatypes are mixed up (uint, ulong, char, (fancy 48 bit unsigned Extra long which wont be accessible I think). The data will be stored in an byte array of that size to manipulate it.
Well, the problem is that the byte orders are a bit crossed like it seems. ulong has byteorder 2,3,0,1 for example. I would like to assigne these values from the fields of the array to their appropriate belonging in the variabales.
For example:
Bin2Count is given by byte 38 to byte 41 in the stream and so I would like to assign
unsigned long Bin2Count[2]=data[38];
unsigned long Bin2Count[3]=data[39];
unsigned long Bin2Count[0]=data[40];
unsigned long Bin2Count[1]=data[41];

http://www.dropletmeasurement.com/manuals/Hardware%20Manuals/DOC-0029%20CDP%20Manual.pdf  Page 33 shows the Byteorder.


Thanks in advance for your help.

I think appending to a string wouldn't work, because an unsigned long is an unsigned long and no string. Or maybe is it possible to create binary strings and append them? But as far as I remember conversions between characters and int weren't that nice.

Magician

You can declare union, look at this as example:
http://arduino.cc/forum/index.php/topic,66206.0/topicseen.html

Aeturnalus

You could also use some bitshifting and OR a few bytes into a long:

Code: [Select]

uint32_t bigNumber = (data[40] << 0) | (data[41] << 8) | (data[38] << 16) | (data[39] << 24); // uint32_t is unsigned 32-bit long

Phyllomedusa

Ah Ok,
thank you (both). So I have two Ideas.
The Union construct looks nice and quite clear in structure (although it's new to me).

Thanks a lot!


robtillaart

Quote
Well, the problem is that the byte orders are a bit crossed like it seems. ulong has byteorder 2,3,0,1 for example


you could define functions to do the above bitshifting for every place where an ulong (U32) or uint (U16) is located, and then reading can be done in a loop as according to the spec the bincounts are at regular intervals.

Some snippets:
Code: [Select]

uint32_t getU32( int pos)
{
 uint32_t val = data[pos+2] | (data[pos+3] << 8) | (data[pos] << 16) | (data[pos+1] << 24);
 return val;
}

uint16_t getU16( int pos)
{
 uint16_t val = data[pos] | (data[pos+1] << 8); // might need to be swapped
 return val;
}

........ somewhere in your code ......

unsigned long binCount[29]; // array to hold all the binCounts.
for (int i=1; i<29; i++)
{
 binCount[i] = getU32(30 + 4*i);  // when i=1, it starts at pos = 34, when i=2, pos = 38 etc.
 Serial.println(binCount[i]);
}
// process the binCountsArray

uint16_t averageTransit = getU16(25);

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Phyllomedusa



you could define functions to do the above bitshifting for every place where an ulong (U32) or uint (U16) is located, and then reading can be done in a loop as according to the spec the bincounts are at regular intervals.

Some snippets:
....



Thanks robtillaart.... it confused me at first sight a bit, but it's clear now. That's been the way I had in mind (otherwise the code would be a bit crowded). I want to use a for loop to acess all bigger packages like BinCount and PBP data.

bombasticbob

is there any reason that the 156-byte array can't be a structure?  That is...

struct something
{
    unsigned char upfront[40];  // the first 40 bytes (re-define as needed)
    unsigned long ulTheData;  // the data I want (byte-flip as needed)
    .... (etc.)
};

Then you reference the data directly, read directly into the structure or declare a pointer to it and assign the address of your data buffer like  "something *pS = (something *)buffer;" and reference members like "pS->ulTheData".  No more problems extracting things from the data using byte offsets.

And, if you need to byte-flip an unsigned long from 'high endian' to 'low endian' you can use this:

unsigned long byteflip(unsigned long TheValue)
{
  union
  {
    unsigned char c[4];
    unsigned long l;
  } a, b;

  b.l = TheValue;
  a.c[0] = b.c[3];
  a.c[1] = b.c[2];
  a.c[2] = b.c[1];
  a.c[3] = b.c[0];

  return a.l;
}

last I checked the above function compiles VERY TIGHT.  Should be part of the library, maybe as 'ntohl' in the Ethernet library [that's where I made use of it, FYI]


Phyllomedusa

A structure would be nice, but first I would like to keep it straight forward to get a running application to use for our probe (fog will be comming soon ;))
When that is running I take another board and go on to make the code smooth.

..want to have a basic running version first not to loose any time ;)

so, thanks for your suggestion. Could be something to try out later.

Go Up