Vonalkövető robot


Rengeteg magyar nyelvű leírás található a neten vonalkövető robotok építéséről, igazából hozzájuk tenni már nem lehet. Mégis úgy döntöttem, hogy meg írom ezt a cikket, elmondom a saját tapasztalataimat a saját szájízem szerint.

Nézzük miről is van szó: a robot maga egy elég egyszerű szerkezet, két áttételes dc motor gondoskodik a meghajtásról, egy ir fényérzékelő sorral detektáljuk a padlón lévő fekete csíkot, valamint mindezt ami üzemelteti egy Arduino Uno rácsatlakoztatott motor meghajtó pajzsal.


Áttételes motor
A két áttételes dc motor 6V, 70mA minimum, ez mindenképp több mint amennyit az Unonk kimenete elbírna(40mA), ezért kell használnunk motor meghajtót ez az én esetemben egy motor shield. 4Dc motor vezérlésére alkalmas egy időben így a két motorral simán elbír. A motorok sebességét vezéreljük PWM jellel (erről itt olvashattok), mivel rövidebb a PWM jel kitöltése annál kevesebb feszt kap a motor, annál lassabban forog.


Öt mozgás formát alkalmazunk: előre menet – minkét motor egyenlő sebességgel forog
enyhe fordulás balra – jobb motor normál sebességgel forog a bal csökkentett sebességgel
enyhe fordulás jobbra – bal motor normál sebességgel forog a jobb csökkentettel
erős fordulás balra – jobb motor normál seb. bal motor áll
erős fordulás jobbra – bal motor normál seb. Jobb motor áll.


IR fényérzékelősor
Saját készítésű alkatrész ami 5db reflektív optocsatolóból áll illetve a belőlük elkészített áramkörökből.
A reflektív optocsatoló egy közös műanyag házba ültetett IR led (adó) és egy fotó tranzisztor(vevő).
Működéséről: az IR led által kibocsájtott fény megfelelő távolságban levő felületről visszaverődve
áramot gerjeszt a fotó tranzisztor bázisában és a tranyó kinyit. A fényerősség mértékétől függően
nyílik az áram útja, így feszültség osztó ellenállással alkalmazva különböző fesz. értékeket kapunk.


Az érzékelő sor kimeneteinek feszültség értékeit az Uno analóg bemenetei dolgozzák majd fel.
Az általam használt motor shielden külön be kellet forrasztani tüskesort az analóg bemenetek számára kialakított forrlyukakba, ezekhez már könnyedén csatlakoztatni lehet az érzékelőket.
Az érzékelő sorba öt darab IR szenzort füzünk fel, egy IR szenzor kapcsolását mutatja be a következő ábra.

Alváz lap

Az alváz hordozza a robotunk összes alkatrészét, ezért két lényeges tulajdonságát kell előtérbe helyezni. Az egyik a megfelelő szilárdság, bírja el a rá ható terheléseket, a másik, hogy legyen lehetőség rajta az alkatrészek rögzítésére. Több lehetőség van: lehet kapni készre gyártott alvázakat önmagukban vagy áttétes motorokkal kerekekkel, vagy készíthetünk magunk műanyagból, fémből, fából. Részemről saját magam készítettem rétegelt lemezből az alvázat. A rögzítéseket lemezcsavarokkal illetve normál csavarokkal távtartók segítségével oldottam meg.


Még néhány szükséges alkatrész: egy bolygó kerék – ez bármilyen kerék lehet a lényeg, hogy
teljesen szabadon el tudjon fordulni. Elem tartó – 4db ceruza vagy nagyobb elem (6V) számára,
kapcsoló – a robot ki/be kapcsolására.


A mechanikai összeépítés mindenkinél egyedi, mindenki a saját módján készíti el ezért nem is foglalkozom vele a továbbiakban.


Említettem már a motor meghajtást motor shield segítségével oldottam meg, a működéséhez le kell tölteni az AFMotor könyvtárat a https://github.com/adafruit/Adafruit-Motor-Shield-library oldalról.

Kicsomagolás, átnevezés AFMotor-ra majd bemásolás az Arduino/ libraries könyvtárba.

A kód :

#include <AFMotor.h>

AF_DCMotor motor_b(4);// a shield 3-as és 4-es kimenetét állítottam be
AF_DCMotor motor_j(3);

int jo_sz,jo_k,koz,ba_k,ba_sz,hatar,seb,tol;//változók az érzékelőkhöz

void setup(){
Serial.begin(9600);
}

void loop(){
// hatar változó azt az értéket tárolja ami alatt már sötét vonalként veszi az adott értéket
hatar=230;
//motor sebessége
seb=200;
//tolerancia a motorok közti eltérést egyenlíti ki
tol=20;
//IR szenzor beméréséhez aktiváljuk a következő sort.
//kiiratas();
//az öt szenzor értékének betárolása a változókba
jo_sz = analogRead(A0);
jo_k = analogRead(A1);
koz = analogRead(A2);
ba_k = analogRead(A3);
ba_sz = analogRead(A4);

//az értékeknek megfelelő esetválasztás
if(koz<hatar)
elore();
if(ba_k<hatar)
jobbra_min();
if(ba_sz<hatar)
balra_max();
if(jo_k<hatar)
balra_min();
if(jo_sz<hatar)
jobbra_max();
// ha nem talál fekete vonalat egyenesen halad tovább
if(jo_sz>hatar&&jo_k>hatar&&koz>hatar&&ba_k>hatar&&ba_sz>hatar)
elore();
//motorok hajtási ideje
delay(20);
//motorok kikapcsolása
motor_j.run(RELEASE);
motor_b.run(RELEASE);
//loop ciklus vége
}

// függvények a kiíratáshoz és a motor vezérléshez
void kiiratas(){
Serial.print("jobb szelso erzekelo: ");
Serial.println(jo_sz);
Serial.print("jobb kozepso erzekelo: ");
Serial.println(jo_k);
Serial.print("kozepso erzekelo: ");
Serial.println(koz);
Serial.print("bal kozepso erzekelo: ");
Serial.println(ba_k);
Serial.print("bal szelso erzekelo: ");
Serial.println(ba_sz);
delay(500);
}

void elore(){
motor_j.run(BACKWARD);
motor_b.run(BACKWARD);
motor_j.setSpeed(seb);
motor_b.setSpeed(seb-tol);
}

void jobbra_min(){
motor_j.run(BACKWARD);
motor_b.run(BACKWARD);
motor_j.setSpeed(seb/2);
motor_b.setSpeed(seb);
}

void balra_min(){
motor_j.run(BACKWARD);
motor_b.run(BACKWARD);
motor_j.setSpeed(seb);
motor_b.setSpeed(seb/2);
}

void jobbra_max(){
motor_b.run(FORWARD);
motor_j.run(RELEASE);
motor_b.setSpeed(seb);
}

void balra_max(){
motor_j.run(FORWARD);
motor_b.run(RELEASE);
motor_j.setSpeed(seb);
}


A program figyeli az öt szenzor értékeit, ha valamelyik értéke egy bizonyos szint alá csökken(hatar)
akkor elindítja a megfelelő motorhajtást. A motor hajtás 20ms-ig hajtja a motorokat majd leállítja azokat, é újra kezdődik az érzékelők figyelése.


Az IR szenzor értékének beállítása a kiiratas() függvénnyel történik, az értékek meghatározásához
aktiváljuk a program elején a következő sort: //kiiratas();
Töltsük fel, nyissuk meg a soros monitort és figyeljük az értékeket. Nagyjából egyforma értékeket kell mutatnia. Ragasszunk fekete szigetelő szalag csíkot arra a felületre ahol használni szeretnénk a
robotunkat, tegyük fölé egymás után az érzékelőket, figyeljük a soros monitoron az értékeket.

A fekete szigszalag értékei alacsonyabbak lesznek, a világosabb felületé magasabbak. A szigszalagos értékre kellene beindulni a különböző motorhajtásoknak, ahhoz hogy biztosan működjön a dolog ehhez az értékhez még hozzá kell adnunk 50-100 között így szélesebb sávra lesz érvényes a működési érték. Ezt az értéket a hatar változóban kell beállítani.


A tol változó a motorok forgása közötti különbséget hívatott kiegyenlíteni. Ez nálam adott sebességen az egyenes haladás teszteléséből állt. A robot valamelyik irányba való elfordulása a másik oldali motor gyorsabb forgását jelenti, ennek a motornak a seb értékét kell csökkenteni mind addig míg egyenesen nem kezd haladni a robotunk. A csökkentés mértékét tárolja a tol változó.


Az építésnél a szenzorok túl messze kerültek nálam, ezért működés közben gyakran megesett, hogy
egy szenzor se észlelt fekete vonalat(mivel két szenzor között bőven elfért a fekete vonal) ezért beépítettem a következő sort:
if(jo_sz>hatar&&jo_k>hatar&&koz>hatar&&ba_k>hatar&&ba_sz>hatar)
elore();

A lényeg az, ha egyik szenzor se észlel fekete vonalat akkor a robot tovább halad egyenesen, így rövid időn belül ráakad a vonalra(ha még van vonal, különben egyenesen világgá megy).

http://youtu.be/EVqiyIkXmFk
A programra bőven ráfér még finomítás, de egy kezdőlépésnek megfelel, mindenki alakítsa izlése szerint.