EEPROM Update help

Hello and welcome to my Youtube channel...... uhh sorry :sweat_smile:. So i am working on a Project which purpose is to Turn on the Leds(there are 4) when the Room is darker using the Photoresistor sensor. If the room is not so Dark then turn on only 1 and if it's more then turn on more Led's. Also i am new with the coding and arduino so i want to Challenge myself so i decided to Store the Photoresistor value in EEPROM. Basically to Update the Value of the photoresistor and not to write since i don't want to waste the Life cycle.

I want to learn how to do it.

I want to you to check/review the code and give me some correction.

NOTE: the Setup test is to play with the Serial monitor :sweat_smile:

THE CODE:

#include <EEPROM.h>
const int ldrsen = A0;
int Led = 13;
int value = 0;
int LedPin2 = 12;
int LedPin3 = 11;
int LedPin4 = 10;
int address = 0;
//
void setup() {
  delay(2000);
  Serial.begin(9600);
  pinMode(LedPin2, OUTPUT);
  pinMode(LedPin3, OUTPUT);
  pinMode(LedPin4, OUTPUT);
  pinMode(Led, OUTPUT); 
  pinMode(ldrsen, INPUT);
  
  // Starting the TEST
  
  Serial.println("======Starting the Test======");
  Serial.println("You should see the Led blinking every 2 sec");
  digitalWrite(Led, HIGH);
  delay(200);
  digitalWrite(Led, LOW);
  delay(200);
  digitalWrite(LedPin2, HIGH);
  delay(200);
  digitalWrite(LedPin2, LOW);
  delay(200);
  digitalWrite(LedPin3, HIGH);
  delay(200);
  digitalWrite(LedPin3, LOW);
  delay(200);
  digitalWrite(LedPin4, HIGH);
  delay(200);
  digitalWrite(LedPin4, LOW);
  delay(200);
  Serial.println("Test 1 is completed");
  Serial.println("Now testing the Photoresistor, Make sure it is connected to the Pin A0");
  delay(2000);
  Serial.println("Starting the test now!");   
   
   rerun:
  value = analogRead(ldrsen) /4;
  
  if(value >1){
    Serial.print("The Photoresistor is connected and here are some value: ");
    delay(200);
    Serial.println(value); 
    delay(200);
    Serial.println(value); 
    delay(200); 
    Serial.println(value);    
  }
    else{
      value = analogRead(ldrsen)/4 ;
        if(value<0)
          Serial.println("Hmm the Photoresistor is not connected");
          Serial.println("Retrying in 5s");
          delay(5000);
          goto rerun;
        }
          Serial.println("======END======");
}


 //*************************LOOP*******************


 
void loop() {
  value = analogRead(ldrsen)/4;
  delay(100);
  EEPROM.update(address, value);
    if(value < 50){
    digitalWrite(Led, HIGH);
  }
  else
  {
    digitalWrite(Led, LOW);
  }
  //Led2
  if(value < 70){
    digitalWrite(LedPin2, HIGH);
  }
  else
  {
    digitalWrite(LedPin2, LOW);
  }
  if(value < 150){
    digitalWrite(LedPin3, HIGH);
  }
  else
  {
    digitalWrite(LedPin3, LOW);
  }
  if(value < 200){
    digitalWrite(LedPin4, HIGH);
  }
  else
  {
    digitalWrite(LedPin4, LOW);
  }
}

Get rid of the goto for a start

If the value variable changes, which it will, the the EEPROM will be written to. Does that satisfy your stated objective ?

Tell me how value can be less than 0.

Use EEPROM.put(), not EEPROM.update().

update() only writes 1 byte and your 'value' is an int which takes 2 bytes (although it will always be 0-255 in your code).

put() can write any sized variable and uses update() under the hood to reduce cycles.

Your EEPROM cell / cells will ahve a longer life if you don't write every cycle of loop(). Although EEPROM.update() is a step in the right direction, it will not help if the reading continuously changes.

I suggest that you add a bit of a guard and only save to EEPROM if the value changes by e.g. more than 10%.

You can also add a variable called e.g. level (values 0, 1, 2, 3) that indicates the active level, set it when you switch leds on/off and store afterwards in EEPROM.

All three will display the same value so there is no point in showing it three times. You have to use analogRead() again if you want to see if the value has changed.

That's a Good idea can you make a Example code for me?

Hmmm i will make those correction thx a lot!

:sweat_smile::sweat_smile::sweat_smile: My bad i will correct it to "2"

I've used the second approach as it was a little easier to implement.

Let's first get rid of the use of goto and the label; there is hardly ever a need for it and certainly not in your scenario.

  while (value < 1)
  {
    value = analogRead(ldrsen) / 4;

    if (value > 1)
    {
      Serial.print("The Photoresistor is connected and here are some value: ");
      delay(200);
      Serial.println(value);
      delay(200);
      Serial.println(value);
      delay(200);
      Serial.println(value);
      Serial.println("======END======");
    }
    else
    {
      Serial.println("Hmm the Photoresistor is not connected");
      Serial.println("Retrying in 5s");
    }
  }

In loop(), you can declare a new variable; I called it lightLevel that will indicate with values 1 .. 4

void loop()
{
  byte lightLevel;
  
  value = analogRead(ldrsen) / 4;
  delay(100);
  if (value < 50)
  {
    digitalWrite(Led, HIGH);
    lightLevel = 1;
  }
  else
  {
    digitalWrite(Led, LOW);
  }
  //Led2
  if (value < 70)
  {
    digitalWrite(LedPin2, HIGH);
    lightLevel = 2;
  }
  else
  {
    digitalWrite(LedPin2, LOW);
  }
  if (value < 150)
  {
    digitalWrite(LedPin3, HIGH);
    lightLevel = 3;
  }
  else
  {
    digitalWrite(LedPin3, LOW);
  }
  if (value < 200)
  {
    digitalWrite(LedPin4, HIGH);
    lightLevel = 4;
  }
  else
  {
    digitalWrite(LedPin4, LOW);
  }

  EEPROM.update(address, lightLevel);
}

And next you can make it more intelligent. Each led is associated with a light level so we will combine them; you can use a struct or a class. I'm more a C than a C++ programmer so will use a struct.

struct LEVELINDICATOR
{
  byte limit;
  const byte ledPin;
};

Next, every time that you start numbering variables (pins in your case), you should think arrays. So we will use an array of LEVELINDICATOR.

LEVELINDICATOR indicators[] =
{
  { 50,  13},
  { 70,  12},
  { 150, 11},
  { 200, 10},
};

If you ever want to add an extra indicator, you can simply add it in above array

Now you have an array of limits and the associated led pins. You can use a macro to calculate how many elements there are in the array

// number of elements in an array of any type (e.g. int, float, struct, ...}
#define NUMELEMENTS(x) (sizeof(x) / sizeof(x[0]))

When using this as demonstrated later, the compiler will do the calculation for you instead of you having to update your code in several places.

The advantage of arrays is that you can iterate through them which makes your code shorter. Instead of e.g. 4 statements, you can use a single statement and repeat it in a for-loop. The below shows how to set the pinMode to OUTPUT in setup(). There are additional print statements so you can follow in serial monitor what is happening; you can remove them when you think that you don't need them anymore.

  Serial.print("There are ");
  Serial.print(NUMELEMENTS(indicators));
  Serial.println(" light levels");

  // loop through the indicators array and set the led pins to output
  for (byte cnt = 0; cnt < NUMELEMENTS(indicators); cnt++)
  {
    pinMode(indicators[cnt].ledPin, OUTPUT);
    Serial.print("Pin ");
    Serial.print(indicators[cnt].ledPin);
    Serial.println(" set to output");
  }

You can use the same approach for your for your test in setup().

Next in loop(), you can also iterate through the indicators array after you have done the analogue reading.

void loop()
{
  byte lightLevel = 0;

  value = analogRead(ldrsen) / 4;
  delay(100);

  // loop through the indicators array and action measurement
  for (byte cnt = 0; cnt < NUMELEMENTS(indicators); cnt++)
  {
    // check if a measured value is below the limit
    if (value < indicators[cnt].limit)
    {
      // led on
      digitalWrite(indicators[cnt].ledPin, HIGH);
      // set lightLevel
      lightLevel = cnt + 1;
      Serial.print("Light level = ");
      Serial.println(lightLevel);
    }
    else
    {
      // led on
      digitalWrite(indicators[cnt].ledPin, LOW);
    }
  }

  EEPROM.update(address, lightLevel);
}

The full code

// number of elements in an array of any type (e.g. int, float, struct, ...}
#define NUMELEMENTS(x) (sizeof(x) / sizeof(x[0]))

#include <EEPROM.h>
const int ldrsen = A0;
int value = 0;
int address = 0;

struct LEVELINDICATOR
{
  byte limit;
  const byte ledPin;
};

LEVELINDICATOR indicators[] =
{
  { 50,  13},
  { 70,  12},
  { 150, 11},
  { 200, 10},
};


//
void setup()
{
  delay(2000);
  Serial.begin(9600);

  Serial.print("There are ");
  Serial.print(NUMELEMENTS(indicators));
  Serial.println(" light levels");

  // loop through the indicators array and set the led pins to output
  for (byte cnt = 0; cnt < NUMELEMENTS(indicators); cnt++)
  {
    pinMode(indicators[cnt].ledPin, OUTPUT);
    Serial.print("Pin ");
    Serial.print(indicators[cnt].ledPin);
    Serial.println(" set to output");
  }

  // set the sensor pin to input
  pinMode(ldrsen, INPUT);

  // Starting the TEST
  Serial.println(" == == == Starting the Test == == == ");
  Serial.println("You should see the Led blinking every 2 sec");

  // loop through the indicators array and set the led pins to output
  for (byte cnt = 0; cnt < NUMELEMENTS(indicators); cnt++)
  {
    digitalWrite(indicators[cnt].ledPin, HIGH);
    delay(200);
    digitalWrite(indicators[cnt].ledPin, LOW);
    delay(200);
  }

  Serial.println("Test 1 is completed");
  Serial.println("Now testing the Photoresistor, Make sure it is connected to the Pin A0");
  delay(2000);
  Serial.println("Starting the test now!");

  value = 0;
  while (value < 1)
  {
    value = analogRead(ldrsen) / 4;

    if (value > 1)
    {
      Serial.print("The Photoresistor is connected and here are some value: ");
      delay(200);
      Serial.println(value);
      delay(200);
      Serial.println(value);
      delay(200);
      Serial.println(value);
      Serial.println(" == == == END == == == ");
    }
    else
    {
      Serial.println("Hmm the Photoresistor is not connected");
      Serial.println("Retrying in 5s");
    }
  }
}

//*************************LOOP*******************

void loop()
{
  byte lightLevel = 0;

  value = analogRead(ldrsen) / 4;
  delay(100);

  // loop through the indicators array and action measurement
  for (byte cnt = 0; cnt < NUMELEMENTS(indicators); cnt++)
  {
    // check if a measured value is below the limit
    if (value < indicators[cnt].limit)
    {
      // led on
      digitalWrite(indicators[cnt].ledPin, HIGH);
      // set lightLevel
      lightLevel = cnt + 1;
      Serial.print("Light level = ");
      Serial.println(lightLevel);
    }
    else
    {
      digitalWrite(indicators[cnt].ledPin, LOW);
    }
  }

  //EEPROM.update(address, lightLevel);
}

How far you want to go is up to you. If the use of struct and array is too complicated, you don't have to use it. But as can be seen, your code becomes significantly smaller and adding extra indicators only requires one change.

First of Thank you and sorry for late response(answering after more than 10 days).

there are some issue that i am facing.

Issue nr: 1

According to my Knowledge the code you Post say that the when the Photoresistor value is High(or better said the room is Brighter) the Level should be 4 and when darker then 1. But here is something tricky when i try the code.

Here is the Serial Monitor Output:

19:53:05.697 -> Light level = 4
19:53:05.793 -> Light level = 4
19:53:05.887 -> Light level = 4
19:53:05.983 -> Light level = 4
19:53:06.079 -> Light level = 4
19:53:06.175 -> Light level = 4
19:53:06.319 -> Light level = 4
19:53:06.416 -> Light level = 3
19:53:06.416 -> Light level = 4
19:53:06.511 -> Light level = 2
19:53:06.511 -> Light level = 3
19:53:06.511 -> Light level = 4
19:53:06.607 -> Light level = 2
19:53:06.607 -> Light level = 3
19:53:06.655 -> Light level = 4
19:53:06.703 -> Light level = 1
19:53:06.703 -> Light level = 2
19:53:06.751 -> Light level = 3
19:53:06.751 -> Light level = 4
19:53:06.799 -> Light level = 1
19:53:06.799 -> Light level = 2
19:53:06.847 -> Light level = 3
19:53:06.847 -> Light level = 4
19:53:06.895 -> Light level = 1
19:53:06.895 -> Light level = 2
19:53:06.943 -> Light level = 3
19:53:06.943 -> Light level = 4
19:53:07.036 -> Light level = 1
19:53:07.036 -> Light level = 2
19:53:07.036 -> Light level = 3
19:53:07.036 -> Light level = 4
19:53:07.132 -> Light level = 1
19:53:07.132 -> Light level = 2
19:53:07.180 -> Light level = 3
19:53:07.180 -> Light level = 4
19:53:07.228 -> Light level = 1
19:53:07.228 -> Light level = 2
19:53:07.276 -> Light level = 3
19:53:07.276 -> Light level = 4
19:53:07.322 -> Light level = 1
19:53:07.322 -> Light level = 2
19:53:07.369 -> Light level = 3
19:53:07.369 -> Light level = 4
19:53:07.416 -> Light level = 1
19:53:07.416 -> Light level = 2
19:53:07.463 -> Light level = 3
19:53:07.463 -> Light level = 4
19:53:07.560 -> Light level = 1
19:53:07.560 -> Light level = 2
19:53:07.560 -> Light level = 3
19:53:07.560 -> Light level = 4
19:53:07.655 -> Light level = 1
19:53:07.655 -> Light level = 2
19:53:07.655 -> Light level = 3
19:53:07.655 -> Light level = 4
19:53:07.750 -> Light level = 1
19:53:07.750 -> Light level = 2
19:53:07.798 -> Light level = 3
19:53:07.798 -> Light level = 4
19:53:07.846 -> Light level = 1
19:53:07.846 -> Light level = 2
19:53:07.895 -> Light level = 3
19:53:07.895 -> Light level = 4
19:53:07.943 -> Light level = 1
19:53:07.943 -> Light level = 2
19:53:07.992 -> Light level = 3
19:53:07.992 -> Light level = 4
19:53:08.038 -> Light level = 1
19:53:08.038 -> Light level = 2
19:53:08.086 -> Light level = 3
19:53:08.086 -> Light level = 4
19:53:08.134 -> Light level = 1
19:53:08.134 -> Light level = 2
19:53:08.183 -> Light level = 3
19:53:08.183 -> Light level = 4
19:53:08.278 -> Light level = 1
19:53:08.278 -> Light level = 2
19:53:08.278 -> Light level = 3
19:53:08.278 -> Light level = 4
19:53:08.374 -> Light level = 1
19:53:08.374 -> Light level = 2
19:53:08.374 -> Light level = 3
19:53:08.374 -> Light level = 4
19:53:08.469 -> Light level = 1
19:53:08.469 -> Light level = 2
19:53:08.518 -> Light level = 3
19:53:08.518 -> Light level = 4
19:53:08.565 -> Light level = 1
19:53:08.565 -> Light level = 2
19:53:08.612 -> Light level = 3
19:53:08.612 -> Light level = 4
19:53:08.660 -> Light level = 1
19:53:08.660 -> Light level = 2
19:53:08.708 -> Light level = 3
19:53:08.708 -> Light level = 4
19:53:08.754 -> Light level = 1
19:53:08.754 -> Light level = 2
19:53:08.801 -> Light level = 3
19:53:08.801 -> Light level = 4
19:53:08.895 -> Light level = 1
19:53:08.895 -> Light level = 2
19:53:08.895 -> Light level = 3
19:53:08.895 -> Light level = 4
19:53:08.989 -> Light level = 1
19:53:08.989 -> Light level = 2
19:53:09.035 -> Light level = 3
19:53:09.035 -> Light level = 4
19:53:09.082 -> Light level = 1
19:53:09.082 -> Light level = 2
19:53:09.129 -> Light level = 3
19:53:09.129 -> Light level = 4
19:53:09.176 -> Light level = 1
19:53:09.176 -> Light level = 2
19:53:09.223 -> Light level = 3
19:53:09.223 -> Light level = 4
19:53:09.317 -> Light level = 1
19:53:09.317 -> Light level = 2
19:53:09.317 -> Light level = 3
19:53:09.317 -> Light level = 4
19:53:09.410 -> Light level = 1
19:53:09.410 -> Light level = 2
19:53:09.410 -> Light level = 3
19:53:09.410 -> Light level = 4
19:53:09.503 -> Light level = 1
19:53:09.503 -> Light level = 2
19:53:09.550 -> Light level = 3
19:53:09.550 -> Light level = 4
19:53:09.598 -> Light level = 1
19:53:09.598 -> Light level = 2
19:53:09.646 -> Light level = 3
19:53:09.646 -> Light level = 4
19:53:09.694 -> Light level = 1
19:53:09.694 -> Light level = 2
19:53:09.741 -> Light level = 3
19:53:09.741 -> Light level = 4
19:53:09.788 -> Light level = 1
19:53:09.788 -> Light level = 2
19:53:09.836 -> Light level = 3
19:53:09.836 -> Light level = 4
19:53:09.932 -> Light level = 1
19:53:09.932 -> Light level = 2
19:53:09.932 -> Light level = 3
19:53:09.932 -> Light level = 4
19:53:10.027 -> Light level = 1
19:53:10.027 -> Light level = 2
19:53:10.027 -> Light level = 3
19:53:10.027 -> Light level = 4
19:53:10.122 -> Light level = 1
19:53:10.122 -> Light level = 2
19:53:10.169 -> Light level = 3
19:53:10.169 -> Light level = 4

The First 4 in Output is when the Room was Lighter and when i try to dark the Photoresistor with an Towel(Like covering the Photoresistor with a towel) , I am getting a weird 1,2,3,4 in Serial Monitor.

It is doing exactly what the code should be doing. It loops over all the elements, incrementing light level to the highest value