This commit is contained in:
thatscringebro 2023-10-05 22:37:03 -04:00
commit dd9329713f
4 changed files with 530 additions and 0 deletions

5
.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
.pio
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/ipch

15
platformio.ini Normal file
View File

@ -0,0 +1,15 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[env:uno]
platform = atmelavr
board = uno
framework = arduino
monitor_speed = 115200

482
src/main.cpp Normal file
View File

@ -0,0 +1,482 @@
#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();
}

28
todo.txt Normal file
View File

@ -0,0 +1,28 @@
DONE 1. Votre réveil matin doit afficher de façon fluide et sans lag différentes informations sur lécran LCD (voir photo ci-haut pour un exemple)
DONE 1. Lheure courante, au format 24h (hh:mm:ss)
DONE 2. La température actuelle en degrés celcius, avec une décimale après la virgule.
DONE 3. Lheure de lalarme, au format 24h (hh:mm)
DONE 4. Si lalarme est activée ou non (ON/OFF)
DONE 5. Tout en respectant les formats daffichage des heures ci-haut, les minutes et les secondes sont remplis avec des zéros à gauche, et
les heures avec un espace blanc à gauche si nécessaire, exemple: _6:08:54) de sorte que peu importe lheure la longueur est toujours la même.
DONE 2. Les informations de lheure dalarme doit être sauvegardée lorsquelle est modifiée et restaurée à chaque démarrage de votre arduino (eeprom)
DONE 3. Lors du démarrage de votre arduino
DONE 1. Votre écran doit afficher lheure par défaut qui est midi (12:00:00).
DONE 2. Lheure de lalarme est la même que la dernière qui a été sauvegardée, ou 12:01 sinon.
DONE 3. Lalarme est activée par défaut
4. Votre réveil-matin possède 4 boutons:
DONE 1. Menu: lorsquappuyé, entre en mode menu et affiche le premier élément du menu (voir plus bas pour la description du format des menus).
2. Set: permet dactiver la modification dune valeur dans le menu courant, et de laccepter une fois modifiée
3. Gauche et Droite: naviguer dans les différents menus et modifier les valeurs du menu actuel lorsquon est en mode modification
5. Lorsque lalarme se déclanche (lheure courante est la même que lheure de lalarme ET lalarme est activée):
DONE 1. Votre buzzer doit émettre un son/musique (au choix) à répétition tant que lutilisateur na pas réagit
2. La LED de lalarme doit flasher en boucle en respectant une séquence de 250ms allumée suivi de 500ms éteinte.
DONE 3. Il est possible de “snoozer” en appuyant sur le bouton Menu (lorsque lalarme est déclanchée, le bouton menu ne fait plus afficher le menu). Une fois le “snooze”
DONE appuyé, lalarme se redéclanchera automatiquement au bout de 2 minutes.
DONE 4. Pour arrêter lalarme une fois quelle sest déclanchée, il faut appuyer simultanément sur les boutons Gauche et Droite. Lalarme reste active et se
DONE redéclanchera le lendemain à lheure voulue