Wednesday, May 8, 2013

Arduino Convert Long to Char Array and Back

I wanted to log data from an Arduino to an SD Card in the most space and time efficient manner possible.   To me this meant storing a four byte long in four bytes.  Bit shifting has always made my head hurt so I turned to Google.   I found the below (in a  couple places) but it did not seem to work:


unsigned long int longInt = 1234567890;
    unsigned char byteArray[4];
              
    // convert from an unsigned long int to a 4-byte array
    byteArray[0] = (int)((longInt >> 24) & 0xFF) ;
    byteArray[1] = (int)((longInt >> 16) & 0xFF) ;
    byteArray[2] = (int)((longInt >> 8) & 0XFF);
    byteArray[3] = (int)((longInt & 0XFF));
 
    unsigned long int anotherLongInt;
 


    anotherLongInt = ( (byteArray[0] << 24) 
                   + (byteArray[1] << 16) 
                   + (byteArray[2] << 8) 
                   + (byteArray[3] ) );


At least until AWOL on the Arduino forum suggested the below:

anotherLongInt = ( ((unsigned long)byteArray[0] << 24) 
                   + ((unsigned long)byteArray[1] << 16) 
                   + ((unsigned long)byteArray[2] << 8) 
                   + ((unsigned long)byteArray[3] ) )


Eureka!  I can now store two longs in eight bytes with a couple of distinct advantages:
  1. Result is fixed size which means I can seek into my file looking for specific entries
  2. Size on disk would generally be less than storing a string representation (unless you are only doing tiny numbers) and particularly if you wanted to do one of fixed size.
  3. Speedy string operations is not what you bought the Arduino for in the first place!  Saving 1,000 long to char arrays took a bit more than a second while the string version (even without padding to fixed size) took more than 10 seconds.
 I have no idea why AWOL's suggestion worked but I am happy to move on.

1 comment:

  1. Thanks for the information! I used the base of your code, but I used a long array instead of a byte array. I'm working Arduino...

    long longArray[4];
    long timeEEPROM;

    for(int i=0; i<4; i++) {
    longArray[i] = EEPROM.read(memPos++);
    }

    timeEEPROM = ( (longArray[0] << 24)
    + (longArray[1] << 16)
    + (longArray[2] << 8)
    + (longArray[3] ) );

    ReplyDelete