Differences

This shows you the differences between two versions of the page.

Link to this comparison view

pm:prj2023:vstoica:fire_alarm [2023/05/28 23:21]
tudor.selea [Software Design]
pm:prj2023:vstoica:fire_alarm [2023/05/29 19:06] (current)
tudor.selea [Software Design]
Line 40: Line 40:
  
 ===== Software Design ===== ===== Software Design =====
 +Implementarea software a proiectului poate fi reprezentata prin urmatoarea diagrama de stari:
 +
 +{{:​pm:​prj2023:​vstoica:​diagrama_de_stari_-_pm.drawio.png?​700|}}
  
 <note tip> <note tip>
Line 89: Line 92:
 </​code>​ </​code>​
  
-   In setup, A0 si A1 sunt setati ca pini de input, A0 primind concentratia de gaz de la senzorul de gaz, iar A1 primind temperatura de la senzorul de temperatura. Buzzer-ul este setat pe HIGH initial deoarece el este activ pe LOW, iar acesta trebuie sa fie activ doar in momentul declansarii alarmei. +In setup, A0 si A1 sunt setati ca pini de input, A0 primind concentratia de gaz de la senzorul de gaz, iar A1 primind temperatura de la senzorul de temperatura. Buzzer-ul este setat pe HIGH initial deoarece el este activ pe LOW, iar acesta trebuie sa fie activ doar in momentul declansarii alarmei. ​Cand alarma este pornita, mesajul "​Loading Fire Alarm..."​ este afisat pe LCD timp de 5 secunde. 
-   ​Cand alarma este pornita, mesajul "​Loading Fire Alarm..."​ este afisat pe LCD timp de 5 secunde.+ 
 +<code c> 
 +void setup() 
 +
 +  pinMode(A0, INPUT); 
 +  pinMode(A1, INPUT); 
 +  pinMode(LED,​ OUTPUT); 
 +  pinMode(buzzer,​ OUTPUT); 
 +   
 +  // LED-ul este setat initial pe LOW 
 +  digitalWrite(LED,​ LOW); 
 + 
 +  // Buzzer-ul este setat initial pe HIGH deoarece el este activ pe LOW 
 +  digitalWrite(buzzer,​ HIGH); 
 +   
 +  // Initializarea LCD-ului 
 +  lcd.begin(16,​ 2); 
 +  lcd.init();​ 
 +  lcd.backlight();​ 
 + 
 +  // Initializarea comunicarii Seriale si a monitorului Serial 
 +  Serial.begin(9600);​ 
 +  ​ 
 +  // ​Cand alarma este pornita, mesajul "​Loading Fire Alarm..."​ este 
 +  // afisat pe LCD 
 +  lcd.setCursor(0,​ 0); 
 +  lcd.print("​Loading Fire"​);​ 
 +  lcd.setCursor(0,​ 1); 
 +  lcd.print("​Alarm..."​);​ 
 +  delay(5000);​ 
 +  lcd.clear();​ 
 +
 + 
 +</​code>​ 
 + 
 +Senzorul de temperatura TMP36 va trimite placutei Arduino o valoare intre 0 si 1024, care este ulterior convertita in grade Celsius. 
 + 
 +<code c> 
 +// Arduino citeste output-ul senzorului de temperatura TMP36 
 +  read_temp = analogRead(A1);​ 
 +  
 +  // Convertim tensiunea citita din valoarea numerica ADC in volti 
 +  temp_voltage = (double)read_temp / 1024; 
 +  temp_voltage *= 5; 
 + 
 +  // Convertim temperatura obtinuta din volti in grade celsius 
 +  // Obs! Offset-ul de 0.5 ajuta la citirea temperaturilor negative 
 +  temp = (temp_voltage - 0.5) * 100; 
 +</​code>​ 
 + 
 +Daca temperatura inregistrata de senzor depaseste 70 de grade Celsius, iar senzorul de gaz detecteaza o densitate a monoxidului de carbon mai mare de 150 ppm, alarma se va declansa prin setarea LED-ului pe HIGH, buzzer-ului pe LOW si prin afisarea mesajului "​Pericol incendiu!!!"​ pe LCD. 
 + 
 +Totodata, variabila "​alarm_trigger"​ va fi actualizata la valoarea 1 si trimisa celei de a doua placute Arduino pentru a activa keypad-ul. 
 + 
 +Programul nu-si va continua executia pana cand "​alarm_trigger"​ nu va fi actualizat la 0 de catre a doua placuta Arduino, confirmand, astfel, dezactivarea cu succes a alarmei. Dupa dezactivarea alarmei, mesajul "​Alarma oprita!"​ va fi afisat ​timp de 5 secunde, dupa care programul va trece la urmatoarea iteratie a loop-ului. 
 +<code c> 
 +// Daca temperatura si concentratia de gaz depasesc valorile limita, 
 +  // LED-ul va fi setat pe HIGH, buzzer-ul va fi setat pe LOW, iar pe ecranul 
 +  // LCD va fi afisat un mesaj care indica pericolul aparitiei unui incendiu  
 +  if (read_gas >= 150 && temp >= 70) 
 +  {  
 +    alarm_trigger = 1; 
 +    digitalWrite(LED,​ HIGH); 
 +    digitalWrite(buzzer,​ LOW); 
 +    lcd.setCursor(0,​ 0); 
 +    lcd.print("​Pericol incendiu"​);​ 
 +    lcd.setCursor(0,​ 1); 
 +    lcd.print("​!!!!!!!!!!!!!!!!"​);​ 
 +     
 +    // Aceasta placuta Arduino va trimite celei de a doua placute Arduino 
 +    // variabila "​alarm_trigger",​ care activeaza tastatura numerica (conectata 
 +    // la a doua placuta Arduino) atunci cand "​alarm_trigger"​ = 1; 
 +    Serial.write(alarm_trigger);​ 
 +     
 +    // Placuta Arduino asteapta de la a doua placuta confirmarea ca alarma a 
 +    // fost dezactivata (alarm_trigger = 0) 
 +    while (1) { 
 +      if (Serial.available()) { 
 +        alarm_trigger = Serial.read();​ 
 +        if (alarm_trigger == 0) { 
 +          break; 
 +        } 
 +      } 
 +    } 
 +     
 +    // In momentul in care alarma a fost oprita, LED-ul este setat pe LOW, buzzer-ul 
 +    // este dezactivat prin setarea pe HIGH, iar mesajul "​Alarma oprita!"​ este afisat 
 +    // pe ecranul LCD timp de 5 secunde, dupa care alarma va fi reactivata 
 +    lcd.clear();​ 
 +    digitalWrite(LED,​ LOW); 
 +    digitalWrite(buzzer,​ HIGH); 
 +    lcd.setCursor(0,​ 0); 
 +    lcd.print("​Alarma oprita!"​);​ 
 +    delay(5000);​ 
 +    lcd.clear();​ 
 +     
 +  } 
 +</​code>​
        
 +Daca alarma nu este activata, ecranul LCD va afisa temperatura camerei, actualizata la fiecare secunda.
 +
 +<code c>
 +    digitalWrite(LED,​ LOW);
 +    digitalWrite(buzzer,​ HIGH);
 +    lcd.setCursor(0,​ 0);
 +    lcd.print("​Temperatura:"​);​
 +    lcd.setCursor(0,​1);​
 +    String output = String(temp) + String((char)0xDF) + String("​C"​);​
 +    lcd.print(output);​
 +</​code>​
 +
 +
 +**Receiver_pm.ino**
 +
 +<note tip>
 +Acest fisier este incarcat pe placuta care controleaza:​
 +  * **Keypad-ul**
 +</​note>​
 +
 +In "​alarm_trigger"​ va fi retinuta variabila trimisa de prima placuta Arduino, care va semnala declansarea alarmei. Matricea "​keys"​ retine simbolurile keypad-ului,​ ROWS si COLS retin dimensiunile keypad-ului,​ iar rowPins si colPins retin pinii alocati pentru fiecare linie si coloana din keypad. Pe baza acestor variabile se va face maparea keypad-ului la Arduino.
 +<code c>
 +#include <​Keypad.h>​
 +
 +#define PASSWORD_LENGTH 10
 +
 +char alarm_trigger;​
 +
 +// Parola introdusa de utilizator
 +char password[PASSWORD_LENGTH];​
 +
 +// Parola corecta
 +char correct_password[PASSWORD_LENGTH]="​13468*#​AD";​
 +char count = 0;
 +
 +// Keypad-ul are 4 linii si 4 coloane
 +const byte ROWS = 4; 
 +const byte COLS = 4; 
 +
 +// Simbolurile keypad-ului
 +char keys[ROWS][COLS] = {
 +  {'​1',​ '​2',​ '​3',​ '​A'​},​
 +  {'​4',​ '​5',​ '​6',​ '​B'​},​
 +  {'​7',​ '​8',​ '​9',​ '​C'​},​
 +  {'​*',​ '​0',​ '#',​ '​D'​}
 +};
 +
 +// Pinii arduino corespunzatori tuturor coloanelor si liniilor
 +// keypad-ului
 +byte rowPins[ROWS] = {9, 8, 7, 6}; 
 +byte colPins[COLS] = {5, 4, 3, 2}; 
 +
 +// Vom genera un keypad pe baza dimensiunilor si a simbolurilor setate
 +// de programator
 +Keypad customKeypad = Keypad(makeKeymap(keys),​ rowPins, colPins, ROWS, COLS); ​
 +</​code>​
 +
 +Daca nu exista conectivitate cu prima placuta Arduino, nu pot fi citite date pe portul serial.
 +
 +Daca exista conectivate,​ se va citi semnalul de alarma trimis de catre prima placuta Arduino in "​alarm_trigger"​. Daca acesta este 1, alarma a fost declansata, astfel ca poate fi introdus codul pentru dezactivarea acesteia. Fiecare tasta apasata de utilizator va fi retinuta in variabila "​customKey"​ si va fi adaugata in array-ul "​password",​ care reprezinta parola introdusa de utilizator. Daca dimensiunea parolei introduse de utilizator este egala cu dimensiunea parolei corecte, se vor compara cele 2 parole. In caz de egalitate (utilizatorul a introdus parola corecta), prima placuta Arduino va fi instiintata de catre a doua placuta Arduino (placuta curenta), ca poate sa dezactiveze alarma, iar keypad-ul va fi dezactivat pana la urmatoarea declansarea a alarmei. In caz contrar, se va reincerca introducerea parolei corecte.
 +<code c>
 +void loop(){
 +
 +  // Daca nu exista conectivitate cu prima placuta Arduino
 +  // nu pot fi citite date pe portul serial
 +  if (Serial.available()) {
 +    Serial.print("​In serial loop..."​);​
 +    Serial.println();​
 +
 +    // Variabila care semnaleaza declansarea alarmei
 +    alarm_trigger = Serial.read();​
 +    ​
 +    if (alarm_trigger == 1) {
 +      Serial.print("​Alarm triggered..."​);​
 +      Serial.println();​
 +
 +      // Daca alarma a fost declansata, se va incerca
 +      // introducerea parolei pana cand este cea corecta
 +      while(1) {
 +
 +        // Tasta apasata de utilizator va fi intoarsa in
 +        // variabila "​customKey"​
 +        char customKey = customKeypad.getKey();​
 +
 +        if(customKey){
 +          ​
 +          // Caracterul corespunzator tastei apasate de
 +          // utilizator va fi adaugat in parola introdusa
 +          // de utilizator
 +          password[count]=customKey;​
 +          Serial.print(password[count]);​
 +          count++;
 +        }
 +
 +        // In momentul in care lungimea parolei introduse
 +        // de utilizator este egala cu lungimea parolei
 +        // corecte, se va verifica daca parola introdusa
 +        // de utilizator este corecta
 +        if(count == PASSWORD_LENGTH - 1){
 +          Serial.println("​ ");
 +
 +          if(strcmp(password,​correct_password) == 0){
 +
 +            // Dupa verificarea parolei introduse de
 +            // utilizator, aceasta va fi stearsa si pregatita
 +            // pentru reintroducerea parolei, cand va fi cazul
 +            while(count !=0) {
 +              password[count]=0;​
 +              count--;
 +            }
 +
 +            // Daca parola introdusa de utilizator este corecta,
 +            // prima placuta Arduino va fi instiintata de catre
 +            // a doua placuta Arduino (placuta curenta), ca poate
 +            // sa dezactiveze alarma
 +            Serial.println("​Correct"​);​
 +            alarm_trigger = 0;
 +            Serial.write(alarm_trigger);​
 +            break;
 +
 +          } else{
 +
 +            // Daca parola introdusa de utilizator este incorecta,
 +            // se va reincerca introducerea parolei
 +            Serial.println("​Incorrect"​);​
 +            alarm_trigger = 1;
 +          }
 +
 +          while(count !=0){
 +              password[count]=0;​
 +              count--;
 +          }
 +        }
 +      }
 +    }
 +  }
 +}
 +</​code>​
 +
 +<​note>​
 +Dupa introducerea unei parole de catre utilizator, aceasta va fi stearsa!
 +</​note>​
 +
 +
 +===== Rezultate obtinute =====
 +{{:​pm:​prj2023:​vstoica:​poza_pm1.jpg?​700|}}\\
 +{{:​pm:​prj2023:​vstoica:​poza_pm4_1.jpg?​700|}}\\
 +{{:​pm:​prj2023:​vstoica:​poza_pm3.jpg?​700|}}\\
 +{{:​pm:​prj2023:​vstoica:​poza_pm2.jpg?​700|}}\\
 +
 +===== Concluzii =====
 +
 +Mi-a placut sa lucrez la acest proiect intrucat am putut sa pun in practica notiunile invatate la laboratoare pentru a realiza un lucru cu aplicatie in viata. Mi-a placut, in special, sa lucrez cu componentele proiectului si sa observ cum se leaga si cum comunica intre ele.
 +
 +===== Download =====
 +{{:​pm:​prj2023:​vstoica:​selea_tudor_octavian_-_332ca_-_proiect_pm.zip|}}
  
 +===== Resurse =====
 +  * https://​ocw.cs.pub.ro/​courses/​pm/​lab/​lab4-2022
 +  * https://​ocw.cs.pub.ro/​courses/​pm/​lab/​lab1-2022
 +  * https://​ocw.cs.pub.ro/​courses/​pm/​lab/​lab6-2022
 +  * https://​www.youtube.com/​watch?​v=sPhcOm3FdOQ&​t=254s&​ab_channel=DomingoMartinez
 +  * https://​linuxhint.com/​serial-uart-communication-between-two-arduino/​
 +  * Proiect AD - Selea Tudor-Octavian (vezi sectiunea Downloads)
  
pm/prj2023/vstoica/fire_alarm.1685305308.txt.gz · Last modified: 2023/05/28 23:21 by tudor.selea
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0