just a nod in the right direction with eeprom please

Hi all,
i have googled for 2 days, i have took many cups of coffee attempting to understand bits n bytes til 3 am and for the life of me.....i dont get it.

the examples vary greatly and confuse you, some use bytes+1 and others look like they have barely no code,

as an example, im trying to save the hour from a ds1307 rtc to the arduino eeprom, im aware the rtc has a ram chip but im reluctant to use it. my writing code is currently

nowH = RTC.get(ds1307_HR);

EEPROM.write(0,nowH);

and my switch code is this

now = (RTC.get(DS1307_HR,true)); //nowh would get current time
nowH = EEPROM.read(0,ds1307_HR);

if (last < nowH){
//do this
}else{
//do that
}

now im fully aware that this will be wrong but a nod to what is wrong about it would be great, i know its a trivial thing to most and yes after 3 days i should have got it but i have a block on it i think lol,

if theres an easier way then id love to know,
thanks :slight_smile:

To get practical help, you need to post your whole code.

I suspect that what you're missing is that the EEPROM interface reads and writes values one byte at a time, so if you are saving a value that is bigger than a byte, you will need to access each byte separately.

If nowH is intended to store the hour within the current day (0 .. 23 or 1 .. 24) then it would be small enough to fit within a single byte so you could just write it to and read it from EEPROM in a single operation. But we can't tell whether it is actually a byte value, because you haven't shown us your whole code.

Could you post a link to the DS1307 library you use ?

You use 'now' to get the current time, but you test the variable 'last'.
Could you use better names ? The names 'nowH' and 'now' and 'last' are confusing. Perhaps: 'hourStored' and 'hourNow'.

hey,
thanks for the replys

im using the ds1307 library from this forum i cant find the link too, unfortunately,
it was Created by D. Sjunnesson 1scale1.com d.sjunnesson (at) 1scale1.com
Modified by bricofoy - bricofoy (at) free.fr

its a very competent library and ill give the example code i am using

/*
 *
 * Read and set through serial port demo sketch for DS1307 I2C rtc clock
 *
 * DS1307 library provided by mattt & D.Sjunnesson, corrected by bricofoy.
 * See DS1307.h for more details.
 *
 * This exemple code is under GNU GPL
 *
 * (c) bricofoy 2012
 *
 */



// This is for compatibility with both arduino 1.0 and previous versions
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif

#include <Wire.h>
#include <DS1307.h>

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


// use explanation message
void use() {
  Serial.println("\nUSE      : u U r R h[00-23]m[00-59]s[00-59]j0[1-7]D[01-31]M[01-12]A[00-49]");
  Serial.println("\nEXEMPLE  : h09m35d03 set time to 09h35 and day of week 3 (thuesday).");
  Serial.println("\nCommands : h** : hour,  m** : minutes, s** : seconds, d0* : day of week");
  Serial.println("           M** : month,  Y** : year,   D** : day of month.");
  Serial.println("           r stops clock, R starts it. ");
  Serial.println("           u or U shows this message, all other caracter shows time.");
}

// DS1307 time read function
void read_RTC() {
	  Serial.print("\nActual time : ");
	  Serial.print(RTC.get(DS1307_HR,true)); //read the hour and also update all the values by pushing in true
	  Serial.print(":");
	  Serial.print(RTC.get(DS1307_MIN,false));//read minutes without update (false)
	  Serial.print(":");
	  Serial.print(RTC.get(DS1307_SEC,false));//read seconds
	  Serial.print(" ");                 // some space for a more happy life
	  Serial.print(RTC.get(DS1307_DOW,false));
	  Serial.print(" ");
	  Serial.print(RTC.get(DS1307_DATE,false));//read date
	  Serial.print("/");
	  Serial.print(RTC.get(DS1307_MTH,false));//read month
	  Serial.print("/");
	  Serial.println(RTC.get(DS1307_YR,false)); //read year
}

// set clock values
void write_RTC() {
      char value=0;
      char command=0;

      command = Serial.read();
      delay(50);				//delay to allow good serial port reading
      value=byte((Serial.read()-48)*10); 	//-48 becaus ASCII value for 0 is 48, 1 is 49, etc and *10 because we read tens first
      delay(50);
      value+=byte((Serial.read()-48));		//and then we read units

      switch (command) {
	case 'h' :
	  RTC.set(DS1307_HR,value);
	  Serial.print("hours set to ");
	  Serial.println(value,DEC);
	  break;
	case 'm' :
	  RTC.set(DS1307_MIN,value);
	  Serial.print("minutes set to ");
	  Serial.println(value,DEC);
	  break;
	case 's' :
	  RTC.set(DS1307_SEC,value);
	  Serial.print("seconds set to ");
	  Serial.println(value,DEC);
	  break;
	case 'D' :
	  RTC.set(DS1307_DATE,value);
	  Serial.print("day of month set to ");
	  Serial.println(value,DEC);
	  break;
	case 'd' :
	  RTC.set(DS1307_DOW,value);
	  Serial.print("day of week set to ");
	  Serial.println(value,DEC);
	  break;
	case 'M' :
	  RTC.set(DS1307_MTH,value);
	  Serial.print("month set to ");
	  Serial.println(value,DEC);
	  break;
	case 'Y' :
	  RTC.set(DS1307_YR,value);
	  Serial.print("year set to ");
	  Serial.println(value,DEC);
	  break;
	case 'u' :
	case 'U' :
	  use();
	  break;
	case 'r' :
	  RTC.stop();
	  Serial.println("Clock stopped");
	  break;
	case 'R' :
	  RTC.start();
	  Serial.println("Clock running");
	  break;
	default :
	  break;
      }
      read_RTC();
}

void loop() {
   if (Serial.available()) {
     write_RTC();
    }
}

i have added nothing to that code,

i know the names are a bit confusing and they were just for an example to be honest.

im still thinking that on reset/power on the first the sketch does is check current time to saved time. it will be a single byte written as a 0 to 23, and this would need be compared to current hour.

lasthour = EEPROM.read(0);
currenthour = RTC.get(DS1307_HR);

if (lasthour < currenthour){
do this
}else{
//do that
}

after 1 hour on time, update eeprom, i have millis working with this to count 60 minutes, its as millis so i can change it easier to half hour if needed.

currenthour = RTC.get(DS1307_HR);
EEPROM.write(0,currenthour);

i hope this helps? any pointers would be great, thanks guys

I think it will look like this:

// Example code, could be wrong

void loop() {
  .....

  int lasthour = EEPROM.read(0);
  int currenthour = RTC.get(DS1307_HR, true);

  if (lasthour < currenthour) {
    // Update lasthour.
    EEPROM.write(0, currenthour);
    // Do something every hour.
    .....
  } 
  else {
    delay(100);
  }

  .....
}

that looks like what it is im trying to achieve but, i cant have it in a loop, the first read from eeprom happens in void.setup and the write happens with a millis since on delay from blink without delay, i felt this was the safest way to ensure i dont kill the eeprom chip with thousands of writes if stuck in a loop,

so edited code would be this?

// Example code, could be wrong


void setup(){
int lasthour = EEPROM.read(0);
int currenthour = RTC.get(DS1307_HR, true);

  if (lasthour < currenthour) {
    // go to this screen
     } 

void loop() {
//all other code

if (millis == an hour){
eeprom.write(0,currenthour);
reset millis to zero
}

the millis part is not correct but it will be, more concerned with the correcting reading/writing to eeprom,

thanks for the help,

You can use millis() to prevent a lot of EEPROM writes.

But you can read the EEPROM as much as you like.
I already reduced the writing in my code.
In my code, the "lasthour < currenthour" will only be valid if the value in EEPROM is lower than the current time. After that the current time is written into the EEPROM.

During that hour, the EEPROM is read many times, but not written.
It is only written if the hour changes.

Perhaps that test should also test for roll-over of the hour.

if (lasthour != currenthour) {

Or do you want to catch up with the hours ? If the Arduino is switched on after 3 hours, it will do the things 3 times ? I hope not, because you have to use the number of seconds since 1970 and that is not in that library.

so your example checks the eeprom every cycle to see if the current our s the same? mkes sense, although, im not sure how that would effect my other compnents such as wav play back and tft screen, the screen already goes pretty slow when the wav is being played from sd, i dont want to add extra stuff for it to slow further?

i think just a general, power on, if less than than current, go to a different start screen, millis can and is reset each time the arduino is set and is simply has it been an hour in millis since it started counting, if yes,write the current hour, if it isnt, wait until it has.

i dont understand what you mean by catching up with the hours? i was kind of thinking thee must be an easier way to see if the arduino was powered on in the last 2 hours and switched off? logging the exact time to eeprom isnt important as its timestamped to sd card anyways in my log file.

any alternative thoughts? or am i in the right area?

  1. With "catch up" I mean that if for example the Arduino was off for three hours, you have to catch up the missing hours and do something three times. That would need another sketch and other library.

  2. But if you only want to do something if the hour changes, the code I gave would be enough. You could also use millis() for that.

  3. Do you only want to check if the Arduino was off for more than one hour ?
    That is another situation, and the code I gave would be wrong.
    What happens if you turn off the Arduino at 3:15, and turn it on the next day at 3:15. How should the Arduino know it has been off for more than one hour ?
    You could use "the number of seconds since 1970", or also use the day of the month and the year. That should also be stored to EEPROM.

-> Question 1: You want to detect at startup if the Arduino was off for more than one hour. Is that right ?

-> Question 2: Do you want to do something if the Arduino is on, and the hour changes ? For example if the time changes from 2:59 to 3:00. Or do you want to do something if the Arduino is on for one hour ? Or is it only to update the EEPROM with a new value ? Using millis() to prevent writing the EEPROM too much can be done, but I would rather read the EEPROM and the RTC and compare them.

i do love the way arduino is so easy to use, and yet the logic of it seems backwards?

thanks for your replys and also posing new questions,

this was supposed to be such a simple thing but now? im not sure

ll its going to do is arduino on, check saved hour to old hour if its been more than one and less that 3 then go to a different function, if more than 3 then do default action.

if you could give me some guidance in this to make it clean and simple using the ds1307 library as above then dude, i will help you in your projects if i can.

thanks again

You can not use only the hour.
If it was off for 25 hours, you have to know that the day has changed.

So you should also store the day and the month to EEPROM.

so how would i compare all that data?

an of statement dont see to cover it? is there an easier way to do this? or anoher method?

it seems to be getting very complicated now just to check if it was turned on a couple hours ago?

it looks like im going to have to learn to use bytes to read the data byte by byte from the eeprom, and compare that to the current time byte.
how would you go about doing it? could watchdog be of use? millis from 1970 would be a massive number but i guess it would be an unsigned int?