////////////////////// ScreenManager.h
# ifndef _SCREEN_MANAGER
# include <LiquidCrystal_I2C.h>
# include <TimeLib.h>
# define LCD_ADRESS 0x27
# define COOLDOWN_TIME 10
class ScreenManager{
private:
LiquidCrystal_I2C lcd;
time_t _since;
bool _up;
public:
ScreenManager();
void setup();
public:
bool check(time_t& t);
const time_t since();
public:
void print_in_line(char* buf, unsigned short l);
void shutdown();
void power_on();
};
# endif
/////////////////////
////////////////////// Clock.h
# ifndef _CLOCK
# include <Arduino.h>
# include <TimeLib.h>
# include <Wire.h>
# include <LiquidCrystal_I2C.h>
# define CLOCK_PRINT_LINE 0 // Affiche sur la 1ere ligne
# define CLOCK_OFFSET 1672531200 // Epoch = Dimanche 1er janvier 2023
class Clock{
public:
Clock();
void setup();
time_t tick();
void display(ScreenManager& screen);
public:
bool has_moved();
time_t get_current();
private:
bool _moved;
time_t _current;
};
# endif
/////////////////////
////////////////////// Buttons3.h
# ifndef _BUTTONS
# include <Arduino.h>
# include <TimeLib.h>
# define NO_BUTTON 0
# define BUTTON1 1
# define BUTTON2 2
# define BUTTON3 3
# define DEFAULT_BUTTON_PIN A0
# define DEFAULT_BUTTON1_PIN A0
# define DEFAULT_BUTTON2_PIN A1
# define DEFAULT_BUTTON3_PIN A2
class Buttons3{
private:
short pressed_button;
short clicked_button;
public:
Buttons3();
void setup(const uint8_t[]);
bool is_clicked();
public:
void capture();
};
# endif
/////////////////////
////////////////////// ScreenManager.c++
/**
* Creation du gestionnaire pour l'écran LCD
*/
ScreenManager::ScreenManager(): lcd{LCD_ADRESS, 16, 2}, _up{false}{}
/**
* Inialisation du gestionnaire
*/
void ScreenManager::setup(){
lcd.init();
lcd.display();
lcd.clear();
}
///// ----- Setters & Getters ----- /////
/**
* Actualise l'etat de l'etat du manager
* @return true si l'ecran est allume
*/
bool ScreenManager::check(time_t& t){
if (_up && (_since + COOLDOWN_TIME) < t){
shutdown();
}
return _up;
}
/**
* Temps écoulé depuis l'allumage
*/
const time_t ScreenManager::since(){
return _since;
}
///// ----- Gestion ----- /////
/**
* Affiche une chaine de caractère sur une ligne
*/
void ScreenManager::print_in_line(char* buf, unsigned short l){
if (!_up) return;
lcd.setCursor(0, l);
lcd.print(buf);
}
/**
* Eteint l'écran
*/
void ScreenManager::shutdown(){
_up = false;
lcd.clear();
lcd.noBacklight();
}
/**
* Allume l'écran
*/
void ScreenManager::power_on(){
_up = true;
_since = now();
lcd.backlight();
}
/////////////////////
////////////////////// Buttons3.c++
/**
* Constructeurs par défaut
*/
Buttons3::Buttons3():
pressed_button{NO_BUTTON}, clicked_button{NO_BUTTON}{}
/**
* Inialisation
*/
void Buttons3::setup(const uint8_t list[]){}
# ifdef _ARDUINO_ANALOG_READ
void Buttons3::capture(){
int tmp = analogRead(DEFAULT_BUTTON_PIN);
if (temp < 200){
if (pressed_button == NO_BUTTON){
clicked_button = NO_BUTTON;
}
else if (clicked_button == NO_BUTTON){
clicked_button = pressed_button;
}
pressed_button = NO_BUTTON;
}
else if (temp < 400)
pressed_button = BUTTON1;
else if (temp < 1000)
pressed_button = BUTTON2;
else
pressed_button = BUTTON3;
}
# else
void Buttons3::capture(){
if (analogRead(DEFAULT_BUTTON1_PIN) == 0)
pressed_button = BUTTON1;
else if (analogRead(DEFAULT_BUTTON2_PIN) == 0)
pressed_button = BUTTON2;
else if (analogRead(DEFAULT_BUTTON3_PIN) == 0)
pressed_button = BUTTON3;
else {
if (pressed_button == NO_BUTTON){
clicked_button = NO_BUTTON;
}
else if (clicked_button == NO_BUTTON){
clicked_button = pressed_button;
}
pressed_button = NO_BUTTON;
}
}
bool Buttons3::is_clicked(){
return clicked_button != NO_BUTTON;
}
# endif
/////////////////////
////////////////////// Clock.c++
Clock::Clock(){}
/**
* Inialise l'horloge numérique
*/
void Clock::setup(){
setTime(CLOCK_OFFSET);
}
/**
* Faire un tick d'horloge si le temps a bouger
*/
time_t Clock::tick(){
time_t t = now();
if (t != _current ){
_current = t;
_moved = true;
}
else
_moved = false;
return _current;
}
/**
* Affiche l'horloge sur un ecran LCD
*/
void Clock::display(ScreenManager& screen){
char buffer[16];
int h = hour(_current);
int m = minute(_current);
int s = second(_current);
int w = weekday(_current);
int D = day(_current);
int M = month(_current);
sprintf(buffer, "%02d/%02d %02d:%02d:%02d", D, M, h, m, s);
screen.print_in_line(buffer, CLOCK_PRINT_LINE);
}
/**
* Le temps a bouger
*/
bool Clock::has_moved(){
return _moved;
}
/**
* L'horaire actuelle
*/
time_t Clock::get_current(){
return _current;
}
/////////////////////
# define DELAY_TIME 10
ScreenManager screen;
Clock clock;
Buttons3 buttons;
void setup(){
Serial.begin(9600);
clock.setup();
screen.setup();
}
void loop(){
time_t t = clock.tick();
buttons.capture();
if (buttons.is_clicked())
handle_click();
if (screen.check(t)){
if (clock.has_moved())
clock.display(screen);
}
//delay(DELAY_TIME);
}
void handle_click(){
screen.power_on();
}