Differences

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

Link to this comparison view

pm:prj2025:vstoica:catalina.buduran [2025/05/18 17:26]
catalina.buduran [Descriere generală]
pm:prj2025:vstoica:catalina.buduran [2025/06/01 18:06] (current)
catalina.buduran
Line 90: Line 90:
   * Listă de piese:   * Listă de piese:
  
-^ Componentă ​        ​^ Funcție ​                                     ^ Observații ​                 ^ Link achiziție ^ +^ Componentă ^ Funcție ^ Observații ^ Link achiziție ​^ Datasheet ​^  
-| Senzor MQ-2        | Detectare gaz/​fum ​                           | Ieșire analogică ​           |https://​www.optimusdigital.ro/​ro/​senzori-de-gaze/​107-modul-senzor-gas-mq-2.html?​srsltid=AfmBOormajFOPYXcsz-QCVE9LG83N2xJM_7tD-XRZJHLsRFOAaUEKouj ​+| Senzor MQ-2       ​| Detectare gaz/​fum ​                          ​| Ieșire analogică ​                                                                           [[https://​www.optimusdigital.ro/​ro/​senzori-de-gaze/​107-modul-senzor-gas-mq-2.html|Optimus MQ-2]] | [[https://​www.pololu.com/​file/​0j309/​mq2.pdf|MQ-2 PDF]] 
-| Senzor flacără ​    ​| Detectare flacără ​                           | Ieșire analogică/​digitală ​  ​| https://​www.optimusdigital.ro/​ro/​senzori-senzori-optici/​110-modul-senzor-de-flacara-.html?​search_query=senzor+flacara&​results=2 ​+| Senzor flacără ​   | Detectare flacără ​                          ​| Ieșire analogică/​digitală ​                                                                  ​[[https://​www.optimusdigital.ro/​ro/​senzori-senzori-optici/​110-modul-senzor-de-flacara-.html|Optimus Flacără]] | [[https://​gazproequipments.ro/​assets/​pdf/​Manual_Flame-detectors_UV-UVIR-IR3.pdf|Senzor flacără]] ​
-| LCD 16x2 I2C       ​| Afișare mesaje ​                              ​| Comunicare I2C              | https://​www.optimusdigital.ro/​ro/​optoelectronice-lcd-uri/​2894-lcd-cu-interfata-i2c-si-backlight-albastru.html?​search_query=LCD+I2C&​results=17 ​+| LCD 16x2 I2C      | Afișare mesaje ​                             | Comunicare I2C                                                                             ​[[https://​www.optimusdigital.ro/​ro/​optoelectronice-lcd-uri/​2894-lcd-cu-interfata-i2c-si-backlight-albastru.html|LCD I2C]] | [[https://​www.handsontec.com/​dataspecs/​module/​I2C_1602_LCD.pdf|LCD]] ​
-| Buzzer pasiv       ​| Alertă sonoră ​                               | Controlat prin PWM          | https://​www.optimusdigital.ro/​ro/​audio-buzzere/​12247-buzzer-pasiv-de-33v-sau-3v.html?​search_query=buzzer+pasiv&​results=14+| Buzzer pasiv      | Alertă sonoră ​                              ​| Controlat prin PWM                                                                         ​[[https://​www.optimusdigital.ro/​ro/​audio-buzzere/​12247-buzzer-pasiv-de-33v-sau-3v.html|Buzzer ​pasiv]] | [[https://​www.farnell.com/​datasheets/​2171929.pdf|Buzzer]] ​
-| LED roșu           ​| Aprins la detecție ​                          ​| Pin digital ​                ​| https://​www.optimusdigital.ro/​ro/​optoelectronice-led-uri/​708-led-infrarosu-de-5-mm-cu-lungime-de-unda-940-nm.html?​search_query=led+rosu&​results=166 ​+| LED roșu          | Aprins la detecție ​                         | Pin digital ​                                                                               [[https://​www.optimusdigital.ro/​ro/​optoelectronice-led-uri/​708-led-infrarosu-de-5-mm-cu-lungime-de-unda-940-nm.html|LED roșu]] | [[https://​www.farnell.com/​datasheets/​1498852.pdf|LED Roșu]] ​
-| LED verde          | Aprins când aerul e curat                    | Pin digital ​                ​| https://​www.optimusdigital.ro/​ro/​optoelectronice-led-uri/​708-led-infrarosu-de-5-mm-cu-lungime-de-unda-940-nm.html?​search_query=led+rosu&​results=166+| LED verde         ​| Aprins când aerul e curat                   ​| Pin digital ​                                                                               [[https://​www.optimusdigital.ro/​ro/​optoelectronice-led-uri/​708-led-infrarosu-de-5-mm-cu-lungime-de-unda-940-nm.html|LED verde]] | [[https://​www.farnell.com/​datasheets/​1498852.pdf|LED Verde]] ​
-| Cablu USB          | Transmitere date către laptop (UART) ​       | Comunicare serială ​         | https://​www.optimusdigital.ro/​ro/​cabluri-cabluri-usb/​3146-cablu-albastru-usb-am-la-bm-30-cm-pentru-arduino-mega-i-uno.html?​search_query=cablu+usb&​results=264 ​+| Cablu USB         ​| Transmitere date către laptop (UART) ​      ​| Comunicare serială ​                                                                        ​[[https://​www.optimusdigital.ro/​ro/​cabluri-cabluri-usb/​3146-cablu-albastru-usb-am-la-bm-30-cm-pentru-arduino-mega-i-uno.html|Cablu USB]] | [[https://​datasheet.octopart.com/​353929-1-TE-Connectivity---AMP-datasheet-536531.pdf|Cablu USB]] 
-| Arduino UNO | Microcontroler – control principal | Comunică cu toate componentele (senzori, buzzer, LED-uri, LCD) prin pini digitali, analogici și I2C. Rulează codul principal ​și gestionează logica proiectului ​| https://​www.optimusdigital.ro/​ro/​compatibile-cu-arduino-uno/​1678-placa-de-dezvoltare-compatibila-cu-arduino-uno-atmega328p-i-ch340.html?​search_query=arduino+un&​results=540 ​+| Arduino UNO       ​| Microcontroler – control principal ​         | Comunică cu toate componentele (senzori, buzzer, LED-uri, LCD) prin pini digitali, analogici și I2C. Rulează codul principal[[https://​www.optimusdigital.ro/​ro/​compatibile-cu-arduino-uno/​1678-placa-de-dezvoltare-compatibila-cu-arduino-uno-atmega328p-i-ch340.html|Arduino UNO]] | [[https://​docs.arduino.cc/​resources/​datasheets/​A000066-datasheet.pdf|Arduino UNO]] 
-| Breadboard | Platformă de conectare fără lipire | Permite conectarea rapidă și temporară a componentelor ​și a firelor. Distribuie 5V și GND către ​senzorii și modulele proiectului ​| https://​www.optimusdigital.ro/​ro/​prototipare-breadboard-uri/​13249-breadboard-300-puncte.html?​search_query=breadboard&​results=125 ​+| Breadboard ​       | Platformă de conectare fără lipire ​         | Permite conectarea rapidă a componentelor. Distribuie 5V și GND către ​toată rețeaua ​       ​[[https://​www.optimusdigital.ro/​ro/​prototipare-breadboard-uri/​13249-breadboard-300-puncte.html|Breadboard]] | [[https://​components101.com/​sites/​default/​files/​component_datasheet/​Breadboard%20Datasheet.pdf| Breadboard]] ​
-| Fire tată-tată | Conectare între componente și breadboard/​arduino ​Se folosesc pentru legarea pinilor plăcii Arduino ​la senzori, buzzer, LED-uri, LCD, prin breadboard. Asigură conexiunile electrice fără lipire ​| https://​www.optimusdigital.ro/​ro/​fire-fire-mufate/​886-set-fire-tata-tata-40p-15-cm.html?​search_query=fire+tata+tata&​results=73&​HTTP_REFERER=https%3A%2F%2Fwww.optimusdigital.ro%2Fro%2Fcautare%3Fcontroller%3Dsearch%26orderby%3Dposition%26orderway%3Ddesc%26search_query%3Dfire%2Btata%2Btata%26submit_search%3D ​| +| Fire tată-tată ​   | Conectare între componente și Arduino ​      Asigură conexiuni electrice fără lipire. Leagă pinii Arduino ​de senzori, buzzer, LED-uri ​  ​[[https://​www.optimusdigital.ro/​ro/​fire-fire-mufate/​886-set-fire-tata-tata-40p-15-cm.html|Fire tată-tată]] | - |
  
 ===== Software Design ===== ===== Software Design =====
  
 +Proiectul este funcțional și implementează următoarele:​
 +
 +  * Detectarea flăcării (senzor digital pe D9)
 +
 +  * Detectarea gazului/​fumului (senzor analogic MQ-2 pe A1)
 +
 +  * Reacție vizuală și sonoră: LED-uri și buzzer
 +
 +  * Transmiterea datelor senzorilor prin UART (Serial) către laptop
 +
 +  * Toate funcționalitățile sunt scrise cu acces direct la registre (PORTx, DDRx, ADC, UART, PWM)
 +
 +Proiectul meu nu folosește biblioteci externe Arduino. Toate funcționalitățile (PWM, UART, ADC, GPIO) au fost implementate folosind registre directe ale microcontrolerului ATmega328P, deoarece reflectă înțelegerea profundă a hardware-ului,​ dar și corelare directă cu conceptele din laborator. Proiectul este scris exclusiv cu registre AVR, fără funcții Arduino. Toate componentele hardware sunt controlate la nivel de low-level, iar proiectul este calibrat și funcțional pe o placă compatibilă Arduino.
 +
 +Calibrarea senzorilor
 +  * Pentru gaz: am stabilit empiric un prag de detecție la > 300 (valoare ADC), testând cu bricheta sau fum de chibrit.
 +  * Pentru flacără: senzorul returnează LOW la detecție, iar pragul este binar (nu necesită calibrare).
 +  * Calibrarea s-a realizat comparând valorile UART în condiții de aer curat vs. poluat.
 +
 +Optimizări realizate
 +  * Folosirea directă a registrelor elimină funcții costisitoare (ex: analogRead(),​ tone()), reducând latențele
 +  * PWM activat doar la nevoie, apoi complet dezactivat pentru a evita zgomot rezidual
 +  * UART rulează asincron, neblocant pentru restul logicii
 +  * Bucla principală are un delay controlat pentru a nu satura UART-ul și pentru a permite actualizări corecte
 +
 +{{pm:​prj2025:​vstoica:​whatsapp_image_2025-05-18_at_18.04.28.jpeg?​450}}
 +
 +
 +{{pm:​prj2025:​vstoica:​whatsapp_image_2025-05-18_at_18.03.42.jpeg?​450}}
 +
 +{{pm:​prj2025:​vstoica:​whatsapp_image_2025-05-18_at_18.05.04.jpeg?​450}}
 +
 +| **Laborator** ​    | **Temă** ​     | **Funcționalitate folosită în proiect** ​                                                                                            |
 +
 +| **Laboratorul 0** | GPIO          | Control LED roșu (D8) și LED verde (D11), citire senzor flacără (D9) prin `PINB` |                         |
 +| **Laboratorul 1** | UART          | Trimitere valori citite de la senzorii de gaz și flacără către laptop prin UART |                                |
 +| **Laboratorul 3** | Timere și PWM | Generare sunet buzzer prin **Timer0** în modul **Fast PWM** pe pinul **PD6** (`TCCR0A`, `OCR0A`) |                          |
 +| **Laboratorul 4** | ADC           | Citire analogică de la senzorul MQ-2 (gaz/fum) prin canalul |
 +| **Laboratorul 6** | I2C           |LCD I2C |
 +
 +Explicarea codului:
 +| **Componentă** ​      | **Funcție din cod**                                             | **Rol principal** ​                                                                
 +| **Buzzer (PWM)** ​    | `pwm_start()` și `pwm_stop()` ​                                  | Pornește/​oprește semnalul sonor generat pe pinul D6 prin Timer0 (Fast PWM)       |
 +| **Senzor gaz (ADC)** | `adc_init()` și `citeste_adc()` ​                                | Inițializează convertorul analog-digital și citește tensiunea de la MQ-2         |
 +| **Serial (UART)** ​   | `uart_init()`,​`uart_transmit()`,​`uart_print()`,​`uart_print_number()` | Trimite mesaje către laptop prin USB pentru a vizualiza starea senzorilor |
 +| **LED-uri și senzori** | în `main()` ​                                                  | LED verde/roșu indică stare normală/​pericol. Senzor flacără (digital pe D9)       |
 +
 +
 +
 +Interacțiunea dintre funcționalități
 +  * Senzorul de flacără (D9 - PB1): citit ca digital ((PINB & (1 << PB1)) == 0) → dacă flacără detectată, devine true.
 +  * Senzorul de gaz (A1 - ADC1): se citește analog cu funcția citeste_adc() → dacă valoarea depășește pragul 300, se consideră pericol.
 +  * LED-urile: LED roșu (D8 - PB0) aprins dacă există pericol (gaz sau flacără), LED verde (D11 - PB3) aprins în mod normal
 +  * Buzzerul: e pornește doar dacă e detectat pericol → se activează PWM prin pwm_start(),​ care setează Timer0 în Fast PWM cu frecvență de 2kHz
 +  * UART: trimite în fiecare ciclu starea citită: "Gaz: 364 | Flacara: 1" către laptop
 +
 +Validarea funcționării
 +  * LED-uri: verificate vizual în funcție de condiții (roșu la pericol, verde normal)
 +  * Buzzer: testat auditiv că pornește doar când e gaz sau flacără, și se oprește complet altfel
 +  * UART: testat în laptop, dacă laptopul primește date
 +  * Senzor gaz: testat cu o brichetă – valorile cresc în UART, buzzer și LED roșu se activează
 +  * Senzor flacără: testat apropiind flacără - detectare instantanee
 +
 +#include <​avr/​io.h>​
 +#include <​util/​delay.h>​
 +#include "​twi.h"​
 +
 +#define LCD_ADDR 0x27
 +#define LCD_BACKLIGHT 0x08
 +#define LCD_ENABLE ​   0x04
 +#define LCD_RS ​       0x01
 +
 +
 +void delay_ms_custom(uint16_t ms) {
 +    for (uint16_t i = 0; i < ms; i++) {
 +        TCNT2 = 0;                   
 +        TIFR2 |= (1 << OCF2A);  ​
 +
 +        while (!(TIFR2 & (1 << OCF2A))) {
 +            //astept (1ms)
 +        }
 +    }
 +}
 +
 +void lcd_send_nibble(uint8_t nibble, uint8_t rs) {
 +    uint8_t data = (nibble & 0xF0) | LCD_BACKLIGHT;​
 +    if (rs) 
 +        data |= LCD_RS;
 +
 +    twi_start();​
 +    twi_write(LCD_ADDR << 1);
 +    twi_write(data | LCD_ENABLE);​
 +    _delay_us(1);​
 +    twi_write(data & ~LCD_ENABLE);​
 +    twi_stop();
 +}
 +
 +void lcd_send_byte(uint8_t data, uint8_t rs) {
 +    lcd_send_nibble(data & 0xF0, rs);
 +    lcd_send_nibble((data << 4) & 0xF0, rs);
 +    delay_ms_custom(1);​
 +}
 +
 +void lcd_command(uint8_t cmd) {
 +    lcd_send_byte(cmd,​ 0);
 +}
 +
 +void lcd_write_char(char c) {
 +    lcd_send_byte(c,​ 1);
 +}
 +
 +void lcd_print(const char* str) {
 +    while (*str) lcd_write_char(*str++);​
 +}
 +
 +void lcd_clear() {
 +    lcd_command(0x01);​
 +    delay_ms_custom(2);​
 +}
 +
 +void lcd_set_cursor(uint8_t col, uint8_t row) {
 +    uint8_t row_offsets[] = {0x00, 0x40};
 +    lcd_command(0x80 | (col + row_offsets[row]));​
 +}
 +
 +void lcd_print_number(uint16_t val) {
 +    char buf[6];
 +    uint8_t i = 0;
 +
 +    if (val == 0) {
 +        lcd_write_char('​0'​);​
 +        return;
 +    }
 +
 +    while (val > 0 && i < 5) {
 +        buf[i++] = '​0'​ + (val % 10);
 +        val /= 10;
 +    }
 +
 +    while (i > 0) {
 +        lcd_write_char(buf[--i]);​
 +    }
 +}
 +
 +void lcd_init() {
 +    delay_ms_custom(50);​
 +    lcd_send_nibble(0x30,​ 0); delay_ms_custom(5);​
 +    lcd_send_nibble(0x30,​ 0); delay_ms_custom(150);​
 +    lcd_send_nibble(0x30,​ 0); delay_ms_custom(150);​
 +    lcd_send_nibble(0x20,​ 0); delay_ms_custom(150);​
 +
 +    lcd_command(0x28);​
 +    lcd_command(0x0C);​
 +    lcd_command(0x06);​
 +    lcd_command(0x01);​
 +    delay_ms_custom(2);​
 +}
 +
 +void pwm_start(uint8_t level) {
 +    DDRD |= (1 << PD6);
 +    TCCR0A = (1 << COM0A1) | (1 << WGM01) | (1 << WGM00);
 +    TCCR0B = (1 << CS01) | (1 << CS00);
 +    OCR0A = level;
 +}
 +
 +void pwm_stop() {
 +    TCCR0A = 0;
 +    TCCR0B = 0;
 +    OCR0A = 0;
 +    PORTD &= ~(1 << PD6);
 +}
 +
 +
 +void adc_init() {
 +    ADMUX = (1 << REFS0) | (1 << MUX0);
 +    ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1);
 +}
 +
 +uint16_t citeste_adc() {
 +    ADCSRA |= (1 << ADSC);
 +    while (ADCSRA & (1 << ADSC));
 +    return ADC;
 +}
 +
 +void uart_init() {
 +    UBRR0 = 103;
 +    UCSR0B = (1 << TXEN0);
 +    UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);
 +}
 +
 +void uart_transmit(char c) {
 +    while (!(UCSR0A & (1 << UDRE0)));
 +    UDR0 = c;
 +}
 +
 +void uart_print(const char* s) {
 +    while (*s) uart_transmit(*s++);​
 +}
 +
 +void uart_print_number(uint16_t n) {
 +    char buffer[6];
 +    uint8_t i = 0;
 +    if (n == 0) {
 +        uart_transmit('​0'​);​
 +        return;
 +    }
 +    while (n > 0 && i < 5) {
 +        buffer[i++] = '​0'​ + (n % 10);
 +        n /= 10;
 +    }
 +    while (i > 0) {
 +        uart_transmit(buffer[--i]);​
 +    }
 +}
 +
 +
 +void timer2_init_ctc(void) {
 +    TCCR2A = (1 << WGM21);
 +    TCCR2B = (1 << CS22);
 +    OCR2A = 188;
 +}
 +
 +
 +int main(void) {
 +    timer2_init_ctc();​
 +    twi_init();
 +    lcd_init();
 +    adc_init();
 +    uart_init();​
 +
 +    // LED roșu (D8), verde (D11), flacara (D9), buzzer (D6)
 +    DDRB |= (1 << PB0) | (1 << PB3);
 +    DDRB &= ~(1 << PB1);             
 +    DDRD |= (1 << PD6);             
 +
 +    //buton (D3)
 +    DDRD &= ~(1 << PD3);
 +    PORTD |= (1 << PD3); 
 +
 +    lcd_set_cursor(0,​ 0);
 +    lcd_print("​Incalzire senzor..."​);​
 +    delay_ms_custom(20000);​
 +    lcd_clear();​
 +
 +    uint8_t pwm_level = 0;
 +    uint8_t alarma_oprita = 0;
 +    uint8_t buton_apasat_ultima = 0;
 +
 +    while (1) {
 +        uint8_t flacara = !(PINB & (1 << PB1));
 +        uint16_t gaz_fum_val = citeste_adc();​
 +        uint8_t fum_detectat = gaz_fum_val > 300;
 +        uint8_t gaz_detectat = gaz_fum_val > 400;
 +        uint8_t pericol = flacara || gaz_detectat || fum_detectat;​
 +
 +        uint8_t buton = !(PIND & (1 << PD3));
 +        if (pericol && buton && !buton_apasat_ultima) {
 +            alarma_oprita = 1;
 +        }
 +        buton_apasat_ultima = buton;
  
-<note tip> +        ​if (!pericol{ 
-Descrierea codului aplicaţiei (firmware):​ +            ​alarma_oprita = 0; 
-  * mediu de dezvoltare (if any) (e.g. AVR Studio, CodeVisionAVR+        }
-  * librării şi surse 3rd-party (e.g. Procyon AVRlib) +
-  * algoritmi şi structuri pe care plănuiţi să le implementaţi +
-  * (etapa 3) surse şi funcţii implementate +
-</​note>​+
  
-===== Rezultate Obţinute =====+        if (pericol) { 
 +            PORTB |(1 << PB0); 
 +            PORTB &~(1 << PB3); 
 +        } else { 
 +            PORTB |(1 << PB3); 
 +            PORTB &~(1 << PB0); 
 +        }
  
-<note tip> +        if (pericol && !alarma_oprita) { 
-Care au fost rezultatele obţinute în urma realizării proiectului vostru. +            if (pwm_level ​255) pwm_level += 5; 
-</​note>​+            ​pwm_start(pwm_level);​ 
 +        } else { 
 +            pwm_level = 0; 
 +            pwm_stop();​ 
 +        }
  
-===== Concluzii =====+        uart_print("​Gaz:​ "); 
 +        uart_print_number(gaz_fum_val);​ 
 +        uart_print("​ | Flacara: "); 
 +        uart_print_number(flacara);​ 
 +        uart_print("​ | Alarma oprita: "); 
 +        uart_print_number(alarma_oprita);​ 
 +        uart_print("​\r\n"​);​
  
-===== Download ===== 
  
-<note warning> +        lcd_clear();​ 
-O arhivă ​(sau mai multe dacă este cazulcu fişierele obţinute în urma realizării proiectuluisurse, scheme, etc. Un fişier README, un ChangeLog, un script de compilare şi copiere automată pe uC crează întotdeauna o impresie bună ;-).+        ​lcd_set_cursor(0, 0)
 +        if (!pericol) { 
 +            lcd_print("​Stare normala"​);​ 
 +        } else { 
 +            if (flacara) { 
 +                lcd_print("​PericolFLACARA"​); 
 +            } else if (gaz_detectat
 +                lcd_print("​Pericol:​ GAZ"​);​ 
 +            } else if (fum_detectat) { 
 +                lcd_print("​Pericol:​ FUM"​);​ 
 +            } 
 +        }
  
-Fişierele se încarcă pe wiki folosind facilitatea **Add Images or other files**. Namespace-ul în care se încarcă fişierele este de tipul **:​pm:​prj20??:​c?​** sau **:​pm:​prj20??:​c?:​nume_student** ​(dacă este cazul). **Exemplu:** Dumitru Alin, 331CC -> **:​pm:​prj2009:​cc:​dumitru_alin**. +        lcd_set_cursor(0, 1)
-</​note>​+        lcd_print("​Alarma:"); 
 +        ​lcd_print_number(alarma_oprita);​
  
-===== Jurnal =====+        delay_ms_custom(300);​ 
 +    }
  
-<note tip> +    return 0; 
-Puteți avea și o secțiune de jurnal în care să poată urmări asistentul de proiect progresul proiectului. +}
-</​note>​+
  
-===== Bibliografie/​Resurse ===== 
  
-<​note>​ 
-Listă cu documente, datasheet-uri,​ resurse Internet folosite, eventual grupate pe **Resurse Software** şi **Resurse Hardware**. 
-</​note>​ 
  
 <​html><​a class="​media mediafile mf_pdf"​ href="?​do=export_pdf">​Export to PDF</​a></​html>​ <​html><​a class="​media mediafile mf_pdf"​ href="?​do=export_pdf">​Export to PDF</​a></​html>​
  
pm/prj2025/vstoica/catalina.buduran.1747578391.txt.gz · Last modified: 2025/05/18 17:26 by catalina.buduran
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