Go Down

Topic: -ve long storage in EEPROM (Read 433 times) previous topic - next topic

g0mgx

Jun 07, 2012, 05:00 pm Last Edit: Jun 07, 2012, 10:03 pm by Coding Badly Reason: 1
Guys

Been lurking a while, but new to Arduino in general.

I'm developing a Ham Radion WSPR beacon using Arduino and I have everything working just fine, except....

I need to have a Calibration Factor to get my Arduino interfaced DDS exactly on frequency and I am trying to store and read back that value from EEPROM. It works fine for +ve numbers but not -ve. I've seen the tutorials on EEPROM writing but nothing I have seen has helped with -ve numbers.

I have tried including a bit test for the value read back, but this doesn't work either:

if (CalFactor >> 31 ==1) { CalFactor = CalFactor - (pow(2,32)-1); }

Can any kind soul here help with this connundrum of mine?

Here's the bit of code I can't get to function with -ve numbers, the value read back for a write of -2 is 288,741,374:

Code: [Select]
#include <EEPROM.h>
#include <math.h>

long CalFactor;
byte temp;
int j;
int i;

void setup()
{

  Serial.begin(9600);        // connect to the serial port

  CalFactor = -2;

  //Writes CalFactor to address 50 + 3 bytes of EEprom
  for (j=0; j<4; j++)  
  { // Step through 4 bytes to make 32 bit word
     for (i=0; i<8; i++)
     { // Step through 8 bit to make 1 byte
       bitWrite(temp,i,(bitRead(CalFactor,j*i+i))); // Assemble bits to make 1 byte
     }
     EEPROM.write(50+j,temp); // Write byte to EEprom
  }
 
  Serial.println("Written to EERPROM ");
  Serial.println(CalFactor);
  Serial.println(CalFactor,BIN);

  CalFactor = 0; // set all bits to zero
 
  // Read back from EEPROM
  for(j=0; j<4; j++)
  {  // Step through 4 bytes to make 32 bit word
     temp = EEPROM.read(50+j); // Get bytes 50 through 53
     for (i=0; i<8; i++)
     { // Set through 8 bit to make 1 byte
        bitWrite(CalFactor,i*j+i,(bitRead(temp,i))); // Assemble bits to make 32 bit word
     }
  }
 
  if (CalFactor >> 31 == 1)
  {
     Serial.println("1st Bit is 1");
//      CalFactor = CalFactor - (pow(2,32)-1);
  }
 
  Serial.println("Read from EERPROM");
  Serial.println(CalFactor);
  Serial.println(CalFactor,BIN);
}

void loop()
{  
}



Moderator edit: [code] [/code] tags added.

majenko

#1
Jun 07, 2012, 05:07 pm Last Edit: Jun 07, 2012, 05:10 pm by majenko Reason: 1
Personally I'd set myself up a union to do this:

Code: [Select]


struct CalFact {
  union {
    long value;
    struct {
      unsigned char b1;
      unsigned char b2;
      unsigned char b3;
      unsigned char b4;
    }__attribute__((packed));
  }__attribute__((packed));
}__attribute__((packed));

struct CalFact CalFactor;


You can then access the calibration factor's value with:

Code: [Select]

CalFactor.value


as in:

Code: [Select]

CalFactor.value=-4983231;


And you can access the individual bytes for reading and writing to eeprom with:

Code: [Select]

CalFactor.b1
through
CalFactor.b4


Write the whole lot to eeprom:

Code: [Select]

EEPROM.write(50,CalFactor.b1);
EEPROM.write(51,CalFactor.b2);
EEPROM.write(52,CalFactor.b3);
EEPROM.write(53,CalFactor.b4);


Read it all back:

Code: [Select]

CalFactor.b1 = EEPROM.read(50);
CalFactor.b2 = EEPROM.read(51);
CalFactor.b3 = EEPROM.read(52);
CalFactor.b4 = EEPROM.read(53);
Get 10% off all 4D Systems TFT screens this month: use discount code MAJENKO10

pylon

It can be very ease:

Writing:
Code: [Select]
for (byte n = 3; n != 255; n--) {
EEPROM.write(address+n, value & 0xFF);
value = value >> 8;
}


Reading:
Code: [Select]
long ival = 0;
for (byte n = 0; n < 4; n++) {
ival = (ival <<8) + EEPROM.read(address + n);
}

g0mgx

Thank you so much!

I have actually spotted why my code didnt work (typical after 3 days staring at it!) but the solutions offered are so much simpler. It's the complexity of mine that had tripped me up.

Thanks again.

Mark.

Go Up