// Projet de session 2022
// Auteur: Nathaniel Courtemanche
// Date: 2022-12-07
// ==============================================
// Un système d’alarme connecté à une centrale de contrôle avec des fonctions qui
// envoi des messages entre deux systèmes, affiche l'heure en temps réel
// sans délais et plus tard va lire la température et de l'humidité, va détecter les mouvements et une
// utilisation d'un clavier numérique pour saisir des valeurs
// ==============================================
#include "mesdefines.h"
// NOTE IMPORTANTE: Ne placez aucune macro, enum, déclaration de fonctions,
// const,include (sauf pour 'mesdefines.h),dans ce fichier.
// Déclaration des objets à portée globale:
TM1637 affichageHorloge(CLK, DIO);
DS1307 horloge;
Adafruit_ILI9341 ecranCentraleSurveillance = Adafruit_ILI9341(TFT_CS, TFT_DC);
LiquidCrystal_I2C ecranPrincipal(LCD_ADRESSE_I2C,LCD_NB_COLONNE,LCD_NB_LIGNE);
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
// ********************************************************
void setup()
// ********************************************************
{
Serial.begin(UART_VITESSE_CONSOLE);
//NOTE: Placer une chaine de caractères entre F() permet de la stocker
// dans la mémoire programme au lieu de la mémoire variable.
//
// Étant donné qu'il n'y a pas beaucoup de mémoire variable,
// c'est une bonne pratique.
#ifdef DEBUG
Serial << F(MSG_DEMARRAGE_DU_PROJET);
Serial << F(MSG_PROJET_PAR);
Serial << F(MSG_DEBUT_INIT);
#endif
initialisationDesAppareils();
#ifdef DEBUG
Serial << F(MSG_FIN_INIT);
#endif
afficherPageEcran(centraleEcranOuverture);
afficherPageEcran(ecranOuverture, UNE_SECONDE * 2);
afficherPageEcran(ecranInstruction);
// Début de Lecture du bouton et affichage de l'heure en mode non bloquant
byte etatBouton = digitalRead(BOUTON);
while (etatBouton == false)
{
etatBouton = digitalRead(BOUTON);
afficherTemps();
} // while()
delay(DELAI_FILTRE_BRUIT_BOUTON);
// Fin de Lecture du bouton
if (connexionALaCentrale()){
afficherPageEcran(systemeEnLigne, UNE_SECONDE * 2);
} // if()
afficherPageEcran(ecranDate);
} // setup()
// ********************************************************
void loop()
// ********************************************************
{
while(!sensorMotion()) // Tant que le sensor n'est pas actif affiche le temps et l'écran date
{
afficherTemps();
afficherPageEcran(ecranDate);
}
if(sensorMotion())
{
saisieDuCode();
} // if
} // loop()
// ********************************************************
void afficherPageEcran(Ecrans ecran, int delai = 0)
// ********************************************************
{
switch(ecran) {
case ecranOuverture: // L'écran de début sur l'écran principal
ecranPrincipal.setCursor(COLONNE_DEBUT, LIGNE_DEBUT);
ecranPrincipal.print(F(FR_TITRE));
ecranPrincipal.setCursor(COLONNE_DEBUT, LIGNE_DEUX);
ecranPrincipal.print(F(LIGNE));
ecranPrincipal.setCursor(COLONNE_DEBUT, LIGNE_TROIS);
ecranPrincipal.print(F(FR_VERSION));
ecranPrincipal.setCursor(COLONNE_DEBUT, LIGNE_QUATRE);
ecranPrincipal.print(F(PAR));
break;
case centraleEcranOuverture: // L'écran de début sur l'écran centrale
ecranCentraleSurveillance.setCursor(ILI_COLONNE_TITRE, ILI_LIGNE_TITRE);
ecranCentraleSurveillance.setTextColor(ILI9341_RED);
ecranCentraleSurveillance.setTextSize(ILI_TITLE_SIZE);
ecranCentraleSurveillance.print(F(CENTRALE_DEBUT));
for(int i = 0; i < LARGEUR_ILI; i++)
{
ecranCentraleSurveillance.drawPixel(i, LIGNE_CENTRALE, ILI9341_WHITE);
}
ecranCentraleSurveillance.setCursor(ILI_COLONNE_DEBUT, ILI_ATTENTE_LIGNE);
ecranCentraleSurveillance.setTextColor(ILI9341_YELLOW);
ecranCentraleSurveillance.setTextSize(ILI_TEXTE_SIZE);
ecranCentraleSurveillance.print(F(ATTENTE));
break;
case ecranInstruction: // L'écran d'instruction sur l'écran principal
ecranPrincipal.setCursor(COLONNE_DEBUT, LIGNE_DEBUT);
ecranPrincipal.print(F(INSTRUCTION_LIGNE1));
ecranPrincipal.setCursor(COLONNE_DEBUT, LIGNE_DEUX);
ecranPrincipal.print(F(INSTRUCTION_LIGNE2));
ecranPrincipal.setCursor(COLONNE_DEBUT, LIGNE_TROIS);
ecranPrincipal.print(F(INSTRUCTION_LIGNE3));
ecranPrincipal.setCursor(COLONNE_DEBUT, LIGNE_QUATRE);
ecranPrincipal.print(F(INSTRUCTION_LIGNE4));
break;
case systemeEnLigne: // L'écran pour montrer que les systeme son en ligne sur les deux
ecranPrincipal.setCursor(COLONNE_DEBUT, LIGNE_DEBUT);
ecranPrincipal.print(F(EN_LIGNE));
ecranPrincipal.setCursor(COLONNE_DEBUT, LIGNE_DEUX);
ecranPrincipal.print(F(LIGNE));
ecranPrincipal.setCursor(COLONNE_DEBUT, LIGNE_TROIS);
ecranPrincipal.print(F(FIN));
ecranPrincipal.setCursor(COLONNE_DEBUT, LIGNE_QUATRE);
ecranPrincipal.print(LIGNE);
ecranCentraleSurveillance.setCursor(ILI_COLONNE_DEBUT, ILI_EN_LIGNE_LIGNE);
ecranCentraleSurveillance.setTextColor(ILI9341_YELLOW);
ecranCentraleSurveillance.setTextSize(ILI_TEXTE_SIZE);
ecranCentraleSurveillance.print(F(EN_LIGNE_CENTRALE));
break;
case ecranDate: // L'écran pour afficher le titre, la date, et le temps que le programme roule depuis
ecranPrincipal.setCursor(COLONNE_DEBUT, LIGNE_DEBUT);
ecranPrincipal.print(F(FR_TITRE));
ecranPrincipal.setCursor(COLONNE_DEBUT, LIGNE_DEUX);
ecranPrincipal.print(F(LIGNE));
afficherTempsEcran();
break;
case ecranPIN: // L'écran pour affiche la saisie du code et l'alerte
ecranPrincipal.setCursor(COLONNE_DEBUT, LIGNE_DEBUT);
ecranPrincipal.print(F(MOUVEMENT));
ecranPrincipal.setCursor(COLONNE_DEBUT, LIGNE_DEUX);
ecranPrincipal.print(F(LIGNE));
ecranPrincipal.setCursor(COLONNE_DEBUT, LIGNE_TROIS);
ecranPrincipal.print(F(CODE));
ecranPrincipal.setCursor(COLONNE_DEBUT, LIGNE_QUATRE);
ecranPrincipal.print(F(RIEN));
}
delay(delai);
} // afficherPageEcran
// ********************************************************
void initialisationDesAppareils() // void pour tous initialiser
// ********************************************************
{
Serial1.begin(UART_VITESSE); //Initialisation du UART de la centrale
Serial3.begin(UART_VITESSE); //Initialisation du UART du système d alarme
ecranPrincipal.begin(LCD_NB_COLONNE, LCD_NB_LIGNE); //Initialisation de la LCD
ecranCentraleSurveillance.begin(); //Initialisation du TFT
pinMode(BOUTON, INPUT); //Initialisation du bouton
horloge.begin(); //Initialisation du 4-digit
affichageHorloge.init(); //Initialisation du RTC
affichageHorloge.set(LUMIERE);
pinMode(SENSOR, INPUT); //Initialisation du PIR Motion-sensor
pinMode(DEL, OUTPUT); //Initialisation de la DEL
} // initialisationDesAppareils
// ********************************************************
boolean connexionALaCentrale() // boolean pour l'envoie d'un message à la centrale de l'arduino MEGA
// ********************************************************
{
Serial1.write(evenement_systeme_enligne);
delay(UNE_SECONDE);
if(Serial3.available()) {
#ifdef DEBUG
Serial << F(TENTATIVE);
Serial << F(ENVOI);
#endif
byte unMessage = Serial3.read();
if(unMessage == evenement_systeme_enligne) {
#ifdef DEBUG
Serial << F(SUCCESS);
#endif
return true;
}
else
{
return false;
}
}// Retourner 'true' ou 'false' selon le cas.
} // connexionALaCentrale
// ********************************************************
boolean sensorMotion() // boolean pour determiner si le sensor aurait détecter un mouvement
// ********************************************************
{
int sensorValue = digitalRead(SENSOR);
if(sensorValue == HIGH) // si valeur du capteur est HIGH (1) alors
{
#ifdef DEBUG
Serial << F(MSG_ALARME);
Serial << F(MSG_LECTURE_ALARME);
Serial << F(MSG_DEBUT_ALARME);
#endif
return true; // Movement
}
else
{
return false; // Pas de movement ...
}// Retourner 'true' ou 'false' selon le cas.
} // sensorMotion
// ********************************************************
void afficherTemps() // void pour faire beeper les deux points
// ********************************************************
{
static unsigned long int momentPresent = millis();
static int deuxPoint;
horloge.getTime();
if (millis() - momentPresent >= UNE_SECONDE / 2) {
momentPresent = millis();
if(deuxPoint % 2)
{
affichageHorloge.point(true); // Affiche les deux points
}
else
{
affichageHorloge.point(false); // N'affiche pas les deux points
}
deuxPoint++;
}// Retourner 'true' ou 'false' selon le cas.
affichageHorloge.display(0, horloge.hour / 10);
affichageHorloge.display(1, horloge.hour % 10);
affichageHorloge.display(2, horloge.minute / 10);
affichageHorloge.display(3, horloge.minute % 10);
} // afficherTemps
// ********************************************************
void afficherTempsEcran() // void pour afficher le temps sur la LCD
// ********************************************************
{
int secondes = millis() / UNE_SECONDE % SECONDES_PAR_MINUTES;
int minutes = millis() / MILLIS_MINUTES % MINUTES_PAR_HEURES;
int heures = millis() / MILLIS_HEURES % HEURES_DANS_UNE_JOURNEE;
int jours = millis() / MILLIS_JOURS % JOURS_DANS_UNE_ANNEE;
horloge.getTime();
ecranPrincipal.setCursor(COLONNE_DEBUT, LIGNE_TROIS);
snprintf(uneChaineDeCaracteres,NB_MAX_CAR, "%s %02d %s", Jour[horloge.dayOfWeek], horloge.dayOfMonth, Mois[horloge.month]);
ecranPrincipal << uneChaineDeCaracteres;
ecranPrincipal.setCursor(COLONNE_DEBUT, LIGNE_QUATRE);
snprintf(uneChaineDeCaracteres,NB_MAX_CAR, "Actif: %03d, %02d:%02d:%02d", jours, heures, minutes, secondes);
ecranPrincipal << uneChaineDeCaracteres;
} // afficherDateEcran
// ********************************************************
void allumerLaDEL(){ // void pour allumer la DEL
digitalWrite(DEL, HIGH);
} // allumerLaDEL
// ********************************************************
// ********************************************************
void eteindreLaDEL(){ // void pour éteindre la DEL
digitalWrite(DEL,LOW);
} // eteindreDEL
// ********************************************************
// ********************************************************
boolean tempsSaisieCode() // boolean pour determiner le nombre de temps autoriser pour entrer le code
// ********************************************************
{
static unsigned long int tempsCode = millis();
if (millis() - tempsCode >= TRENTE_SECONDES)
{
tempsCode = millis();
return true;
} // if
else
{
return false;
} // else
}// Retourner 'true' ou 'false' selon le cas.
// ********************************************************
void saisieDuCode() // void qui permet de saisir le code et de definir sa somme
// ********************************************************
{
int somme = 0;
int result = 0;
allumerLaDEL();
afficherPageEcran(ecranPIN);
ecranPrincipal.setCursor(COLONNE_DEBUT, LIGNE_QUATRE);
ecranPrincipal.print(F(CURSOR));
while (tempsSaisieCode() == false && result < 4)
{
int valeurCle = 0;
afficherTemps();
char key = keypad.getKey();
if (key != NO_KEY) { // Si touche appuyée
valeurCle = key - 48; // convertir la valeur du caractère en valeur numérique. Par exemple, '0' vaut 48.
somme += valeurCle;
#ifdef DEBUG
Serial << key;
#endif
ecranPrincipal << key;
result++;
} // if
} // while
while (digitalRead(SENSOR))
{
afficherTemps();
} // while
somme_code(somme);
} // saisieDuCode
// ********************************************************
void somme_code(int somme) // void qui selon la somme de saisieDuCode, permet de voir si le code est soit bon ou mauvais
// ********************************************************
{
if(somme == 20) // Si le code est correct
{
eteindreLaDEL();
afficherPageEcran(ecranDate);
#ifdef DEBUG
Serial << F(MSG_CODE);
Serial << somme;
Serial << F(MSG_CODE_VALIDATION);
Serial << F(MSG_CODE_CORRECT);
#endif
} // if
else // Si le code n'est pas correct
{
eteindreLaDEL();
afficherPageEcran(ecranDate);
#ifdef DEBUG
Serial << F(MSG_CODE);
Serial << somme;
Serial << F(MSG_CODE_VALIDATION);
Serial << F(MSG_CODE_INCORRECT);
#endif
} // else
} // somme_code