Differences

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

Link to this comparison view

pm:prj2025:vstoica:catalina.buduran [2025/05/26 09:23]
catalina.buduran
pm:prj2025:vstoica:catalina.buduran [2025/06/01 18:06] (current)
catalina.buduran
Line 101: Line 101:
 | 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]] | | 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 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ă]] | - | | 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 =====
  
 Proiectul este funcțional și implementează următoarele:​ Proiectul este funcțional și implementează următoarele:​
Line 141: Line 143:
 | **Laboratorul 4** | ADC           | Citire analogică de la senzorul MQ-2 (gaz/fum) prin canalul | | **Laboratorul 4** | ADC           | Citire analogică de la senzorul MQ-2 (gaz/fum) prin canalul |
 | **Laboratorul 6** | I2C           |LCD I2C | | **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;
 +
 +        if (!pericol) {
 +            alarma_oprita = 0;
 +        }
 +
 +        if (pericol) {
 +            PORTB |= (1 << PB0);
 +            PORTB &= ~(1 << PB3);
 +        } else {
 +            PORTB |= (1 << PB3);
 +            PORTB &= ~(1 << PB0);
 +        }
 +
 +        if (pericol && !alarma_oprita) {
 +            if (pwm_level < 255) pwm_level += 5;
 +            pwm_start(pwm_level);​
 +        } else {
 +            pwm_level = 0;
 +            pwm_stop();
 +        }
 +
 +        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"​);​
 +
 +
 +        lcd_clear();​
 +        lcd_set_cursor(0,​ 0);
 +        if (!pericol) {
 +            lcd_print("​Stare normala"​);​
 +        } else {
 +            if (flacara) {
 +                lcd_print("​Pericol:​ FLACARA"​);​
 +            } else if (gaz_detectat) {
 +                lcd_print("​Pericol:​ GAZ");
 +            } else if (fum_detectat) {
 +                lcd_print("​Pericol:​ FUM");
 +            }
 +        }
 +
 +        lcd_set_cursor(0,​ 1);
 +        lcd_print("​Alarma:"​);​
 +        lcd_print_number(alarma_oprita);​
 +
 +        delay_ms_custom(300);​
 +    }
 +
 +    return 0;
 +}
  
  
pm/prj2025/vstoica/catalina.buduran.1748240598.txt.gz · Last modified: 2025/05/26 09:23 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