Ce projet a été réalisé dans le cadre du projet développement du semestre 2. Les élèves ayant participé au projet sont : Florian BOYRIVENT, Bérengère GRIFFON, Michel LE ROLLAND et Kun PENG. Le but de ce projet est de réaliser un système domotique permettant d’alerter par SMS le propriétaire de la maison en cas d’écart à la normale d’une donnée de la maison telle que la température, l’humidité ou encore la présence d’un intrus.
Nous avons réalisé le cahier des charges, un premier prototype avec un capteur de température et la communication par SMS, et un second prototype, qui prolonge le premier, avec une mise en réseau de capteurs de température et la disponibilité du réseau GSM.
Prototype 2 avec un réseau de capteurs de température, la communication par SMS et la disponibilité du réseau GSM
Matériel utilisé :
- Carte arduino UNO
- Fils
- 1 résistance 4,7kOhms
- 3 capteurs de température DS18B20
- Breadboard
- Shield GPRS SIM900
- Une carte SIM
Montage :
Diverses remarques :
– La librairie Arduino OneWire doit être téléchargée pour faire fonctionner le capteur de température avec la carte Arduino.
– La librairie Time doit être ajouté pour permettre à l’Arduino de décompter le temps.
– La taille du buffer Arduino doit être modifiée pour valoir 256.
Résultat :
Le système enverra un SMS d’alerte lorsque la température sortira de l’intervalle de température prédéfini (par défaut entre 15°C et 25°C), sauf si le réseau GSM n’est pas disponible où dans ce cas le système se mettra en attente et enverra le message lorsque le réseau sera retrouvé. Un second SMS de retour à la normale lorsque la température revient dans l’intervalle prédéfini est aussi envoyé.
L’utilisateur pourra également interroger le système par SMS, en envoyant un message de la forme « Temp numéro_du_capteur », le système lui renverra alors la température mesurée par le capteur pour lequel il a fait la demande. Si le SMS envoyé n’est pas du bon format, celui-ci ne sera pas traité.
Code :
Le code suivant est celui de notre prototype final. Pour les fonctions de base et le code des autres prototypes, se référer au lien Github suivant : https://github.com/telefab/capteursSMS
#include <SoftwareSerial.h> #include <OneWire.h> #include <Time.h> #define DS18B20 0x28 #define BROCHE_ONEWIRE 4 #define SEUIL_BAS 15.0 #define SEUIL_HAUT 25.0 #define TEMPS_ATTENTE 600 // Temps d'attente entre deux mesures de la température (en sec) #define TEMPS_ATTENTE_SECURITE 60 // Temps d'attente pour la mesure de vérification (en sec) #define TEMPS_ATTENTE_VEILLE 60 // Temps d'attente entre deux vérifications du réseau mobile (en sec) #define NOMBRE_CAPTEURS_MAX 10 // Nombre maximum de capteurs en série autorisé (valeur >= 1) #define SIM_PIN_CODE "0000" // Code Pin de la carte SIM // Variables relatives aux capteurs OneWire ds(BROCHE_ONEWIRE); byte adresseCapteurs[NOMBRE_CAPTEURS_MAX][8]; // Adresse des capteurs float temperatureCapteurs[NOMBRE_CAPTEURS_MAX]; boolean intervalleCapteurs[NOMBRE_CAPTEURS_MAX]; time_t tempsPrecedentCapteurs[NOMBRE_CAPTEURS_MAX]; int nombre_capteurs = 0; int capteurMesure = 0; // Variables relatives au module GPRS SoftwareSerial GPRS (7, 8); // GPRS : relatif au shield GPRS ; Serial : relatif à l'ordinateur String phone_number = "+336********"; // Numéro par défaut String msg = ""; // Mémoire tampon de la communication avec le module GPRS int CorpsSMS = false; // Est mis à 1 quand le prochain message du shield GPRS contiendra le contenu du SMS String numeroSMS; String numeroTemp = phone_number; boolean veille = true; time_t tempsPrecedentVeille; void setup() { delay (3000); GPRS.begin(19200); // Fréquence du module tempsPrecedentVeille = now(); // Setup Capteurs int i=0; Serial.begin(9600); // Initialisation du port série ds.reset(); ds.reset_search(); while ((nombre_capteurs < NOMBRE_CAPTEURS_MAX) && (ds.search(adresseCapteurs[nombre_capteurs]))) // Recherche des différents capteurs { tempsPrecedentCapteurs[nombre_capteurs] = now(); // Initialisation des variables du capteur temperatureCapteurs[nombre_capteurs] = (SEUIL_BAS + SEUIL_HAUT) / 2; intervalleCapteurs[nombre_capteurs] = true; nombre_capteurs++; } } void loop() { if (GPRS.available()) { executionGPRS(); } else { time_t time = now(); if ((time-tempsPrecedentVeille) >= TEMPS_ATTENTE_VEILLE)< { reseauIndisponible(); // Vérification du réseau tempsPrecedentVeille = time; } if (!veille) { if ((time-tempsPrecedentCapteurs[capteurMesure]) >= TEMPS_ATTENTE) { mesureCapteur(capteurMesure); // Mesure sur le capteur tempsPrecedentCapteurs[capteurMesure] = time; } capteurMesure++; if (capteurMesure == nombre_capteurs) { capteurMesure = 0; } } } } void mesureCapteur (const int i) // Demande de la température du capteur i { getTemperature (&temperatureCapteurs[i], adresseCapteurs[i]); if (intervalleCapteurs[i] & ((temperatureCapteurs[i] < SEUIL_BAS) | (temperatureCapteurs[i] > SEUIL_HAUT))) // On sort de l'intervalle acceptable { delay (TEMPS_ATTENTE_SECURITE*1000); // Attente tempsPrecedentCapteurs[i] = now(); getTemperature (&temperatureCapteurs[i], adresseCapteurs[i]); if ((temperatureCapteurs[i] < SEUIL_BAS) | (temperatureCapteurs[i] > SEUIL_HAUT)) // Seconde vérification { reseauIndisponible(); // Vérification du réseau tempsPrecedentVeille = now(); if (!veille) { intervalleCapteurs[i]=false; envoyerUnMessage (temperatureCapteurs[i], true, i+1); } } } else if (!intervalleCapteurs[i] & (temperatureCapteurs[i] > SEUIL_BAS) & (temperatureCapteurs[i] < SEUIL_HAUT)) // On rentre à nouveau dans cet intervalle { delay (TEMPS_ATTENTE_SECURITE*1000); // Attente tempsPrecedentCapteurs[i] = now(); getTemperature (&temperatureCapteurs[i], adresseCapteurs[i]); if ((temperatureCapteurs[i] > SEUIL_BAS) & (temperatureCapteurs[i] < SEUIL_HAUT)) // Seconde vérification { reseauIndisponible(); // Vérification du réseau tempsPrecedentVeille = now(); if (!veille) { intervalleCapteurs[i]=true; envoyerUnMessage (temperatureCapteurs[i], true, i+1); } } } } void getTemperature (float *temp, const byte addr[]) { byte data[2]; ds.reset(); ds.select(addr); // Sélectionne le capteur de température ds.write(0x44,1); // Lance la mesure de température delay(800); ds.reset(); // Reset pour envoyer maintenant la demande de lecture ds.select(addr); ds.write(0xBE); // Demande de lecture du scratchpad data[0] = ds.read(); // Lit les 2 premiers octets du scratchpad sur lesquels est contenue la température data[1] = ds.read(); *temp = ((data[1] << 8) | data[0]) * 0.0625; // Conversion en degrés celsius } void executionGPRS () { char SerialInByte = (unsigned char)GPRS.read(); // Réception du caractère envoyé par le module GPRS if (SerialInByte == 13) { // Si le message se termine par un <CR> alors on traite le message gestionCommunicationGPRS(); } else if (SerialInByte != 10) { // On ignore le caractère interligne msg += String(SerialInByte); // Stockage du caractère dans la mémoire tampon } } void gestionCommunicationGPRS () { // Interprete le message du GPRS shield et agit en conséquence if (msg.indexOf("+CPIN: SIM PIN") >= 0) { // Demande du code Pin de la carte SIM GPRS.print("AT+CPIN="); // Envoi du code Pin GPRS.println( SIM_PIN_CODE ); } if (msg.indexOf("Call Ready") >= 0) { // Le réseau mobile est disponible GPRS.println("AT+CMGF=1"); } // Utilisation du mode texte pour la gestion des messages SMS // Opérations relatives à la réception d'un SMS if (msg.indexOf("+CMTI") >= 0) { // Phase 1 : début de réception d'un SMS int iPos = msg.indexOf(","); numeroSMS = msg.substring(iPos+1); GPRS.print("AT+CMGR="); // Demande de lecture des informations du message GPRS.println(numeroSMS); } if (msg.indexOf("+CMGR:") >= 0) { // Phase 2 : réception du numéro de l'expéditeur int iPos = msg.indexOf("+33"); numeroTemp = msg.substring(iPos, iPos+12); CorpsSMS = true; msg = ""; return; } // Le prochain message contiendra le corps du SMS if (CorpsSMS == 1) { // Phase 3 : corps du SMS traiterSMS(msg); // Traitement du corps du message GPRS.print("AT+CMGD="); // Suppression du SMS pour ne pas encombrer la carte SIM GPRS.println(numeroSMS); delay(1000); } msg = ""; // Efface le contenu de la mémoire tampon des messages du GPRS shield CorpsSMS = false; } void traiterSMS(const String smsText) { for (int i=0; i < nombre_capteurs; i++) { if (smsText.indexOf("Temp "+String(i+1)) >= 0) { // Demande d'envoi de la température du capteur i phone_number = numeroTemp; // Remplacement du numéro envoyerUnMessage (temperatureCapteurs[i], false, i+1); delay(1000); } } } void envoyerUnMessage(const float temp, const boolean messageAutomatique, const int numeroCapteur) { delay(500); GPRS.print("AT+CMGS=\""); // Parametrage du numéro GPRS.print(phone_number); GPRS.print("\"\r\n"); while(GPRS.read()!='>'); if (messageAutomatique) { // Corps du SMS : 3 possibilités if (!intervalleCapteurs[numeroCapteur-1]) { GPRS.print("Attention, le seuil critique de temperature dans le capteur "); GPRS.print(numeroCapteur); GPRS.print(" a ete atteint. La temperature est de "); } else { GPRS.print("La temperature dans le capteur "); GPRS.print(numeroCapteur); GPRS.print(" est de nouveau acceptable. Elle est de "); } } else { GPRS.print("La temperature dans le capteur "); GPRS.print(numeroCapteur); GPRS.print(" est de "); } GPRS.print(temp, 2); GPRS.print(" degres celsius."); delay(500); GPRS.write(0x1A); // Finalisation du SMS et envoi GPRS.write(0x0D); GPRS.write(0x0A); delay(20000); } void reseauIndisponible() // Gère le réseau mobile { GPRS.print("AT+CREG?\r\n"); // Demande de l'enregistrement sur le réseau while (!GPRS.available()); while (GPRS.read() != 44); // Jusqu'à la virgule ',' veille = GPRS.read() != 49; // Analyse du résultat : ‘1’ ou pas }
Bonjour,
Est-ce que le code est totalement fonctionnel ?
Bonjour,
oui, le code est fonctionnel.
Est-ce que je peut utiliser le même code pour un shield GSM sim900 ?? qu’est ce que je doit modifier ?? merci d’avance
Bonjour
J’ai essayé ce code; mais après avoir un petit modification je rencontre un problème. Voici alors les modifications:
– ligne 6: #define SEUIL_BAS 2.0
– ligne 7: #define SEUIL_HAUT 8.0
– ligne 16: byte adresseCapteurs[NOMBRE_CAPTEURS_MAX][1]; // Adresse des capteurs
– ligne 24: SoftwareSerial GPRS (2, 3); // GPRS : relatif au shield GPRS ; Serial : relatif à l’ordinateur
– ligne 25: String phone_number = « +261343726819 »; // Numéro par défaut
– ligne 148: int iPos = msg.indexOf(« +261 »);
Après ces modifications, je le téléverser et l’erreur est:
2:21: fatal error: OneWire.h: No such file or directory
Quand je modifie la ligne 2 par: #include il y a encore l’erreur: 3:18: fatal error: Time.h: No such file or directory
Sur ce dernier, je n’arrive encore la solution. Pourrez-vous me donner une solution s’il vous plait?
à bientôt! merci
Bjr, avec la solution MEMOGuard il est possible de récupérer l’ensemble des alertes, pour tous les capteurs.. bonne lecture cdt
bonjour
ou est la foction now() ?
tilise ligne 36, 44, 55,80, 85, 95, 100
Cordialement
dans la lib time.h
il faut ajouter
#include
#include
cdt
je ne comprends pas. meme probleme avec now qui n’est pas declare
dans la lib time.h
il faut ajouter
#include quoi ?
#include et quoi ?
cdt
Bonjour,
J’aimerai savoir si vous avez fait une simulation de ce système. Si oui, comment ? Et avec quoi ?
Merci d’avance