Table of Contents

Roomba

Introducere

Voi implementa un robot de aspirat. Spre deosebire de un Roomba adevărat, robotul de aspirat are forma unei mașinuțe, va folosi un senzor ultrasonic si un servomotor ca sa evite obstacolele, si va face viraje pe loc, deoarece fiecare roata va fi controlată independent folosind PWM.
Pentru partea de aspirat, voi folosi o sticla ca suport și un motoraș cu ventilator.
Considerând camera dreptunghiulară, robotul va încerca sa o parcurgă pe toată in zig-zag. Se deplasează înainte, pana de de un obstacol (peretele), moment în care investighează direcțiile posibile, folosind senzorul ultrasonic, si alege calea cea mai libera.
Scopul robotului e sa automatizeze curățenia prin casa.

Probleme ce pot apărea:

  • Cu cât sunt mai multe obstacole in camera, cu atât robotul va da mai puțin randament, deoarece ii trebuie un algoritm mai inteligent de evitare a obstacolelor si recalcularea traiectoriei.
  • Nu se creează suficient vid in recipient pentru a aspira.

Descriere generală

Schema bloc

Hardware Design

Lista de piese
Schema electrica

Conexiuni între pini

Shield-ul pentru motoare se atașează direct pe Arduino. În urma consultării datasheet-ului pentru Adafruit Motor Shield V1, acesta folosește următorii pini:

Pinii menționați mai sus sunt folosiți pentru controlul PWM al motoarelor.

Următorii pini sunt folosiți mereu de shield, indiferent dacă sunt conectate motoare sau indiferent de câte sunt conectate, deoarece sunt conectați la latch-ul 74HC595:

Pinii senzorului ultrasonic au fost legați astfel:

Servomotorul se leagă pe shield la S1, iar conform datasheet-ului:

Bateriile se leagă la EXT_PWR de pe shield.

Software Design

Mediu de dezvoltare

Librarii

Librăria AFMotor.h expune o interfața pentru a controla motoare prin intermediul shield-ului ales.
Librăria pune la dispoziție clasa AF_DCMotor, care primește ca parametru un număr de motor, scris pe shield, si oferă funcții pentru controlul motoarelor, precum run sau setSpeed.
AFMotor.h este un wrapper pentru PWM.

Librăria Servo.h expune o interfața pentru a lucra mai ușor cu servomotoarele.
Librăria pune la dispoziție clasa Servo, si o serie de metode prin care servomotorul este configurat si utilizat.
Pentru a specifica pin-ul unde e conectat servomotorul se folosește metoda attach.
Pentru a controla servomotorul, avem metoda write, care folosește in spate PWM si Timere.

Structura codului

Robotul Roomba va funcționa pe baza unui FSM, cu următoarele stări:

Controlul Motoarelor

Funcțiile pentru controlul motoarelor sunt in headerul MotorControl.h.
Am scris niște API-uri pentru a controla mai ușor mișcarea robotului, folosindu-ma de metodele expuse in AFMotor.h:

void stopMotors();
void forwardMotors();
void backwardMotors();
void turnLeftMotors();
void turnRightMotors();
Măsurarea distanței

Funcțiile pentru măsurarea distanței sunt in headerul Sonar.h.
Am creat un API pentru a controla senzorul ultrasonic, folosind cunoștiințele dobândite in laboratoarele de GPIO, Timere și Întreruperi. Am vrut sa folosesc Timer2 pentru a măsura timpul fără millis, dar suprascrierea ISR-ului de Overflow intervine peste librăria ce expune API-ul pentru motoare si apăreau conflicte. Totuși, am folosit întreruperi pentru măsurarea distanței.

void initSonar(void);
void initEchoInterrupt(void);
void sendTriggerPulse(void);
uint16_t measureDistance(void);

Cum funcționează ?
Se generează o întrerupere pe pinul la care este legat ECHO al senzorului ultrasonic la fiecare schimbare a semnalului.
Când TRIG emite unda, ECHO trece pe HIGH, iar când se întoarce unda, ECHO trece pe LOW. Se retine timestampul pentru fiecare dintre aceste evenimente si se face diferența, pentru a calcula timpul dus-întors al undei. Știind viteza sunetului, si timpul dus-întors, putem calcula ușor distanța parcursă.

Alegerea unei noi direcții

Pentru alegerea unei noi direcții, FSM-ul din main folosește mai multe API-uri, definite in ServoControl.h:

void initServoControl(void);
void lookAtRightInstant(int angle);
void lookAtLeftInstant(int angle);
void lookCenter(void);
void initLookPoints(void);
void clearLookPoints(void);
void scanAllLookPoints(void);
int getBestAngle(void);

Robotul alege direcția prin rotirea servomotorului la mai multe unghiuri predefinite pentru a scana distanțele din stânga, centru și dreapta. Pe baza acestor măsurători, se selectează unghiul cu cea mai mare distanță liberă, iar robotul se va orienta spre acea direcție pentru a evita obstacolele.

Rezultate Obţinute

Concluzii

Proiectul demonstrează posibilitatea realizării unui robot de curățenie funcțional, cu un design modular și scalabil. Limitările țin mai ales de lipsa unui algoritm mai sofisticat pentru detecția și ocolirea obstacolelor, precum și de eficiența sistemului de aspirare.

Download

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.

Jurnal

Video demonstrativ

https://www.youtube.com/shorts/H-P-53NL3jc

Imagini

Bibliografie/Resurse

Listă cu documente, datasheet-uri, resurse Internet folosite, eventual grupate pe Resurse Software şi Resurse Hardware.

Resurse Hardware

https://cdn-learn.adafruit.com/downloads/pdf/adafruit-motor-shield.pdf

https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf

https://www.circuito.io/blog/arduino-uno-pinout/

Resurse software

https://github.com/adafruit/Adafruit-Motor-Shield-library/tree/master

Cod sursa

https://github.com/cristiantudor1607/RoombaCar

Export to PDF