// Basic RTC clock using Attiny85
// press blue to enter, shift or leave setting mode,
// press green to increase hours or minutes
//TODO: Make settings more responsive
#include <ButtonGestures.h>
#include <Wire.h>
#include <TM1637TinyDisplay.h>
// DS1307 related
#define DS1307_ADDR 0x68
byte seconds,minutes,hours;
// Instantiate TM1637TinyDisplay Class
TM1637TinyDisplay display(3, 4); //PB3, PB4
//TM1637 has no address and is not using I2C
ButtonGestures buttonState(PB1, LOW, INPUT_PULLUP); //blue
ButtonGestures buttonSet(PB5, LOW, INPUT_PULLUP); //green
//state: 0 (normal), 1=set hours, 2=set minutes
byte state = 0;
const byte dms = 100;
const byte blk[2] = {0,0};
bool upd = false;
void setup() {
display.begin();
Wire.begin();
delay(100);
}
void loop() {
upd = false;
uint8_t s = buttonSet.check_button();
if (s==SINGLE_PRESS_SHORT) {
if (state==1) {
hours = (hours==23) ? 0 : hours + 1;
setTime();
upd = true;
} else if (state==2) {
minutes = (minutes==59) ? 0 : minutes + 1;
setTime();
upd = true;
}
}
s = buttonState.check_button();
if (s==SINGLE_PRESS_SHORT) {
state = (state==2) ? 0 : state + 1;
}
switch (state) {
case 0:
display.showNumberDec(hours, 0b01000000, false, 2, 0);
display.showNumberDec(minutes, 0, true, 2, 2);
break;
case 1: //hours blinking
display.showNumberDec(minutes, 0, true, 2, 2);
if(upd || millis() & 512) {
display.showNumberDec(hours, 0b01000000, false, 2, 0);
} else {
display.setSegments(blk,2,0);
}
break;
case 2: //minutes blinking
display.showNumberDec(hours,0b01000000, false, 2, 0);
if(upd || millis() & 512) {
display.showNumberDec(minutes, 0, true, 2, 2);
} else {
display.setSegments(blk,2,2);
}
break;
}
delay(dms);
//reload time from RTC
getTime();
}
void getTime(){
byte wireRet = 0;
Wire.beginTransmission(DS1307_ADDR); // reset DS1307 register pointer
Wire.write(0);
wireRet = Wire.endTransmission();
if (wireRet) delay(1500);
wireRet = Wire.requestFrom(DS1307_ADDR, 3); // request n bytes from DS1307
if (wireRet) delay(1500);
seconds = bcdToDec(Wire.read()); //read bytes received
minutes = bcdToDec(Wire.read());
hours = bcdToDec(Wire.read());
}
byte bcdToDec(byte val) { // Convert binary coded decimal to normal decimal numbers
return (val>>4) * 10 + (val & 15);
//Each set of 4 bits represents a digit
}
byte decToBcd(byte val) { // Convert to BCD
return (int)(val/10)*16 + val - 10*(int)(val/10);
}
void setTime() {
byte wireRet = 0;
Wire.beginTransmission(DS1307_ADDR);
Wire.write(0); // reset register pointer
Wire.write(decToBcd(seconds)); // write the seconds, with the stop bit clear to restart
Wire.write(decToBcd(minutes));
Wire.write(decToBcd(hours));
wireRet = Wire.endTransmission();
return wireRet;
}