Differences

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

Link to this comparison view

pm:prj2024:sseverin:iconstantinescu1206 [2024/05/27 03:52]
iconstantinescu1206 [Software Design]
pm:prj2024:sseverin:iconstantinescu1206 [2024/05/27 04:44] (current)
iconstantinescu1206 [Concluzii]
Line 31: Line 31:
  
 {{:​pm:​prj2024:​sseverin:​feline_feeder2.jpeg?​300|}} {{:​pm:​prj2024:​sseverin:​feline_feeder2.jpeg?​300|}}
- 
 ===== Software Design ===== ===== Software Design =====
  
-<note tip> +===Mediu de Dezvoltare=== 
-Mediu de Dezvoltare +  ​* **Arduino IDE** 
-  * Arduino IDE+ 
 + 
 +===Librării și surse 3rd-party=== 
 +  * **Wire.h**: Biblioteca standard Arduino pentru comunicarea I2C. 
 +  * **RTClib.h**:​ Biblioteca pentru manipularea modulelor RTC, cum ar fi DS3231. 
 +  * **LiquidCrystal_I2C.h**:​ Biblioteca pentru controlul afișajului LCD I2C. 
 +  * **Servo.h**:​ Biblioteca pentru controlul servo motoarelor. 
 +  * **Keypad.h**:​ Biblioteca pentru interfațarea cu un keypad matricial.
  
-Librării și surse 3rd-party 
-  * Wire.h: Biblioteca standard Arduino pentru comunicarea I2C. 
-  * RTClib.h: Biblioteca pentru manipularea modulelor RTC, cum ar fi DS3231. 
-  * LiquidCrystal_I2C.h:​ Biblioteca pentru controlul afișajului LCD I2C. 
-  * Servo.h: Biblioteca pentru controlul servo motoarelor. 
-  * Keypad.h: Biblioteca pentru interfațarea cu un keypad matricial. 
-</​note>​ 
  
 === Algoritmi și structuri implementate === === Algoritmi și structuri implementate ===
  
-=== Controlul motoarelor: ===+**1. Inițializare și configurare hardware:**
  
-  * Controlul direcției ​și vitezei motoarelor prin PWM (Pulse Width Modulation) și pini de direcție. +  * Configurarea modulelor RTC, LCD și servo. 
-  * Funcții pentru mișcarea înainte (moveForward),​ înapoi (moveBackward) și oprirea motoarelor (stopMotors). +  * Configurarea interfeței cu keypad-ul. 
-  * Măsurarea distanței: Utilizarea senzorilor Sharp IR pentru a măsura distanța față de obstacolele din față și din dreapta robotului. +  * Configurarea unui timer pentru ​controlul duratei de activare ​a servo-ului. 
-  * Stabilirea unor praguri minime și maxime pentru distanțele detectate. Folosirea corectiilor ​pentru a elimina snake-like movement si a avea o traiectorie mai dreapta.+  * Configurarea unui buton pentru ​intrarea în modul de setare ​a orei de hrănire.
  
-<note tip> +**2. Funcționalitate principală:**
-Algoritmul de control:+
  
-  * Proportional Control (P): Utilizat pentru ajustarea vitezei motoarelor în funcție de eroarea dintre distanța dorită ​și distanța măsurată. +  * Afișarea timpului curent pe afișajul LCD. 
-  * Detecția obstacolelor:​ Dacă un obstacol este detectat ​în față, robotul ​se oprește și efectuează o serie de manevre pentru a evita obstacolul. +  * Detectarea și intrarea ​în modul de setare a timpului de hrănire când se apasă butonul. 
-  * Menținerea distanței față de perete: Ajustarea poziției robotului pentru a menține o distanță constantă față de peretele din dreapta. +  * Permite utilizatorului să introducă ora de hrănire utilizând keypad-ul. 
-  * Interupere externă: Utilizarea unei întreruperi externe pentru a detecta schimbările unui pin specific (motorDirection2A) ​și pentru a trimite un semnal pe un alt pin (signalPin). +  * Stocarea ​și afișarea orei de hrănire setate.
-</​note>​+
  
 +**3. Controlul hrănirii automate:**
  
 +  * Compararea orei curente cu ora de hrănire setată.
 +  * Activarea servo-ului pentru a deschide compartimentul de hrană la ora setată.
 +  * Folosirea unui timer pentru a menține servo-ul activat pentru o perioadă specificată de timp.
  
-==== Etapa 3: Surse și funcții implementate ==== 
  
 +===Surse şi Funcţii Implementate===
  
-Inițializarea motoarelor:+1. Configurarea hardware:
  
-Se seteaza pinii driverului pe output si se ataseaza intreruperea ​la un pin de directie ​(odata cu modificarea lui se va aprinde ulterior un led)+**void configure_timer2()**:​ Configurarea timerului 2 pentru generarea unei întreruperi ​la fiecare 1 ms. 
 +<​code>​ 
 +void configure_timer2()  
 +{ 
 +  TCCR2A = 0; 
 +  TCCR2B = 0; 
 +  TCNT2 = 0; 
 +  OCR2A = 249; 
 +  TCCR2A |= (1 << WGM21); 
 +  TCCR2B |= (1 << CS22); 
 +   
 +} 
 +</​code>​
  
 +**void init_timer2()**:​ Inițializarea timerului 2.
 <​code>​ <​code>​
-void setup() { +void init_timer2()  
-  ​pinMode(motorSpeedPinA,​ OUTPUT); +{ 
-  ​pinMode(motorDirection1A,​ OUTPUT); +  ​TIMSK2 |= (1 << OCIE2A); 
-  ​pinMode(motorDirection2A,​ OUTPUT);+} 
 +</​code>​
  
-  pinMode(motorSpeedPinB,​ OUTPUT); +**void configure_button()**: Configurarea butonului de intrare în modul de setare a orei de hrănire. 
-  ​pinMode(motorDirection1B,​ OUTPUT); +<​code>​ 
-  ​pinMode(motorDirection2B,​ OUTPUT);+void configure_button()  
 +{ 
 +  DDRD&​=~(1<<​PD2); 
 +  ​PORTD|=(1<<​PD2); 
 +  ​PCICR |= (1 << PCIE2); 
 +  PCMSK2 |= (1 << PCINT18); 
 +} 
 +</​code>​
  
-  analogWrite(motorSpeedPinA,​ 0); +2. Funcții ISR (Interrupt Service Routine):
-  digitalWrite(motorDirection1A,​ HIGH); +
-  digitalWrite(motorDirection2A,​ LOW);+
  
-  analogWrite(motorSpeedPinB,​ 0); +**ISR(TIMER2_COMPA_vect)**: Funcția de întrerupere pentru Timerul 2 care controlează durata de activare a servo-ului. 
-  ​digitalWrite(motorDirection1B,​ LOW); +<​code>​ 
-  ​digitalWrite(motorDirection2B,​ HIGH); +ISR(TIMER2_COMPA_vect)  
- +{ 
-  ​attachInterrupt(digitalPinToInterrupt(motorDirection2A),​ handlePinChange,​ CHANGE); +  ​if (timer2Flag)  
- +  { 
-  ​Serial.begin(9600);+    ​unsigned long currentMillis = millis(); 
 +    if (currentMillis - previousMillis >= interval) ​ 
 +    { 
 +      servo.write(0); 
 +      timer2Flag = false; 
 +    } 
 +  }
 } }
 </​code>​ </​code>​
  
- +**ISR(PCINT2_vect)**: Funcția ​de întrerupere ​pentru ​butonul ​de setare ​a orei de hrănire.
-Controlul mișcării: +
- +
-Am facut functiile ​de moveForward si moveBackward,​ fara turnLeft si turnRight ​pentru ​ca abordarea cu un indice ​de corectie ma restrange la a avea 2 parametri, deci pentru left si right unul din parametri va fi 0. +
 <​code>​ <​code>​
-void moveForward(int leftSpeed, int rightSpeed) { +ISR(PCINT2_vect) 
-  ​digitalWrite(motorDirection1A,​ HIGH); +{ 
-  digitalWrite(motorDirection2A,​ LOW); +  ​if (!(PIND & (1 << PD2)))  
-  digitalWrite(motorDirection1B,​ LOW); +  ​{ 
-  ​digitalWrite(motorDirection2B,​ HIGH); +    ​setTimeMode = true; 
- +  ​}
-  analogWrite(motorSpeedPinA,​ leftSpeed); +
-  ​analogWrite(motorSpeedPinB,​ rightSpeed);​+
 } }
 +</​code>​
  
-void moveBackward() { +3.Setarea timpului de hrănire:
-  digitalWrite(motorDirection1A,​ LOW); +
-  digitalWrite(motorDirection2A,​ HIGH); +
-  digitalWrite(motorDirection1B,​ HIGH); +
-  digitalWrite(motorDirection2B,​ LOW);+
  
-  analogWrite(motorSpeedPinA,​ baseSpeed); +**DateTime getDateTime()**:​ Funcția care permite utilizatorului să introducă ora de hrănire folosind keypad-ul și returnează un obiect DateTime cu ora setată. 
-  ​analogWrite(motorSpeedPinB, baseSpeed); +<​code>​ 
-} +DateTime getDateTime()  
- +{ 
-void stopMotors() { +  DateTime now = rtc.now(); 
-  ​analogWrite(motorSpeedPinA, 0); +  ​int hour = 0; 
-  ​analogWrite(motorSpeedPinB, 0);+  int minute = 0; 
 +  int h = 0; 
 +  int m = 0; 
 +  while (1)  
 +  { 
 +    char key; 
 +    if (key = keypad.getKey()) 
 +    { 
 +      if (key >= '​0'​ && key <= '​9'​)  
 +      { 
 +        if(h == 0) 
 +        { 
 +          hour += (key - '​0'​);​ 
 +          h = 1; 
 +        } 
 +        else if(h == 1) 
 +        { 
 +          hour *= 10; 
 +          hour += (key - '​0'​);​ 
 +          h = 2; 
 +        }  
 +        else if(m == 0) 
 +        { 
 +          minute += (key - '​0'​);​ 
 +          m = 1; 
 +        }  
 +        else if(m == 1) 
 +        { 
 +          minute *= 10; 
 +          minute += (key - '​0'​);​ 
 +          m = 2; 
 +        } 
 +        lcd.setCursor(0, 1); 
 +        ​if(hour<​10 && h==2) 
 +        { 
 +          lcd.print("​0"​);​ 
 +        ​} 
 +        ​lcd.print(hour);​ 
 +        ​lcd.print(":"​); 
 +        if(minute<​10 && m==2) 
 +        ​{ 
 +          ​lcd.print("​0"​);​ 
 +        } 
 +        lcd.print(minute);​ 
 +      }  
 +      else if (key == '​*'​)  
 +      { 
 +        hour = 0; 
 +        minute = 0; 
 +        h = 0; 
 +        m = 0; 
 +        lcd.setCursor(0, 1); 
 +        lcd.print(" ​     "); 
 +        lcd.setCursor(0, 1); 
 +        lcd.print("​00:​00"​);​ 
 +      }  
 +      else if (key == '#'​)  
 +      { 
 +        if (hour < 24 && minute < 60)  
 +        { 
 +          break; 
 +        }  
 +        else 
 +        { 
 +          hour = 0; 
 +          minute = 0; 
 +          h = 0; 
 +          m = 0; 
 +          lcd.clear();​ 
 +          lcd.print("​The time is"​);​ 
 +          lcd.setCursor(0,​ 1); 
 +          lcd.print("​incorrect."​);​ 
 +          delay(2000);​ 
 +          lcd.clear();​ 
 +          lcd.print("​Set feeding time:"​);​ 
 +          lcd.setCursor(0,​ 1); 
 +          lcd.print(" ​     "); 
 +          lcd.setCursor(0,​ 1); 
 +          lcd.print("​00:​00"​);​ 
 +        } 
 +      } 
 +    } 
 +  ​} 
 +  return DateTime(now.year(), now.month(),​ now.day(), hour, minute, 0);
 } }
 </​code>​ </​code>​
  
 +4.Funcții de inițializare:​
  
-Gestionarea întreruperii:+**void setup()**: Funcția de setup pentru inițializarea tuturor componentelor hardware și setarea inițială a RTC-ului.
  
-Functia seteaza un flag, o variabila volatile bool care se va verifica constant in functia ​de loop.+5.Funcția principală ​de loop: 
 + 
 +**void loop()**: Funcția principală care rulează în buclă infinită, afișând ora curentă și verificând dacă este timpul de hrănire.
  
-<​code>​ 
-void handlePinChange() { 
-  pin2Changed = true; 
-} 
-</​code>​ 
 ===== Rezultate Obţinute ===== ===== Rezultate Obţinute =====
  
Line 147: Line 245:
 ===== Concluzii ===== ===== Concluzii =====
  
 +Mi-a placut foarte mult sa lucrez la acest proiect. Ma asteptam sa fie mai usor putin dar a fost super interesant sa lucrez la partea de hardware si chiar sa imi iasa :))). Poate voi testa proiectul si cu pisica mea. 
 ===== Download ===== ===== Download =====
  
 <note warning> <note warning>
-O arhivă (sau mai multe dacă este cazul) cu fişierele obţinute în urma realizării proiectului: surse, scheme, etc. Un fişier README, un ChangeLog, un script de compilare şi copiere automată pe uC crează întotdeauna o impresie bună ;-). +Descarcare arhiva: **{{:pm:prj2024:sseverin:felinefeeder.zip|}}**
- +
-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**.+
 </​note>​ </​note>​
  
-===== Jurnal ===== 
- 
-<note tip> 
-Puteți avea și o secțiune de jurnal în care să poată urmări asistentul de proiect progresul proiectului. 
-</​note>​ 
  
 ===== Bibliografie/​Resurse ===== ===== Bibliografie/​Resurse =====
  
 <​note>​ <​note>​
-Listă cu documente, datasheet-uri, resurse Internet folosite, eventual grupate pe **Resurse Software** şi **Resurse Hardware**.+https://​www.youtube.com/​watch?​v=BiWoA81fgTE&​list=WL&​index=48&​t=1s 
 +https://​circuitdigest.com/​microcontroller-projects/​automatic-pet-feeder-using-arduino 
 +[[https://​ocw.cs.pub.ro/​courses/​pm/​lab/​lab2-2023]]
 </​note>​ </​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/prj2024/sseverin/iconstantinescu1206.1716771171.txt.gz · Last modified: 2024/05/27 03:52 by iconstantinescu1206
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