arduino-alarm/src/main.cpp
thatscringebro dd9329713f init
2023-10-05 22:37:03 -04:00

483 lines
11 KiB
C++

#include <Arduino.h>
#include <LiquidCrystal.h>
#include <EEPROM.h>
// Pin Definitions
#define MENU_BUTTON A2
#define SET_BUTTON A3
#define GAUCHE_BUTTON A4
#define DROITE_BUTTON A5
#define BUZZER_PIN 8
#define ALARM_LED_PIN 13
#define TEMPERATURE_SENSOR_PIN A0
#define ALARM_SETTINGS_ADDRESS 0
#define ALARM_SET_FLAG_ADDRESS 2
#define LCD_D2 2
#define LCD_D3 3
#define LCD_D4 4
#define LCD_D5 5
#define LCD_D11 11
#define LCD_D12 12
// LCD Configuration
LiquidCrystal lcd(LCD_D12, LCD_D11, LCD_D5, LCD_D4, LCD_D3, LCD_D2);
// Global Variables
bool alarmEnabled = true;
bool editMode = false;
bool editingHour = false;
bool editingMinute = false;
bool editingSecond = false;
bool isAlarmSet = false;
bool menuButtonPressed = false;
bool setButtonPressed = false;
bool gaucheButtonPressed = false;
bool droiteButtonPressed = false;
unsigned int hour = 0;
unsigned int minute = 0;
unsigned int second = 0;
byte setHour = 12;
byte setMinute = 0;
byte setSecond = 0;
byte alarmHour = 0;
byte alarmMinute = 0;
float temperature = 0.0;
int ledTimer = 0;
enum MenuState {
MENU_OFF,
MENU_TIME,
MENU_ALARM_TIME,
MENU_ALARM_STATUS
};
MenuState menuState = MENU_OFF;
// Alarm State
enum AlarmState {
ALARM_OFF,
ALARM_ON,
ALARM_SNOOZE,
};
AlarmState alarmState = ALARM_OFF;
unsigned long alarmStartTime = 0;
const unsigned long snoozeDuration = 120000; // 2 minutes snooze duration (in milliseconds)
void updateTemperature() {
// Read temperature from the sensor and return the value
int valeur = analogRead(TEMPERATURE_SENSOR_PIN);
//Formule pour transformer en degré -> 10000 pour resistance 10k, 3977 pour beta
double voltage = valeur * 5.0 / 1023.0;
double resistance = 10000.0 * voltage / (5.0 - voltage);
double tempKelvin = 1.0 / (1.0 / 298.15 + log(resistance / 10000.0) / 3977);
double tempCelcius = tempKelvin - 273.15;
temperature = tempCelcius;
}
void updateTime() {
// Update the time variables based on the elapsed time
second = millis() / 1000;
minute = second / 60;
hour = second / 3600;
minute %= 60;
second %= 60;
hour %= 24;
}
void displayTime() {
// Display current time on the LCD
lcd.setCursor(0, 0); // Set cursor to top-left corner
char str[16];
snprintf(str, sizeof(str), "%02d:%02d:%02d", hour + setHour, minute + setMinute, second + setSecond);
lcd.print(str);
}
void displayTemperature() {
// Display temperature on the LCD
lcd.setCursor(9, 0); // Set cursor to top-right corner
lcd.print(String(temperature, 2));
}
void displayAlarmStatus() {
// Display alarm status (ON/OFF) and time on the bottom row of the LCD
lcd.setCursor(0, 1); // Set cursor to the start of the second row
char str[16];
snprintf(str, sizeof(str), "%02d:%02d", alarmHour, alarmMinute);
// Display alarm status and time
if (alarmEnabled)
{ lcd.print(str); lcd.print(" (ON)"); }
else
{ lcd.print(str); lcd.print(" (OFF)"); }
}
void displayMenuTop(){
lcd.setCursor(0, 0);
lcd.print("Menu: ");
lcd.setCursor(6, 0);
switch (menuState) {
case MENU_TIME:
lcd.print("Heure");
break;
case MENU_ALARM_TIME:
lcd.print("Alarme");
break;
case MENU_ALARM_STATUS:
lcd.print("Alarme");
break;
}
}
void displayMenuInfo(){
lcd.setCursor(0, 1);
char str[16];
switch (menuState) {
case MENU_TIME:
snprintf(str, sizeof(str), "%02d:%02d:%02d", hour + setHour, minute + setMinute, second);
lcd.print(str);
break;
case MENU_ALARM_TIME:
snprintf(str, sizeof(str), "%02d:%02d", alarmHour, alarmMinute);
lcd.print(str);
break;
case MENU_ALARM_STATUS:
if(alarmEnabled)
lcd.print("ON");
else
lcd.print("OFF");
break;
}
}
void handleMenuButton() {
if(digitalRead(MENU_BUTTON))
menuButtonPressed = false;
if(!menuButtonPressed){
if(!digitalRead(MENU_BUTTON)){
if(alarmState == ALARM_ON){
snoozeAlarm();
return;
}
switch (menuState) {
case MENU_OFF:
lcd.clear();
menuState = MENU_TIME;
break;
case MENU_TIME:
lcd.clear();
menuState = MENU_ALARM_TIME;
break;
case MENU_ALARM_TIME:
lcd.clear();
menuState = MENU_ALARM_STATUS;
break;
case MENU_ALARM_STATUS:
lcd.clear();
menuState = MENU_OFF;
break;
}
menuButtonPressed = true;
}
}
}
void handleSetButton() {
if(digitalRead(SET_BUTTON))
setButtonPressed = false;
if(!setButtonPressed){
if(!digitalRead(SET_BUTTON)){
switch (menuState) {
case MENU_OFF:
break;
case MENU_TIME:
if(!editMode){
editMode = true;
}
else{
if(!editingHour){
editingHour = true;
}
else{
editingHour = false;
if(!editingMinute){
editingMinute = true;
}
else{
editingMinute = false;
if(!editingSecond){
editingSecond = true;
}
else{
editingSecond = false;
editMode = false;
}
}
}
}
break;
case MENU_ALARM_TIME:
if(!editMode){
editMode = true;
}
else{
if(!editingHour){
editingHour = true;
}
else{
editingHour = false;
if(!editingMinute){
editingMinute = true;
}
else{
editingMinute = false;
editMode = false;
setAlarm();
}
}
}
break;
case MENU_ALARM_STATUS:
if(!editMode){
editMode = true;
}
else{
editMode = false;
}
break;
}
setButtonPressed = true;
}
}
}
void handleGaucheButton() {
if(digitalRead(GAUCHE_BUTTON))
gaucheButtonPressed = false;
if(!gaucheButtonPressed){
if(!digitalRead(GAUCHE_BUTTON)){
if(alarmState == ALARM_ON){
if(!digitalRead(DROITE_BUTTON)){
stopAlarm();
}
}
switch (menuState) {
case MENU_OFF:
break;
case MENU_TIME:
if(editMode){
if(editingHour){
setHour++;
}
if(editingMinute){
setMinute++;
}
if(editingSecond){
setSecond++;
}
}
break;
case MENU_ALARM_TIME:
if(editMode){
if(editingHour){
alarmHour++;
}
if(editingMinute){
alarmMinute++;
}
}
break;
case MENU_ALARM_STATUS:
if(editMode){
lcd.clear();
if(alarmEnabled)
alarmEnabled = false;
else
alarmEnabled = true;
}
break;
}
gaucheButtonPressed = true;
}
}
}
void handleDroiteButton() {
if(digitalRead(DROITE_BUTTON))
droiteButtonPressed = false;
if(!droiteButtonPressed){
if(!digitalRead(DROITE_BUTTON)){
switch (menuState) {
case MENU_OFF:
break;
case MENU_TIME:
if(editMode){
if(editingHour){
setHour--;
}
if(editingMinute){
setMinute--;
}
if(editingSecond){
setSecond--;
}
}
break;
case MENU_ALARM_TIME:
if(editMode){
if(editingHour){
alarmHour--;
}
if(editingMinute){
alarmMinute--;
}
}
break;
case MENU_ALARM_STATUS:
break;
}
droiteButtonPressed = true;
}
}
}
void checkAlarm() {
if (alarmEnabled && (hour + setHour == alarmHour) && (minute + setMinute == alarmMinute) && alarmState == ALARM_OFF) {
// Set alarm state to sound
alarmState = ALARM_ON;
alarmStartTime = millis();
}
}
void stopAlarm() {
alarmState = ALARM_OFF;
noTone(BUZZER_PIN);
digitalWrite(ALARM_LED_PIN, LOW);
}
void snoozeAlarm() {
alarmState = ALARM_SNOOZE;
alarmStartTime = millis();
}
void restoreAlarmSettings() {
// Read alarm settings from EEPROM and set variables accordingly
// If no settings are found, use default values
byte storedHour = EEPROM.read(ALARM_SETTINGS_ADDRESS);
byte storedMinute = EEPROM.read(ALARM_SETTINGS_ADDRESS + 1);
isAlarmSet = EEPROM.read(ALARM_SET_FLAG_ADDRESS);
// Check if EEPROM contains valid alarm settings
if (isAlarmSet && storedHour != 255 && storedMinute != 255) {
alarmHour = storedHour;
alarmMinute = storedMinute;
} else {
// Default alarm time (12:01) if EEPROM is empty or contains invalid data
alarmHour = 12;
alarmMinute = 1;
isAlarmSet = false;
}
}
void saveAlarmSettings() {
// Save alarm settings and the alarm set flag to EEPROM
EEPROM.write(ALARM_SETTINGS_ADDRESS, alarmHour);
EEPROM.write(ALARM_SETTINGS_ADDRESS + 1, alarmMinute);
EEPROM.write(ALARM_SET_FLAG_ADDRESS, isAlarmSet);
}
void setAlarm() {
isAlarmSet = true;
// Save alarm settings and the alarm set flag to EEPROM when the alarm is set
saveAlarmSettings();
}
void clearAlarm() {
// Clear the alarm and update the alarm set flag in EEPROM
alarmHour = 6;
alarmMinute = 0;
isAlarmSet = false;
saveAlarmSettings();
}
void setup() {
//For debugging
Serial.begin(115200);
// Initialize LCD
lcd.begin(16, 2);
// Restore alarm settings from EEPROM
restoreAlarmSettings();
// Initialize buttons as inputs
pinMode(MENU_BUTTON, INPUT_PULLUP);
pinMode(SET_BUTTON, INPUT_PULLUP);
pinMode(GAUCHE_BUTTON, INPUT_PULLUP);
pinMode(DROITE_BUTTON, INPUT_PULLUP);
}
void loop() {
if(menuState == MENU_OFF){
// Update temperature
updateTemperature();
// Update time
updateTime();
// Display information on LCD
displayTime();
displayTemperature();
displayAlarmStatus();
// Check and activate the alarm
checkAlarm();
// Handle the alarm state
switch (alarmState) {
case ALARM_OFF:
stopAlarm();
break;
case ALARM_ON:
tone(BUZZER_PIN, 300);
break;
case ALARM_SNOOZE:
// Check if snooze duration has passed
if (millis() - alarmStartTime >= snoozeDuration) {
alarmState = ALARM_ON;
alarmStartTime = millis();
}
break;
}
}
else{
displayMenuTop();
displayMenuInfo();
}
// Handle button presses
handleMenuButton();
handleSetButton();
handleGaucheButton();
handleDroiteButton();
}