init
This commit is contained in:
commit
dd9329713f
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal 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
15
platformio.ini
Normal 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
482
src/main.cpp
Normal 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
28
todo.txt
Normal 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. L’heure 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. L’heure de l’alarme, au format 24h (hh:mm)
|
||||
DONE 4. Si l’alarme est activée ou non (ON/OFF)
|
||||
DONE 5. Tout en respectant les formats d’affichage 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 l’heure la longueur est toujours la même.
|
||||
|
||||
DONE 2. Les informations de l’heure d’alarme doit être sauvegardée lorsqu’elle 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 l’heure par défaut qui est midi (12:00:00).
|
||||
DONE 2. L’heure de l’alarme est la même que la dernière qui a été sauvegardée, ou 12:01 sinon.
|
||||
DONE 3. L’alarme est activée par défaut
|
||||
|
||||
4. Votre réveil-matin possède 4 boutons:
|
||||
DONE 1. Menu: lorsqu’appuyé, 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 d’activer la modification d’une valeur dans le menu courant, et de l’accepter une fois modifiée
|
||||
3. Gauche et Droite: naviguer dans les différents menus et modifier les valeurs du menu actuel lorsqu’on est en mode modification
|
||||
|
||||
5. Lorsque l’alarme se déclanche (l’heure courante est la même que l’heure de l’alarme ET l’alarme est activée):
|
||||
DONE 1. Votre buzzer doit émettre un son/musique (au choix) à répétition tant que l’utilisateur n’a pas réagit
|
||||
2. La LED de l’alarme 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 l’alarme est déclanchée, le bouton menu ne fait plus afficher le menu). Une fois le “snooze”
|
||||
DONE appuyé, l’alarme se redéclanchera automatiquement au bout de 2 minutes.
|
||||
DONE 4. Pour arrêter l’alarme une fois qu’elle s’est déclanchée, il faut appuyer simultanément sur les boutons Gauche et Droite. L’alarme reste active et se
|
||||
DONE redéclanchera le lendemain à l’heure voulue
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user