// Binary Clock Prototype on the Arduino UNO
//
// Full Binary Clock functionality on the Arduino UNO
// using the DS3231 Real-Time Clock
//#include <ds3231.h>
#include <Wire.h>
#define DS1307_ADDR 0x68
uint8_t seconds, minutes, hours;
#define DISPLAY_REFRESH_RATE 100
#define NUM_LEDS 13
// hour MSD
#define h_MSD_1 12
#define h_MSD_2 11
// hour LSD
#define h_LSD_1 10
#define h_LSD_2 9
#define h_LSD_4 8
#define h_LSD_8 7
// second MSB
#define s_MSB_4 6
#define s_MSB_2 7
#define s_MSB_1 8
// second LSB
#define s_LSB_8 2
#define s_LSB_4 3
#define s_LSB_2 4
#define s_LSB_1 5
uint8_t leds[NUM_LEDS] = {
h_MSD_1,
h_MSD_2,
h_LSD_1,
h_LSD_2,
h_LSD_4,
h_LSD_8,
s_MSB_1,
s_MSB_2,
s_MSB_4,
s_LSB_1,
s_LSB_2,
s_LSB_4,
s_LSB_8
};
void setup() {
Serial.begin(115200);
Wire.begin();
// Set-Time by writing to DS3231
Wire.beginTransmission(DS1307_ADDR); // start communication using DS3231 hex address
Wire.write(0x00);
Wire.write(dectoBcd(seconds)); // write seconds in BCD format, 0100(MSB) and 0111(LSB)
// Wire.write(0x01); // Not required for next address
Wire.write(dectoBcd(minutes));
Wire.endTransmission();
// Configure ALL led pins to be a digital OUTPUT
for (uint8_t i = 0; i < NUM_LEDS; i++)
pinMode(leds[i],OUTPUT);
}
void loop() {
Wire.beginTransmission(DS1307_ADDR);
Wire.write(0); // Start reading from address 0 (seconds)
Wire.endTransmission();
Wire.requestFrom(DS1307_ADDR, 3); // Request seconds, minutes, hours, day, date, month, year
if (Wire.available()) { // Also works when 'if' statement removed
seconds = bcdToDec(Wire.read() & 0x7F); // Mask the high bit of seconds
minutes = bcdToDec(Wire.read() & 0x7F);
// Print to Serial Monitor
if (minutes < 10) Serial.print("0");
Serial.print(minutes);
Serial.print(":");
if (seconds < 10) Serial.print("0"); // Add a '0' to seconds
Serial.print(seconds);
Serial.println();
// Get hour and minute from DS3231
uint8_t h = minutes;
// Obtain LSD of hour and minute
uint8_t sLSB = seconds % 10;
uint8_t hLSD = h % 10;
Serial.print("sLSB: "); Serial.println(sLSB);
//Serial.print("hLSD: "); Serial.println(hLSD);
// Toggle LEDs for hour MSD
if (h >= 10 && h < 20)
digitalWrite(h_MSD_1,HIGH);
else
digitalWrite(h_MSD_1,LOW);
if (h >= 20 && h < 24)
digitalWrite(h_MSD_2,HIGH);
else
digitalWrite(h_MSD_2,LOW);
// Toggle LEDs for hour LSD
if (hLSD == 1 || hLSD == 3 || hLSD == 5 || hLSD == 7 || hLSD == 9)
digitalWrite(h_LSD_1,HIGH);
else
digitalWrite(h_LSD_1,LOW);
if (hLSD == 2 || hLSD == 3 || hLSD == 6 || hLSD == 7)
digitalWrite(h_LSD_2,HIGH);
else
digitalWrite(h_LSD_2,LOW);
if (hLSD == 4 || hLSD == 5 || hLSD == 6 || hLSD == 7)
digitalWrite(h_LSD_4,HIGH);
else
digitalWrite(h_LSD_4,LOW);
if (hLSD == 8 || hLSD == 9)
digitalWrite(h_LSD_8,HIGH);
else
digitalWrite(h_LSD_8,LOW);
// Toggle LEDs for minute MSB
if ((seconds >= 10 & seconds < 20) | (seconds >= 30 & seconds < 40) | (seconds >= 50 & seconds < 60)) { // if seconds = 10 - 19 or 30 - 39 or 50 - 59
digitalWrite(s_MSB_1, HIGH);
}
else {
digitalWrite(s_MSB_1, LOW);
}
if (seconds >= 20 & seconds < 40) { // if seconds = 20 - 39
digitalWrite(s_MSB_2, HIGH);
}
else {
digitalWrite(s_MSB_2, LOW);
}
if (seconds >= 40 & seconds < 60) { // if s = 40 - 59
digitalWrite(s_MSB_4, HIGH);
}
else {
digitalWrite(s_MSB_4, LOW);
}
// Toggle LEDs for minutes LSB
if (sLSB == 1 | sLSB == 3 | sLSB == 5 | sLSB == 7 | sLSB == 9) {
digitalWrite(s_LSB_1, HIGH);
}
else {
digitalWrite(s_LSB_1,LOW);
}
if (sLSB == 2 | sLSB == 3 | sLSB == 6 | sLSB == 7) {
digitalWrite(s_LSB_2,HIGH);
}
else {
digitalWrite(s_LSB_2,LOW);
}
if (sLSB == 4 | sLSB == 5 | sLSB == 6 | sLSB == 7) {
digitalWrite(s_LSB_4,HIGH);
}
else {
digitalWrite(s_LSB_4,LOW);
}
if (sLSB == 8 | sLSB == 9) {
digitalWrite(s_LSB_8,HIGH);
}
else {
digitalWrite(s_LSB_8,LOW);
}
}
delay(DISPLAY_REFRESH_RATE);
}
byte bcdToDec(byte val) {
return ((val / 16 * 10) + (val % 16));
}
byte dectoBcd(byte val) {
return ((val / 10 * 16) + (val % 10)); // This works the same as below
//return ((val / 10 << 4) + (val % 10)); // This works the same as above
}