Pages: [1] 2 3   Go Down
Author Topic: EEPROM overwite previous data?  (Read 2626 times)
0 Members and 1 Guest are viewing this topic.
Cape Town South Africa
Offline Offline
Edison Member
*
Karma: 19
Posts: 1217
A newbie with loads of posts, and still so much to learn !
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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 :-
Code:
/*
 * 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) ");   
}








Logged

With my mobile phone I can call people and talk to them -  how smart can you get ?

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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.

Quote
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.

Quote
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).
Logged

Cape Town South Africa
Offline Offline
Edison Member
*
Karma: 19
Posts: 1217
A newbie with loads of posts, and still so much to learn !
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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 60*60*24 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......
« Last Edit: August 11, 2011, 10:50:30 am by Boffin1 » Logged

With my mobile phone I can call people and talk to them -  how smart can you get ?

Cape Town South Africa
Offline Offline
Edison Member
*
Karma: 19
Posts: 1217
A newbie with loads of posts, and still so much to learn !
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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 :-)

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

With my mobile phone I can call people and talk to them -  how smart can you get ?

Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 524
Posts: 26473
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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?
Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Cape Town South Africa
Offline Offline
Edison Member
*
Karma: 19
Posts: 1217
A newbie with loads of posts, and still so much to learn !
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.....?
Logged

With my mobile phone I can call people and talk to them -  how smart can you get ?

Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 524
Posts: 26473
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.

Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Cape Town South Africa
Offline Offline
Edison Member
*
Karma: 19
Posts: 1217
A newbie with loads of posts, and still so much to learn !
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks Rob

I will have a look at that now
Logged

With my mobile phone I can call people and talk to them -  how smart can you get ?

Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 524
Posts: 26473
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 524
Posts: 26473
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

After declaring the addresses & variables, do this to read the current time:
Code:
// 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.
Code:
/*
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);
  }
}



Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Cape Town South Africa
Offline Offline
Edison Member
*
Karma: 19
Posts: 1217
A newbie with loads of posts, and still so much to learn !
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

With my mobile phone I can call people and talk to them -  how smart can you get ?

Cape Town South Africa
Offline Offline
Edison Member
*
Karma: 19
Posts: 1217
A newbie with loads of posts, and still so much to learn !
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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 :-
Code:

// 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();
« Last Edit: August 12, 2011, 07:07:40 pm by Boffin1 » Logged

With my mobile phone I can call people and talk to them -  how smart can you get ?

Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 524
Posts: 26473
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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 5*10  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.
Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 524
Posts: 26473
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.

Code:
/*
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);

  }
}
Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Cape Town South Africa
Offline Offline
Edison Member
*
Karma: 19
Posts: 1217
A newbie with loads of posts, and still so much to learn !
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

With my mobile phone I can call people and talk to them -  how smart can you get ?

Pages: [1] 2 3   Go Up
Jump to: