I bought a bunch of parts awhile back with the good intention of building a bright, blue LED clock for my desk at work. Unfortunately, I got side tracked and the parts sat in my parts bin for a month or two. When I had a little too much caffeine in my system last weekend, I hit the parts box and built that clock. Needless to say it wasn’t as easy as it looked…
Parts List
- 1x Arduino
- 1x Sparkfun Serial 7-Segment Display
- 1x Macetech Chronodot
- 1x Solderless Breadboard
Wiring
- SFE Display Slave Select to Pin 10
- SFE Display MOSI to 11
- SFE Display MISO to 12
- SFE Display SCK to 13
- SFE Display VCC to 5v
- SFE Display GND to GND
- Chronodot SDA to Arduino Pin 4
- Chronodot SCL to Arduino Pin 5
- Chronodot VCC to 5v
- Chronodot GND to GND
Code
The code below is a modified version of the Chronodot demo code. If you uncomment the set_time() call, it will set the time to the HH:MM passed to the function.
#include <Wire.h> #include <String.h> int ss = 10; //csn int mosi = 11; int miso = 12; int sck = 13; void setup() { //chronodot Wire.begin(); //Display Serial.begin(9600); //Set baud Serial.write(0x7F); Serial.write(0x02); //Reset display Serial.write(0x7A); Serial.write(0x76); //Set brightness Serial.write(0x7A); Serial.write(0x01); //Set colon Serial.write(0x77); Serial.write(0x10); // clear /EOSC bit // Sometimes necessary to ensure that the clock // keeps running on just battery power. Once set, // it shouldn't need to be reset but it's a good // idea to make sure. Wire.beginTransmission(0x68); // address DS3231 Wire.send(0x0E); // select register Wire.send(0b00011100); // write register bitmap, bit 7 is /EOSC Wire.endTransmission(); //set_time(23, 59, 00); } void loop() { // send request to receive data starting at register 0 Wire.beginTransmission(0x68); // 0x68 is DS3231 device address Wire.send(0); // start at register 0 Wire.endTransmission(); Wire.requestFrom(0x68, 3); // request three bytes (seconds, minutes, hours) while(Wire.available()) { int seconds = Wire.receive(); // get seconds int minutes = Wire.receive(); // get minutes int hours = Wire.receive(); // get hours seconds = (((seconds & 0b11110000)>>4)*10 + (seconds & 0b00001111)); // convert BCD to decimal minutes = (((minutes & 0b11110000)>>4)*10 + (minutes & 0b00001111)); // convert BCD to decimal hours = (((hours & 0b00100000)>>5)*20 + ((hours & 0b00010000)>>4)*10 + (hours & 0b00001111)); // convert BCD to decimal (assume 24 hour mode) //Serial.print(hours); Serial.print(":"); Serial.print(minutes); Serial.print(":"); Serial.println(seconds); displayTime(hours, minutes); } //Set colon on Serial.write(0x77); Serial.write(0x10); delay(500); //Set colon off Serial.write(0x77); Serial.write(0x01); delay(1000); } byte decToBcd(byte val) { return ( (val/10*16) + (val%10) ); } void displayTime(int hours, int minutes){ String h_str = String(hours); if(h_str.length() < 2){ h_str = '0'+h_str; } String m_str = String(minutes); if(m_str.length() < 2){ m_str = '0'+m_str; } String timeStr = h_str; timeStr.concat(m_str); Serial.write(timeStr.charAt(0)); Serial.write(timeStr.charAt(1)); Serial.write(timeStr.charAt(2)); Serial.write(timeStr.charAt(3)); } void set_time(int hours, int minutes, int seconds) { Wire.beginTransmission(104); Wire.send(0); Wire.send(decToBcd(seconds)); Wire.send(decToBcd(minutes)); Wire.send(decToBcd(hours)); Wire.endTransmission(); } |
We need to see if we can grab the i2c pins on the ATMEGA328 that is on the back of that 7-segment display and have it talk directly to the chronodot – it would greatly reduce the parts cost…and be the basis for an awesome digital watch :)