This shows you the differences between two versions of the page.
pm:prj2025:vstoica:catalina.buduran [2025/05/26 09:40] 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 164: | Line 166: | ||
* Senzor gaz: testat cu o brichetă – valorile cresc în UART, buzzer și LED roșu se activează | * 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 | * 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; | ||
+ | } | ||
+ | |||
<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> | ||