Go Down

Topic: -ve long storage in EEPROM (Read 458 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);

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
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy