Pages: [1]   Go Down
Author Topic: Assign each Byte of a long or int a value  (Read 474 times)
0 Members and 1 Guest are viewing this topic.
Marburg/GER
Offline Offline
Newbie
*
Karma: 0
Posts: 19
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Montreal
Online Online
Edison Member
*
Karma: 23
Posts: 2485
Per aspera ad astra.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

0
Offline Offline
Sr. Member
****
Karma: 0
Posts: 360
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

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

Marburg/GER
Offline Offline
Newbie
*
Karma: 0
Posts: 19
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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!

Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 168
Posts: 12428
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Rob Tillaart

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

Marburg/GER
Offline Offline
Newbie
*
Karma: 0
Posts: 19
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


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.
Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 30
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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]

Logged

Marburg/GER
Offline Offline
Newbie
*
Karma: 0
Posts: 19
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 smiley-wink)
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 smiley-wink

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

Pages: [1]   Go Up
Jump to: