This is an old revision of the document!
Prezentarea pe scurt a proiectului vostru:
Proiectul constă într-o mașinuță inteligentă cu trei moduri de operare: control manual prin Bluetooth folosind o aplicație pe smartphone, mod automat în care evită obstacolele
Scopul acestui proiect pentru mine este să învăț cum pot integra diferite tehnologii, precum senzorii, comunicația Bluetooth și algoritmii de control, într-un sistem robotic funcțional. Mi se pare un proiect interesant și provocator, care mă ajută să înțeleg mai bine cum lucrează componentele între ele. În plus, îmi oferă ocazia să aplic ceea ce am învățat la școală într-un mod practic și interactiv. Consider că este o experiență utilă atât pentru dezvoltarea mea personală, cât și pentru viitoarele proiecte în domeniul tehnologiei și automatizării.
Ideea de la care am pornit a fost să fac o mașinuță controlată prin Bluetooth, o dorință pe care o aveam încă din copilărie, pentru că mi s-a părut mereu ceva foarte interesant. Pe parcurs, m-am gândit cum aș putea să o îmbunătățesc și să o fac mai inteligentă, așa că am adăugat senzori pentru a evita obstacolele si prapastii. Astfel, proiectul a devenit mult mai complex și mai captivant, combinând pasiunea din copilărie cu noile cunoștințe tehnice.
Proiectul este util prin ceea ce face, pentru că reproduce, la scară mică, funcționalități întâlnite în tehnologia reală – cum ar fi mașinile autonome sau sistemele inteligente de transport. Modul automat ajută la înțelegerea principiilor de evitare a obstacolelor, folosite la roboți sau mașini autonome. </note>
Lista de piese:
Componentă | Cantitate |
---|---|
Placă de plastic | 1 |
ESP32 | 1 |
Kit motor reductor + roată plastic cu cauciuc | 4 |
Punte H Dublă MX1508, DC | 1 |
Senzor ultrasunete HC SR-04P | 1 |
Breadboard 400 puncte | 2 |
Senzor IR | 1 |
LCD 1602 cu interfață I2C | 1 |
Baterie 18650 | 2 |
Modul powerbank 18650 | 1 |
Servomotor SG90 | 1 |
Suport acumulatori 18650, 2S | 1 |
</note>
Mașina funcționează în două moduri distincte, controlate din aplicația de pe smartphone (Dabble):
Modul Manual (default la conectare) Modul Automat: Evitare obstacole + prăpastii
Starea 0 → Așteptare conectare Bluetooth (Idle):
Starea 1 → Mod Manual (Bluetooth GamePad activ):
Starea 2 → Mod Automat (Evitare obstacole și prăpastii):
Starea 3 → Revenire la Manual:
Setup
void setup() { Serial.begin(115200); setUpPinModes(); Dabble.begin("MyBluetoothCar"); Wire.begin(25, 26); // SDA, SCL lcd.init(); lcd.backlight(); lcd.setCursor(0, 0); lcd.print("Conecteaza-te"); lcd.setCursor(0, 1); lcd.print("sefule "); Serial.println("Dabble și LCD inițiate, aștept conectarea..."); }
—
Main Loop
void loop() { Dabble.processInput(); if (!Dabble.isAppConnected()) { lcd.setCursor(0, 0); lcd.print("Conecteaza-te "); lcd.setCursor(0, 1); lcd.print("sefule "); delay(1000); return; } static bool wasConnected = false; if (!wasConnected) { lcd.clear(); lcd.setCursor(0, 0); lcd.print("Mod: Manual"); wasConnected = true; } if (GamePad.isTrianglePressed()) { Serial.println("Mod obstacole+prapastie activat"); obstacleAvoidanceMode = true; lcd.clear(); lcd.setCursor(0, 0); lcd.print("Mod: Obstacole+"); lcd.setCursor(0, 1); lcd.print("Prapastii "); } if (GamePad.isCrossPressed()) { Serial.println("Mod automat oprit, revenire la manual"); obstacleAvoidanceMode = false; stopMotors(); lcd.clear(); lcd.setCursor(0, 0); lcd.print("Mod: Manual"); } if (obstacleAvoidanceMode) { avoidObstacles(); return; } if (GamePad.isUpPressed()) moveForward(); else if (GamePad.isDownPressed()) moveBackward(); else if (GamePad.isLeftPressed()) turnLeft(); else if (GamePad.isRightPressed()) turnRight(); else stopMotors(); }
—
Auxiliary Functions
// 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() { digitalWrite(IN1, HIGH); digitalWrite(IN2, LOW); digitalWrite(IN3, HIGH); digitalWrite(IN4, LOW); Serial.println("Înainte"); } void moveBackward() { digitalWrite(IN1, LOW); digitalWrite(IN2, HIGH); digitalWrite(IN3, LOW); digitalWrite(IN4, HIGH); Serial.println("Înapoi"); } void turnLeft() { digitalWrite(IN1, LOW); digitalWrite(IN2, HIGH); digitalWrite(IN3, HIGH); digitalWrite(IN4, LOW); Serial.println("Stânga"); } void turnRight() { digitalWrite(IN1, HIGH); digitalWrite(IN2, LOW); digitalWrite(IN3, LOW); digitalWrite(IN4, HIGH); Serial.println("Dreapta"); } void stopMotors() { digitalWrite(IN1, LOW); digitalWrite(IN2, LOW); digitalWrite(IN3, LOW); digitalWrite(IN4, LOW); Serial.println("Oprire"); }
—
Sensor and Navigation Functions
// 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) { 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; } if (distance <= OBSTACLE_DISTANCE) { stopMotors(); lcd.setCursor(0, 1); lcd.print("Obstacol STOP "); delay(100); moveBackward(); delay(300); stopMotors(); delay(200); distanceR = lookRight(); delay(200); distanceL = lookLeft(); delay(200); if (distanceR >= distanceL) { turnRight(); delay(500); stopMotors(); } else { turnLeft(); delay(500); stopMotors(); } } else { moveForward(); lcd.setCursor(0, 1); lcd.print("Drum liber "); } }
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.
LCD Help: https://www.youtube.com/watch?v=860eErq9c3E>