Digital Clock//RTC 1302 & DHT Sensor

by hetvi in Circuits > Arduino

458 Views, 2 Favorites, 0 Comments

Digital Clock//RTC 1302 & DHT Sensor

images (1).jpg
images.jpg
images (2).jpg

This will teach you how to use a RTC 1302 module and 4 digit seven segment with no prior experience and how to code them together to make a digital clock that'll allow you to switch between the two modes. With just a little math and wiring, you have yourself a digital clock! Below this tutorial is a quick tutorial on a LED chaser with a 4017 IC (Decade counter), 555 timer, and potentiometer to toggle the time. This adds as a little visual touch to the project.

Also optional is a DHT sensor whose library and tutorial you can find here:

https://www.arduino.cc/reference/en/libraries/dht-sensor-library/

This component is quite simple to operate as it simply checks the humidity using true and false statements and then projects it to a serial monitor/the segment display in the same way this tutorial will show you how to display the time from the RTC module.

Supplies

  • RTC (1302)
  • Arduino
  • 4 digit seven segment display
  • DHT sensor
  • Wires

Wire Your Components.

IMG-6101.PNG
7cf47ea7cac7d3a1623aa4ffefa62f6c.png

For the seven segment, I simply followed the pinout as shown in the image above. It wires the same way a single 7 segment display does, but there are four additional pins for each of the digits and one to power all the decimal points. This can be tedious, so ensure you wire correctly! This is a common cathode display where all the cathode connections are joined to logic "0" and thus, are lit by applying a "HIGH" command as demonstrated in the code to light up each segment. No library is required for this project, though there is a 7 seg library available.

Many blogs/research suggest that you use a resistor when connecting each of the digits to the arduino, but I personally found that this limits the brightness of the display by a lot (even with a low 330 ohm), so I avoided it for the entirety of the project.

For the RTC module, connect ground and power to the appropriate pins. The RTC component sources current from a lithium battery in order to keep time until an arduino/power is connected for it to be used and operated. This lithium battery only sinks current into the RTC--not the arduino/program. Then, connect the SCL (Clock), I/O (Data), and RST (Reset) to pins of your choice. I connected them to A5, A4 and A3 respectively. In order to set this component up, download the library called RTC by Makuna: https://github.com/Makuna/Rtc.

These pins do not need to be (though they can be) PWM pins as this is a digital clock and we will only operate where power is either HIGH or LOW.

Code the Components Seperately (optional)

C56078AE-8385-4138-A669-2797465B2C51.jpg
IMG-6022.PNG
IMG-6011.jpg

(to ensure they work). This is a very important step for me as it allows me to understand the components I'm working with and each of the new commands used to communicate between the arduino and component.

Now, the seven segment is quite easy. An array can be implemented to code each of the segments, though I chose to do the manual (g, HIGH), (f,LOW) method for each of the digits (this depends on if your using a common cathode/anode 4 digit/7segment). In the loop, you can run a timer by downloading the TimerOne.h library and use functions like clearLeds to clear the seven segment after displaying a number, pickDigit to light up the appropriate digit, pickNumber to choose what number to display (and divide/remainder operation to choose a number between 0 and 9999) and ensure you have a very quick delay. The segment display is unable to display all the numbers at the same time, so it uses persistence of vision to trick the reader into thinking that it's all at once.

The RTC module has very specific variables that need to be learned before coding the project. It first needs to check if the date time is valid, and this can be done via the serial monitor to ensure the timed displayed is correct. Ensure you reference the code below to check if it is working. Note that the variables hours, minutes, seconds, date and time are seperated.

A little about the OPTIONAL DHT: The DHT works when ions release a substrate that increases the conductivity between electrodes within the sensor. This change in resistance determines the humidity in the air. This sensor reads similar to the RTC where it checks if the humidity/temperature is valid and then prints to the serial monitor. Code is featured below.

Code and Explanation.

2EFFFB9A-E308-4E21-85E1-D7943E2182C8.jpg
download.png
//Include the necessary libraries (RTC by Makuna)
<p>#include 
  <br>#include 
ThreeWire myWire(A4,A5,A3); // IO, SCLK, CE
RtcDS1302
 Rtc(myWire);</p><p>


//Define the variables: Seven segment
int a = 2;
int b = 3;
int c = 4;
int d = 5;
int e = 6;
int f = 7;
int g = 8;
int p = 9;
int d4 = 13;
int d3 = 12;
int d2 = 11;
int d1 = 10;</p><p>

void setup()
{
  //set all the pins of the LED display as output
  pinMode(d1, OUTPUT);
  pinMode(d2, OUTPUT);
  pinMode(d3, OUTPUT);
  pinMode(d4, OUTPUT);
  pinMode(a, OUTPUT);
  pinMode(b, OUTPUT);
  pinMode(c, OUTPUT);
  pinMode(d, OUTPUT);
  pinMode(e, OUTPUT);
  pinMode(f, OUTPUT);
  pinMode(g, OUTPUT);
  pinMode(p, OUTPUT);</p><p>  

Serial.begin(9600); 
  Rtc.Begin();</p><p>   

 RtcDateTime compiled = RtcDateTime(__DATE__, __TIME__);
    printDateTime(compiled);
    Serial.println();</p><p>    if (!Rtc.IsDateTimeValid()) 
    {
        Rtc.SetDateTime(compiled);
    }</p><p>    if (Rtc.GetIsWriteProtected())
    {
        Rtc.SetIsWriteProtected(false);
    }</p><p>    if (!Rtc.GetIsRunning())
    {
        Rtc.SetIsRunning(true);
    }</p><p>    RtcDateTime now = Rtc.GetDateTime();
    if (now < compiled) 
    {
        Rtc.SetDateTime(compiled);
    }
} </p><p>void printDateTime(const RtcDateTime& dt)
{
            dt.Hour(),
            dt.Minute();
}</p><p>void clearLEDs() //clear the 7-segment display screen
{
  digitalWrite(a, LOW);
  digitalWrite(b, LOW);
  digitalWrite(c, LOW);
  digitalWrite(d, LOW);
  digitalWrite(e, LOW);
  digitalWrite(f, LOW);
  digitalWrite(g, LOW);
}</p><p>void pickNumber(int x)
{
  switch(x)
  {
    default: 
    zero(); 
    break;
    case 1: 
    one(); 
    break;
    case 2: 
    two(); 
    break;
    case 3: 
    three(); 
    break;
    case 4: 
    four();
    break;
    case 5: 
    five(); 
    break;
    case 6: 
    six(); 
    break;
    case 7: 
    seven(); 
    break;
    case 8: 
    eight(); 
    break;
    case 9: 
    nine(); 
    break;
  }
} </p><p>void 

pickDigit(int x) //light up a 7-segment display
{
  digitalWrite(d1, HIGH);
  digitalWrite(d2, HIGH);
  digitalWrite(d3, HIGH);
  digitalWrite(d4, HIGH);
  digitalWrite(p,LOW);</p><p>    
  switch(x)
  {
    case 0: 
    digitalWrite(d1, LOW);//Light d1 up 
    break;
    case 1: 
    digitalWrite(d2, LOW);//Light d2 up 
    break;
    case 2: 
    digitalWrite(d3, LOW); //Light d3 up 
    break;
    default:
    digitalWrite(d4, LOW); //Light d4 up
    break;
  }
}</p><p>

#define countof(a) (sizeof(a) / sizeof(a[0]))</p><p>void zero() //the 7-segment led display 0
{
  digitalWrite(a, HIGH);
  digitalWrite(b, HIGH);
  digitalWrite(c, HIGH);
  digitalWrite(d, HIGH);
  digitalWrite(e, HIGH);
  digitalWrite(f, HIGH);
  digitalWrite(g, LOW);
}</p><p>void one() 
{
  digitalWrite(a, LOW);
  digitalWrite(b, HIGH);
  digitalWrite(c, HIGH);
  digitalWrite(d, LOW);
  digitalWrite(e, LOW);
  digitalWrite(f, LOW);
  digitalWrite(g, LOW);
}</p><p>void two() 
{
  digitalWrite(a, HIGH);
  digitalWrite(b, HIGH);
  digitalWrite(c, LOW);
  digitalWrite(d, HIGH);
  digitalWrite(e, HIGH);
  digitalWrite(f, LOW);
  digitalWrite(g, HIGH);
}</p><p>void three()
{
  digitalWrite(a, HIGH);
  digitalWrite(b, HIGH);
  digitalWrite(c, HIGH);
  digitalWrite(d, HIGH);
  digitalWrite(e, LOW);
  digitalWrite(f, LOW);
  digitalWrite(g, HIGH);
}</p><p>void four() 
{
  digitalWrite(a, LOW);
  digitalWrite(b, HIGH);
  digitalWrite(c, HIGH);
  digitalWrite(d, LOW);
  digitalWrite(e, LOW);
  digitalWrite(f, HIGH);
  digitalWrite(g, HIGH);
}</p><p>void five()
{
  digitalWrite(a, HIGH);
  digitalWrite(b, LOW);
  digitalWrite(c, HIGH);
  digitalWrite(d, HIGH);
  digitalWrite(e, LOW);
  digitalWrite(f, HIGH);
  digitalWrite(g, HIGH);
}</p><p>void six() 
{
  digitalWrite(a, HIGH);
  digitalWrite(b, LOW);
  digitalWrite(c, HIGH);
  digitalWrite(d, HIGH);
  digitalWrite(e, HIGH);
  digitalWrite(f, HIGH);
  digitalWrite(g, HIGH);
}</p><p>void seven()
{
  digitalWrite(a, HIGH);
  digitalWrite(b, HIGH);
  digitalWrite(c, HIGH);
  digitalWrite(d, LOW);
  digitalWrite(e, LOW);
  digitalWrite(f, LOW);
  digitalWrite(g, LOW);
 
}</p><p>void eight() 
{
  digitalWrite(a, HIGH);
  digitalWrite(b, HIGH);
  digitalWrite(c, HIGH);
  digitalWrite(d, HIGH);
  digitalWrite(e, HIGH);
  digitalWrite(f, HIGH);
  digitalWrite(g, HIGH);
}</p><p>void nine() 
{
  digitalWrite(a, HIGH);
  digitalWrite(b, HIGH);
  digitalWrite(c, HIGH);
  digitalWrite(d, HIGH);
  digitalWrite(e, LOW);
  digitalWrite(f, HIGH);
  digitalWrite(g, HIGH);
}</p><p>void DEGREES()
{
  digitalWrite(a, HIGH);
  digitalWrite(b, HIGH);
  digitalWrite(c, LOW);
  digitalWrite(d, LOW);
  digitalWrite(e, LOW);
  digitalWrite(f, HIGH);
  digitalWrite(g, HIGH);
}</p><p>

void loop()//call on each of the variables
{
   RtcDateTime now = Rtc.GetDateTime();

   clearLEDs();
   pickDigit(0);
   pickNumber(now.Hour()/10);
   delay(5);
   
   clearLEDs();
   pickDigit(1);
   pickNumber(now.Hour()%10);
   delay(5);
   
   clearLEDs();
   pickDigit(2);
   pickNumber(now.Minute()/10);
   delay(5);
   
   clearLEDs();
   pickDigit(3);
   pickNumber(now.Minute()%10);
   delay(5);</p><p>   


 clearLEDs();
   digitalWrite(p,HIGH);
   delay(1);
   digitalWrite(d2,LOW);
   delay(1);
  

//Check the function of the RTC in the serial monitor
   Serial.print(now.Hour()/10);
   Serial.print(now.Hour()%10);
   Serial.print(":");
   Serial.print(now.Minute()/10);
   Serial.println(now.Minute()%10);
}</p>

Tips/Mistakes I Made

IMG-6104.PNG
  • Incorrectly wiring the seven segment display
  • Silly mistakes; i.e the incorrect function was called upon
  • Forgetting to clear the leds//the clearLeds function
  • using the incorrect RTC library
  • Coding the decimal point; There weren't many resources on how to do this, but I ended up just setting p,HIGH in the void loop where d2 is HIGH
  • Avoid making changes to the wiring when the arduino uno is plugged in. Most people don't, but it's probably better for keeping the arduino and components in good hands.

Optional LED Chaser

IMG-6058.jpg
IMG-6057.jpg
waveforms-tim47.gif

This chaser has a 555 timer configured to work in astable mode- so the output loops in a LOW and HIGH state. In other words, the timer works to generate a square wave as shown in the image above by acting as an oscillator. The capacitor and potentiometer work to change the duration of each of these pulses. This pulsating current is then sinked to the clock input of the decade counter and works to switch this output to the next LED instead of pulsing on just one. Once this pulse reaches the last LED, it resets and repeats the entire process.

Conclusion

IMG-6105.PNG
IMG-6057.jpg

This simple digital clock can be made with an RTC 1302 Module, Arduino, DHT sensor and anode 4 digit seven segment display. Add the LED chaser into this project for a visual appeal.

Code for the RTC and 7 Segment Tests.

//RTC

#include <ThreeWire.h>  
#include <RtcDS1302.h>

ThreeWire myWire(A4,A5,A3); // IO, SCLK, CE
RtcDS1302<ThreeWire> Rtc(myWire);

void setup () 
{
    Serial.begin(9600);

    Serial.print("compiled: ");
    Serial.print(__DATE__);
    Serial.println(__TIME__);

    Rtc.Begin();

    RtcDateTime compiled = RtcDateTime(__DATE__, __TIME__);
    printDateTime(compiled);
    Serial.println();

    if (!Rtc.IsDateTimeValid()) 
    {
        // Common Causes:
        //    1) first time you ran and the device wasn't running yet
        //    2) the battery on the device is low or even missing

        Serial.println("RTC lost confidence in the DateTime!");
        Rtc.SetDateTime(compiled);
    }

    if (Rtc.GetIsWriteProtected())
    {
        Serial.println("RTC was write protected, enabling writing now");
        Rtc.SetIsWriteProtected(false);
    }

    if (!Rtc.GetIsRunning())
    {
        Serial.println("RTC was not actively running, starting now");
        Rtc.SetIsRunning(true);
    }

    RtcDateTime now = Rtc.GetDateTime();
    if (now < compiled) 
    {
        Serial.println("RTC is older than compile time!  (Updating DateTime)");
        Rtc.SetDateTime(compiled);
    }
    else if (now > compiled) 
    {
        Serial.println("RTC is newer than compile time. (this is expected)");
    }
    else if (now == compiled) 
    {
        Serial.println("RTC is the same as compile time! (not expected but all is fine)");
    }
}

void loop () 
{
    RtcDateTime now = Rtc.GetDateTime();

    printDateTime(now);
    Serial.println();

    delay(5000); // five seconds
}

#define countof(a) (sizeof(a) / sizeof(a[0]))

void printDateTime(const RtcDateTime& dt)
{
    char datestring[20];

    snprintf_P(datestring, 
            countof(datestring),
            PSTR("%02u/%02u/%04u %02u:%02u:%02u"),
            dt.Month(),
            dt.Day(),
            dt.Year(),
            dt.Hour(),
            dt.Minute(),
            dt.Second() );
    Serial.print(datestring);
}


//Seven Segment Timer 

#include<TimerOne.h>
int a = 2;
int b = 3;
int c = 4;
int d = 5;
int e = 6;
int f = 7;
int g = 8;
int p = 9;
int d1 = 13;
int d2 = 12;
int d3 = 11;
int d4 = 10;
long n = 0;// n represents the value displayed on the LED display. For example, when n=0, 0000 is displayed. The maximum value is 9999. 
int x = 100;
int del = 5;//Set del as 5; the value is the degree of fine tuning for the clock
int count = 0;//Set count=0. Here count is a count value that increases by 1 every 0.1 second, which means 1 second is counted when the value is 10
void setup()
{
  //set all the pins of the LED display as output
  pinMode(d1, OUTPUT);
  pinMode(d2, OUTPUT);
  pinMode(d3, OUTPUT);
  pinMode(d4, OUTPUT);
  pinMode(a, OUTPUT);
  pinMode(b, OUTPUT);
  pinMode(c, OUTPUT);
  pinMode(d, OUTPUT);
  pinMode(e, OUTPUT);
  pinMode(f, OUTPUT);
  pinMode(g, OUTPUT);
  pinMode(p, OUTPUT);

  Timer1.initialize(100000); // set a timer of length 100000 microseconds (or 0.1 sec – or 10Hz => the led will blink 5 times, 5 cycles of on-and-off, per second)
  Timer1.attachInterrupt( add ); // attach the service routine here
}
/***************************************/ 
void loop()
{
  
  clearLEDs();//clear the 7-segment display screen
  pickDigit(0);//Light up 7-segment display d1
  pickNumber((n/1000));// get the value of thousand
  delay(del);//delay 5ms

  clearLEDs();//clear the 7-segment display screen
  pickDigit(1);//Light up 7-segment display d2
  pickNumber((n%1000)/100);// get the value of hundred
  delay(del);//delay 5ms

  clearLEDs();//clear the 7-segment display screen
  pickDigit(2);//Light up 7-segment display d3
  pickNumber(n%100/10);//get the value of ten
  delay(del);//delay 5ms

  clearLEDs();//clear the 7-segment display screen
  pickDigit(3);//Light up 7-segment display d4
  pickNumber(n%10);//Get the value of single digit
  delay(del);//delay 5ms
}
/**************************************/ 
void pickDigit(int x) //light up a 7-segment display
{
  //The 7-segment LED display is a common-cathode one. So also use digitalWrite to  set d1 as high and the LED will go out
  digitalWrite(d1, HIGH);
  digitalWrite(d2, HIGH);
  digitalWrite(d3, HIGH);
  digitalWrite(d4, HIGH);
  digitalWrite(p, LOW);

  switch(x)
  {
    case 0: 
    digitalWrite(d1, LOW);//Light d1 up 
    break;
    case 1: 
    digitalWrite(d2, LOW); //Light d2 up 
    break;
    case 2: 
    digitalWrite(d3, LOW); //Light d3 up 
    break;
    default: 
    digitalWrite(d4, LOW); //Light d4 up 
    break;
  }
}
//The function is to control the 7-segment LED display to display numbers. Here x is the number to be displayed. It is an integer from 0 to 9 
void pickNumber(int x)
{
  switch(x)
  {
    default: 
    zero(); 
    break;
    case 1: 
    one(); 
    break;
    case 2: 
    two(); 
    break;
    case 3: 
    three(); 
    break;
    case 4: 
    four(); 
    break;
    case 5: 
    five(); 
    break;
    case 6: 
    six(); 
    break;
    case 7: 
    seven(); 
    break;
    case 8: 
    eight(); 
    break;
    case 9: 
    nine(); 
    break;
  }
} 
void clearLEDs() //clear the 7-segment display screen
{
  digitalWrite(a, LOW);
  digitalWrite(b, LOW);
  digitalWrite(c, LOW);
  digitalWrite(d, LOW);
  digitalWrite(e, LOW);
  digitalWrite(f, LOW);
  digitalWrite(g, LOW);
  digitalWrite(p, LOW);
}

void zero() //the 7-segment led display 0
{
  digitalWrite(a, HIGH);
  digitalWrite(b, HIGH);
  digitalWrite(c, HIGH);
  digitalWrite(d, HIGH);
  digitalWrite(e, HIGH);
  digitalWrite(f, HIGH);
  digitalWrite(g, LOW);
}

void one() //the 7-segment led display 1
{
  digitalWrite(a, LOW);
  digitalWrite(b, HIGH);
  digitalWrite(c, HIGH);
  digitalWrite(d, LOW);
  digitalWrite(e, LOW);
  digitalWrite(f, LOW);
  digitalWrite(g, LOW);
}

void two() //the 7-segment led display 2
{
  digitalWrite(a, HIGH);
  digitalWrite(b, HIGH);
  digitalWrite(c, LOW);
  digitalWrite(d, HIGH);
  digitalWrite(e, HIGH);
  digitalWrite(f, LOW);
  digitalWrite(g, HIGH);
}void three() //the 7-segment led display 3
{
  digitalWrite(a, HIGH);
  digitalWrite(b, HIGH);
  digitalWrite(c, HIGH);
  digitalWrite(d, HIGH);
  digitalWrite(e, LOW);
  digitalWrite(f, LOW);
  digitalWrite(g, HIGH);
}

void four() //the 7-segment led display 4
{
  digitalWrite(a, LOW);
  digitalWrite(b, HIGH);
  digitalWrite(c, HIGH);
  digitalWrite(d, LOW);
  digitalWrite(e, LOW);
  digitalWrite(f, HIGH);
  digitalWrite(g, HIGH);
}

void five() //the 7-segment led display 5
{
  digitalWrite(a, HIGH);
  digitalWrite(b, LOW);
  digitalWrite(c, HIGH);
  digitalWrite(d, HIGH);
  digitalWrite(e, LOW);
  digitalWrite(f, HIGH);
  digitalWrite(g, HIGH);
}

void six() //the 7-segment led display 6
{
  digitalWrite(a, HIGH);
  digitalWrite(b, LOW);
  digitalWrite(c, HIGH);
  digitalWrite(d, HIGH);
  digitalWrite(e, HIGH);
  digitalWrite(f, HIGH);
  digitalWrite(g, HIGH);
}

void seven() //the 7-segment led display 7
{
  digitalWrite(a, HIGH);
  digitalWrite(b, HIGH);
  digitalWrite(c, HIGH);
  digitalWrite(d, LOW);
  digitalWrite(e, LOW);
  digitalWrite(f, LOW);
  digitalWrite(g, LOW);
}

void eight() //the 7-segment led display 8
{
  digitalWrite(a, HIGH);
  digitalWrite(b, HIGH);
  digitalWrite(c, HIGH);
  digitalWrite(d, HIGH);
  digitalWrite(e, HIGH);
  digitalWrite(f, HIGH);
  digitalWrite(g, HIGH);
}

void nine() //the 7-segment led display 9
{
  digitalWrite(a, HIGH);
  digitalWrite(b, HIGH);
  digitalWrite(c, HIGH);
  digitalWrite(d, HIGH);
  digitalWrite(e, LOW);
  digitalWrite(f, HIGH);
  digitalWrite(g, HIGH);
}
/*******************************************/
void add()
{
  // Toggle LED
  count ++;
  if(count == 10)
  {
    count = 0;
    n++;
    if(n == 10000)
    {
      n = 0;
    }
  }
}