

NOTE: Prendre le temps de regarder la simulation au complet
#include "Streaming.h"
#include <LiquidCrystal_I2C.h>
// ********************************************************
// Les enum
enum codesAlarme {
evenement_detection_mouvement,
ACK_evenement_detection_mouvement,
evenement_systeme_enligne,
ACK_evenement_systeme_enligne
};
// ********************************************************
// ********************************************************
// Les constantes (MACRO)
#define UART_CENTRALE Serial3
#define UART_SYSTEME_ALARME Serial1
#define UART_VITESSE_CONSOLE 9600
#define UART_VITESSE_CENTRALE 115200
#define UNE_SECONDE 1000
#define DEMI_SECONDE 500
#define DELAI_TRANSMISSION_MESSAGE UNE_SECONDE * 2
#define BOUTON_DELAI_REBOND 50
#define LCD_NB_LIGNE 4
#define LCD_NB_COLONNE 20
#define LCD_LIGNE1 0
#define LCD_LIGNE2 1
#define LCD_LIGNE3 2
#define LCD_LIGNE4 3
#define LCD_PREMIERE_COLONNE 0
#define LCD_ADRESSE_I2C 0x27
#define DETECTEUR_MOUVEMENT_ENTREE 7
// ********************************************************
// Déclaration des fonctions
void initialisationDesAppareils();
// ********************************************************
// ********************************************************
// Variables Globales
LiquidCrystal_I2C ecranPrincipal(LCD_ADRESSE_I2C,LCD_NB_COLONNE,LCD_NB_LIGNE);
// ********************************************************
// ********************************************************
// Début du programme
// ********************************************************
// ********************************************************
void setup()
// ********************************************************
{
Serial.begin(UART_VITESSE_CONSOLE);
initialisationDesAppareils();
ecranPrincipal.setCursor(0,1);
ecranPrincipal << "Connexion ....";
if (connexionALaCentrale()){
ecranPrincipal.setCursor(0,2);
ecranPrincipal << "Systeme en ligne";
}
}
// ********************************************************
void loop()
// ********************************************************
{
bool alarmeON = true;
afficherTempsEcoule();
if (digitalRead(DETECTEUR_MOUVEMENT_ENTREE)) {
Serial << "DETECTEUR_MOUVEMENT_ENTREE\n";
ecranPrincipal.clear();
ecranPrincipal << "Detection mouvement";
Serial << "Aviser la centrale de l'intrusion\n";
envoyerMessageVersLaCentrale(evenement_detection_mouvement);
while(digitalRead(DETECTEUR_MOUVEMENT_ENTREE)); // S'assurer que le détecteur est détendu.
ecranPrincipal.clear();
}
} // loop()
// ********************************************************
void initialisationDesAppareils()
// ********************************************************
{
ecranPrincipal.begin(LCD_NB_COLONNE,LCD_NB_LIGNE);
ecranPrincipal.backlight();
ecranPrincipal << "Initialisation...";
UART_SYSTEME_ALARME.begin(UART_VITESSE_CENTRALE);
UART_CENTRALE.begin(UART_VITESSE_CENTRALE);
pinMode(DETECTEUR_MOUVEMENT_ENTREE, INPUT);
} // initialisationDesAppareils
// ********************************************************
boolean connexionALaCentrale()
// ********************************************************
{
byte codeAlarme;
Serial << F("Tentative de connexion à la centrale ...") << endl;
UART_SYSTEME_ALARME.write(evenement_systeme_enligne);
delay(DELAI_TRANSMISSION_MESSAGE);
if (UART_CENTRALE.available()){
Serial << F("UART_CENTRALE.available()") << endl;
codeAlarme = UART_CENTRALE.read();
switch (codeAlarme) {
case evenement_systeme_enligne:
Serial << F("evenement_systeme_enligne") << endl;
Serial << F("Succes: Connexion à la centrale ...") << endl;
//afficherPageEcran(centraleSystemeEnLigne);
return true;
break;
default:
Serial << "Evenement non traité" << endl;
break;
} // switch
} // if available()
return false;
} // connexionALaCentrale
// ********************************************************
boolean envoyerMessageVersLaCentrale(codesAlarme message)
// ********************************************************
{
byte codeAlarme;
Serial << F("envoyerMessageVersLaCentrale") << endl;
UART_SYSTEME_ALARME.write(message);
delay(DELAI_TRANSMISSION_MESSAGE);
if (UART_CENTRALE.available()){
Serial << F("UART_CENTRALE.available()") << endl;
Serial << F("La centrale a reçu le message: ");
codeAlarme = UART_CENTRALE.read();
switch (codeAlarme) {
case evenement_detection_mouvement:
Serial << F("evenement_detection_mouvement") << endl;
return true;
break;
default:
Serial << "Evenement non traité" << endl;
break;
} // switch
} // if available()
return false;
} // connexionALaCentrale
// ***************************************************
void afficherTempsEcoule() {
// ***************************************************
static unsigned long depart = millis();
if (millis() - depart < UNE_SECONDE) return;
char bufferLigneLCD[21]; // Vecteur pour construire le message à afficher
depart = millis(); // Réinitialiser le temps qui passe ...
unsigned long tempsEcoule = millis() / 1000;
int secondes = tempsEcoule % 60;
int minutes = (tempsEcoule / 60 ) % 60;
int heures = (tempsEcoule / 3600 ) % 24;
int jours = 0;
snprintf(bufferLigneLCD, LCD_NB_COLONNE + 1, "Actif: %03d, %02d:%02d:%02d", 0, heures, minutes, secondes );
ecranPrincipal.setCursor(LCD_PREMIERE_COLONNE,LCD_LIGNE4);
ecranPrincipal.print(bufferLigneLCD);
} // afficherTemps()
// ********************************************************
// Fin du programme
// ********************************************************
NOTE: Ce code source est fonctionnel et produit le résultat de l’animation de la simulation 1.1
{
"version": 1.02,
"author": "Alain Boudreault",
"editor": "wokwi",
"parts": [
{ "type": "wokwi-arduino-mega", "id": "mega", "top": -16.21, "left": 449.2, "attrs": {} },
{
"type": "wokwi-lcd2004",
"id": "lcd1",
"top": -218.29,
"left": 469.8,
"attrs": { "pins": "i2c", "background": "blue", "color": "white" }
},
{
"type": "wokwi-pir-motion-sensor",
"id": "pir1",
"top": -216.95,
"left": 373.95,
"attrs": {}
}
],
"connections": [
[ "mega:19", "mega:14", "black", [ "v-16.99", "h-48" ] ],
[ "mega:18", "mega:15", "black", [ "h9.69", "v-16.99", "h-47.57", "v16.99" ] ],
[ "pir1:OUT", "mega:7", "black", [ "v15.38", "h-9.53", "v85.45", "h268.33" ] ],
[ "mega:49", "mega:51", "black", [ "v0.51", "h-4.54" ] ],
[
"pir1:GND",
"mega:GND.1",
"black",
[ "v17.09", "h-0.33", "v24.3", "h-0.09", "v21.41", "h-18.52", "v38.03", "h197.02" ]
],
[ "lcd1:GND", "pir1:GND", "black", [ "h-0.09", "v123.66", "h-83.59" ] ],
[ "lcd1:VCC", "pir1:VCC", "black", [ "v-9.83", "h-0.93", "v124.21", "h-102.21" ] ],
[ "pir1:VCC", "mega:5V", "black", [ "v100.95", "h242.96", "v93.43", "h0.08" ] ],
[ "lcd1:SDA", "mega:SDA", "black", [ "v104.88", "h-63.62", "v38.29", "h139.02" ] ],
[ "lcd1:SCL", "mega:SCL", "black", [ "v95.38", "h-63.62", "v38.3", "h129.02" ] ]
],
"dependencies": {}
}
La fonction doit retourner une valeur de type enum ‘codesAlarme‘ transmit par UART_CENTRALE . Par exemple, si la fonction ‘envoyerMessageVersLaCentrale‘ reçoit la valeur ‘evenement_detection_mouvement‘, ce code doit être transmit à UART_CENTRALE et UART_SYSTEME_ALARME attend la réponse. Cette réponse sera le code transmit avec comme préfix ‘ACK‘.
Par exemple: envoyerMessageVersLaCentrale(evenement_detection_mouvement) doit retourner ACK_evenement_detection_mouvement.
// Exemple
#define CODE_INVALIDE -1
placerIciLeBonType envoyerMessageVersLaCentrale(codesAlarme message)
{
byte codeAlarme;
Serial << F("envoyerMessageVersLaCentrale") << endl;
UART_SYSTEME_ALARME.write(message);
delay(DELAI_TRANSMISSION_MESSAGE);
if (UART_CENTRALE.available()){
Serial << F("UART_CENTRALE.available()") << endl;
Serial << F("La centrale a reçu le message: ");
codeAlarme = UART_CENTRALE.read();
switch (codeAlarme) {
case evenement_detection_mouvement:
Serial << F("evenement_detection_mouvement") << endl;
// *************** Section à compléter !!
// A - La centrale doit transmettre le code de confirmation 'ACK_evenement_detection_mouvement'
// B - Le système d'alarme attend la réponse de la centrale
// C - Le système d'alarme lit la réponse de la centrale et la retourne (return).
break;
default: Serial << "Evenement non traité" << endl;
break;
} // switch
} // if available()
return CODE_INVALIDE;
} // connexionALaCentrale