This is an old revision of the document!
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.
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:
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.
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.
Robotul Roomba va funcționa pe baza unui FSM, cu următoarele stări:
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();
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, pentru a calcula timpul dus-întors al undei. Știind viteza sunetului, obținem distanța.
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.