Programming EEPROM to save the users input

Hi all. I am trying to make a program in which when i press and hold a push button for 3sec the lights cycle will be set to run for 12hrs starting from the time push button was pressed. e.g, if i press and hold the push button at 10am, the lights cycle will start from 10am to 10pm. The cycle should remain that way until i decide to change it by press + hold the button at my desired time

So far i have developed that program but the problem I have is to save the push button input in eeprom memory for if the Arduino might be plugged off, the Arduino must remember the last push button input.

#include <Wire.h>
#include "RTClib.h"
#include <EEPROM.h>

#define lightSignalPin 6
#define lightsPin 13
#define pumpsPin 9
#define buttonManualWateringPin 12
#define lightButtonSetTimePin 8

#define sensorPin A1

RTC_DS1307 rtc;

char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

//boolean isPressed = false; 

//////////************************************Manual watering variables**********************************************///////
int lightState = 0;

// variables will change:
int buttonLightsState = 0;         // variable for reading the pushbutton status
int lightsProgramState = 0;
int levelSensorState = 1; //reads pushbutton status

int buttonSetTimeProgramState =0;
long buttonSetTimeMillis = 0;
const long buttonSetTimeInterval = 3000;   


void setup() {
  // put your setup code here, to run once:
while (!Serial); // for Leonardo/Micro/Zero

  Serial.begin(9600);
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }

  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
   //  rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2022, 5, 31, 10, 35, 20));
  }
  
  // Initializing pins

  pinMode(pumpsPin, OUTPUT);
  pinMode(buttonManualWateringPin, INPUT_PULLUP);
  pinMode(lightSignalPin, OUTPUT);
  pinMode(lightsPin, OUTPUT);
  pinMode(lightButtonSetTimePin, INPUT_PULLUP);
  pinMode(sensorPin, INPUT_PULLUP);
  
EEPROM.get(0, lightState);
}

void loop() {
  // put your main code here, to run repeatedly:
  
  pressingButton();
}

void pressingButton(void){
  levelSensorState = digitalRead(lightButtonSetTimePin);
  DateTime now = rtc.now();
  unsigned long currentlightsCycleMillis = millis();
  //waiting for button to be pressed
  if (buttonSetTimeProgramState == LOW && lightsProgramState == 0) {
    buttonSetTimeMillis = currentlightsCycleMillis;
    lightsProgramState = 1;
  }
  else if (lightsProgramState == 1 && buttonSetTimeProgramState == HIGH) {
        lightsProgramState = 0; //reset
  }
  if(currentlightsCycleMillis - buttonSetTimeMillis > buttonSetTimeInterval && lightsProgramState == 1) {
    lightsProgramState = 2;
    buttonSetTimeMillis = currentlightsCycleMillis;

  lightSettings();
  }
  
  else{
  
  if (lightState == 0){
    if(now.hour() >= 6 && now.hour() <= 18){
    Serial.println("Lights ON by default");
    digitalWrite(lightsPin, HIGH);
    }
    if(now.hour() > 18){
      Serial.println("Lights OFF default");
    digitalWrite(lightsPin, LOW);
      }
    
    }
  }
  

}

void lightSettings(){

   DateTime now = rtc.now();
  
    // Once per minute...
   int selector = now.hour();
      // ...Display the time...
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.println("");

 switch (selector){
  case 6:
    if(now.hour() >= 6 && now.hour() <= 18){
    Serial.println("Lights ON state 1");
    digitalWrite(lightsPin, HIGH);
    }
    if(now.hour() > 18){
      Serial.println("Lights OFF 1");
    digitalWrite(lightsPin, LOW);
      }
    lightState = 1;
    lightsProgramState = 0;
   break;

   case 7: 
    if(now.hour() >=7 && now.hour() <= 19 ){
    Serial.println("Lights ON state 2");
    digitalWrite(lightsPin, HIGH);
    }
    if(now.hour() > 19){
      Serial.println("Lights OFF 2");
    digitalWrite(lightsPin, LOW);
      }
   lightState = 2;
   lightsProgramState = 0;
   break;

    case 8:


    if(now.hour() >= 8 && now.hour() <= 20){
    Serial.println("Lights ON state 3");
    digitalWrite(lightsPin, HIGH);
    }
    if(now.hour() > 20){
      Serial.println("Lights OFF 3");
    digitalWrite(lightsPin, LOW);
      }
   lightState = 3;
   lightsProgramState = 0;
   break;

   case 9: 
    if(now.hour() >=9 && now.hour() <= 21 ){
    Serial.println("Lights ON state 4");
    digitalWrite(lightsPin, HIGH);
    }
    if(now.hour() > 21){
      Serial.println("Lights OFF 4");
    digitalWrite(lightsPin, LOW);
      }
   lightState = 4;
   lightsProgramState = 0;
   
   break;

    case 10:

    if(now.hour() >= 10 && now.hour() <= 22){
    Serial.println("Lights ON state 5");
    digitalWrite(lightsPin, HIGH);
    }
    if(now.hour() > 22){
      Serial.println("Lights OFF 5");
    digitalWrite(lightsPin, LOW);
      }
   lightState = 5;
   lightsProgramState = 0;
   break;

   case 11: 
  
    if(now.hour() >=11 && now.hour() <= 23 ){
    Serial.println("Lights ON state 6");
    digitalWrite(lightsPin, HIGH);
    }
    if(now.hour() > 23){
      Serial.println("Lights OFF 6");
    digitalWrite(lightsPin, LOW);
      }
   lightState = 6;
   lightsProgramState = 0;
   break;

    case 12:

    if(now.hour() >= 12 ){
    Serial.println("Lights ON state 7");
    digitalWrite(lightsPin, HIGH);
    }
    if(now.hour() == 00){
      Serial.println("Lights OFF 7");
    digitalWrite(lightsPin, LOW);
      }
   lightState = 7;
   lightsProgramState = 0;
   break;

   case 13: 
 
    if(now.hour() >=13){
    Serial.println("Lights ON state 8");
    digitalWrite(lightsPin, HIGH);
    }
    if(now.hour() == 1){
      Serial.println("Lights OFF 8");
    digitalWrite(lightsPin, LOW);
      }
   lightState = 8;
   lightsProgramState = 0;
   break;

   case 14: 
 
    if(now.hour() >=14 && now.hour() <= 2 ){
    Serial.println("Lights ON state 9");
    digitalWrite(lightsPin, HIGH);
    }
    if(now.hour() == 2){
      Serial.println("Lights OFF 9");
    digitalWrite(lightsPin, LOW);
      }
   lightState = 9;
   lightsProgramState = 0;
   break;

   case 15: 
 
    if(now.hour() >=15 && now.hour() <= 3 ){
    Serial.println("Lights ON from 00 to 12");
    digitalWrite(lightsPin, HIGH);
    }
    if(now.hour() == 3){
      Serial.println("Lights OFF 10");
    digitalWrite(lightsPin, LOW);
      }
    lightState = 10;
    lightsProgramState = 0;
   break;
   
   case 5: 
 
    if(now.hour() >=5 && now.hour() <= 17 ){
    Serial.println("Lights ON from 5 to 17");
    digitalWrite(lightsPin, HIGH);
    }
    if(now.hour() == 17){
      Serial.println("Lights OFF 11");
    digitalWrite(lightsPin, LOW);
      }
    lightState = 11;
    lightsProgramState = 0;
   break;
   
    default:
    Serial.println("Lights ON by default");
    lightState = 0;
    if(now.hour() >= 6 && now.hour() <= 18){
    Serial.println("Lights ON");
    digitalWrite(lightsPin, HIGH);
    }
    if(now.hour() > 18){
      Serial.println("Lights OFF");
    digitalWrite(lightsPin, LOW);
      }
     
  }
 EEPROM.put(0, lightState);
}

I'm not sure how program the eeprom. I did read some documents about it and tried to find some examples online but I don't know how to implement it in my code. Please assist.

TIA

I understand the intended behaviour (save to eeprom, read back in setup). How does the actual behaviour differ?

I'm not sure if i quite follow the question but with how I programmed it now (having EEPROM.get() in the setup and EEPROM.get() in the lightSettings() loop), Switch button does no longer work. Lights cycle remain on default regardless of the time i pushed the button. but the code works fine when i comment out eeprom syntax. Meaning I can press and hold the switch button and the light cycle will start from the time I pressed the button.
image

Should not the lights cycle start at 10:00:03 am and stay up to 10:00:03 pm as the push button will remain pressed for 3-sec?

"+ hold" -- is it a second push button connected at some DPin of the Arduino?

Which Arduino are you using -- UNO/NANO/MEGA?

Which button is that? You have two in the #defines; one is actually never used and the other one is used in below

But you never use levelSensorState anywhere in your code to take a decision.

Perform a simple experiment to establish that Button-press time is recorded and is later restored correctly after disruption of power to the Arduino UNO. Where do you want to save the time -- in the MCU's EEPROM or RTC's EEPROM?

No you only "press + hold" push button for 3 sec to kick in the lights cycle. After button is released it then got reset to 0 to wait for another action from the user.

It's only one push button to set-up the time

I am using nano

I have actually tried example from this site Arduino EEPROM Explained | Random Nerd Tutorials, and it save the state easily and restore it. But I think it is slightly different with my case as I want to keep and store the light cycle not the last led state.

I'm sorry for confusion. I'll include only the correct code that defines one button:

#include <Wire.h>
#include "RTClib.h"
#include <EEPROM.h>

#define lightsPin 13

#define lightButtonSetTimePin 8

RTC_DS1307 rtc;

char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

//boolean isPressed = false; 

//////////************************************Manual watering variables**********************************************///////
int lightState = 0;

// variables will change:
int buttonLightsState = 0;         // variable for reading the pushbutton status
int lightsProgramState = 0;


int buttonSetTimeProgramState =0;
long buttonSetTimeMillis = 0;
int buttonState = 0;
const long buttonSetTimeInterval = 3000;   


void setup() {
  // put your setup code here, to run once:
while (!Serial); // for Leonardo/Micro/Zero

  Serial.begin(9600);
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }

  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
   //  rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2022, 5, 31, 10, 35, 20));
  }
  
  // Initializing pins

  pinMode(lightsPin, OUTPUT);
  pinMode(lightButtonSetTimePin, INPUT_PULLUP);
  
EEPROM.get(0, lightState);
}

void loop() {
  // put your main code here, to run repeatedly:
  
  pressingButton();
}

void pressingButton(void){
  buttonState = digitalRead(lightButtonSetTimePin);
  DateTime now = rtc.now();
  unsigned long currentlightsCycleMillis = millis();
  //waiting for button to be pressed
  if (buttonState == LOW && lightsProgramState == 0) {
    buttonSetTimeMillis = currentlightsCycleMillis;
    lightsProgramState = 1;
  }
  else if (lightsProgramState == 1 && buttonSetTimeProgramState == HIGH) {
        lightsProgramState = 0; //reset
  }
  if(currentlightsCycleMillis - buttonSetTimeMillis > buttonSetTimeInterval && lightsProgramState == 1) {
    lightsProgramState = 2;
    buttonSetTimeMillis = currentlightsCycleMillis;

  lightSettings();
  }
  
  else{
  
  if (lightState == 0){
    if(now.hour() >= 6 && now.hour() <= 18){
    Serial.println("Lights ON by default");
    digitalWrite(lightsPin, HIGH);
    }
    if(now.hour() > 18){
      Serial.println("Lights OFF default");
    digitalWrite(lightsPin, LOW);
      }
    
    }
  }
  

}

void lightSettings(){

   DateTime now = rtc.now();
  
    // Once per minute...
   int selector = now.hour();
      // ...Display the time...
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.println("");

 switch (selector){
  case 6:
    if(now.hour() >= 6 && now.hour() <= 18){
    Serial.println("Lights ON state 1");
    digitalWrite(lightsPin, HIGH);
    }
    if(now.hour() > 18){
      Serial.println("Lights OFF 1");
    digitalWrite(lightsPin, LOW);
      }
    lightState = 1;
    lightsProgramState = 0;
   break;

   case 7: 
    if(now.hour() >=7 && now.hour() <= 19 ){
    Serial.println("Lights ON state 2");
    digitalWrite(lightsPin, HIGH);
    }
    if(now.hour() > 19){
      Serial.println("Lights OFF 2");
    digitalWrite(lightsPin, LOW);
      }
   lightState = 2;
   lightsProgramState = 0;
   break;

    case 8:


    if(now.hour() >= 8 && now.hour() <= 20){
    Serial.println("Lights ON state 3");
    digitalWrite(lightsPin, HIGH);
    }
    if(now.hour() > 20){
      Serial.println("Lights OFF 3");
    digitalWrite(lightsPin, LOW);
      }
   lightState = 3;
   lightsProgramState = 0;
   break;

   case 9: 
    if(now.hour() >=9 && now.hour() <= 21 ){
    Serial.println("Lights ON state 4");
    digitalWrite(lightsPin, HIGH);
    }
    if(now.hour() > 21){
      Serial.println("Lights OFF 4");
    digitalWrite(lightsPin, LOW);
      }
   lightState = 4;
   lightsProgramState = 0;
   
   break;

    case 10:

    if(now.hour() >= 10 && now.hour() <= 22){
    Serial.println("Lights ON state 5");
    digitalWrite(lightsPin, HIGH);
    }
    if(now.hour() > 22){
      Serial.println("Lights OFF 5");
    digitalWrite(lightsPin, LOW);
      }
   lightState = 5;
   lightsProgramState = 0;
   break;

   case 11: 
  
    if(now.hour() >=11 && now.hour() <= 23 ){
    Serial.println("Lights ON state 6");
    digitalWrite(lightsPin, HIGH);
    }
    if(now.hour() > 23){
      Serial.println("Lights OFF 6");
    digitalWrite(lightsPin, LOW);
      }
   lightState = 6;
   lightsProgramState = 0;
   break;

    case 12:

    if(now.hour() >= 12 ){
    Serial.println("Lights ON state 7");
    digitalWrite(lightsPin, HIGH);
    }
    if(now.hour() == 00){
      Serial.println("Lights OFF 7");
    digitalWrite(lightsPin, LOW);
      }
   lightState = 7;
   lightsProgramState = 0;
   break;

   case 13: 
 
    if(now.hour() >=13){
    Serial.println("Lights ON state 8");
    digitalWrite(lightsPin, HIGH);
    }
    if(now.hour() == 1){
      Serial.println("Lights OFF 8");
    digitalWrite(lightsPin, LOW);
      }
   lightState = 8;
   lightsProgramState = 0;
   break;

   case 14: 
 
    if(now.hour() >=14 && now.hour() <= 2 ){
    Serial.println("Lights ON state 9");
    digitalWrite(lightsPin, HIGH);
    }
    if(now.hour() == 2){
      Serial.println("Lights OFF 9");
    digitalWrite(lightsPin, LOW);
      }
   lightState = 9;
   lightsProgramState = 0;
   break;

   case 15: 
 
    if(now.hour() >=15 && now.hour() <= 3 ){
    Serial.println("Lights ON from 00 to 12");
    digitalWrite(lightsPin, HIGH);
    }
    if(now.hour() == 3){
      Serial.println("Lights OFF 10");
    digitalWrite(lightsPin, LOW);
      }
    lightState = 10;
    lightsProgramState = 0;
   break;
   
   case 5: 
 
    if(now.hour() >=5 && now.hour() <= 17 ){
    Serial.println("Lights ON from 5 to 17");
    digitalWrite(lightsPin, HIGH);
    }
    if(now.hour() == 17){
      Serial.println("Lights OFF 11");
    digitalWrite(lightsPin, LOW);
      }
    lightState = 11;
    lightsProgramState = 0;
   break;
   
    default:
    Serial.println("Lights ON by default");
    lightState = 0;
    if(now.hour() >= 6 && now.hour() <= 18){
    Serial.println("Lights ON");
    digitalWrite(lightsPin, HIGH);
    }
    if(now.hour() > 18){
      Serial.println("Lights OFF");
    digitalWrite(lightsPin, LOW);
      }
     
  }
 EEPROM.put(0, lightState);
}

Hi guys. So i have managed to come up with a bit of code that works exactly how I want.

  1. The push button is pressed and hold for 3sec.
  2. The lightSettings loop is triggered then depend on the time the button was pressed, the lights cycle starts there. e.g The push button is pressed at 5:00, the lights will come on till 17:00.
  3. If there is any power interruption, the Arduino still remember the last set lighting cycle.
#include <Wire.h>
#include "RTClib.h"
#include <EEPROM.h>

RTC_DS1307 rtc;
#define lightsPin 13

#define lightButtonSetTimePin 8

char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

//////////************************************Manual watering variables**********************************************///////
int lightState = 0;

// variables will change:
int buttonLightsState = 0;         // variable for reading the pushbutton status
int lightsProgramState = 0;


int buttonSetTimeProgramState =0;
long buttonSetTimeMillis = 0;
int buttonState = 0;
const long buttonSetTimeInterval = 3000;   


void setup() {
  // put your setup code here, to run once:
while (!Serial); // for Leonardo/Micro/Zero

  Serial.begin(9600);
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }

  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running!");
  }
  
  // Initializing pins

  pinMode(lightsPin, OUTPUT);
  pinMode(lightButtonSetTimePin, INPUT_PULLUP);
  EEPROM.get(0, lightState);
  
}

void loop() {
  // put your main code here, to run repeatedly:
buttonPressed();
seTime();
}

void buttonPressed(){
  
  buttonState = digitalRead(lightButtonSetTimePin);
  DateTime now = rtc.now();
  unsigned long currentlightsCycleMillis = millis();
  //waiting for button to be pressed
  if (buttonState == LOW && lightsProgramState == 0) {
    buttonSetTimeMillis = currentlightsCycleMillis;
    lightsProgramState = 1;
    Serial.print("Button pressed");
  }
  else if (lightsProgramState == 1 && buttonSetTimeProgramState == HIGH) {
        lightsProgramState = 0; //reset
  }
  if(currentlightsCycleMillis - buttonSetTimeMillis > buttonSetTimeInterval && lightsProgramState == 1) {
    lightsProgramState = 2;
    buttonSetTimeMillis = currentlightsCycleMillis;
    lightSettings();
  }  
  
}

void seTime(void){
  
    // Get the current date and time
    DateTime now = rtc.now();

    if(lightState == 1){
      if(now.hour() >= 5 && now.hour() < 17){
    Serial.println("Lights ON state 1 from memory");
    digitalWrite(lightsPin, HIGH);
    }
    if(now.hour() == 17){
      Serial.println("Lights OFF 1");
    digitalWrite(lightsPin, LOW);
      }   
    }
    if(lightState == 2){
      if(now.hour() >= 6 && now.hour() < 18){
    Serial.println("Lights ON state 2 from memory");
    digitalWrite(lightsPin, HIGH);
    }
    if(now.hour() == 18){
      Serial.println("Lights OFF 2");
    digitalWrite(lightsPin, LOW);
      }  
    }

    if(lightState == 3){
      if(now.hour() >= 7 && now.hour() < 19 ){
    Serial.println("Lights ON state 3 from memory");
    digitalWrite(lightsPin, HIGH);
    }
    if(now.hour() == 19){
      Serial.println("Lights OFF 3 from memory");
    digitalWrite(lightsPin, LOW);
      }  
    }
//more lightState cycle loop to be added
}

void lightSettings(){

   DateTime now = rtc.now();
  
    // Once per minute...
   int selector = now.hour();
      // ...Display the time...
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.println("");

 switch (selector){
  case 5:
    if(now.hour() >= 5 && now.hour() < 17){
    Serial.println("Lights ON state 1");
    digitalWrite(lightsPin, HIGH);
    }
    if(now.hour() == 17){
      Serial.println("Lights OFF 1");
    digitalWrite(lightsPin, LOW);
      }
      lightState = 1;
   break;

   case 6: 
    if(now.hour() >=6 && now.hour() < 18  ){
    Serial.println("Lights ON state 2");
    digitalWrite(lightsPin, HIGH);
    }
    if(now.hour() == 18){
      Serial.println("Lights OFF 2");
    digitalWrite(lightsPin, LOW);
      }
      lightState = 2;
   break;

   case 7: 
    if(now.hour() >=7 && now.hour() < 19 ){
    Serial.println("Lights ON state 3");
    digitalWrite(lightsPin, HIGH);
    }
    if(now.hour() == 19){
      Serial.println("Lights OFF 3");
    digitalWrite(lightsPin, LOW);
      }
      lightState = 3;
   break;
//more hours loop to be added
 }
 EEPROM.put(0, lightState);
}

I want to know if there anyhow or anyway that I can make this code short rather because at the moment I still have to add more if statement for all hours on the clock. From 12:00 to 00:00 and the purpose for this is because I want anytime I press and hold the push button, then the new lights cycle is set.

If there's anyone who can help then that'll be more appreciated.

Thanks everyone

I think the above lines could could be reduced to:

  case 5:
 //   if(now.hour() >= 5 && now.hour() < 17){
    Serial.println("Lights ON state 1");
    digitalWrite(lightsPin, HIGH);
  //  }
//    if(now.hour() == 17){
 //     Serial.println("Lights OFF 1");
//    digitalWrite(lightsPin, LOW);
//      }
      lightState = 1;
   break;

The now.hour() is 5 which is less than 17; so, there is no need of doing &&.
With case 5:, you will never find now.hour() == 17; rather, it is still 5.

@GolamMostafa Yes you are right actually. Thanks, that'll reduce the length of the code.
So since I will be adding more code to accommodate all hours on the clock and this means lightState add up to lightState = 20;, How can I make it be possible for EEPROM to store two bytes?

20 still fits in one byte :wink:

If you don't want to worry about the size of a variable, you can use EEPROM.put() and EEPROM.get().

Nice! Thanks guys :grin:.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.