Create a gist now

Instantly share code, notes, and snippets.

// 4 digit 7 segment clock
// 2010 kennethfinnegan.blogspot.com
// http://kennethfinnegan.blogspot.com/2010/01/arduino-four-digit-clock.html
#include <Wire.h>
#define DS1307 B1101000
// LED Driver pins
#define LEDDATA 12
#define LEDCLOCK 11
#define LEDLATCH 10
// Anode pins for the 4 digits
int digits[] = {2,3,4,5};
// bitfield for the digits 0-9
// This was built based on how I happened to plug
// in the wires between the driver and display.
// You'll want to rebuild this for your pinout
byte segments[] = {
B00111111,
B00100100,
B10001111,
B10100111,
B10110100,
B10110011,
B10111011,
B00100110,
B10111111,
B10110110};
byte second=0, minute=0, hour=0;
void updatedisplay();
byte DECTOBCD(byte val);
byte BCDTODEC(byte val);
void setup() {
Wire.begin();
pinMode(digits[0], OUTPUT);
pinMode(digits[1], OUTPUT);
pinMode(digits[2], OUTPUT);
pinMode(digits[3], OUTPUT);
pinMode(LEDDATA, OUTPUT);
pinMode(LEDCLOCK, OUTPUT);
pinMode(LEDLATCH, OUTPUT);
// I didn't bother using the latch
// But you could to get better brightness
digitalWrite(LEDLATCH, HIGH);
}
byte curdig = 0, prevdig = 0;
void loop() {
// Display the next digit
updatedisplay();
}
void updatedisplay() {
// Update time from DS1307
Wire.beginTransmission(DS1307);
Wire.send(0x00);
Wire.endTransmission();
Wire.requestFrom(DS1307, 3);
second = BCDTODEC(Wire.receive() & 0x7f);
minute = BCDTODEC(Wire.receive());
hour = BCDTODEC(Wire.receive() & 0x3f);
byte temphour = hour % 12;
if (temphour == 0) {
// Not zero based, not one based, but 12. What the F, world?
temphour = 12;
}
byte digitvalue, bitfield;
switch (curdig) {
case 0: // low minute digit
digitvalue = minute % 10;
bitfield = segments[digitvalue];
break;
case 1: // high minute digit
digitvalue = minute / 10;
bitfield = segments[digitvalue];
break;
case 2: // low hour digit
digitvalue = temphour % 10;
bitfield = segments[digitvalue];
// Blink the decimal to show the clock is running
bitfield |= (second & 1) << 6;
break;
case 3: // high hour digit
digitvalue = temphour / 10;
// Blank on 0
bitfield = digitvalue ? segments[digitvalue] : 0;
break;
}
// Turn off the previous digit
digitalWrite(digits[prevdig], LOW);
// Setup the new digit
shiftOut(LEDDATA, LEDCLOCK, MSBFIRST, bitfield);
// Turn on the new digit
digitalWrite(digits[curdig], HIGH);
// Leave it on for the next cycle of time updates, etc
prevdig = curdig;
// Move on to the next digit for the next call
curdig = (curdig+1) % 4;
}
byte DECTOBCD(byte val) {
return ((val/10)<<4) + (val%10);
}
byte BCDTODEC(byte val) {
return (val>>4) * 10 + (val & 0xf);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment