Go Down

Topic: RTC DS1307 - Am I writing/reading to/from this device? (Read 294 times) previous topic - next topic

rayva

I don't believe I am accessing the RTC DS1307 but rather addressing the UNO and reading its "own clock".
I say this because I can "setTime" (in setup) and display the time correctly for hours, BUT, if I reset the UNO the time resorts back to my original "setTime" value.

I chose DS1302RTC.h because I believe that I can manipulate time elements individually.

I don't think the RTC has made any contribution to my sketch!

I have included relevant code segments:

Code: [Select]

/*
 * These are snippets from my (LONG) sketch, I have only included the relevant RTC sections.
 */
#include <Wire.h>                     
#include <Time.h>
#include <DS1307RTC.h>

// ----------------------------------------------------------------------------
void setup(void) {
  delay(500);

// Manual RTC set
// uncomment to setTime & RTC.set(now()  for first time download - hrs and mins only!
// format is: setTime(hour(),minute(),second(),day(),month(), year());
  setTime(8,17,1,1,1, 1);            // only interested in HH MM
  RTC.set(now());                    // sending the onboard time to the RTC
// !!! this updates my TFTLCD display correctly with 08:17

if (time_t timeNow = now())
  { tft.println("                RTC success!");}
  else
   {tft.setTextColor(RED);
    tft.println("                RTC failed!");}
// !!! never fails?

// ----------------------------------------------------------------------------
void loop(void)
 { 
   CheckButtons();                           // check time adjust buttons every 500mS
       
   if (LoopTick > 0)                         // test 1 minute timer
    {LoopTick --;}
   if (LoopTick == 0)
   { TFTupdate();                            // update display every minute
     LoopTick = 120;
   }
    delay(500);                              // 120 x 500mS = 1 minute
  }
// !!! No apparent problem

// ----------------------------------------------------------------------------
 // Update display every minute
 void TFTupdate()
 {   
    time_t timeNow = now();
   
    tft.fillScreen(BLACK);
    tft.setCursor(0, 50);
    tft.setFont(&FreeSansBold18pt7b);
    tft.setTextSize(2);
    tft.print("   ") ;
    if (hour(timeNow) < 10)
      {tft.print(" ");}                        // leading space for hours
    tft.print(hour(timeNow), DEC);
    tft.print(":") ;   
    if (minute(timeNow) < 10)
      {tft.print("0");}                         // leading 0 for minutes
    tft.print(minute(timeNow), DEC);
 }
// !!! Display updates correctly

// ----------------------------------------------------------------------------
   void CheckButtons()
  {
    time_t timeNow = now();
    uint8_t NewHr = hour(timeNow);
    uint8_t NewMn = minute(timeNow);
   
    if (digitalRead(But_Hrs) == LOW)              // read Hour adj
      { NewHr ++;
        setTime(NewHr, minute(), 1, 1, 1, 1);
        RTC.set(now());
        LoopTick = 1;                             // 0,5 secs to restore display
      }
    if (digitalRead(But_Mins) == LOW)             // read Min adj   
      { NewMn ++;
        setTime(hour(), NewMn, 1, 1, 1, 1);
        RTC.set(now());
        LoopTick = 1;                              // 0,5 secs to restore display
      }           
  }
// !!! Display updates correctly


I have searched far and wide and often find examples which can't even compile!
e.g. DS1302RTC.h/example/setTime.ino fails on 'tmElements_t' does not name a type.

Some examples switch between Time.h and TimeLib.h for one reason or the other.

My wife has threatened to trade me in if I lose any more hair! If you recognize my problem, please assist.

Blue Eyes

You might be using old or mismatched versions of the DS1307RTC and Time libraries, see the note about newer versions on the Arduino Playground .  

I followed the links there, then on to GitHub for the libraries and can confirm that the SetTime example compiles for an Uno.

UKHeliBob

Code: [Select]

  setTime(8, 17, 1, 1, 1, 1);        // only interested in HH MM
  RTC.set(now());                    // sending the onboard time to the RTC

Every time you execute this line of code you set the time to the same value.

Run the program then comment out these 2 lines then compile and upload the program again.
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

cattledog

Code: [Select]
I don't believe I am accessing the RTC DS1307 but rather addressing the UNO and reading its "own clock".

Correct. You are only reading the time with time library commands, and never directly access the rtc memory.

You can use setSyncProvider(RTC.get)  to link the time library internal clock with the RTC. See the time library example "TimeRTC".

Alternatively, you can directly read the RTC time using the syntax of the DS1307 library. See the DS1307 library example "Read Test".

odometer

Here is the code I use to read the date and time from the RTC.
The only library it uses is the Wire library which is already included with the Arduino software.

This should print the date and time to the serial monitor. Remember to select the correct baud rate.
Note that I number the weekdays starting from 1 for Monday. Some people prefer to use 1 for Sunday.

Code: [Select]

#include <Wire.h>

byte ss=0, mi=0, hh=0, wd=6, dd=1, mo=1, yy=0;
 
void setup()
{
  Wire.begin();
  Serial.begin(9600);
 
  // clear /EOSC bit
  // Sometimes necessary to ensure that the clock
  // keeps running on just battery power. Once set,
  // it shouldn't need to be reset but it's a good
  // idea to make sure.
//  Wire.beginTransmission(0x68); // address DS3231
//  Wire.write(0x0E); // select register
//  Wire.write(0b00011100); // write register bitmap, bit 7 is /EOSC
//  Wire.endTransmission();
}
 
void loop()
{
  // ask RTC for the time
  // send request to receive data starting at register 0
  Wire.beginTransmission(0x68); // 0x68 is DS3231 device address
  Wire.write((byte)0); // start at register 0
  Wire.endTransmission();
  Wire.requestFrom(0x68, 7); // request seven bytes (ss, mi, hh, wd, dd, mo, yy)
  // check for a reply from the RTC, and use it if we can
  if (Wire.available() >= 7) {
    // if we're here, we got a reply and it is long enough
    // so now we read the time
    ss = bcd2bin(Wire.read()); // get seconds
    mi = bcd2bin(Wire.read()); // get minutes
    hh = bcd2bin(Wire.read()); // get hours
    wd = bcd2bin(Wire.read());
    dd = bcd2bin(Wire.read());
    mo = bcd2bin(Wire.read());
    yy = bcd2bin(Wire.read());
    // show that we successfully got the time
    Serial.print("Got the time: ");
    printTime();
  }
  else {
    // if we're here, that means we were unable to read the time
    Serial.println("Unable to read time from RTC");
  }
  delay(500);
}

byte bcd2bin(byte x) {
  // converts from binary-coded decimal to a "regular" binary number
  return ((((x >> 4) & 0xF) * 10) + (x & 0xF)) ;
}

void printTime() {
  // just like it says on the tin
  Serial.print ("\'");
  if (yy<10) Serial.print("0"); Serial.print(yy,DEC); Serial.print("-");
  if (mo<10) Serial.print("0"); Serial.print(mo,DEC); Serial.print("-");
  if (dd<10) Serial.print("0"); Serial.print(dd,DEC); Serial.print("(");
  switch (wd) {
    case 1: Serial.print("Mon"); break;
    case 2: Serial.print("Tue"); break;
    case 3: Serial.print("Wed"); break;
    case 4: Serial.print("Thu"); break;
    case 5: Serial.print("Fri"); break;
    case 6: Serial.print("Sat"); break;
    case 7: Serial.print("Sun"); break;
    default: Serial.print("Bad"); 
  }
  Serial.print(") ");
  if (hh<10) Serial.print("0"); Serial.print(hh,DEC); Serial.print(":");
  if (mi<10) Serial.print("0"); Serial.print(mi,DEC); Serial.print(":");
  if (ss<10) Serial.print("0"); Serial.print(ss,DEC); Serial.println("");
}


rayva

Gentlemen, thank you for your assistance.

I started with one suggestion "SyncProvider(RTC.get)" and I get my first error:
(relevant lines)

Code: [Select]

#include <Wire.h>                     // I2C
#include <Time.h>
#include <TimeLib.h>
#include <DS1307RTC.h>
.
.
In void setup:
SyncProvider(RTC.get);
.
.
exit status 1
'SyncProvider' was not declared in this scope


I will explore this option for a while  and will probably end up by byte bashing DS1307 registers.
I, being an ASM dinosaur, this is home ground for me!

I wish you guys would refer to the RTC IC as the RTC. The Arduino board IS NOT a Real Time Clock, it is, at best, an inaccurate emulation of a clock. My board "clock" has lost 3 minutes in 9 hours.

kenwood120s

I wish you guys would refer to the RTC IC as the RTC. The Arduino board IS NOT a Real Time Clock
Where did anyone refer to the Arduino itself as an RTC?

Pretty sure everyone knows that.


cattledog

Quote
I started with one suggestion "SyncProvider(RTC.get)" and I get my first error:
Quote
You can use setSyncProvider(RTC.get)  to link the time library internal clock with the RTC. See the time library example "TimeRTC".You can use setSyncProvider(RTC.get)  to link the time library internal clock with the RTC. See the time library example "TimeRTC".
Only in your mind is SyncProvider(RTC.get) the same as setSyncProvider(RTC.get).

You were directed to library example code for reference. Instead of looking at that, you invented new syntax. People on this forum want to help you, but you must put in the basis work yourself.

rayva

Everywhere! Refer to all RTC classes and you may see where my confusion arises from.

UKHeliBob

Everywhere! Refer to all RTC classes and you may see where my confusion arises from.
I would be interested in links to some examples.
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

rayva

Try this example:

  setTime(19,22,0,14,9,2017);
  RTC.set(now());                    // sending the onboard time to the RTC.

Doesn't go any where near the IC. Note "RTC.set" is not, it is "board.set"

rayva

Dear Cattledog,

My apologies, my cut and paste did not include "set". Your suggestion works.

I will now figure out how to write to  the RTC using SyncProvider. I haven't found a method yet but I will keep on trying.

Thank you for your help.

cattledog

Code: [Select]
RTC.set(now());                    // sending the onboard time to the RTC.
Doesn't go any where near the IC. Note "RTC.set" is not, it is "board.set"


I can assure you that RTC.set(time_t t) is a DS1307.h command addressing the RTC chip. It t the takes the "unix" time stamp as an input, and  that value is returned by the now() command which is part of the time library. It requires the wire library Wire.h to write to the chip.

Please provide an example which compiles and runs which demonstrates that RTC.set(now()) doesn't go anywhere near the IC.

The DS1307 library files and time library files are on your computer. It is always best to refer to them if there is confusion. File path in windows is
Code: [Select]
C:\Users\YOU\Documents\Arduino\libraries\DS1307RTC\DS1307RTC.cpp
C:\Users\YOU\Documents\Arduino\libraries\DS1307RTC\DS1307RTC.h



rayva

"Please provide an example which compiles and runs which demonstrates that RTC.set(now()) doesn't go anywhere near the IC."

Code: [Select]

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

void setup()  {

// First time upload, then comment next 2 lines out for subsequent uploads

  //setTime(10, 54, 0, 15, 9,2017);
  //RTC.set(now());             // manually send time to the RTC.
   
  Serial.begin(9600);
  Serial.print("Reboot  ");
 
  setSyncProvider(RTC.get);   // the function to get the time from the RTC
 
  if(timeStatus()!= timeSet)
     Serial.println("Unable to sync with the RTC");
  else
     Serial.println("RTC has fetched the system time");   
}

void loop()
{
   digitalClockDisplay();
   delay(60000);
}

void digitalClockDisplay(){
  // digital clock display of the time
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print("    ");
  Serial.print(day());
  Serial.print(" ");
  Serial.print(month());
  Serial.print(" ");
  Serial.print(year());
  Serial.println();
}

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);
}

[b]Serial monitor:[/b]
Time set on first upload using:
setTime(10, 54, 0, 15, 9,2017);
RTC.set(now());                    // manually send time to the RTC.

[b]Extracts from Serial monitor log:[/b]

Reboot  RTC has fetched the system time
10:54:00    15 9 2017
10:55:00    15 9 2017
.
.
.
11:37:01    15 9 2017
11:38:01    15 9 2017


-------------------------------------------------
(Power reset, Upload shetch to start serial monitor. Lines below commented out
 to to prevent a repeat of setTime
  //setTime(10, 54, 0, 15, 9,2017);
  //RTC.set(now());             // manually send time to the RTC

Reboot  RTC has fetched the system time
10:54:16    15 9 2017
10:55:16    15 9 2017
.
.
.
11:20:17    15 9 2017
11:21:17    15 9 2017


-------------------------------------------------
(Reset UNO)

Reboot  RTC has fetched the system time
11:22:55    15 9 2017
11:23:55    15 9 2017
.
.
.
11:50:56    15 9 2017
11:51:56    15 9 2017


Please note that the removal of power will set the "clock" back to my original setTime



odometer

@rayva:

If you're still having trouble, you might want to try doing what I describe here:
http://forum.arduino.cc/index.php?topic=53422.msg2031756#msg2031756

It won't help you with the RTC libraries, but then again, those libraries are just a means to an end, and there is more than one means to that end.

Go Up