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