Differences

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

Link to this comparison view

pm:prj2025:fstancu:dan.vrinceanu [2025/05/27 23:58]
dan.vrinceanu [Software Design]
pm:prj2025:fstancu:dan.vrinceanu [2025/05/28 09:28] (current)
dan.vrinceanu [Main application flow]
Line 78: Line 78:
   * LCD-ul afișează din nou: Mod: Manual   * LCD-ul afișează din nou: Mod: Manual
  
-===== Main application flow=====+==== Motivația Alegerii Bibliotecilor ==== 
 + 
 +=== Arduino Libraries === 
 + 
 +  ==== Motivația Alegerii Bibliotecilor ==== 
 + 
 +=== ESP32 Robotics Libraries === 
 + 
 +  #include <​DabbleESP32.h> ​      // Control Bluetooth cu aplicația mobilă Dabble (GamePad virtual) ​  
 +  #include <​ESP32Servo.h> ​       // Compatibilitate PWM pentru control precis al servomotoarelor pe ESP32   
 +  #include <​NewPing.h> ​          // Măsurători rapide și stabile cu senzorul ultrasonic HC-SR04 ​  
 +  #include <​Wire.h> ​             // Comunicație I²C între ESP32 și periferice ​  
 +  #include <​LiquidCrystal_I2C.h>​ // Afișare text pe LCD 16x2 cu interfață I²C   
 + 
 +Justificare: ​  
 +Am ales aceste biblioteci pentru a realiza un sistem robotic autonom cu control manual prin Bluetooth și feedback vizual. 
 + 
 +- `DabbleESP32` permite interacțiunea prin aplicația mobilă fără componente fizice externe. ​  
 +- `ESP32Servo` este necesară pentru compatibilitate cu PWM-ul specific ESP32, esențial în orientarea senzorului ultrasonic. ​  
 +- `NewPing` asigură măsurători eficiente ale distanței fără blocaje, utile pentru evitarea obstacolelor. ​  
 +- `Wire` este standard pentru comunicație I²C, permițând integrarea simplă a mai multor senzori sau afișaje. ​  
 +- `LiquidCrystal_I2C` oferă un mod convenabil de a afișa mesaje de stare, diagnostic sau feedback pentru utilizator. 
 + 
 +==== Laboratoarele ==== 
 + 
 +=== Laboratorul 0: GPIO === 
 +Folosit pentru controlul pinilor digitali – pornirea/​opirea motoarelor, citirea stării senzorului IR. 
 + 
 +=== Laboratorul 1: UART === 
 +Utilizat pentru comunicarea serială cu computerul prin Serial.begin() – afişează mesaje de stare și debug. 
 + 
 +=== Laboratorul 3: Timere. PWM === 
 +PWM este folosit pentru a controla poziția servomotorului (ex: rotirea senzorului ultrasonic pentru detectarea obstacolelor). 
 + 
 +===  Laboratorul 6: I2C === 
 + 
 +Folosit pentru comunicarea cu ecranul LCD 1602 prin interfața I2C – afişează mesaje despre obstacole, prăpastii sau conexiunea cu aplicația. 
 + 
 +==== Element de Noutate al Proiectului ==== 
 + 
 +Integrarea controlului manual prin Bluetooth (Dabble) cu un sistem autonom de evitare a obstacolelor și prăpastiilor. ​  
 +Robotul poate schimba direcția și viteza în timp real, oferind feedback pe LCD și folosind un servomotor pentru scanare laterală. ​  
 +Această combinație de autonomie și interactivitate mobilă face proiectul versatil și inovator. 
 + 
 +==== Calibrarea senzorilor ==== 
 +Senzor ultrasonic (HC-SR04) 
 +Am setat o distanță maximă de detecție (200 cm) și un prag pentru obstacol (20 cm). 
 +Am testat valorile în monitorul serial pentru a verifica funcționarea corectă. 
 +Senzor IR 
 +Am calibrat detectarea marginii ca semnal LOW. 
 +Am verificat comportamentul apropiind senzorul de o margine (ex. masă). 
 +Servomotor + senzor ultrasonic 
 +Am setat unghiuri fixe (50° și 130°) pentru scanare laterală. 
 +Am verificat că senzorul măsoară distanța corect în ambele direcții. 
 + 
 + 
 +===== Main application flow =====
  
 **Setup** **Setup**
-    * Initializează comunicația serială la 115200 baud. +    * Inițializează comunicația serială la 115200 baud. 
-    * Configurează ​pinii pentru ​motoaresenzor ​IR, ultrasunete și servomotor. +    * Configurează ​pinurile ​pentru
-    * Atașează servomotorul și îl setează la poziția de mijloc (90°)+        - Motoare (IN1IN2, IN3, IN4) 
-    * Pornește ​conexiunea Bluetooth cu Dabble (`Dabble.begin`). +        - Senzor ​IR (prăpastie) 
-    * Inițializează LCD-ul ​I2C (pe pini SDA = 25, SCL = 26). +        - Ultrasunete (TRIGECHO) 
-    * Afișează mesaj de așteptare ​pe ecran.+        - Servomotor (SERVO_PIN) 
 +    * Atașează servomotorul și îl poziționează inițial ​la 90°. 
 +    * Inițializează ​conexiunea Bluetooth cu aplicația ​Dabble
 +    * Configurează magistrala I2C (Wire.begin) ​pentru LCD
 +    * Inițializează LCD-ul (16x2și aprinde lumina de fundal
 +    * Afișează mesaj pe ecran: "​Conecteaza-te,​ sefule"​.
  
 <code cpp> <code cpp>
Line 106: Line 167:
 } }
 </​code>​ </​code>​
 +
 +---
  
 **Main Loop** **Main Loop**
-    * Procesează comenzile ​din aplicația ​Dabble ​(Bluetooth).+    * Procesează comenzile ​de la Dabble.
     * Dacă aplicația nu e conectată:     * Dacă aplicația nu e conectată:
-        - Afișează mesaj de conectare ​și așteaptă.+        - Afișează mesaj și iese temporar din buclă.
     * La prima conectare:     * La prima conectare:
-        - Afișează ​pe LCD "Mod: Manual"​. +        - Afișează "Mod: Manual" ​pe LCD
-    * Dacă se apasă ​butonul ​Triunghi (▲): +    * Dacă se apasă Triunghi (▲): 
-        - Activează modul de evitare a obstacolelor ​și prăpastiei+        - Activează modul automat (evitarea ​obstacolelor ​+ margini)
-    * Dacă se apasă ​butonul ​X (✖):+    * Dacă se apasă X (✖):
         - Dezactivează modul automat și revine la control manual.         - Dezactivează modul automat și revine la control manual.
-    * În modul automat: +    * Dacă modul automat ​este activ
-        - Apelează ​funcția ​`avoidObstacles()`+        - Apelează `avoidObstacles()` ​și iese din `loop`
-            - Verifică senzorul IR pentru margine. +    * Altfel
-            - Măsoară distanța cu senzorul cu ultrasunete. +        - Controlează ​robotul în mod **manual** ​cu D-pad
-            - Decide dacă merge înainte sau se întoarce+            ​▲ = înainte 
-    * În modul manual+            ▼ = înapoi 
-        - Controlează ​mișcările ​cu D-pad-ul (↑ ↓ ← →). +            - ◄ = stânga 
-        În absența comenzilor, ​oprește ​motoarele.+            - ► = dreapta 
 +            - Nimic = oprește
  
 <code cpp> <code cpp>
Line 150: Line 214:
   }   }
  
-  // Activare mod evitare obstacole și prăpastii 
   if (GamePad.isTrianglePressed())   if (GamePad.isTrianglePressed())
   {   {
Line 163: Line 226:
   }   }
  
-  // Dezactivare mod automat 
   if (GamePad.isCrossPressed())   if (GamePad.isCrossPressed())
   {   {
Line 181: Line 243:
   }   }
  
-  // Control manual +  ​if (GamePad.isUpPressed()) moveForward();​ 
-  if (GamePad.isUpPressed())+  else if (GamePad.isDownPressed()) moveBackward();​ 
 +  else if (GamePad.isLeftPressed()) turnLeft();​ 
 +  else if (GamePad.isRightPressed()) turnRight();​ 
 +  else stopMotors();​ 
 +
 +</code> 
 + 
 +--- 
 + 
 +**Auxiliary Functions** 
 + 
 +<code cpp> 
 +// Configurează toate pinurile relevante și inițializează servomotorul. 
 +void setUpPinModes() 
 +
 +  pinMode(IN1,​ OUTPUT); 
 +  pinMode(IN2,​ OUTPUT); 
 +  pinMode(IN3,​ OUTPUT); 
 +  pinMode(IN4,​ OUTPUT); 
 +  pinMode(IR_SENSOR_PIN,​ INPUT); 
 + 
 +  myServo.attach(SERVO_PIN);​ 
 +  myServo.write(90);​ 
 +  Serial.println("​Servomotor inițiat la 90°"​);​ 
 +
 + 
 +// Mișcări de bază pentru robot: 
 +void moveForward() 
 +
 +  GPIO.out_w1ts = (1 << IN1) | (1 << IN3); // Set IN1 și IN3 HIGH 
 +  GPIO.out_w1tc = (1 << IN2) | (1 << IN4); // Set IN2 și IN4 LOW 
 +  Serial.println("​Înainte"​);​ 
 +
 + 
 +void moveBackward() 
 +
 +  GPIO.out_w1ts = (1 << IN2) | (1 << IN4); // Set IN2 și IN4 HIGH 
 +  GPIO.out_w1tc = (1 << IN1) | (1 << IN3); // Set IN1 și IN3 LOW 
 +  Serial.println("​Înapoi"​);​ 
 +
 + 
 +void turnLeft() 
 +
 +  GPIO.out_w1ts = (1 << IN2) | (1 << IN3); // IN2 și IN3 HIGH 
 +  GPIO.out_w1tc = (1 << IN1) | (1 << IN4); // IN1 și IN4 LOW 
 +  Serial.println("​Stânga"​);​ 
 +
 + 
 +void turnRight() 
 +
 +  GPIO.out_w1ts = (1 << IN1) | (1 << IN4); // IN1 și IN4 HIGH 
 +  GPIO.out_w1tc = (1 << IN2) | (1 << IN3); // IN2 și IN3 LOW 
 +  Serial.println("​Dreapta"​);​ 
 +
 + 
 +void stopMotors() 
 +
 +  GPIO.out_w1tc = (1 << IN1) | (1 << IN2) | (1 << IN3) | (1 << IN4); // Toți LOW 
 +  Serial.println("​Oprire"​);​ 
 +
 +</​code>​ 
 + 
 +--- 
 + 
 +**Sensor and Navigation Functions** 
 + 
 +<code cpp> 
 +// Returnează distanța măsurată cu ultrasunete. 
 +int readPing() 
 +
 +  delay(70);​ 
 +  int cm = sonar.ping_cm();​ 
 +  if (cm == 0) cm = MAX_DISTANCE;​ 
 + 
 +  Serial.print("​Distanță:​ ")
 +  Serial.print(cm);​ 
 +  Serial.println("​ cm"​);​ 
 +  return cm; 
 +
 + 
 +// Rotește servomotorul spre dreapta, măsoară, revine. 
 +int lookRight() 
 +
 +  myServo.write(50);​ 
 +  delay(500);​ 
 +  int distance = readPing();​ 
 +  myServo.write(90);​ 
 +  return distance; 
 +
 + 
 +// Rotește servomotorul spre stânga, măsoară, revine. 
 +int lookLeft() 
 +
 +  myServo.write(130);​ 
 +  delay(500);​ 
 +  int distance = readPing();​ 
 +  myServo.write(90);​ 
 +  return distance; 
 +
 + 
 +// Evită obstacole și margini. Apelată în mod automat. 
 +void avoidObstacles() 
 +
 +  int senzorIR = digitalRead(IR_SENSOR_PIN);​ // LOW = prăpastie 
 +  int distanceR = 0; 
 +  int distanceL = 0; 
 +  distance = readPing();​ 
 + 
 +  if (senzorIR == LOW)
   {   {
-    ​moveForward();+    ​stopMotors()
 +    lcd.setCursor(0,​ 1); 
 +    lcd.print("​Prapastie STOP  "); 
 +    delay(200);​ 
 + 
 +    moveBackward();​ 
 +    delay(400);​ 
 +    stopMotors();​ 
 +    delay(200);​ 
 + 
 +    turnLeft(); // întoarcere completă 
 +    delay(700);​ 
 +    stopMotors();​ 
 +    delay(200);​ 
 +    return;
   }   }
-  else if (GamePad.isDownPressed())+ 
 +  ​if (distance <= OBSTACLE_DISTANCE)
   {   {
 +    stopMotors();​
 +    lcd.setCursor(0,​ 1);
 +    lcd.print("​Obstacol STOP   "​);​
 +    delay(100);
     moveBackward();​     moveBackward();​
-  } +    delay(300); 
-  else if (GamePad.isLeftPressed()) +    ​stopMotors(); 
-  { +    delay(200)
-    ​turnLeft(); + 
-  } +    distanceR = lookRight(); 
-  ​else ​if (GamePad.isRightPressed()) +    ​delay(200);​ 
-  { +    ​distanceL = lookLeft(); 
-    ​turnRight();+    ​delay(200);​ 
 + 
 +    ​if (distanceR >= distanceL) 
 +    { 
 +      turnRight()
 +      delay(500); 
 +      ​stopMotors();​ 
 +    ​
 +    else 
 +    { 
 +      turnLeft(); 
 +      delay(500);​ 
 +      stopMotors();​ 
 +    }
   }   }
   else   else
   {   {
-    ​stopMotors();+    ​moveForward(); 
 +    lcd.setCursor(0,​ 1); 
 +    lcd.print("​Drum liber      ");
   }   }
 } }
Line 209: Line 413:
 {{:​pm:​prj2025:​fstancu:​img_2149.jpg?​260|}} {{:​pm:​prj2025:​fstancu:​img_2149.jpg?​260|}}
 } }
 +===== VIDEO =====
 +https://​www.youtube.com/​shorts/​16-T-_LEwkY
 +
 ===== Rezultate Obţinute ===== ===== Rezultate Obţinute =====
 {{:​pm:​prj2025:​fstancu:​img_dan1.jpg?​307|}} {{:​pm:​prj2025:​fstancu:​img_dan1.jpg?​307|}}
Line 215: Line 422:
  
 ===== Concluzii ===== ===== Concluzii =====
 +Acest proiect este un robot autonom controlabil prin Bluetooth, capabil să evite obstacole și prăpastii cu ajutorul senzorilor, oferind în același timp control manual precis prin aplicația Dabble. Este o combinație reușită între inteligență integrată, interfață prietenoasă și control adaptiv al motoarelor.
 ===== Download ===== ===== Download =====
- +{{:pm:prj2025:fstancu:bluetoothcar_v1.1_vrinceanu.zip|}}
-<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ă ;-). +
- +
-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>​ +
- +
-===== 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>​ +LCD Help: 
-Listă cu documente, datasheet-uri,​ resurse Internet folosite, eventual grupate pe **Resurse Software** şi **Resurse Hardware**. +https://www.youtube.com/watch?​v=860eErq9c3E>
-</note>+
  
-<​html><​a class="​media mediafile mf_pdf"​ href="?​do=export_pdf">​Export to PDF</a></html>+Piese: 
 +https://sigmanortec.ro 
 +https://​www.optimusdigital.ro/​ro/​
  
pm/prj2025/fstancu/dan.vrinceanu.1748379489.txt.gz · Last modified: 2025/05/27 23:58 by dan.vrinceanu
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