Writing potentiometer value to EEPROM over 255 [SOLVED]

Hi everyone,

I have read many discussions on this topic, but I have a more particular problem. I need to save a value to EEPROM that I’ve read from the potentiometer, from 0 to 1023.

If the value is over 255, it automatically saves it as 255, due to being 8 bytes. What is the solution for this?

Here is the code :

#include <EEPROM.h>

int buttonPin = 8;
int buttonState;
void setup()
{
  Serial.begin(9600);
}

void loop()
{
  buttonState = digitalRead(buttonPin);
  int sensorValue = analogRead(A0);
  Serial.println(sensorValue);
  delay(100);
  
  if(buttonState == HIGH)
  {
    Serial.println("Button pressed");
    EEPROM.write(10, sensorValue);
  }
  else if (buttonState == LOW)
    Serial.print("");
    
    Serial.print("EEPROM VALUE : ");
    Serial.println(EEPROM.read(10));
}

Thanks and all the best.

You need to write and read the value as 2 bytes See: http://arduino.cc/en/Reference/LowByte and:http://arduino.cc/en/Reference/HighByte

This is a reply from a forum member

int test = 0xABCD;   // 16 bits
byte hi, lo;  // 8 bits each

hi = HighByte(test);  //in case you're wondering this should be 0xAB
lo = LowByte(test);    // and this should be 0xCD.

So basically, he wrote a hex value in the int variable? Do I have to do that? Because I don't know the exact value of the potentiometer, I know the value the moment when I press the button, so how do I convert that value to hi and lo bytes?

The hex is just to make it easier to see what the example does - it's not relevant to your situation.

You simply have to use highbyte and lowbyte to extract two 8 bit values from your sensor reading. Then you can write them individually to EEPROM. When it comes time to read the data back, you can use the word function to combine them again or use shift plus and operations.

This should give you an idea of how to do it.

void setup() 
{
  Serial.begin(115200);
  int myInt = analogRead(A0);
  byte myHigh = highByte(myInt);
  byte myLow = lowByte(myInt);
  Serial.println(myLow);
  Serial.println(myHigh);
}

void loop() 
{
}

It’s been a while since I messed around with EEPROM, but I used a union. The following fragment shows what I did.

union {
   byte myArray[2];
   unsigned int value;
} myUnion;


void setup() {

  Serial.begin(115200);
  myUnion.value = 300;
  Serial.print("value = ");
  Serial.println(myUnion.value);
  Serial.print("myArray[0] = ");
  Serial.print(myUnion.myArray[0], HEX);
  Serial.print("     myArray[1] = ");
  Serial.println(myUnion.myArray[1], HEX);

}

void loop() {

}

Using this approach I don’t have to worry about the Endian problem regardless of the host architecture.

Here is the code I have. I added the word function, which from the documentation should be written correctly, but it only outputs 0, nothing happens.

#include <EEPROM.h>

int buttonPin = 8;
int buttonState;

int sensorValue;
byte myHigh = highByte(sensorValue);
byte myLow = lowByte(sensorValue);

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  sensorValue = analogRead(A0); 
  buttonState = digitalRead(buttonPin); 
  Serial.println(sensorValue);
  delay(500);
  
  if(buttonState == HIGH)
  {
    Serial.println("Button pressed");
    EEPROM.write(10, word(myHigh, myLow));
  }
  else if (buttonState == LOW)
    Serial.print("");
  
    Serial.print("EEPROM VALUE : ");
    Serial.println(EEPROM.read(10));
}

@econjack

I tried your example but how will I implement this for my EEPROM problem? This reads temporary value and doesn't store it anywhere.

Have you looked at the EEPROM_WriteAnything template?

fsimon: Here is the code I have. I added the word function, which from the documentation should be written correctly, but it only outputs 0, nothing happens.

....
    EEPROM.write(10, word(myHigh, myLow));
 ....

EEPROM.write() writes a single byte to a single location. You could use

    EEPROM.write(10,myHigh);
    EEPROM.write(11, myLow);

to write to successive locations then read back the 2 bytes and combine them using word()

@fsimon: If you can't figure it out from what I wrote, you need to stop trying to solve this problem, pick up a good beginning programming book, and read it until you understand what I wrote in my answer.

fsimon,

//save value in two bytes
EEPROM.write(10, lowByte(sensorValue));
EEPROM.write(11, highByte(sensorValue));
//retrieve saved value
sensorValue = word(EEPROM.read(11), EEPROM.read(10));

p

Okay, so I added three buttons in the code and I would like to explain once again so that there are absolutely no misunderstandings.

In the code bellow, I have three buttons, attached on pins 8, 9, and 10.

There are 3 int variables, the sensor values. I tried to convert the values using high and low bytes but I failed.

Then, as you can see, when I press the first button, I need to save the value of the potentiometer in EEPROM under adresses 10 and 11, and later read it using the sensorValue1 variable.

The same principle applies for the rest of the buttons and variables.

At the end, when outputting, the sensor values are all zeros.

#include <EEPROM.h>

int buttonPin1 = 8;
int buttonPin2 = 9;
int buttonPin3 = 10;

int buttonState1;
int buttonState2;
int buttonState3;

int sensorValue1;
byte myHigh1 = highByte(sensorValue1);
byte myLow1 = lowByte(sensorValue1);

int sensorValue2;
byte myHigh2 = highByte(sensorValue2);
byte myLow2 = lowByte(sensorValue2);

int sensorValue3;
byte myHigh3 = highByte(sensorValue3);
byte myLow3 = lowByte(sensorValue3);

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  sensorValue1 = analogRead(A0);
  sensorValue2 = analogRead(A0);
  sensorValue3 = analogRead(A0);
  
  buttonState1 = digitalRead(buttonPin1);
  buttonState2 = digitalRead(buttonPin2); 
  buttonState3 = digitalRead(buttonPin3);
  
  Serial.print("Sensor 1 : ");  
  Serial.println(sensorValue1);
  
  Serial.print("Sensor 2 : ");  
  Serial.println(sensorValue2);
  
  Serial.print("Sensor 3 : ");  
  Serial.println(sensorValue3);
  
  delay(500);
  
  if(buttonState1 == HIGH)
  {
    Serial.println("Button pressed");
    EEPROM.write(10, myHigh1);
    EEPROM.write(11, myLow1);
  }
  else if (buttonState1 == LOW)
    Serial.print("");
    
  if(buttonState2 == HIGH)
  {
    Serial.println("Button pressed");
    EEPROM.write(12, myHigh2);
    EEPROM.write(13, myLow2);
  }
  else if (buttonState2 == LOW)
    Serial.print("");
    
  if(buttonState3 == HIGH)
  {
    Serial.println("Button pressed");
    EEPROM.write(14, myHigh3);
    EEPROM.write(15, myLow3);
  }
  else if (buttonState3 == LOW)
    Serial.print("");
    
  sensorValue1 = word(EEPROM.read(11), EEPROM.read(10));
  sensorValue2 = word(EEPROM.read(13), EEPROM.read(12));
  sensorValue3 = word(EEPROM.read(15), EEPROM.read(14));
  
  Serial.print("Sensor Value 1 : ");
  Serial.println(sensorValue1);
  
  Serial.print("Sensor Value 2 : ");
  Serial.println(sensorValue2);
  
  Serial.print("Sensor Value 3 : ");
  Serial.println(sensorValue3);
  
  delay(1000);
}

@econjack

  • I have a fair understanding in programming, mostly C++, and I know what your code does, I need to study it further yes, if this example doesn’t work I’ll surely dive more into it. Thanks for the help.

@AWOL

  • Yes, I have, although I don’t know how to access only the variables I need with this line :
if (digitalRead(13) == HIGH)
      eeprom_write_block((const void*)&settings, (void*)0, sizeof(settings));

Because as you see, mostly I need to manipulate several variables with one or several buttons. How can I only write one variable instead of the whole settings struct?

How can I only write one variable instead of the whole settings struct?

If the variable is already a member of a struct that is already in EEPROM, it might be worthwhile looking at the offsetof macro.

Alternatively, if your EEPROM write already does a readback and only writes EEPROM locations that have changed, then you needn't worry about writing only individual structure members, unless timing is critical.

int sensorValue1;
byte myHigh1 = highByte(sensorValue1);
byte myLow1 = lowByte(sensorValue1);

int sensorValue2;
byte myHigh2 = highByte(sensorValue2);
byte myLow2 = lowByte(sensorValue2);

int sensorValue3;
byte myHigh3 = highByte(sensorValue3);
byte myLow3 = lowByte(sensorValue3);

Since sensorValueN is 0, myHighN and myLowN are also going to be 0.

You need to split the values in sensorValueN into high and low bytes AFTER assigning a value to sensorValueN.

I have a fair understanding in programming, mostly C++, and I know what your code does,

You could have fooled me after you clack handed attempts at writing code. Try this function:-

void write_int_to_EEPROM(int point, int Value){
point = point *2;
EEPROM.write(point, Value & 0xff);
EEPROM.write(point+1, Value >> 8);
}

@PaulS

  • I added the high and low bytes in the loop function, and now it saves values like Sensor Value 1 : -28159, Sensor Value 2 : -28671 etc while the sensor value really is 500.

@Grumpy_Mike

  • I will try it out and post the results.

@PaulS - I added the high and low bytes in the loop function, and now it saves values like Sensor Value 1 : -28159, Sensor Value 2 : -28671 etc while the sensor value really is 500.

So, you changed the code, and didn't post it.

I suspect that line 578 is the culprit.

Sorry, here’s the code.

#include <EEPROM.h>

int buttonPin1 = 8;
int buttonPin2 = 9;
int buttonPin3 = 10;

int buttonState1;
int buttonState2;
int buttonState3;

int sensorValue1;
int sensorValue2;
int sensorValue3;

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  sensorValue1 = analogRead(A0);
  byte myHigh1 = highByte(sensorValue1);
  byte myLow1 = lowByte(sensorValue1);

  sensorValue2 = analogRead(A0);
  byte myHigh2 = highByte(sensorValue2);
  byte myLow2 = lowByte(sensorValue2);
  
  sensorValue3 = analogRead(A0);
  byte myHigh3 = highByte(sensorValue3);
  byte myLow3 = lowByte(sensorValue3);
  
  buttonState1 = digitalRead(buttonPin1);
  buttonState2 = digitalRead(buttonPin2); 
  buttonState3 = digitalRead(buttonPin3);
  
  Serial.print("Sensor 1 : ");  
  Serial.println(sensorValue1);
  
  Serial.print("Sensor 2 : ");  
  Serial.println(sensorValue2);
  
  Serial.print("Sensor 3 : ");  
  Serial.println(sensorValue3);
  
  delay(500);
  
  if(buttonState1 == HIGH)
  {
    Serial.println("Button pressed");
    EEPROM.write(10, myHigh1);
    EEPROM.write(11, myLow1);
  }
  else if (buttonState1 == LOW)
    Serial.print("");
    
  if(buttonState2 == HIGH)
  {
    Serial.println("Button pressed");
    EEPROM.write(12, myHigh2);
    EEPROM.write(13, myLow2);
  }
  else if (buttonState2 == LOW)
    Serial.print("");
    
  if(buttonState3 == HIGH)
  {
    Serial.println("Button pressed");
    EEPROM.write(14, myHigh3);
    EEPROM.write(15, myLow3);
  }
  else if (buttonState3 == LOW)
    Serial.print("");
    
  sensorValue1 = word(EEPROM.read(11), EEPROM.read(10));
  sensorValue2 = word(EEPROM.read(13), EEPROM.read(12));
  sensorValue3 = word(EEPROM.read(15), EEPROM.read(14));
  
  Serial.print("Sensor Value 1 : ");
  Serial.println(sensorValue1);
  
  Serial.print("Sensor Value 2 : ");
  Serial.println(sensorValue2);
  
  Serial.print("Sensor Value 3 : ");
  Serial.println(sensorValue3);
  
  delay(1000);
}
  sensorValue1 = word(EEPROM.read(11), EEPROM.read(10));

You wrote the high byte into address 10, and the low byte into 11. Don't you think it would be better to reassemble them in the correct order?