EEPROM overwite previous data?

I have at last got my RTC board running using the Time.h and DS1307RTC.h libraries.

The TimeRTCLogger example appears to be almost right for the project I am playing with , which is a sign showing the days since the last event, date of previous event, and previous longest days between events.

I know the DS1307 will keep the time for years, but I have a couple of questions

Firstly, I can only see the Syncing the time from the RTC during Set up ?
is it keeping time with its now() call ?

Secondly ,
if this project is unplugged at some time, presumably the prevEventTime will be lost when the micro boots up again.
Could I store prevEventTime as eeprom_write_byte and eeprom_read_byte ?

If so would it be in the same address - ie overwrite the previous one?

I only expect an event every few weeks, so the 10,000 write cycles will be fine - ( I am 63 years old )
BTW The events are nothing to do with romance !

the code follows :-

/*
 * TimeRTCLogger.pde
 * example code illustrating adding and subtracting Time.
 * 
 * this sketch logs pin state change events
 * the time of the event and time since the previous event is calculated and sent to the serial port. 
 */

#include <Time.h>  
#include <Wire.h>  
#include <DS1307RTC.h>  // a basic DS1307 library that returns time as a time_t

const int nbrInputPins  = 6;             // monitor 6 digital pins 
const int inputPins[nbrInputPins] = {2,3,4,5,6,7};  // pins to monitor
boolean state[nbrInputPins] ;            // the state of the monitored pins
time_t  prevEventTime[nbrInputPins] ;    // the time of the previous event

void setup()  {
  Serial.begin(9600);
  setSyncProvider(RTC.get);   // the function to sync the time from the RTC  
  for(int i=0; i < nbrInputPins; i++){
     pinMode( inputPins[i], INPUT);
    digitalWrite( inputPins[i], HIGH);  // uncomment these lines if 
     state[i] = HIGH;                    // pull-up resistors are wanted
  }
}

void loop()
{
   for(int i=0; i < nbrInputPins; i++)
   {
     boolean val = digitalRead(inputPins[i]); 
     if(val != state[i])
     {
        time_t duration = 0; // the time since the previous event
        state[i] = val;
        time_t timeNow = now();
        if(prevEventTime[i] > 0)  
           // if this was not the first state change, calculate the time from the previous change
           duration = duration = timeNow - prevEventTime[i];         
        logEvent(inputPins[i], val, timeNow, duration );  // log the event
        prevEventTime[i] = timeNow;                       // store the time for this event  
     }
   }
}

void logEvent( int pin, boolean state, time_t timeNow, time_t duration)
{
   Serial.print("Pin ");
   Serial.print(pin);
   if( state == HIGH)
      Serial.print(" went High at ");
   else   
     Serial.print(" went  Low at ");
   showTime(timeNow); 
   if(duration > 0){
     // only display duration if greater than 0  
     Serial.print(", Duration was ");
     showDuration(duration);
   }
   Serial.println();
}


void showTime(time_t t){
  // display the given time 
  Serial.print(hour(t));
  printDigits(minute(t));
  printDigits(second(t));
  Serial.print(" ");
  Serial.print(day(t));
  Serial.print(" ");
  Serial.print(month(t));
  Serial.print(" ");
  Serial.print(year(t)); 
}

void printDigits(int digits){
  // utility function for digital clock display: prints preceding colon and leading 0
  Serial.print(":");
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);
}

void showDuration(time_t duration){
// prints the duration in days, hours, minutes and seconds
  if(duration >= SECS_PER_DAY){
     Serial.print(duration / SECS_PER_DAY);
     Serial.print(" day(s) "); 
     duration = duration % SECS_PER_DAY;     
  }
  if(duration >= SECS_PER_HOUR){
     Serial.print(duration / SECS_PER_HOUR);
     Serial.print(" hour(s) "); 
     duration = duration % SECS_PER_HOUR;     
  }
  if(duration >= SECS_PER_MIN){
     Serial.print(duration / SECS_PER_MIN);
     Serial.print(" minute(s) "); 
     duration = duration % SECS_PER_MIN;     
  }
  Serial.print(duration);
  Serial.print(" second(s) ");   
}

Firstly, I can only see the Syncing the time from the RTC during Set up ?
is it keeping time with its now() call ?

In setup, you define what function to call to sync the time. The calls to now() determine if it is time to sync, or not, and invoke the specified function if it is.

Could I store prevEventTime as eeprom_write_byte and eeprom_read_byte ?

Yes and no. Yes, you can store prevEventTime in EEPROM. No, prevEventTime is not a byte, so those are not the correct functions.

If so would it be in the same address - ie overwrite the previous one?

If you tell it to use the same address(es) every time, then yes, it will overwrite the previous value(s).

Thanks Paul
So I could perhaps save the current time and current date as two bytes in eeprom, after any event, and reconstitute it back into the same format as prevEventTime in setup ?
Can I read eeprom in setup?

OR perhaps save the now() whenever an event occurs. ( in seconds since Jan1 1970 ) , but divided by 606024 when an event occurs which will give me the number of complete days in one byte, and save that to eeprom as dayselapsed

Then when booting up after a power interruption , I could just work in days ?? but now I am moving away from a sketch that is actually working......

I can usually McGuiver a way to make a sketch work , but this seemingly simple project has me going round in circles ( I am obviously in new ground with the RTC and eeprom - and cannot understand some of the dozens of examples I have looked at )

As I see it, if I could simply store the current time "now() " in eeprom whenever there is an event, if the power goes off for a few days , at setup I can read the old current time from eeprom, to calculate the previous date, and the days since event.

( I would also need to store the previous best, but that is just a byte ( 0-99 days ) and I can do that I think ! )

I have tried dividing the seconds into days and masking off the higher and lower bytes to store in this form, but I loose the hours and could end up with the wrong day count

Might I be better off storing the date of the previous event as separate bytes for YY MM DD, and use a look up table for the months to calculate the days since last event ?

I have spent 43 of the last 48 hours trying to get this right and it is driving me nuts! I stupidly made a promise I could get it done by the weekend - it looked so easy :slight_smile:

Has anyone seen a working sketch that they can point me to? or give some advice..

The RTC chip also has 56 bytes of memory - why not store the time there and then read it back in similar manner as reading the other time elements? You have a battery going, yes?

Thanks Rob, I wondered about that, is that the RC register they talk about in the datasheet?

I can store the previous best number ( 0-99) preferably in 2 bytes ( so I can just use each one - tens and units - easily for the display.) Although I still have to compare it to the current elapsed days to see which is the "best"

The date can be yyyy mm dd or seconds since 1970 . so I don't know the best way to try to store it.

If I store it in seconds since 1/1/1970 I can easily divide down the difference between latest and stored seconds to get elapsed days, but I still will need to display the previous date after a power down.....?

In your void setup, read the current time, read the stored time, do the math to see elapsed, store the new current time in the RAM.
In your void loop, store the time in RAM after every read, then your downed time won't be more than 1 pass thru loop off.

Thanks Rob

I will have a look at that now

Did you see the RTC_I2C_test.pde (something like that, you can browse my posts in member section)
that I posted for halejandro and Magician?
Has simple wire.h commands to write the registers, get the time.
I think I only wrote to 1 RAM address, process is simple to write/read a larger amount tho.
Let me know if you can't find it.

After declaring the addresses & variables, do this to read the current time:

// Reset the register pointer  
    Wire.beginTransmission(RTC_address);  
    Wire.send(0x00);  
    Wire.endTransmission(); 

// Now read the current time registers
    Wire.requestFrom(RTC_address,8 );  
    seconds = Wire.receive();  
    minutes = Wire.receive();  
    hours = Wire.receive();  
    day_week = Wire.receive();  
    date_month = Wire.receive();  
    month = Wire.receive();  
    year = Wire.receive();  
    sqwe = Wire.receive();

// Reset the register pointer  
    Wire.beginTransmission(RTC_address);  
    Wire.send(0x08);  // RAM 0x08-0x3F 
    Wire.endTransmission(); 

// Write it to RAM  
    Wire.beginTransmission(RTC_address,8);  //  haven't tried this myself   
    Wire.send(seconds);  
    Wire.send(minutes);   
    Wire.send(hours);   
    Wire.send(day_week);   
    Wire.send(date_month);   
    Wire.send(month);   
    Wire.send(year);   
    Wire.send(sqwe); 
    Wire.endTransmission();

My complete code listing - I was using my Bobuino & RS232MON, expected TXT out, sent HEX in.

/*
Test of RTC DS1307 via I2C.
 Counts 
 Seconds, 
 Minutes, 
 Hours, 
 Date of the Month, 
 Month, 
 Day of the week, and 
 Year with Leap-Year
 
 56 bytes battery backed RAM
 Square Wave Output, can connect to INT2/D6 or PD7
 */

#include <Wire.h>

//variables
byte seconds_address = 0x00;
byte seconds; // bit 7 = Clock Halt, Enabled = 0, Halt = 1
// bits 6-5-3 = tens of seconds 0-6,  bits 3-2-1-0 = units of seconds, 0-9
byte minutes_address = 0x01;
byte minutes;  // bits 6-5-4 = tens of minutes, bits 3-2-1-0 = units of minutes
byte hours_address = 0x02; 
byte hours;  // 7=0. 6 = 1 for 12 hr, 0 for 24 hr.
// bit 5: 12 hr mode = AM(0)/PM(1). 24 hr mode = upper tens of hrs
// bit 4 =  lower tens of hrs, bits 3-2-1-0 = units of hours (0-9)
byte day_week_address = 0x03; 
byte day_week = 0; // range 01-07
byte date_month_address = 0x04;
byte date_month = 0; // range 01-31
byte month_address = 0x05;
byte month = 0; // range 01-12
byte year_address = 0x06;
int year = 0; // upper byte 0-9, lower byte 0-9
byte square_address = 0x07;
byte sqwe = 0;  // square wave enable
// Out-0-0-Sqwe-0-0-RS1-RS0
// Out, Sqwe = 0/0 - Square wave output = 0
// Out, Sqwe = 1/0 - Square wave output = 1
// Out, Sqwe = 0/1 or 1/1 - Square wave output per RS1/RS0
// RS1/RS0 = 00 = 1 Hz
// RS1/RSo = 01 = 4 KHz
// RS1/RS0 = 10 = 8 KHz
// RS1/RS0 = 11 = 32 KHz
byte RTC_ram_address = 0x08; //range = 08-63, 0x08-0x3F

int RTC_address = 0x68; // 1101 000 

byte incomingCommand = 0;
byte RTC_write_command = 0;
byte RTC_read_command = 0;
byte RTC_ram_command = 0;
// use F0xx, F1xx,F2xx, F3xx, F4xx, F5xx, F6xx, F7xx
// to send one register write commands
// use E0xx to read registers back
// use C0xx to read RAM back
byte incomingRegister = 0;
byte RTC_register = 0;
byte incomingData = 0;
byte new_data = 0;
byte outgoingData = 0;
int delay_time = 100;

unsigned long currentMillis = 0;
unsigned long previousMillis = 0;
unsigned long duration = 5000;

void setup() {
  Wire.begin(); // no address, we are master
  Serial1.begin (57600);  
  Serial1.flush();
  currentMillis = millis();  
}

void loop() {

  if (Serial1.available() >1){
    incomingCommand = Serial1.read();
    //incomingRegister = Serial.read();
    incomingData = Serial1.read();
    Serial1.print ("command ");
    Serial1.println (incomingCommand & 0xF0, HEX);
    Serial1.print ("register ");
    Serial1.println(incomingCommand & 0x0F, HEX);
    Serial1.print ("data ");
    Serial1.println (incomingData, HEX);
  }
  // *******************************************
  RTC_write_command = incomingCommand & 0xF0;  // mask off high byte
  if (RTC_write_command == 0xF0){  // e033check for Write command
    RTC_register = incomingCommand & 0x0F;  // mask off low btye
    incomingCommand = 0;
    new_data = incomingData;
    Serial1.print (" Sending a command ");
    switch (RTC_register){
    case 0: // write seconds
        Serial1.println ("Seconds ");
      Wire.beginTransmission(RTC_address); // select device
      Wire.send(seconds_address);          // queue the register
      Wire.send(new_data);                  // queue data
      Wire.endTransmission();            // send it
      delay (delay_time);
      break;
    case 1: // write minutes
    Serial1.print ("Minutes ");
      Wire.beginTransmission(RTC_address); // select device
      Wire.send(minutes_address);          // queue the register
      Wire.send(new_data);                  // queue data
      Wire.endTransmission();            // send it
      delay (delay_time);
      break;
    case 2: // write hours
        Serial1.print ("Hours ");
      Wire.beginTransmission(RTC_address); // select device
      Wire.send(hours_address);          // queue the register
      Wire.send(new_data);                  // queue data
      Wire.endTransmission();            // send it
     delay (delay_time);
      break;
    case 3: // write day
        Serial1.print ("Day ");
      Wire.beginTransmission(RTC_address); // select device
      Wire.send(day_week_address);          // queue the register
      Wire.send(new_data);                  // queue data
      Wire.endTransmission();            // send it
     delay (delay_time);
      break;
    case 4: // write date of month
        Serial1.print ("Day of Month ");
      Wire.beginTransmission(RTC_address); // select device
      Wire.send(date_month_address);          // queue the register
      Wire.send(new_data);                  // queue data
      Wire.endTransmission();            // send it
     delay (delay_time);
      break;
    case 5: // write month
        Serial1.print ("Month ");
      Wire.beginTransmission(RTC_address); // select device
      Wire.send(month_address);          // queue the register
      Wire.send(new_data);                  // queue data
      Wire.endTransmission();            // send it
     delay (delay_time);
      break;
    case 6: // write year
        Serial1.print ("Year ");
      Wire.beginTransmission(RTC_address); // select device
      Wire.send(year_address);          // queue the register
      Wire.send(new_data);                  // queue data
      Wire.endTransmission();            // send it
     delay (delay_time);
      break;
    case 7: // write square wave
        Serial1.print ("Square Wave ");
    Serial1.println (RTC_register, HEX);
      Wire.beginTransmission(RTC_address); // select device
      Wire.send(square_address);          // queue the register
      Wire.send(new_data);                  // queue data
      Wire.endTransmission();            // send it
     delay (delay_time);
      break;
    case 8: // write RAM
        Serial1.print ("RAM ");
    Serial1.println (RTC_register, HEX);
      Wire.beginTransmission(RTC_address); // select device
      Wire.send(RTC_ram_address);          // queue the register
      Wire.send(new_data);                  // queue data
      Wire.endTransmission();            // send it
     delay (delay_time);
      break;
      // all others,do nothing
      Serial.println ("Invalid command ");
    }  // end Switch
  } // end if command == F
  // ************************************

  currentMillis = millis();
  if ( (currentMillis - previousMillis) >= duration){
    previousMillis = currentMillis;  
    // Reset the register pointer  
    Wire.beginTransmission(RTC_address);  
    Wire.send(0x00);  
    Wire.endTransmission();   

    Wire.requestFrom(RTC_address,8 );  
    seconds = Wire.receive();  
    minutes = Wire.receive();  
    hours = Wire.receive();  
    day_week = Wire.receive();  
    date_month = Wire.receive();  
    month = Wire.receive();  
    year = Wire.receive();  
    sqwe = Wire.receive();

    // Seconds 
    // bit 7 = Clock Halt, Enabled = 0, Halt = 1
    // bits 6-5-3 = tens of seconds 0-6,  bits 3-2-1-0 = units of seconds, 0-9 

    // Hours
    // 7=0. 6 = 1 for 12 hr, 0 for 24 hr.
    // bit 5: 12 hr mode = AM(0)/PM(1). 24 hr mode = upper tens of hrs
    // bit 4 =  lower tens of hrs, bits 3-2-1-0 = units of hours (0-9)

    Serial1.print ("Hrs " );
    Serial1.print (hours, HEX);
    Serial1.print (" Mins ");
    Serial1.print (minutes, HEX);
    Serial1.print (" Secs ");
    Serial1.print (seconds, HEX);
    Serial1.print (" Day ");
    Serial1.print (day_week, HEX);
    Serial1.print (" Date ");
    Serial1.print (date_month, HEX);
    Serial1.print (" Month ");
    Serial1.print (month, HEX);
    Serial1.print (" Year 20");
    Serial1.print (year, HEX);
    Serial1.print (" Square Wave ");
    Serial1.println (sqwe, HEX);
  }
}

Thanks Rob

What must I change ( apart from the Serial ) to get the main part working with the normal usb?

Just remove the HEX from all the Serialprints ?

I get ÿ?ñn¢³30 ¿<ðn¢³30 ¿>ðo£322¡ÿ>ñn£°23aß?ño£°23áÿ?ñ at the moment on the monitor

BTW Rob, The Bobuino with bells, whistles, inter-cooler and turbo looks really cool !

I don't like to just cut'n'paste without trying to understand the code, I have put some comments on your code to see if I understand it :-

// Reset the register pointer                          //  because the DS1307 sequences through all the addresses ?
    Wire.beginTransmission(RTC_address);         // this would be 0x68 , the address for all DS1307s ?
    Wire.send(0x00);                                        // starts the sequence back at 00 ( seconds and CH ) ?
    Wire.endTransmission(); 

// Now read the current time registers
    Wire.requestFrom(RTC_address,8 );    //  imports current time and control in bcd format, sequencing through as above ?
    seconds = Wire.receive();                 //  extract 1 byte from above, 1 nibble tens seconds, one units seconds  ?
    minutes = Wire.receive();                 // and so on
    hours = Wire.receive();  
    day_week = Wire.receive();  
    date_month = Wire.receive();  
    month = Wire.receive();  
    year = Wire.receive();  
    sqwe = Wire.receive();

// Reset the register pointer                    
    Wire.beginTransmission(RTC_address);  
    Wire.send(0x08);  // RAM 0x08-0x3F      // advance the pointer to the start of the eeprom or battery ram ?
    Wire.endTransmission(); 

// Write it to RAM  
    Wire.beginTransmission(RTC_address,8);  //   I dont need time,  but need to save previous best ( 0-99 ) 
    Wire.send(seconds);  
    Wire.send(minutes);   
    Wire.send(hours);   
    Wire.send(day_week);   
    Wire.send(date_month);   
    Wire.send(month);   
    Wire.send(year);   
    Wire.send(sqwe); 
    Wire.endTransmission();

Intercooler & turbo, I like that!

Did you change Serial1 to just Serial?
Guess I'm gonna have to rewrite that test to work over the IDE Serial Monitor also.
I was using the ATMega1284 Serial1 port because I was downloadigng sketches over the USB to test, and it let me check out more of the card.

Section 1 question - yes, starts the access at Register address 0. RTC_address = 0x68, which is the DS1307 I2C address

Section 2 question - imports the data from registers 0-7, assigns to the variables shown. Data may have to be maniputed to do math on them as generally the high nibble represents one thing and the low nibble something else.
So for example if the seconds came back as 0x57, you would do
Seconds_time = (highByte(seconds)*10 + lowByte(seconds)); to get the function of ((seconds >>4)10) + (0x0F && seconds) (to yield 510 7)

3rd section - yes, point to start battery of RAM

4th section - not sure what you are saving, thought you needed time as you were determing time elapsed since some event. Got 56 bytes, save away.

Got it updated to work with IDE serial monitor. Biggest change was making Serial1 Serial,
receiving 4 bytes instead of 2, testing for ASCII characters in the IF and Swith:case, and putting the 2nd pair of ASCII bytes together to make a real byte to send to the DS1307.

Nothing complicated.
I also added some prints so one could see what the commands turned into, and changed some prints to println to look a little cleaner.
Let me know that you can follow this.
Data rate is 57600, make sure you set serial monitor to match.

/*
Test of RTC DS1307 via I2C.
 Counts 
 Seconds, 
 Minutes, 
 Hours, 
 Date of the Month, 
 Month, 
 Day of the week, and 
 Year with Leap-Year
 
 56 bytes battery backed RAM
 Square Wave Output, can connect to INT2/D6 or PD7 (on a "Bobuino" www.crossroadsfencing.com/BobuinoRev17)
 */

/*
Modified to Run thru IDE Serial port
*/
#include <Wire.h>

//variables
byte seconds_address = 0x00;
byte seconds; // bit 7 = Clock Halt, Enabled = 0, Halt = 1
// bits 6-5-3 = tens of seconds 0-6,  bits 3-2-1-0 = units of seconds, 0-9

byte minutes_address = 0x01;
byte minutes;  // bits 6-5-4 = tens of minutes, bits 3-2-1-0 = units of minutes

byte hours_address = 0x02; 
byte hours;  // 7=0. 6 = 1 for 12 hr, 0 for 24 hr.
// bit 5: 12 hr mode = AM(0)/PM(1). 24 hr mode = upper tens of hrs
// bit 4 =  lower tens of hrs, bits 3-2-1-0 = units of hours (0-9)

byte day_week_address = 0x03; 
byte day_week = 0; // range 01-07

byte date_month_address = 0x04;
byte date_month = 0; // range 01-31

byte month_address = 0x05;
byte month = 0; // range 01-12

byte year_address = 0x06;
int year = 0; // upper byte 0-9, lower byte 0-9

byte square_address = 0x07;
byte sqwe = 0;  // square wave enable
// Out-0-0-Sqwe-0-0-RS1-RS0
// Out, Sqwe = 0/0 - Square wave output = 0
// Out, Sqwe = 1/0 - Square wave output = 1
// Out, Sqwe = 0/1 or 1/1 - Square wave output per RS1/RS0
// RS1/RS0 = 00 = 1 Hz
// RS1/RSo = 01 = 4 KHz
// RS1/RS0 = 10 = 8 KHz
// RS1/RS0 = 11 = 32 KHz

byte RTC_ram_address = 0x08; //range = 08-63, 0x08-0x3F

int RTC_address = 0x68; // 1101 000 

byte incomingCommand = 0;
byte RTC_write_command = 0;
byte RTC_read_command = 0;
byte RTC_ram_command = 0;

// use F0xx, F1xx,F2xx, F3xx, F4xx, F5xx, F6xx, F7xx
// to send one register write commands
// use E0xx to read registers back - not coded yet
// use C0xx to read RAM back - not coded yet

byte incomingRegister = 0;
byte RTC_register = 0;
byte incomingData1 = 0;
byte incomingData2 = 0;
byte new_data = 0;
byte outgoingData = 0;
int delay_time = 100;

unsigned long currentMillis = 0;
unsigned long previousMillis = 0;
unsigned long duration = 5000;

void setup() {
  Wire.begin(); // no address, we are master
  Serial.begin (57600);  
  Serial.flush();
  currentMillis = millis();  
}

void loop() {

  if (Serial.available() >3){
    incomingCommand = Serial.read();
    incomingRegister = Serial.read();
    incomingData1 = Serial.read();
    incomingData1 = incomingData1 - 0x30; // convert ASCII to HEX
    incomingData2 = Serial.read();
    incomingData2 = incomingData2 - 0x30;  // convert ASCII to HEX
    new_data = (incomingData1 << 4) + incomingData2;  // put the Upper/Lower nibbles together
    Serial.print ("command ");
    Serial.println (incomingCommand);
    Serial.print ("register ");
    Serial.println(incomingRegister);
    Serial.print ("data1 ");
    Serial.println (incomingData1, HEX);
    Serial.print ("data2 ");
    Serial.println (incomingData2, HEX);
    Serial.print ("combined data ");    
    Serial.println (new_data, HEX);
    
  }
  // *******************************************
//  RTC_write_command = incomingCommand & 0xF0;  // mask off high byte
//  if (RTC_write_command == 0xF0){  // check for Write command
if ((incomingCommand == 'F') | (incomingCommand == 'f')){
  incomingCommand = 0;  // reset for next pass
//    RTC_register = incomingCommand & 0x0F;  // mask off low btye
//    incomingCommand = 0;
//    new_data = incomingData;
    Serial.println (" Sending a command ");
//    switch (RTC_register){
switch (incomingRegister){
  case '0': // write seconds
        Serial.println ("Seconds ");
      Wire.beginTransmission(RTC_address); // select device
      Wire.send(seconds_address);          // queue the register
      Wire.send(new_data);                  // queue data
      Wire.endTransmission();            // send it
      delay (delay_time);
      break;
    case '1': // write minutes
    Serial.println ("Minutes ");
      Wire.beginTransmission(RTC_address); // select device
      Wire.send(minutes_address);          // queue the register
      Wire.send(new_data);                  // queue data
      Wire.endTransmission();            // send it
      delay (delay_time);
      break;
    case '2': // write hours
        Serial.println ("Hours ");
      Wire.beginTransmission(RTC_address); // select device
      Wire.send(hours_address);          // queue the register
      Wire.send(new_data);                  // queue data
      Wire.endTransmission();            // send it
     delay (delay_time);
      break;
    case '3': // write day
        Serial.println ("Day ");
      Wire.beginTransmission(RTC_address); // select device
      Wire.send(day_week_address);          // queue the register
      Wire.send(new_data);                  // queue data
      Wire.endTransmission();            // send it
     delay (delay_time);
      break;
    case '4': // write date of month
        Serial.println ("Day of Month ");
      Wire.beginTransmission(RTC_address); // select device
      Wire.send(date_month_address);          // queue the register
      Wire.send(new_data);                  // queue data
      Wire.endTransmission();            // send it
     delay (delay_time);
      break;
    case '5': // write month
        Serial.println ("Month ");
      Wire.beginTransmission(RTC_address); // select device
      Wire.send(month_address);          // queue the register
      Wire.send(new_data);                  // queue data
      Wire.endTransmission();            // send it
     delay (delay_time);
      break;
    case '6': // write year
        Serial.println ("Year ");
      Wire.beginTransmission(RTC_address); // select device
      Wire.send(year_address);          // queue the register
      Wire.send(new_data);                  // queue data
      Wire.endTransmission();            // send it
     delay (delay_time);
      break;
    case '7': // write square wave
        Serial.println ("Square Wave ");
    Serial.println (RTC_register, HEX);
      Wire.beginTransmission(RTC_address); // select device
      Wire.send(square_address);          // queue the register
      Wire.send(new_data);                  // queue data
      Wire.endTransmission();            // send it
     delay (delay_time);
      break;
    case '8': // write RAM
        Serial.print ("RAM ");
    Serial.println (RTC_register, HEX);
      Wire.beginTransmission(RTC_address); // select device
      Wire.send(RTC_ram_address);          // queue the register
      Wire.send(new_data);                  // queue data
      Wire.endTransmission();            // send it
     delay (delay_time);
      break;
      // all others,do nothing
      Serial.println ("Invalid command ");
    }  // end Switch
  } // end if command == 'F'
  // ************************************

  currentMillis = millis();
  if ( (currentMillis - previousMillis) >= duration){
    previousMillis = currentMillis;  
    // Reset the register pointer  
    Wire.beginTransmission(RTC_address);  
    Wire.send(0x00);  
    Wire.endTransmission();   

    Wire.requestFrom(RTC_address,8 );  
    seconds = Wire.receive();  
    minutes = Wire.receive();  
    hours = Wire.receive();  
    day_week = Wire.receive();  
    date_month = Wire.receive();  
    month = Wire.receive();  
    year = Wire.receive();  
    sqwe = Wire.receive();

    // Seconds 
    // bit 7 = Clock Halt, Enabled = 0, Halt = 1
    // bits 6-5-3 = tens of seconds 0-6,  bits 3-2-1-0 = units of seconds, 0-9 

    // Hours
    // 7=0. 6 = 1 for 12 hr, 0 for 24 hr.
    // bit 5: 12 hr mode = AM(0)/PM(1). 24 hr mode = upper tens of hrs
    // bit 4 =  lower tens of hrs, bits 3-2-1-0 = units of hours (0-9)

    Serial.print ("Hrs " );
    Serial.print (hours, HEX);
    Serial.print (" Mins ");
    Serial.print (minutes, HEX);
    Serial.print (" Secs ");
    Serial.print (seconds, HEX);
    Serial.print (" Day ");
    Serial.print (day_week, HEX);
    Serial.print (" Date ");
    Serial.print (date_month, HEX);
    Serial.print (" Month ");
    Serial.print (month, HEX);
    Serial.print (" Year 20");
    Serial.print (year, HEX);
    Serial.print (" Square Wave ");
    Serial.println (sqwe, HEX);

  }
}

That looks great, don't now how you are going to get time for fencing now your a moderator !

I will try that sketch out when I have had my morning coffee.

The extra byte I need to save is historically the best number of days between events, which could have been 5 events ago, but its simply compared to the latest one at an event time, and the largest is then stored as the best.

Well, we're in slow summer period right now (late July-August), classes start up again Sept 6, I will probably around much less then!

The sketch works, I will be using it as additional test for checking out Bobuino's.

I am still getting oã1?.}¢bz?ÿlc1?.}¢bz?ÿlc1dÞ~¢c{?ÿ when I switch on.

I set my port 27 that I am using to 57600.

Where does the F0xx E0xx C0xx come from ?

port 27? Wow, I hadn't seen above 15.
Is that going to the IDE Serial Monitor or something else?
F012, etc are numbers you send to the serial port.
From the IDE Serial port, you type in F004, Enter, for instance to set the Seconds to 4

Does the stuff you see come out every 5 seconds?
I can send you a screen shot of it running when I get up in a few hours, so I am pretty sure it is something on your end.

I have 2 Arduinos, one runs on port13 and the other on 27, which is handy when I have them both on for wireless/data links.

I have drawn out ( my printer died yesterday ) the memory map of the 1307, and the addresses for each byte say 00H to 07H, so I was wondering where the F and E and C come from?

Yes the symbols appear in short bursts every 5 seconds.

Its definitely something my end :slight_smile: I am going groggy with all this, and have had about 8 hours sleep since Wednesday, so I think I might do some assembly and give my mind a break ! I have 3 projects on the go at once suddenly !

The F, E, and C were added as command discriminators, so I could enter F037 for instance, the software breaks it down as:
F, writing to a Register,
0, register to write to,
3, upper nibble of data to write,
7, lower nibble of data to write,
Then put the 3 & 7 together into 0x37,
and send out via the I2C
0x68, the DS1307 address
0x00, the register
0x37, the data

I then read back the first 8 registers as a group.

C, as in C0 to C7, was going to be used to read a register.
E, as in E008 to E03F , was going to be used to read a RAM address.
I just haven't written them.

Made it easy to enter any value manually for testing, and with reading all 8 back at once and displaying I could see that it was accepted.