EEPROM, How to use it?

Hi guys,

I have a value in my project which determines the overall calculation being performed. This value can be calibrated by a user.

At the moment, it must be calibrated every time the device is powered up.

This is not ideal, and I came across EEPROM and that I can use that as a non-volatile memory storage

  • at least for a a certain amount of cycles (100,000 I think it was)

Im aware its about using addresses but i really do no know where to read and write in my code or how to make use of it

I stumbled across a library someone made

and its useful to me because I am using floats, and this person has already put that capability in.

Any help with this matter would really be fantastic.

I stumbled across a library someone made

Extended EEPROM library for Arduino | Thijs.Elenbaas.net

and its useful to me because I am using floats, and this person has already put that capability in.

Any help with this matter would really be fantastic.

You've got a library that you say has all the feature you need. So, what else do you need?

Hand-holding happens in Gigs and Collaboration, usually for a fee.

Well i dont know how to use it, I mean i have tried and it seems like nothing has really happened.

I tried to write using something like

EEPROM.writeFloat(0,original)

(orginal being the my default number i used)

and tried to read using

output = EEPROM.readFloat(0);

then I went around and changed where ever my calculation had original, and changed it to output.

Im not sure i really observed anything.

EEPROM.write(address,value);

Variable = EEPROM.read(address);

Weedpharma

Save the value in the program, on restarting read in setup()

I tried to write using something like

EEPROM.writeFloat(0,original)

(orginal being the my default number i used)

and tried to read using

output = EEPROM.readFloat(0);

then I went around and changed where ever my calculation had original, and changed it to output.

Im not sure i really observed anything.

Handwaving gets you no points for style. Post your real code, and your serial output that proves that you have a problem.

Have you installed the library?

Have you tried to run the example included in the library? What was the result?

First of all, there is no “hand waving” going on as you put it. Secondly, im not using a serial monitor - im using an LCD display

#include <LiquidCrystal.h>
#include <EEPROMex.h>

/******************************************
 * 
 * 
 * 
 ******************************************/

LiquidCrystal lcd(8,9,4,5,6,7);    // Required LCD pins

/*****************************************
 * Definitions
 *****************************************/
float original =2.67857; // 2.67857lux per mV
float Variable =0.0;

//int address = 0;
int countMINUS = 0; // Counter used to increment in Cal Menu
int countPLUS = 0;  // Counter used to decrement in Cal Menu
int i=0;
int j=0;
int initial=0;      // A count to run initial loop
int calFlag=1;      // Flag used to exit loop
int firstFlag=1;    // Flag used to exit loop    
int selectFlag=1;   // Flag used to exit loop
int holdFlag=1;     // Flag used to exit  loop
int lcd_key = 0;    // use to read LCD buttons
int adc_key_in = 0; // used to read the voltage of the LCD buttons

#define btnRIGHT 0
#define btnUP 1
#define btnDOWN 2
#define btnLEFT 3
#define btnSELECT 4
#define btnNONE 5



/* ---------Button Information--------------
 
 Right: 0.00V ; 0 @ 10 bit
 
 UP: 0.71V ; 145 @ 10 bit
 
 DOWN: 1.61V ; 329 @ 10 bit
 
 LEFT: 2.47V ; 505 @ 10 bit
 
 SELECT: 3.62V ; 741 @ 10 bit
 
 -------------------------------------------*/


/*******************************************
 * Setup
 *******************************************/
void setup()
{
  Variable = EEPROM.readFloat(0);
  lcd.begin(16,2);        // Start
  lcd.setCursor(0,0);     //Top left
  lcd.print("Hi");
  lcd.setCursor(0,1);     // Botton left
  lcd.print("There");
  delay(3000);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("MENU: Press");  
  lcd.setCursor(0,1);
  lcd.print("SELECT to start");

}
/*****************************************************
 * Main loop
 ******************************************************/

//Set up such that only the select button can be pressed initially.
//Then the swtich case is used.

void loop()
{
  
  if(initial==0){
    while(firstFlag!=0)
    {
      lcd_key = read_LCD_buttons(); //
      if(adc_key_in<850 && adc_key_in > 650) firstFlag =0;
    }
    initial++;
  }
  firstFlag = 1;
  lcd_key=read_LCD_buttons(); // read the buttons
  button_switch_case(lcd_key);
}


/*****************************************************
 * Reading the buttons
 *****************************************************/

//When a button is pressed, There is drop from 5V to the specified voltage for that button.
//Sometimes the voltage may not equal the same voltage every time, and so a range used such that
//the button press always falls within that range.

int read_LCD_buttons()
{
  adc_key_in = analogRead(A0); // read value

  if(adc_key_in > 1000) return btnNONE;

  if(adc_key_in < 50) return btnRIGHT;

  if(adc_key_in < 250) return btnUP;

  if(adc_key_in < 450) return btnDOWN;

  if(adc_key_in < 650) return btnLEFT;

  if(adc_key_in < 850) return btnSELECT;

  return btnNONE; // If all else fails
} 




/********************************************************************************
 * btnRIGHT for call
 ********************************************************************************/
void casebtnRIGHT()
{
  while(holdFlag!=0){

    lcd_key=read_LCD_buttons();
    if(adc_key_in<850 && adc_key_in>650)
    {
      holdFlag=0;
    }
    lcd_key=read_LCD_buttons();
    if(adc_key_in <50 && adc_key_in>0){
      lcd.clear();
      float photoDiode_1 = analogRead(A1); 
      float photoDiode_2 = analogRead(A1); 
      float photoDiode_3 = analogRead(A1);
      float averagetoprint = ((photoDiode_1)+(photoDiode_2)+(photoDiode_3))/3;
      float voltage_1 = photoDiode_1 * ((5.0 / 1023.0)*1000);  
      float voltage_2 = photoDiode_2 * ((5.0 / 1023.0)*1000);
      float voltage_3 = photoDiode_3 * ((5.0 / 1023.0)*1000); 
      float averageVoltage = ((voltage_1)+(voltage_2)+(voltage_3))/3; 
      float lux = original * averageVoltage;
      lcd.print("SEL:BACK >:AGAIN");
      lcd.setCursor(0,1);   
      lcd.print(lux); 
      lcd.print( " Lux");
      delay(1000);
      lcd_key=read_LCD_buttons();
      if(adc_key_in<850 && adc_key_in>650)casebtnSELECT();
      if(adc_key_in<850 && adc_key_in>650) holdFlag=0;
    }
  }
  holdFlag=1; 
  casebtnSELECT();

}

/*******************************************************************************
 * btnLEFT for call
 *******************************************************************************/
void casebtnLEFT()
{

  while(selectFlag!=0)
  {
    lcd.clear();
    float photoDiode_1 = analogRead(A1);
    float photoDiode_2 = analogRead(A1);       
    float photoDiode_3 = analogRead(A1);        
    float averagetoprint = ((photoDiode_1)+(photoDiode_2)+(photoDiode_3))/3;      
    float voltage_1 = photoDiode_1 * ((5.0 / 1023.0)*1000);       
    float voltage_2 = photoDiode_2 * ((5.0 / 1023.0)*1000);        
    float voltage_3 = photoDiode_3 * ((5.0 / 1023.0)*1000);       
    float averageVoltage = ((voltage_1)+(voltage_2)+(voltage_3))/3;      
    float lux = original * averageVoltage;    
    lcd.print("Hold SEL: BACK"); 
    lcd.setCursor(0,1);
    lcd.print(lux);
    lcd.print( " Lux");
    delay(1000);
    lcd_key=read_LCD_buttons();
    if(adc_key_in<450 && adc_key_in >50) caseNOTHING();
    if(adc_key_in<850&&adc_key_in>650) selectFlag=0;
  }
  selectFlag=1;
}




/********************************************************************************
 * btnUP for call
 ********************************************************************************/
void casebtnUP()
{
  lcd_key=read_LCD_buttons();
  casebtnSELECT();

}



/********************************************************************************
 * btnDOWN for call
 ********************************************************************************/
void caseCAL()
{
  lcd.clear();
  lcd.print("Calibration");
  delay(3000);

  while(calFlag!=0)
  {
    lcd.clear();
    lcd.print("-");
    lcd.setCursor(6,0);
    lcd.print(Variable);
    lcd.setCursor(15,0);
    lcd.print("+");
    lcd.setCursor(3,1);
    float photoDiode_1 = analogRead(A1);
    float photoDiode_2 = analogRead(A1);
    float photoDiode_3 = analogRead(A1);
    float averagetoprint = ((photoDiode_1)+(photoDiode_2)+(photoDiode_3))/3;
    float voltage_1 = photoDiode_1 * ((5.0 / 1023.0)*1000);
    float voltage_2 = photoDiode_2 * ((5.0 / 1023.0)*1000);
    float voltage_3 = photoDiode_3 * ((5.0 / 1023.0)*1000);
    float averageVoltage = ((voltage_1)+(voltage_2)+(voltage_3))/3;
    float lux = original * averageVoltage;
    lcd.print(lux);
    lcd.print("  Lux");
    delay(1000);
    lcd_key=read_LCD_buttons();
    if(adc_key_in<50 && adc_key_in >=0)
    { 
      countMINUS=0;
      if(countPLUS<=50)original=(Variable + 0.1);
      countPLUS++;
      if(countPLUS>50 && countPLUS <=100) Variable = (Variable + 0.5);
      countPLUS++;
      if(countPLUS>100 && countPLUS <=200) Variable = (Variable + 1); 
      countPLUS++;
      if(countPLUS>200 && countPLUS <=300) Variable = (Variable + 5); 
      countPLUS++;
      if(countPLUS>300) Variable = (Variable + 10); 
      countPLUS++;
    }
    if(adc_key_in<650 && adc_key_in >450) 
    {
      countPLUS=0;
      if(countMINUS<=50)Variable =(Variable  - 0.1);
      countMINUS++;
      if(countMINUS>50 && countMINUS <=100) Variable  = (Variable  - 0.5);
      countMINUS++;
      if(countMINUS>100 && countMINUS <=200) Variable  = (Variable  - 1); 
      countMINUS++;
      if(countMINUS>200 && countMINUS <=300) Variable  = (Variable  - 5); 
      countMINUS++;
      if(countMINUS>300) Variable  = (Variable  - 10); 
      countMINUS++;
    }

    if(adc_key_in<850 && adc_key_in>650)
    {
      EEPROM.writeFloat(0,original);
      calFlag=0;
    }

    if(adc_key_in<250 && adc_key_in>50) 
    {
      original= 2.67857;
      lcd.clear();
      lcd.print("Default Restored");
      delay(3000);

    }

  }
  calFlag=1;
  countPLUS=0;
  countMINUS=0;
  casebtnSELECT();


}



/********************************************************************************
 * btnSELECT for call
 ********************************************************************************/
void casebtnSELECT()
{
  lcd.clear();
  lcd.print("<: Continuous");
  lcd.setCursor(0,1);
  lcd.print(">: Hold, V: CAL");
  lcd_key=read_LCD_buttons();
  if(adc_key_in<450 && adc_key_in>250) caseCAL;
  if(adc_key_in<50&& adc_key_in>=0) casebtnRIGHT();
  if(adc_key_in<650  && adc_key_in>450) casebtnLEFT();
}
/********************************************************************************
 * Call for nothing
 ********************************************************************************/
void caseNOTHING()
{

}


/*********************************************************************************
 * Switch case for buttons
 **********************************************************************************/

void button_switch_case(int lcd_key)
{
  switch (lcd_key)    //Depending on button pressed, perform action
  {

    /*******************************************************************************
     * Right Button
     *******************************************************************************/
  case btnRIGHT:    
    {
      casebtnRIGHT();   
      break;  
    }


    /*******************************************************************************
     * Left Button
     *******************************************************************************/
  case btnLEFT: 
    {
      casebtnLEFT();
      break;
    }   


    /*******************************************************************************
     * UP Button
     *******************************************************************************/
  case btnUP:
    {
      casebtnUP();
      break;
    }

    /*******************************************************************************
     * Down Button
     *******************************************************************************/
  case btnDOWN:
    {
      caseCAL();
      break;
    }

    /*******************************************************************************
     * Select Button
     *******************************************************************************/
  case btnSELECT:
    {
      casebtnSELECT();
      break;
    }
    /*******************************************************************************
     * No Button Pressed
     *******************************************************************************/
  case btnNONE:
    {
      caseNOTHING();
      break;
    }
  }
}

problem is that im expecting things to be saved even powered down. But theyre not
[/code]

Library is installed - i added all the files - there are no error codes

Im trying to write in the case for Cal section

You can go in different directions:

When it is just a float you can use the AVR GCC function eeprom_write_float and eeprom_read_float. You can also use the Nick Gammon I2C_anything.

For myself, I prefer a struct with data with a checksum, and the AVR GCC functions. I have a struct with values in PROGMEM as default, and the settings in EEPROM. When the struct is small, I write the complete struct to EEPROM using eeprom_update_block(), even if only a single bit was changed. At start I read the struct from EEPROM and check the checksum, if that is wrong, I use memcpy_P to load the values from PROGMEM.

MrDropsy:
problem is that im expecting things to be saved even powered down. But theyre not

That’s because of this line:

  if(adc_key_in<450 && adc_key_in>250) caseCAL;

http://www.gammon.com.au/forum/?id=12153#trap9

Ok that mistake makes sense, however that doesnt seem to be why nothing is saving. Or maybe something is saving and im just not recognising it.

Ok my calibration is clearly storing now however for some reason, my buttons to increment and decrement dont work as well. Before using any of the eeprom they were much more responsive.

Interestingly, the decrement button works better.

EDIT: never mind, that was a simple mistake - i think its actually working now

Thanks everyone