Go Down

Topic: Arduino Clock with 7-Seg LED, DS1307 & 74HC595 (Read 9090 times) previous topic - next topic

Stanley

Finally made my first useful application for Arduino after so many breadboard prototyping - a 4 digit clock.

It is made using an Arduino, DS1307 realtime clock, four 35mm 7-segments LEDs and driven by four 74HC595 shift registers.

The fun part of this is that I can customize the behavior of the display like blinks or scrolls, add sensors or relays, do time related functions ...  

Wiring is a bit messy...  I have not acquired the skills to etch my own PCB yet... I take one small steps at a time...

Most of the shift register codes are taken from Paul site :- http://www.sqlskills.com/blogs/paulselec/post/Arduino-cascading-shift-registers-to-drive-7-segment-displays.aspx

Needed 7 220R to get consistency LED brightness...


The battery holder is a bit big and took up a lot of real estate on the veroboard...


Details article about the Arduino clock on my blog : http://arduino-for-beginners.blogspot.com/


nRF24L01+ UNO Adapter for Sale :-
http://arduino-for-beginners.blogspot.com/p/nrf-adapter-for-sale.html

Paul Randal


Warren Reeve

Hi Stanley, could you possibly post the sketch/code up?
Many thanks
Warren

PS> Looks good! :)

Stanley

Here is the sketch :-

Realtime clock with 74595 shift registers on 7-segment LED common cathode.

Stanley

Code: [Select]

/*
Original sketch from Paul Electronics 7-segment shift register posting
RTC libraries from http://jeelabs.net/projects/cafe/wiki/RTClib
Setting realtime clock on-compile was from Ladyada.net

Pin assignment on the 74595 to 7-segment common cathode as follows :-

QA - a
QB - b
QC - c
QD - d
QE - e
QF - f
QG - g

3 & 8 are common cathode
resistors is 220R

I just combine both the codes together and make it work...

Can add in temp sensors or a piezo for hourly chime

Stanley
http://arduino-for-beginners.blogspot.com


*/

#include <Wire.h>
#include "RTClib.h"
const int  g_pinData = 10;
const int  g_pinCommLatch = 11;
const int  g_pinClock = 12;
const int ledPin = 13;

RTC_DS1307 RTC;

// Definitions of the 7-bit values for displaying digits
byte g_digits [10];

// Current number being displayed
int g_numberToDisplay = 0;

// Number of shift registers in use
const int g_registers = 4;

// Array of numbers to pass to shift registers
byte g_registerArray [g_registers];

void setup()
{

 Wire.begin();
 RTC.begin();

 // Only set the time on compile if the RTC is not running...
 if ( !RTC.isrunning()) {
   Serial.println("RTC is NOT running!");
   // following line sets the RTC to the date & time this sketch was compiled
   RTC.adjust(DateTime(__DATE__, __TIME__));
 }

 pinMode (g_pinCommLatch, OUTPUT);
 pinMode (g_pinClock, OUTPUT);
 pinMode (g_pinData, OUTPUT);
 pinMode (speakerPin, OUTPUT);
 pinMode (ledPin, OUTPUT);
 
 Serial.begin (9600);

 int a = 1, b = 2, c = 4, d = 8, e = 16, f = 32, g = 64;

 g_digits [0] = a + b + c + d +e + f;
 g_digits [1] = b + c;
 g_digits [2] = a + b + g + e + d;
 g_digits [3] = a + b + g + c + d;
 g_digits [4] = f + g + b + c;
 g_digits [5] = a + f + g + c + d;
 g_digits [6] = a + f + g + c + d + e;
 g_digits [7] = a + b + c;
 g_digits [8] = a + b + c + d + e + f + g;
 g_digits [9] = a + b + c + d + g + f;


} // setup

// Simple function to send serial data to one or more shift registers by iterating backwards through an array.
// Although g_registers exists, they may not all be being used, hence the input parameter.
void sendSerialData (
byte registerCount,  // How many shift registers?
byte *pValueArray)   // Array of bytes with LSByte in array [0]
{
 // Signal to the 595s to listen for data
 digitalWrite (g_pinCommLatch, LOW);

 for (byte reg = registerCount; reg > 0; reg--)
 {
   byte value = pValueArray [reg - 1];

   for (byte bitMask = 128; bitMask > 0; bitMask >>= 1)
   {
     digitalWrite (g_pinClock, LOW);
     digitalWrite (g_pinData, value & bitMask ? HIGH : LOW);
     digitalWrite (g_pinClock, HIGH);
   }
 }
 // Signal to the 595s that I'm done sending
 digitalWrite (g_pinCommLatch, HIGH);
}  // sendSerialData

// Print a message specifying valid inputs, given the number of registers defined and then consume all current input.
void badNumber ()
{
 int dummy;

 Serial.print ("Please enter a number from 0 to ");
 for (int loop = 0; loop < g_registers; loop++)
 {
   Serial.print ("9");
 }
 Serial.println (" inclusive.");

 while (Serial.available () > 0)
 {
   dummy = Serial.read ();
   delay (10);
 }
} //badNumber

// Read a number from the PC with no more digits than the defined number of registers.
// Returns: number to display. If an invalid number was read, the number returned is the current number being displayed
//
int readNumberFromPC ()
{
 byte incomingByte;
 int  numberRead;
 byte incomingCount;

 if (Serial.available () > 0)
 {
   numberRead = 0;
   incomingCount = 0;

   while (Serial.available () > 0)
   {
     incomingByte = Serial.read () - 48;
     incomingCount++;

     if (incomingByte < 0 || incomingByte > 9 || incomingCount > g_registers)
     {
       badNumber ();
       return g_numberToDisplay;
     }

     numberRead = 10 * numberRead + incomingByte;

     // Necessary to get all input in one go.
     delay (10);
   }

   Serial.print ("Now displaying: ");
   Serial.println (numberRead, DEC);

   return numberRead;
 }

 return g_numberToDisplay;
} // readNumberFromPC


void loop()
{
 int hour,minute,sec,disp = 0;

 DateTime now = RTC.now();

 hour = now.hour();
 minute = now.minute();
 sec = now.second();

 /* Serial output debugging for the date & time
 
  Serial.print(now.year(), DEC);
  Serial.print('/');
  Serial.print(now.month(), DEC);
  Serial.print('/');
  Serial.print(now.day(), DEC);
  Serial.print(' ');

  Serial.print(hour);
  Serial.print(':');
  Serial.print(minute);
  Serial.print(':');    
  Serial.print(sec);
  Serial.println();
 */
 
 // Original code
 //g_numberToDisplay = readNumberFromPC ();
 
 
 // Push the hour 2 digits to the left by multiplying 100
 disp = (hour * 100) + minute;
 g_numberToDisplay = disp;

 if (g_numberToDisplay < 10)
 {
   g_registerArray [0] = g_digits [0];
   g_registerArray [1] = g_digits [0];
   g_registerArray [2] = g_digits [0];
   g_registerArray [3] = g_digits [g_numberToDisplay];
 }
 else if (g_numberToDisplay < 100)
 {
   g_registerArray [0] = g_digits [0];
   g_registerArray [1] = g_digits [0];
   g_registerArray [2] = g_digits [g_numberToDisplay / 10];
   g_registerArray [3] = g_digits [g_numberToDisplay % 10];
 }
 else if (g_numberToDisplay < 1000)
 {
   g_registerArray [0] = g_digits [0];
   g_registerArray [1] = g_digits [g_numberToDisplay / 100];
   g_registerArray [2] = g_digits [(g_numberToDisplay % 100) / 10];
   g_registerArray [3] = g_digits [g_numberToDisplay % 10];
 }
 else
 {
   g_registerArray [0] = g_digits [g_numberToDisplay / 1000];
   g_registerArray [1] = g_digits [(g_numberToDisplay % 1000) / 100];
   g_registerArray [2] = g_digits [(g_numberToDisplay % 100) / 10];
   g_registerArray [3] = g_digits [g_numberToDisplay % 10];
 }

 sendSerialData (g_registers, g_registerArray);
 
 // Blink the LED to indicate seconds
 digitalWrite(ledPin,HIGH);
 delay(500);
 digitalWrite(ledPin,LOW);
 delay(500);

} // loop


nRF24L01+ UNO Adapter for Sale :-
http://arduino-for-beginners.blogspot.com/p/nrf-adapter-for-sale.html

SirPoonga

Nice.

This picture with this gave me an idea.  That bike is the Victory Cross Country, I plan on getting that next year.  I noticed how well the LEDs reflected off of the windshield.  So that got me thinking, 7 segment display, GPS, and Arduino I could make a HUD.  Include a button to toggle between time and speed.

herctrap

this is mine version


[media]http://www.youtube.com/watch?v=ERU6gUmrJ3w[/media]
*read the description

Stanley

Nice clock on the fireplace  :)

I should have go for 6 digits instead of four!!!

I modified mine to include a DHT11 temp/relative humidity sensor that will be display for 1 sec each every 10 secs.

I also display the voltage of the SecretVoltmeter as I find that using different 5V power source, like USB power, linear regulated power supply, mobile phone charger and switching power supply, it gives a different temp reading relative of the input voltage.



nRF24L01+ UNO Adapter for Sale :-
http://arduino-for-beginners.blogspot.com/p/nrf-adapter-for-sale.html

Go Up