Help: RTC for counting up

hello everyone,
Am proceeding well with my arduino projects, programming with arduino is funny for beginners and challenging as well...anyway let me go strait to my point:

This time i want to use Real Time Clock (RTC-DS1307 ) for counting up number of days from 00 day to 99 days i.e counting up ( incrementing by one number) at the interval of 24hrs.
i have

  1. Arduino Uno
  2. RTC-ds1307
  3. crystal 32.768kHz
  4. 2 pull up resistor each 2.2k
  5. 2 Seven Segment Displays(Common Cathode)
  6. 2 shift register, 74HC595
  7. 16 resistor of 680Ohm for connection between shift registers and seven segment displays

up to now i can to count from 00 to 99 with the use of millis(), but problem comes as i introduce RTC.....i want to use RTC for assisting counting number of days because millis() is messing on me once the arduino power is off.

find attachment of my diagram it is in pdf please try to zoom it and u will see it very clear, in my diagram i put two pull up resistor of 2.2k. Other people were arguing somewhere that "it not correct to put pull up resistor with the reason that it is embedded in AtMega328". Someone to justify this

below i have a arduino sketch for counting, anyone with the help in both diagram and arduino sketch i will appriciate.

#define LATCH 12
#define CLK 13
#define DATA 11
#include <Wire.h>
#include "RTClib.h"

RTC_DS1307 rtc;

//This is the dec value of each number stored in an array by index num

int i,j;
int digitOne[10] = {63,6,91,79,102,109,125,7,127,103};
int digitTwo[10]= {63,6,91,79,102,109,125,7,127,103};

void setup(){
  Serial.begin(57600);
  pinMode(LATCH, OUTPUT);
  pinMode(CLK, OUTPUT);
  pinMode(DATA, OUTPUT);

#ifdef AVR
  Wire.begin();
#else
  Wire1.begin(); // Shield I2C pins connect to alt I2C bus on Arduino Due
#endif
  rtc.begin();
  
}

void loop(){
  DateTime now = rtc.now();
  for(int i=0; i<10; i++){
    for(int j=0; j<10; j++){
      digitalWrite(LATCH, LOW);
      shiftOut(DATA, CLK, MSBFIRST, ~digitTwo[j]); // digitTwo
      shiftOut(DATA, CLK, MSBFIRST, ~digitOne[i]); // digitOne
      digitalWrite(LATCH, HIGH);
      unsigned long startTime = millis();
      while (millis() - startTime < now.day()); //wait 1 day(24hrs)
    }
  }
}

thanks

DIAGRAM.pdf (87.6 KB)

Are you familiar with Time.h library?

BulldogLowell:
Are you familiar with Time.h library?

not so much BulldogLowell,

i have just basic knowledge of RTC, help me please if am wrong somewhere,

walterkim:
i have just basic knowledge of RTC, help me please if am wrong somewhere,

Install the library on your IDE and play with the examples... you will certainly find it straightforward to solve this problem.

You can do this without using the Time.h library, and in some ways it may be more simple.

You know the time from reading the RTC. Since you are using RTClib.h you may want to work with now.unixtime() rather than handling day and month rollovers. The now.unixtime() function is one of the advantages of using RTClib.h and doesn't require the time library.

You will have a known starting point, and every 86400 seconds you can increment your counter. You can also use
now.unixtime()/86400UL which will give you days since since midnight 1/1/1970 and increment on that value.

The Time Keeper Register (see: http://datasheets.maximintegrated.com/en/ds/DS1307.pdf) keeps the date, wouldn't be easier just to track that? There are plenty of articles on "days between two dates"...google just gave me over 82 million hits. Surely one would work.

thats guts for your good advices, i have tried to go through time.lib as advised but am still have some difficulties,
there are functions like hour(t), day(t), (now.unixtime() + 86400), now.day(). i think i need to use them in my arduino counter sketch for counting at the interval of every 24hrs, unfortunately its not taking me to the right track yet.
may you please tell me how can i go on with this code, i will appreciate.

#define LATCH 12
#define CLK 13
#define DATA 11

// Date and time functions using a DS1307 RTC connected via I2C and Wire lib

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

RTC_DS1307 rtc;

//This is the hex value of each number stored in an array by index num
int digitOne[10] = {63,6,91,79,102,109,125,7,127,103};
int digitTwo[10]= {63,6,91,79,102,109,125,7,127,103};

int i;

void setup(){
 
  pinMode(LATCH, OUTPUT);
  pinMode(CLK, OUTPUT);
  pinMode(DATA, OUTPUT);
   Serial.begin(57600);
#ifdef AVR
  Wire.begin();
#else
  Wire1.begin(); // Shield I2C pins connect to alt I2C bus on Arduino Due
#endif
  rtc.begin();
 
}

void loop(){
 
  DateTime now = rtc.now();
  
  for(int i=0; i<10; i++){
    for(int j=0; j<10; j++){
      digitalWrite(LATCH, LOW);
      shiftOut(DATA, CLK, MSBFIRST, ~digitTwo[j]); // digitTwo
      shiftOut(DATA, CLK, MSBFIRST, ~digitOne[i]); // digitOne
      digitalWrite(LATCH, HIGH);
      now.day();//wait for 32hrs
      //now.unixtime() + 86400;//waiting for 24hrs
    }
  }
}

thanks
walter

look to create your initial start time from which you want to count:

startTime = now.unixtime();

then compare by dividing Unix time elapsed by the number of seconds in a day:

int dayCount = (now.unixtime() - startTime) / 86400;

econjack, thank you for your good documents on time keeper register, i appreciate that....
what i have i my mind is that the RTC suppose to count 86400second(24hrs) and signal arduino to increment seven segment by one value. so if the arduino power is off may be for 48hrs then RTC continues to run and once seven segment gets power that is arduimo power is back, i expect seven segment display to show day 3 instead of the day 2 hwen the power was off....
please assist me where am wrong in the above code(rply #7)

BulldogLowell, do u mean i put like this?

void loop(){
 
  DateTime now = rtc.now();
  
  for(int i=0; i<10; i++){
    for(int j=0; j<10; j++){
      digitalWrite(LATCH, LOW);
      shiftOut(DATA, CLK, MSBFIRST, ~digitTwo[j]); // digitTwo
      shiftOut(DATA, CLK, MSBFIRST, ~digitOne[i]); // digitOne
      digitalWrite(LATCH, HIGH);
      //now.day();//wait for 32hrs
      
      unsigned long startTime = now.unixtime();
      int dayCount = (now.unixtime() - startTime)/ 86400;//waiting for 24hrs
      dayCount++;
  

    }
    
      }
    }

I think you want to so something like this (won't compile and I cannot test):

//other stuff
unsigned long startTime;

void setup()
{
  startTime = now.unixtime();
}
  void loop()
{
  int dayCount = (now.unixtime() - startTime)/ 86400;
  displayDaycount(dayCount);
}
displayDaycount(int numberOfDays)
{
  //put your display update here
}

if you want the counter to survive a power cycle, you have to store the startTime in some form of persistent memory (e.g. EEPROM).

i have tried(below code) wht u have told me to do but its not working still,

i think may be i will need to put dayCount++ somewhere for the increment, also there is an error in this code its states "now was not declared in this scope "

#define LATCH 12
#define CLK 13
#define DATA 11

int i,j;
int digitOne[10] = {63,6,91,79,102,109,125,7,127,103};
int digitTwo[10]= {63,6,91,79,102,109,125,7,127,103};

//other stuff
unsigned long startTime;

void setup()
{
  startTime = now.unixtime();
  pinMode(LATCH, OUTPUT);
  pinMode(CLK, OUTPUT);
  pinMode(DATA, OUTPUT);
}
  void loop()
{
  int dayCount = (now.unixtime() - startTime)/ 86400;
  displayDaycount(dayCount);
}
displayDaycount(int numberOfDays)
{
  for(int i=0; i<10; i++){
    for(int j=0; j<10; j++){
      digitalWrite(LATCH, LOW);
      shiftOut(DATA, CLK, MSBFIRST, ~digitTwo[j]); // digitTwo
      shiftOut(DATA, CLK, MSBFIRST, ~digitOne[i]); // digitOne
      digitalWrite(LATCH, HIGH);
      
        }
  }
}

help please

Merry Christmas

also there is an error in this code its states "now was not declared in this scope "

Please post your entire code, but it look like you left somethingimportant out of the latest version.

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

RTC_DS1307 rtc;

cattledog,this is my whole code, but still showing that error

#define LATCH 12
#define CLK 13
#define DATA 11

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

RTC_DS1307 rtc;

int i,j;
int digitOne[10] = {63,6,91,79,102,109,125,7,127,103};
int digitTwo[10]= {63,6,91,79,102,109,125,7,127,103};


unsigned long startTime;

void setup()
{
  
   Serial.begin(57600);
#ifdef AVR
  Wire.begin();
#else
  Wire1.begin(); // Shield I2C pins connect to alt I2C bus on Arduino Due
#endif
  rtc.begin();

  startTime = now.unixtime();
  pinMode(LATCH, OUTPUT);
  pinMode(CLK, OUTPUT);
  pinMode(DATA, OUTPUT);
}
  void loop()
{
  int dayCount = (now.unixtime() - startTime)/ 86400;
  displayDaycount(dayCount);
}
displayDaycount(int numberOfDays)
{
  for(int i=0; i<10; i++){
    for(int j=0; j<10; j++){
      digitalWrite(LATCH, LOW);
      shiftOut(DATA, CLK, MSBFIRST, ~digitTwo[j]); // digitTwo
      shiftOut(DATA, CLK, MSBFIRST, ~digitOne[i]); // digitOne
      digitalWrite(LATCH, HIGH);
      
        }
  }
}

I got your program to compile with the changes I have noted.

#define LATCH 12
#define CLK 13
#define DATA 11

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

RTC_DS1307 RTC; //RTC needs to be in Capitol letters

//int i,j; //comment out, declared locally in displayDaycount function

int digitOne[10] = {
  63,6,91,79,102,109,125,7,127,103};
int digitTwo[10]= {
  63,6,91,79,102,109,125,7,127,103};


unsigned long startTime;



void setup()
{

  Serial.begin(57600);
#ifdef AVR
  Wire.begin();
#else
  Wire1.begin(); // Shield I2C pins connect to alt I2C bus on Arduino Due
#endif
  RTC.begin();

  DateTime now = RTC.now();//reads RTC for startTime

  startTime = now.unixtime();
  pinMode(LATCH, OUTPUT);
  pinMode(CLK, OUTPUT);
  pinMode(DATA, OUTPUT);
}
void loop()

{
  DateTime now = RTC.now();//reads RTC for current time
  int dayCount = (now.unixtime() - startTime)/ 86400L;//make 86400 long 
  displayDaycount(dayCount);
}

void displayDaycount(int numberOfDays)//function need void type
{
  for(int i=0; i<10; i++){
    for(int j=0; j<10; j++){
      digitalWrite(LATCH, LOW);
      shiftOut(DATA, CLK, MSBFIRST, ~digitTwo[j]); // digitTwo
      shiftOut(DATA, CLK, MSBFIRST, ~digitOne[i]); // digitOne
      digitalWrite(LATCH, HIGH);

    }
  }
}

cattledog:
I got your program to compile with the changes I have noted.

hi cattledog,its still not working with those changes....."RTC " and "Counting using delay" are working well separately but let me ask this.... i have a delay function of 1000msec i.e delay(1000) and i would like to replace it with RTC i.e now.second()==1; what should i do ?

i have tried the below code but its still not working...any help there i will appriciate..

delay(1000);
unsigned long startTime=now.second();
while (now.second() - startTime < 1)

thanx
walter

Unless you repeat now = RTC.now();, the value of now.second() will not get updated, so the loop will never end.

i have succeeded to count after every three seconds, but the way i arrange i don't know if the code is smart enough, please check the below code........

int digitOne[10]= {192,249,164,176,153,146,130,248,128,152};
int digitTwo[10]= {192,249,164,176,153,146,130,248,128,152};


void loop{

 if(now.second()==3){
  
      digitalWrite(LATCH, LOW);
      shiftOut(DATA, CLK, MSBFIRST, ~digitTwo[0]); // digitTwo
      shiftOut(DATA, CLK, MSBFIRST, ~digitOne[1]); // digitOne
      digitalWrite(LATCH, HIGH);
    }
  
  if(now.second()==6){
  
      digitalWrite(LATCH, LOW);
      shiftOut(DATA, CLK, MSBFIRST, ~digitTwo[0]); // digitTwo
      shiftOut(DATA, CLK, MSBFIRST, ~digitOne[2]); // digitOne
      digitalWrite(LATCH, HIGH);
    }
  
  if(now.second()==9){
  
      digitalWrite(LATCH, LOW);
      shiftOut(DATA, CLK, MSBFIRST, ~digitTwo[0]); // digitTwo
      shiftOut(DATA, CLK, MSBFIRST, ~digitOne[3]); // digitOne
      digitalWrite(LATCH, HIGH);
    }
  
  if(now.second()==12){
  
      digitalWrite(LATCH, LOW);
      shiftOut(DATA, CLK, MSBFIRST, ~digitTwo[0]); // digitTwo
      shiftOut(DATA, CLK, MSBFIRST, ~digitOne[4]); // digitOne
      digitalWrite(LATCH, HIGH);
    }
  
  if(now.second()==15){
  
      digitalWrite(LATCH, LOW);
      shiftOut(DATA, CLK, MSBFIRST, ~digitTwo[0]); // digitTwo
      shiftOut(DATA, CLK, MSBFIRST, ~digitOne[5]); // digitOne
      digitalWrite(LATCH, HIGH);
    }
  
  if( now.second()==18){
  
      digitalWrite(LATCH, LOW);
      shiftOut(DATA, CLK, MSBFIRST, ~digitTwo[0]); // digitTwo
      shiftOut(DATA, CLK, MSBFIRST, ~digitOne[6]); // digitOne
      digitalWrite(LATCH, HIGH);
    }
  
  if(now.second()==21){
  
      digitalWrite(LATCH, LOW);
      shiftOut(DATA, CLK, MSBFIRST, ~digitTwo[0]); // digitTwo
      shiftOut(DATA, CLK, MSBFIRST, ~digitOne[7]); // digitOne
      digitalWrite(LATCH, HIGH);
    }
  
  if(now.second()==24){
  
      digitalWrite(LATCH, LOW);
      shiftOut(DATA, CLK, MSBFIRST, ~digitTwo[0]); // digitTwo
      shiftOut(DATA, CLK, MSBFIRST, ~digitOne[8]); // digitOne
      digitalWrite(LATCH, HIGH);
    }
  
  if(now.second()==27){
  
      digitalWrite(LATCH, LOW);
      shiftOut(DATA, CLK, MSBFIRST, ~digitTwo[0]); // digitTwo
      shiftOut(DATA, CLK, MSBFIRST, ~digitOne[9]); // digitOne
      digitalWrite(LATCH, HIGH);
    }
  
  if(now.second()==30){
  
      digitalWrite(LATCH, LOW);
      shiftOut(DATA, CLK, MSBFIRST, ~digitTwo[1]); // digitTwo
      shiftOut(DATA, CLK, MSBFIRST, ~digitOne[0]); // digitOne
      digitalWrite(LATCH, HIGH);
    }
  
  if(now.second()==33){
  
      digitalWrite(LATCH, LOW);
      shiftOut(DATA, CLK, MSBFIRST, ~digitTwo[1]); // digitTwo
      shiftOut(DATA, CLK, MSBFIRST, ~digitOne[1]); // digitOne
      digitalWrite(LATCH, HIGH);
    }
  
  if(now.second()==36){
  
      digitalWrite(LATCH, LOW);
      shiftOut(DATA, CLK, MSBFIRST, ~digitTwo[1]); // digitTwo
      shiftOut(DATA, CLK, MSBFIRST, ~digitOne[2]); // digitOne
      digitalWrite(LATCH, HIGH);
    }
  
  if(now.second()==39){
  
      digitalWrite(LATCH, LOW);
      shiftOut(DATA, CLK, MSBFIRST, ~digitTwo[1]); // digitTwo
      shiftOut(DATA, CLK, MSBFIRST, ~digitOne[3]); // digitOne
      digitalWrite(LATCH, HIGH);
    }
  
  if(now.second()==42){
  
      digitalWrite(LATCH, LOW);
      shiftOut(DATA, CLK, MSBFIRST, ~digitTwo[1]); // digitTwo
      shiftOut(DATA, CLK, MSBFIRST, ~digitOne[4]); // digitOne
      digitalWrite(LATCH, HIGH);
    }
  
  if(now.second()==45){
  
      digitalWrite(LATCH, LOW);
      shiftOut(DATA, CLK, MSBFIRST, ~digitTwo[1]); // digitTwo
      shiftOut(DATA, CLK, MSBFIRST, ~digitOne[5]); // digitOne
      digitalWrite(LATCH, HIGH);
    }
  

  if(now.second()==48){
  
      digitalWrite(LATCH, LOW);
      shiftOut(DATA, CLK, MSBFIRST, ~digitTwo[1]); // digitTwo
      shiftOut(DATA, CLK, MSBFIRST, ~digitOne[6]); // digitOne
      digitalWrite(LATCH, HIGH);
    }
     
     
  if(now.second()== 51){
  
      digitalWrite(LATCH, LOW);
      shiftOut(DATA, CLK, MSBFIRST, ~digitTwo[1]); // digitTwo
      shiftOut(DATA, CLK, MSBFIRST, ~digitOne[7]); // digitOne
      digitalWrite(LATCH, HIGH);
    }
    
    
  if(now.second()== 54){
  
      digitalWrite(LATCH, LOW);
      shiftOut(DATA, CLK, MSBFIRST, ~digitTwo[1]); // digitTwo
      shiftOut(DATA, CLK, MSBFIRST, ~digitOne[8]); // digitOne
      digitalWrite(LATCH, HIGH);
    }
    
    
  if(now.second()== 57){
  
      digitalWrite(LATCH, LOW);
      shiftOut(DATA, CLK, MSBFIRST, ~digitTwo[1]); // digitTwo
      shiftOut(DATA, CLK, MSBFIRST, ~digitOne[9]); // digitOne
      digitalWrite(LATCH, HIGH);
    }
    
    
  if(now.second()== 59){
  
      digitalWrite(LATCH, LOW);
      shiftOut(DATA, CLK, MSBFIRST, ~digitTwo[2]); // digitTwo
      shiftOut(DATA, CLK, MSBFIRST, ~digitOne[0]); // digitOne
      digitalWrite(LATCH, HIGH);
    }
    
    
  if(now.second()== 0){
  
      digitalWrite(LATCH, LOW);
      shiftOut(DATA, CLK, MSBFIRST, ~digitTwo[2]); // digitTwo
      shiftOut(DATA, CLK, MSBFIRST, ~digitOne[1]); // digitOne
      digitalWrite(LATCH, HIGH);
    }
    
    
  if(now.second()== 1){
  
      digitalWrite(LATCH, LOW);
      shiftOut(DATA, CLK, MSBFIRST, ~digitTwo[0]); // digitTwo
      shiftOut(DATA, CLK, MSBFIRST, ~digitOne[0]); // digitOne
      digitalWrite(LATCH, HIGH);
    }
}

That looks very clumsy.

To start with these arrays are the same

int digitOne[10]= {192,249,164,176,153,146,130,248,128,152};
int digitTwo[10]= {192,249,164,176,153,146,130,248,128,152};

so you really only need one of them which should be defined as const byte anyway. You don't yet have a problem with memory but using one array of bytes will take one quarter of the memory so it is a good habit to get into.

As to the program itself why can't you use the value of now.seconds() as the index to the digit arrays directly ? I assume that the digit arrays hold the pattern of LED segments needed to display each digit from 0 to 9. Is that right ?