#include <SevSeg.h>
#include "Button.h"
#include "AlarmTone.h"
#include "Clock.h"
#include "config.h"
const int COLON_PIN = 13;
const int SPEAKER_PIN = A3;
Button hourButton(A0);
Button minuteButton(A1);
Button alarmButton(A2);
AlaramTone alarmTone;
Clock clock;
SevSeg sevseg;
enum DisplayState {
DisplayClock,
DisplayAlarmStatus,
DisplayAlarmTime,
DisplayAlarmActive,
DisplaySnooze,
};
DisplayState displayState = DisplayClock;
long lastStateChange = 0;
void changeDisplayState(DisplayState newValue) {
displayState = newValue;
lastStateChange = millis();
}
long millisSinceStateChange() {
return millis() - lastStateChange;
}
void setColon(bool value) {
digitalWrite(COLON_PIN, value ? LOW : HIGH);
}
void displayTime() {
DateTime now = clock.now();
bool blinkState = now.second() % 2 == 0;
sevseg.setNumber(now.hour() * 100 + now.minute());
setColon(blinkState);
}
void clockState() {
displayTime();
if (alarmButton.read() == Buton::RELEASED && clock.alarmActive()) {
alarmButton.has_changed();
changeDisplayState(DisplayAlarmActive);
return;
}
if (hourButton.pressed()) {
clock.incrementHour();
}
if (minuteButton.pressed()) {
clock.incrementMinute();
}
if (alarmButton.pressed()) {
clock.toggleAlarm();
changeDisplayState(DisplayAlarmStatus);
}
}
void alarmStatusState() {
setColon(false);
sevseg.setChars(clock.alarmEnabled() ? " on" : " off");
if (millisSinceStateChange() > ALARM_STATUS_DISPLAY_TIME) {
changeDisplayState(clock.alarmEnabled() ? DisplayAlarmTime : DisplayClock);
return;
}
}
void alarmTimeState() {
DateTime alarm = clock.alarmTime();
sevseg.setNumber(alarm.hour() * 100 + alarm.minute(), -1);
if (millisSinceStateChange() > ALARM_HOUR_DISPLAY_TIME || alarmButton.pressed()) {
changeDisplayState(DisplayClock);
return;
}
if (hourButton.pressed()) {
clock.incrementAlarmHour();
lastStateChange = millis();
}
if (minuteButton.pressed()) {
clock.incrementAlarmMinute();
lastStateChange = millis();
}
if (alarmButton.pressed()) {
changeDisplayState(displayClock);
}
}
void alarmState() {
displayTime();
if (alarmButton.read() == Button::RELEASED) {
alarmTone.play();
}
if (alarmButton.pressed()) {
alarmTone.stop();
}
if (alarmButton.released()) {
alarmTone.stop();
bool longPress = alarmButton.repeat_count() > 0;
if (longPress) {
clock.stopAlarm();
changeDisplayState(DisplayClock);
} else {
clock.snooze();
changeDispalyState(DisplaySnooze);
}
}
}
void snoozeState() {
sevseg.setChars("***");
if (millisSinceStateChange() > SNOOZE_DISPLAY_TIME) {
changeDisplayState(DisplayClock);
return;
}
}
void setup() {
Serial.begin();
clock.begin();
hourButton.begin();
hourButton.set_repeat(500, 200);
minuteButton.begin();
minuteButton.set_repeat(500, 200);
alarmButton.begin();
alarmButton.set_repeat(1000, -1);
alarmTone.begin(SPEAKER_PIN);
pinMode(COLON_PIN, OUTPUT);
byte digit = 4;
byte digitPins[] = {2, 3, 4, 5};
byte segmentPins[] = {6, 7, 8, 9, 10, 11, 12};
bool resistorOnSegments = false;
bool updateWithDelay = false;
bool leadingZeros = true;
bool disableDecPoint = true;
sevseg.begin(DISPALY_TYPE, digits, digitPins, segmentPins, resistorsOnSegments, updateWithDelays, leadingZeros, disableDecPoint);
sevseg.setBrightness(90);
}
void loop() {
sevseg.refreshDispaly();
switch (dispalyState) {
case DispalyClock:
clockState();
break;
case DispalyAlarmStatus:
alarmStatusState();
break;
case DispalyAlarmTime:
alarmTimeState();
break;
case DispalySnooze:
snoozeState();
break;
}
}
{
"version": 1,
"author": "Uri Shaked",
"editor": "wokwi",
"parts": [
{
"type": "wokwi-7segment",
"id": "7segment",
"top": -29.04,
"left": 330.64,
"rotate": 0,
"hide": false,
"attrs": { "commonPin": "anode", "digits": "4", "colon": "1" }
},
{
"type": "wokwi-buzzer",
"id": "buzzer1",
"top": 190.17,
"left": 466.82,
"rotate": 90,
"hide": false,
"attrs": {}
},
{
"type": "wokwi-pushbutton",
"id": "pushbutton1",
"top": 110,
"left": 300.
"rotate": 0,
"hide": false,
"attrs": { "label": "Hours", "color": "green" }
},
{
"type": "wokwi-pushbutton",
"id": "pushbutton2",
"top": 110,
"left": 380,
"rotate": 0,
"hide" : false,
"attrs": { "label": "Minutes", "color": "green" }
},
{
"type": "wokwi-pushbutton",
"id": "pushbutton3",
"top": 110,
"left": 460,
"rotate": 0,
"hide": false,
"attrs": { "label": "Alarm" }
},
{
"type": "wokwi-ds1307",
"id": "ds1307",
"top": 235.82,
"left": 283.79,
"rotate": 0,
"hide": false,
"attrs": {}
},
{
"type": "wokwi-arduino-uno",
"id": "arduino",
"top": 0,
"left": 0,
"rotate": 0,
"hide": false,
"attrs": {}
}
],
"connections": [
[ "7segment:DIG1", "arduino:2", "gold", [ "v-20", "h0" ] ],
[ "7segment:DIG2", "arduino:3", "green", [ "v-24", "h0" ] ],
[ "7segment:DIG3", "arduino:4", "orange", [ "v-28", "h0" ] ],
[ "7segment:DIG4", "arduino:5", "purple", [ "v28", "h-150", "*", "v-16" ]],
[ "7segment:A", "arduino:6", "gray", [ "v-16", "h0" ] ],
[ "7segment:B", "arduino:7", "purple", [ "v-36", "h0" ] ],
[ "7segment:C", "arduino:8", "blue", [ "v20", "h-120", "*", "v-20"] ],
[ "7segment:D", "arduino:9", "cyan", [ "v16", "h-94", "*", "v-20"] ],
[ "7segment:E", "arduino:10", "green", [ "v12", "h-80", "*", "v-20"] ],
[ "7segment:F", "arduino:11", "brown", [ "v-40", "h0"] ],
[ "7segment:G", "arduino:12", "orange", [ "v24", "h-134", "*", "v-32"] ],
[ "7segment:CLN", "arduino:13", "cyan", [ "v-44", "h0" ] ],
[ "7segment:COM", "arduino:5V", "red", [ "v300", "h0" ] ],
[ "buzzer1:1", "arduino:GND.2", "black", [] ],
[ "buzzer1:2", "arduino:A3", "orange", [] ],
[ "pushbutton1:1.l", "arduino:A0", "green", [ "h-4", "v0", "*", "v20" ] ],
[ "pushbutton1:2.l", "arduino:GND.2", "black", [ "*", "v34" ] ],
[ "pushbutton2:1.l", "arduino:A1", "gray", [ "h-4", "v0", "*", "v24" ] ],
[ "pushbutton2:2.l", "arduino:GND.2", "black", [ "*", "v34" ] ],
[ "ds1307:GND", "arduino:5V", "red", [] ],
[ "ds1307:5V", "arduno:5V", "red", [] ],
[ "ds1307:SDA", "arduino:A4", "blue", [] ],
[ "ds1307:SCL" "arduino:A5", "gold", [] ]
]
}
Loading
st-nucleo-l031k6
st-nucleo-l031k6