Differences

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

Link to this comparison view

pm:prj2026:alexandru.jipa2803:eduard.ghelbereu [2026/05/23 02:41]
eduard.ghelbereu
pm:prj2026:alexandru.jipa2803:eduard.ghelbereu [2026/05/24 03:32] (current)
eduard.ghelbereu
Line 121: Line 121:
  
 Aceste functionalitati sunt legate direct de continutul laboratoarelor:​ GPIO si lucrul cu registrele sunt introduse in laboratorul 0, timerele si intreruperile in laboratorul 2, PWM-ul in laboratorul 3, SPI-ul in laboratorul 5, iar I2C-ul in laboratorul 6. Aceste functionalitati sunt legate direct de continutul laboratoarelor:​ GPIO si lucrul cu registrele sunt introduse in laboratorul 0, timerele si intreruperile in laboratorul 2, PWM-ul in laboratorul 3, SPI-ul in laboratorul 5, iar I2C-ul in laboratorul 6.
 +
 +==== Fragmente relevante de cod ====
 +
 +=== Configurarea comunicatiei I2C pentru LCD ===
 +
 +Display-ul LCD foloseste magistrala I2C/TWI. Comunicatia este initializata prin configurarea registrelor TWSR, TWBR si TWCR.
 +
 +<code c>
 +void twi_init() {
 +  TWSR = 0x00;
 +  TWBR = 72;
 +  TWCR = (1 << TWEN);
 +}
 +</​code>​
 +
 +Registrul TWBR stabileste viteza magistralei I2C, iar bitul TWEN activeaza perifericul TWI al microcontrollerului. Aceasta functionalitate este folosita pentru transmiterea comenzilor si caracterelor catre display.
 +
 +=== Trimiterea datelor catre cele doua registre 74HC595 ===
 +
 +Pentru controlul celor 16 LED-uri am folosit doua registre 74HC595. Astfel, toate LED-urile pot fi controlate folosind doar 3 pini ai microcontrollerului.
 +
 +<code c>
 +void shift595_send(uint16_t value) {
 +  PORTB &= ~(1 << LATCH_PIN);
 +
 +  for (int i = 15; i >= 0; i--) {
 +    if (value & (1 << i)) PORTD |= (1 << DATA_PIN);
 +    else PORTD &= ~(1 << DATA_PIN);
 +
 +    PORTD |= (1 << CLOCK_PIN);
 +    _delay_us(2);​
 +    PORTD &= ~(1 << CLOCK_PIN);
 +  }
 +
 +  PORTB |= (1 << LATCH_PIN);
 +}
 +</​code>​
 +
 +Functia trimite pe rand cei 16 biti catre registre. Primii 8 biti controleaza LED-urile rosii, iar ceilalti 8 biti controleaza LED-urile verzi. La final, semnalul latch actualizeaza iesirile registrelor.
 +
 +=== Calcularea locurilor libere si actualizarea LED-urilor ===
 +
 +Senzorii IR sunt cititi periodic. In functie de starea fiecarui senzor, se aprinde LED-ul verde pentru loc liber sau LED-ul rosu pentru loc ocupat.
 +
 +<code c>
 +for (uint8_t i = 0; i < 8; i++) {
 +  if (senzori_liber[i]) {
 +    locuri++;
 +    leduri |= (1 << i);
 +  } else {
 +    leduri |= (1 << (i + 8));
 +  }
 +}
 +
 +shift595_send(leduri);​
 +</​code>​
 +
 +Variabila leduri contine starea tuturor celor 16 LED-uri. Bitii 0-7 sunt folositi pentru LED-urile verzi, iar bitii 8-15 pentru LED-urile rosii.
 +
 +=== Configurarea PWM pentru servo motor ===
 +
 +Servo motorul este controlat cu Timer1, folosind iesirea OC1A de pe pinul PB1 / D9.
 +
 +<code c>
 +void servo_init() {
 +  DDRB |= (1 << PB1);
 +
 +  TCCR1A = (1 << COM1A1) | (1 << WGM11);
 +  TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS11);
 +
 +  ICR1 = 39999;
 +}
 +</​code>​
 +
 +Timer1 este configurat in mod Fast PWM, cu perioada de aproximativ 20 ms, potrivita pentru controlul unui servo motor. Pozitia barierei este setata prin modificarea registrului OCR1A.
 +
 +<code c>
 +void servo_write(uint8_t angle) {
 +  if (angle == 0) {
 +    OCR1A = 2000;
 +  } else {
 +    OCR1A = 4000;
 +  }
 +}
 +</​code>​
 +
 +Valoarea OCR1A determina durata impulsului PWM. Pentru proiect, valorile au fost calibrate astfel incat bariera sa aiba doua pozitii clare: coborata si ridicata.
 +
 +=== Initializarea comunicatiei SPI pentru RFID ===
 +
 +Modulul RC522 comunica prin SPI. Pinii MOSI, SCK si SS sunt configurati ca iesiri, iar MISO ca intrare.
 +
 +<code c>
 +void spi_init() {
 +  DDRB |= (1 << PB2) | (1 << PB3) | (1 << PB5);
 +  DDRB &= ~(1 << PB4);
 +
 +  PORTB |= (1 << RFID_SS);
 +
 +  SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR0);
 +}
 +</​code>​
 +
 +Bitul SPE activeaza perifericul SPI, iar MSTR configureaza microcontrollerul ca master. RC522 functioneaza ca dispozitiv slave.
 +
 +=== Citirea UID-ului cardului RFID ===
 +
 +Pentru detectarea cardului RFID se trimite o comanda REQA, apoi se foloseste comanda anticollision pentru citirea UID-ului.
 +
 +<code c>
 +bool rfid_read_uid(uint8_t *uid) {
 +  rfid_write(0x09,​ 0x26);
 +  rfid_write(0x01,​ 0x0C);
 +  rfid_setBit(0x0D,​ 0x80);
 +
 +  _delay_ms(10);​
 +
 +  if (!(rfid_read(0x04) & 0x30)) return false;
 +
 +  rfid_write(0x09,​ 0x93);
 +  rfid_write(0x09,​ 0x20);
 +
 +  _delay_ms(10);​
 +
 +  for (uint8_t i = 0; i < 5; i++) {
 +    uid[i] = rfid_read(0x09);​
 +  }
 +
 +  return true;
 +}
 +</​code>​
 +
 +Daca nu este detectat niciun card, functia intoarce false. Daca un card este prezent, UID-ul este salvat intr-un vector si ulterior afisat pe LCD.
 +
 +=== Logica principala a proiectului ===
 +
 +Bucla principala actualizeaza permanent starea parcarii si verifica daca a fost citit un card RFID.
 +
 +<code c>
 +while (1) {
 +  int locuri = actualizeaza_parcarea();​
 +
 +  if (rfid_read_uid(uid)) {
 +    afiseaza_uid(uid);​
 +
 +    if (locuri == 0) {
 +      lcd_print("​Acces refuzat"​);​
 +    } else {
 +      deschide_bariera();​
 +    }
 +
 +    rfid_halt();​
 +    _delay_ms(500);​
 +    rfid_init();​
 +  }
 +
 +  _delay_ms(150);​
 +}
 +</​code>​
 +
 +Aceasta este partea care leaga toate modulele intre ele: senzorii determina disponibilitatea locurilor, RFID-ul declanseaza cererea de acces, iar servo motorul actioneaza bariera daca exista locuri libere.
 +
 +=== Actionarea barierei si feedback-ul sonor ===
 +
 +La acces permis, bariera este ridicata, buzzerul este activat, apoi dupa o pauza bariera este coborata automat.
 +
 +<code c>
 +void deschide_bariera() {
 +  lcd_clear();​
 +  lcd_print("​Acces permis"​);​
 +
 +  servo_write(90);​
 +  buzzer_on_2s();​
 +
 +  _delay_ms(2000);​
 +
 +  lcd_clear();​
 +  lcd_print("​Bariera jos");
 +
 +  servo_write(0);​
 +  buzzer_on_2s();​
 +}
 +</​code>​
 +
 +Buzzerul functioneaza pe durata miscarii barierei, oferind feedback sonor utilizatorului.
  
 ==== Structura software ==== ==== Structura software ====
Line 190: Line 375:
   - cazul in care parcarea este plina si accesul este refuzat.   - cazul in care parcarea este plina si accesul este refuzat.
  
-Link demo video: ​TODO+Link demo video: ​https://​youtube.com/​shorts/​kGitde-WedE?​is=PO4sWVbsrNmVk2R9 
 + 
 +==== Github ==== 
 + 
 +https://​github.com/​EduardG05/​ProiectPM 
 + 
 +==== Bibliografie ==== 
 + 
 +https://​www.pcbasic.com/​ro/​blog/​ir_sensors.html 
 + 
 +https://​ocw.cs.pub.ro/​courses/​pm/​proiect/​xplainedmini 
 + 
 +https://​components101.com/​sites/​default/​files/​component_datasheet/​SG90%20Servo%20Motor%20Datasheet.pdf 
 + 
 +https://​www.nxp.com/​docs/​en/​data-sheet/​MFRC522.pdf
  
 <​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/prj2026/alexandru.jipa2803/eduard.ghelbereu.1779493280.txt.gz · Last modified: 2026/05/23 02:41 by eduard.ghelbereu
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