#pragma GCC push_options
#pragma GCC optimize ("O1")
// I2C
#include <Wire.h>
// RTC
#include <DS3231.h>
// Use 74HC164 shift registers
// Init DS3231 RTC
DS3231 rtc;
bool h12;
bool hPM;
int btnHr = 10;
int btnMin = 9;
int btnTemp = 8;
int regData = 5;
int regClk = 6;
void setup() {
// Buttons
for(int i = 8; i < 11; i++)
pinMode(i,INPUT);
// Shift register
for(int i = 5; i < 7; i++)
pinMode(i,OUTPUT);
// RTC
Wire.begin();
rtc.setClockMode(false); // 24 hour
// Check RTC for problems
if(!rtc.oscillatorCheck()) {
// RTC NOT OK, set values to known ones
rtc.setMinute(0);
rtc.setHour(12);
}
}
byte minute, hour, previousMinute, previousHour, needsUpdate, previousTemp, decTemp;
const uint8_t seg[] = {
// gfedcba
0b0111111, // 0
0b0000110, // 1
0b1011011, // 2
0b1001111, // 3
0b1100110, // 4
0b1101101, // 5
0b1111101, // 6
0b0000111, // 7
0b1111111, // 8
0b1101111, // 9
0b1100011, // degree
0b0111001, // C
0b1000000 // -
};
void loop() {
// Get time from RTC
minute = rtc.getMinute();
hour = rtc.getHour(h12, hPM);
// Avoid refreshing if possible since we have no latch
if(previousMinute != minute || previousHour != hour || needsUpdate != 0) {
previousMinute = minute;
previousHour = hour;
needsUpdate = 0;
shiftOut(regData, regClk, MSBFIRST, seg[minute%10]);
shiftOut(regData, regClk, MSBFIRST, seg[minute/10]);
shiftOut(regData, regClk, MSBFIRST, seg[hour%10]);
shiftOut(regData, regClk, MSBFIRST, seg[hour/10]);
} else {delay(10);}
// Hour up
if(digitalRead(10)) {
if(rtc.getHour(h12, hPM) == 23) {
rtc.setHour(0);
} else {
rtc.setHour(rtc.getHour(h12, hPM) + 1);
}
while(digitalRead(10));
}
// Minute up, set seconds to 0
if(digitalRead(9)) {
if(rtc.getMinute() == 59) {
rtc.setMinute(0);
}
rtc.setSecond(0);
rtc.setMinute(rtc.getMinute() + 1);
while(digitalRead(9));
}
if(digitalRead(8)) { needsUpdate = 1; }
// Show temperature reading from RTC
while(digitalRead(8)) {
decTemp = (int)rtc.getTemperature();
if(previousTemp != decTemp || needsUpdate != 0) {
previousTemp = decTemp;
needsUpdate = 0;
if(decTemp > -9999) {
// OK
shiftOut(regData, regClk, MSBFIRST, seg[11]);
shiftOut(regData, regClk, MSBFIRST, seg[10]);
shiftOut(regData, regClk, MSBFIRST, seg[decTemp%10]);
shiftOut(regData, regClk, MSBFIRST, seg[decTemp/10]);
} else {
shiftOut(regData, regClk, MSBFIRST, seg[11]);
shiftOut(regData, regClk, MSBFIRST, seg[10]);
shiftOut(regData, regClk, MSBFIRST, seg[12]);
shiftOut(regData, regClk, MSBFIRST, seg[12]);
}
} else {delay(10);}
if(!digitalRead(8)) { needsUpdate = 1; break; }
}
}
#pragma GCC pop_options