Skip to content

Instantly share code, notes, and snippets.

@PhirePhly
Created February 17, 2010 09:02
Show Gist options
  • Save PhirePhly/306446 to your computer and use it in GitHub Desktop.
Save PhirePhly/306446 to your computer and use it in GitHub Desktop.
// 2010 Kenneth Finnegan
// Arduino Dot Matrix Clock
// kennethfinnegan.blogspot.com
// http://kennethfinnegan.blogspot.com/2010/02/dot-matrix-arduino-clock.html
// Note: There is commented out code throughout
// that can be uncommented to use a switch on
// pin 13 to toggle the first two columns between
// the date and the current temperature in F read
// from the 10 bit temperature sensor on the DS3232
// A pulldown resistor with the switch to high is
// needed hardware wise. Enjoy.
#include <Wire.h>
// CONSTS
#define DS3232 B1101000
// PINS
#define LED_DATA 11
#define LED_CLK 10
#define LED_LATCH 9
//#define TEMPDISPSEL 13
byte ledcolumn[] = {3,4,5,6,7};
// GLOBAL VARIABLES
byte displaystate[5] = {0};
// FUNCTIONS
void multiplexdisplay();
void downloadtime();
byte DECTOBCD(byte val);
byte BCDTODEC(byte val);
void setup() {
int i;
Wire.begin();
pinMode(LED_DATA, OUTPUT);
pinMode(LED_CLK, OUTPUT);
pinMode(LED_LATCH, OUTPUT);
//pinMode(TEMPDISPSEL, INPUT);
for (i=0; i<5; i++) {
pinMode(ledcolumn[i], OUTPUT);
}
}
void loop() {
downloadtime();
multiplexdisplay();
}
void multiplexdisplay() {
static int prevcol = 0;
int newcol = (prevcol+1)%5;
// Setup the driver for the next column
shiftOut(LED_DATA, LED_CLK, MSBFIRST, displaystate[newcol]);
// Turn off previous column
digitalWrite(ledcolumn[prevcol], LOW);
// Pulse latch to update driver output as quickly as possible
digitalWrite(LED_LATCH, HIGH);
// Turn on new column
digitalWrite(ledcolumn[newcol], HIGH);
digitalWrite(LED_LATCH, LOW);
prevcol = newcol;
}
void downloadtime() {
int second, minute, hour, mhour, day, month;
Wire.beginTransmission(DS3232);
Wire.send(0x00);
Wire.endTransmission();
Wire.requestFrom(DS3232, 6);
second = BCDTODEC(Wire.receive() & 0x7F);
minute = BCDTODEC(Wire.receive());
hour = BCDTODEC(Wire.receive() & 0x3F);
Wire.receive(); // Ignore day of week
day = BCDTODEC(Wire.receive());
month = BCDTODEC(Wire.receive() & 0x7F);
displaystate[0] = month;
displaystate[1] = day;
mhour = (hour%12==0)?12:hour%12;
displaystate[2] = (hour/12)<<6 | mhour;
displaystate[3] = minute;
displaystate[4] = second;
/* Temperature display easter egg!!!
if (digitalRead(TEMPDISPSEL)) {
Wire.beginTransmission(DS3232);
Wire.send(0x11);
Wire.endTransmission();
Wire.requestFrom(DS3232, 2);
long temp = 32;
temp += (Wire.receive() * 9) / 5;
temp += (Wire.receive() >> 5) / 5;
// Convert to Fahrenheit
displaystate[0] = temp/10;
displaystate[1] = temp%10;
// Tell the DS3232 to perform a temperature conversion
// every second instead of the default one every 64 seconds
static int prevconv=0;
if (prevconv != millis()/1000) {
prevconv = millis() / 1000;
Wire.beginTransmission(DS3232);
Wire.send(0x0E);
Wire.send(B00100000);
Wire.endTransmission();
}
}*/
}
// Not actually used, but is needed to update time on DS3232,
// if you were not lazy enough to actually bother implementing
// a button system to set the clock.
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