Miskolci Egyetem Gépészmérnöki és Informatikai Kar Villamosmérnöki Intézet Elektrotechnikai-Elektronikai Intézeti Tanszék
Villamosmérnöki szak Elektronikai tervezés és gyártás szakirány
Többfunkciós hobbirobot építése és vezérlése Arduino UNO mikrovezérlő kártya segítségével Szakdolgozat
Németh Gábor GHDNV7 2014/2015 1. félév
Eredetiségi nyilatkozat
Alulírott Németh Gábor
(neptun kód: GHDNV7)
a Miskolci Egyetem Gépészmérnöki és Informatikai Karának végzős szakos hallgatója ezennel büntetőjogi és fegyelmi felelősségem tudatában nyilatkozom és aláírásommal igazolom, hogy a
Többfunkciós hobbirobot építése és vezérlése Arduino UNO mikrovezérlő kártya segítségével
című szakdolgozatom saját, önálló munkám; az abban hivatkozott szakirodalom felhasználása a forráskezelés szabályi szerint történt. Tudomásul veszem, hogy plágiumnak számít: - szószerinti idézet közlése idézőjel és hivatkozás megjelölése nélkül; - tartalmi idézet hivatkozás megjelölése nélkül; - más publikált gondolatainak saját gondolatként való feltüntetése. Alulírott kijelentem, hogy a plágium fogalmát megismertem, és tudomásul veszem, hogy plágium esetén a szakdolgozat visszavonásra kerül.
Miskolc, 2014. november 28.
hallgató aláírása
2
Tartalomjegyzék Bevezetés .................................................................................................................................... 4 I.
Robottechnika, a hobbirobotok mechanikai kialakítása és vezérlési módszerei ................. 5 1. A robot fogalma .............................................................................................................. 5 2. A robotok történelme ...................................................................................................... 5 3. Mechanikai kialakítás és vezérlési módszerek................................................................ 9 3.1 Hexapod ................................................................................................................... 9 3.2 Quadrocopter.......................................................................................................... 11 3.3 Egyensúlyozó robotok ........................................................................................... 12
II. Többfunkciós hobbirobot megtervezése ............................................................................ 15 1. Arduino Board-ok és Shild-ek ...................................................................................... 15 2. Arduino Uno R3 és fejlesztőkörnyezete ....................................................................... 17 2.1 Arduino Uno R3 ..................................................................................................... 17 2.2 Fejlesztőkörnyezet ................................................................................................. 19 3. Felhasznált eszközök, szenzorok, alkatrészek .............................................................. 25 4. Felhasznált eszközök, szenzorok, alkatrészek vezérlése .............................................. 28 4.1 DC motorok vezérlése............................................................................................ 28 4.2 Ultrahang szenzor vezérlése .................................................................................. 34 4.3 Léptetőmotor vezérlése .......................................................................................... 38 4.4 A giroszkóp és a szervo motor vezérlése ............................................................... 41 4.5 Bluetooth modul megtervezése és programozása .................................................. 45 4.6 Fotoellenállás programozása .................................................................................. 48 5. A felhasználó általi irányítás megvalósítása ................................................................. 49 6. Az önálló mozgás megvalósítása .................................................................................. 52 III. Többfunkciós hobbirobot megépítése................................................................................ 57 Következtetések ........................................................................................................................ 63 Összefoglaló.............................................................................................................................. 64 Summary .................................................................................................................................. 65 Források .................................................................................................................................. 66 Melléklet .................................................................................................................................. 68
3
Bevezetés A szakdolgozatom témájának keresése során olyan témakört szerettem volna kidolgozni,
amely
hozzátartozik
az
érdeklődési
körömhöz.
Választásom
a
hobbirobotokra esett, mivel ezek a programozható eszközök régóta foglalkoztattak. Manapság egyre nagyobb teret nyernek a különböző feladatokat ellátó robotok, amelyek helytállnak mind a háztartásban, például a robotporszívó, mind pedig a hobbi világában. Szakdolgozatom első felében tanulmányozom ezek felépítését, a hozzá csatlakoztatható eszközöket,
érzékelőket,
szenzorokat,
illetve
megismerkedem
magával
a
fejlesztőkörnyezettel. A második részben egy saját tervezésű robotot fogok bemutatni az általam megtervezett funkciókkal. Célom egy olyan hobbirobot megtervezése és megépítése, amely képes a helyváltoztatásra mind magától, mind pedig a felhasználó által.
4
I.
Robottechnika, a hobbirobotok mechanikai kialakítása és vezérlési módszerei 1. A robot fogalma
A robot olyan többfunkciós eszköz, amely saját programja szerint mozog, mozgat eszközöket, anyagokat, illetve különböző feladatok elvégzésére képes. A robotokat sokféle szempont szerint lehet csoportosítani (alkalmazási területük, jellemzőik, felépítésű, vezérlésük szerint stb.). [1]
2. A robotok történelme Már a 17. és 18. században olyan ezermesterek voltak, akik olyan szerkezetek megvalósításán törekedtek, amely az emberek munkáját megkönnyítené. Az 1700-as években 2 híres robot készült. Mindkét mű Jacques de Vaucanson nevéhez fűződik, amelyek közül az egyik egy fuvolázó mechanikus baba volt. Ez a robot képes volt a fuvolát a szájához tartani, fújni, valamint az ujjaival a billentyűket mozgatni és 11 fuvolajáték előadására volt képes.
1. ábra. The Tambourine Player [2]
5
A másik alkotása, amely 1738-ban készült el, egy hápogó kacsa volt. Ez a szerkezet nemcsak hangot adott ki és lépegetett, hanem úszkálni és lubickolni is képes volt. Ezek mellett még a kacsa emésztését is megépítette, azaz ivott, evett és szimulálni tudta az emésztés végtermékét is.
2. ábra. Kacsa robot [2] 1772-ben Pierre Jaquet-Droz svájci órás megalkotta az ’írót’, amely egy fiú alak volt. Ez a robot egy tollat fogott a kezébe és azt a tintába mártva René Descartes szavait papírra vetette („Gondolkodom, tehát vagyok.”).
3. ábra. „Író”[2]
6
Két év múlva megalkotta az „Író” párját a „Tervezőt”, amely különböző rajzokat tudott készíteni. Kempelen Farkas műve egy sakkautomata volt, amelynél egy töröknek öltöztetett baba ellen kellett játszani. Igazság szerint nem a gép játszott, hanem a sakk dobozában egy igazi játékos mozgatta a bábukat egy igen bonyolult kerékrendszer segítségével. A szerkezet nem a sakktudásával került bele a történelembe, hanem a kerékrendszer bonyolult szerkezetével, amely abban az időben nagy műszaki teljesítménynek számított.
4. ábra. Sakkautomata [2] A robotok építése a 19. században is folytatódott H. Millardet művével, amely egy konstruált képet festő baba volt, illetve George Moore „szaladó mozdonyával”, amelynek ember formája volt és a gőzgép által hajtott lépései kétszer gyorsabbak voltak, mint egy normál emberé. Manapság már a bonyolultabb tevékenységeket ésszerűbb robotokkal elvégeztetni, mivel napi 24 órát és a hét minden napján képesek dolgozni. Az első sorozatgyártású ipari robot 1959-ben jelent meg a Planet Corporation által és az első szerelési műveletre tervezett robot az Olivetti SIGMA volt 1975-ben. Majd 1985-ben megjelenik a robotok harmadik generációja a mobil robotok és a harcászati robotok fejlesztésével, illetve 1998-tól az egészségügyben is megjelennek a robotok orvosi alkalmazásai.
7
5. ábra. Orvosi robot [2] A különböző robottípusok folyamatos fejlesztés alatt állnak mind a mai napig és a szakértők igyekeznek a 21. század csúcstechnológiáját megalkotni. Fejlődésük alapján három generációs csoportba sorolták a robotokat: Első generációs robotok Ezeket a robotokat ’vak’ robotoknak is nevezik azért, mert környezetünkből érkező jelek nem befolyásolják a robot működését. Második generációs robotok A második generációs robotok már érzékelőkkel vannak ellátva, így alkalmazkodni tudnak a környezeti változásokhoz. Általában helyzet, erő, nyomaték, hőmérséklet érzékelőt alkalmaznak, de emellett sok különféle szenzor létezik még. Harmadik generációs robotok Azért alkalmazzák komplex feladatokban őket, mert érzékelőkkel van ellátva, amelyekkel használva a környezeti változásokat érzékeli, illetve adatgyűjtésre és adatfeldolgozásra is képesek, amely segítségével önálló döntéseket hozhat. A különböző robotok között léteznek ’hobbirobotok’ is, amelyeket szintén különféle csoportokba lehet sorolni. A három generációs csoportból a hobbirobotok a harmadik generációba tartoznak, ugyanis érzékelőket, szenzorokat alkalmaznak a tájékozódáshoz, valamint a mikrovezérlő által adatok gyűjtésére és feldolgozására is képesek. [2] 8
3. Mechanikai kialakítás és vezérlési módszerek Kialakításukat tekintve sokféle megvalósítás létezik, amely különböző funkciók elvégzésére alkalmassá teszik a hobbirobotokat. Ilyen mechanikai kialakítás lehet például egy lépegető robot vagy valamilyen repülésre alkalmas szerkezet. A robot vázának tervezésekor ügyelni kell arra, hogy maga a váz ne legyen túl nehéz a robotot mozgató elektronika számára, azaz, hogy magát robotot a saját súlya ne akadályozza a mozgásban. Olyan anyagból célszerű megépíteni a robot vázát, amely mind szilárdsági szempontból, mind pedig a súly szempontjából megfelel a robot szerkezetének. Általában préselt fából, műanyagból vagy plexiből készül a robotok mechanikai váza. A váz megtervezésékor a másik fontos szempont, amelyet figyelembe kell venni, az elektronika elhelyezése. Például célszerű magát a mikrovezérlő kártyát könnyen hozzáférhető helyre rakni.
3.1
Hexapod
A hexapod egy olyan lépegető robot, amelynek 6 lába van, és úgy mozog, mint egy igazi rovar.
6. ábra Hexapod [3] Ennek a robotnak a váza préselt fából készült. A 6. ábrán jól látható a robot tervezője által készített megfogó kar, amellyel a robot különböző tárgyak elmozdítására képes. A vázon különböző méretű és alakú lyukak találhatók, amelyek a szenzorok, érzékelők, motorok elhelyezésére, illetve vezetékek kivezetésére szolgálnak.
9
Mivel a hexapodnak 6 lába van és valóságos mozgásra képes, ezért minden lábnál két darab szervo motort találunk, amelyek a lábak mozgásáért felelősek, illetve a megfogó kart is szervomotorok vezérlik. Maga a hexapod elektronikája nem bonyolult, ugyanis a szervo motorokon kívül a roboton csak egy érzékelő és egy bluetooth modul található. Az érzékelő a robot tárgyaknak, illetve falnak ütközését hivatott megelőzni, a bluetooth modul pedig a számítógéppel való kapcsolatot biztosítja.
7. ábra A rendszer folyamatábrája [3] A mikrovezérlőre feltöltendő program már nem olyan egyszerű, mivel a joystick gombjait be kell programozni az egyes funkciókhoz, a bluetooth modult be kell állítani az AT parancsok segítségével, illetve az AVR-re meg kell írni azt a programot, amely a szervo motorokat vezérli a mozgásnak megfelelően. [3]
10
3.2
Quadrocopter
A quadrocopter egy olyan repülni képes hobbirobot, amely négy rotort segítségével fent tud maradni a levegőben.
8. ábra Quadrocopter [4] A robot vázának könnyűnek kell lennie, mivel a roboton lévő egyenáramú motorok kisteljesítményűek és így nem bírnák felemelni magát a szerkezetet, illetve minél könnyebb a quadrocopter teste, annál könnyebb irányítani. Ennek a szerkezetnek a súlya 88 gramm az akkumulátorral együtt. A 8. ábrán jól látható a négy légcsavar, amelyből kettő piros, kettő pedig fekete színű. Ez az irányítás megkönnyítését szolgálja, mivel a piros légcsavarok a quadrocopter elejét jelzik. Magát a testet egy rugalmas műanyag védi, amelyben a vezérlő elektronika található.
9. ábra Quadrocopter elektronikája [4]
11
Az elektronika általában egy mikrovezérlő kártyából, egy giroszkóp rendszerből és egy vezeték nélküli kapcsolatot létrehozó bluetooth modulból áll. Gyakran ezekre a robotokra felszerelnek még egy kamera modult is, amelynek a súlya szintén nem nehéz, körülbelül 3 gramm. A sötétben való repülés, illetve a láthatóság megkönnyítése érdekében a rotorok alatt általában LED-ek találhatók, amelyek szintén különböző színűek, ezzel segítve a quadrocopter irányítását.
10. ábra A quadrocopter távirányítója [4] A 10. ábrán a quadrocopter távirányítója látható, amelyen két darab joystick, egy LCD kijelző és különböző trimmer kapcsolók helyezkednek el. A két joystick a gáz adásért és a mozgásokért felelős, miközben a trimmer kapcsolók a quadricopter kiegyensúlyozását biztosítják. Az LCD kijelzőn sok hasznos információ van feltüntetve, ilyen például a gázadás mértéke, az aktuális mód, a trimmer kapcsolók állása, az akkumulátor feszültsége. [4]
3.3 Egyensúlyozó robotok Az egyensúlyozó robot működési elvének az alapja az inverzingához hasonló, amely úgy működik, hogy egy adott robot szerkezetének teteje valamelyik irányba dőlni kezd, akkor a robot alját úgy kell vezérelni, hogy a dőlés irányába induljon el, azaz arra kell mozgatni a robotot, amerre a teteje dől. Maga a szerkezet két részből áll, egy ingából és egy alsó részből, amely a mozgást teszi lehetővé.
12
11. ábra Az inverzinga működési elve [5] Az egyensúlyozó robot elektronikájának felépítése nagyon egyszerű, hiszen egy DC motorból, dőlésszög érzékelőből és egy digitális szabályzóból áll. A robot mozgatásához, azaz egyensúlyba tartásához szükséges a DC motor, amely valamilyen fogaskerekes megoldással kapcsolódik a kerekek tengelyéhez. A dőlésszög érzékelő a robot felső részét található, amely infravörös sugárral működik, mégpedig úgy, hogy az érzékelő adója (infravörös LED dióda) kibocsátja, a vevője (fotodióda) pedig detektálja a vízszintes talajról visszavert sugarat. Ha a kibocsátott sugár és a talaj közötti szög kisebb vagy nagyobb, mint 90 fok, azaz a visszavert sugár mennyisége nő vagy csökken, akkor a mikrovezérlőre írt program által vezérelt DC motorok működésbe lépnek. Az érzékelőből érkező jelek egy diszkrét PID szabályzón keresztül jutnak el a mikrovezérlőbe.
12. ábra Egyensúlyozó robot [5]
13
A Murata egy olyan japán elektronikai alkatrészeket gyártó cég, amely egyensúlyozó robotok fejlesztésével is foglalkozik. Az általuk fejlesztett Murata Boy (2005) és Murata Girl (2008) olyan egyensúlyozni képes mini robotok, amelyek önállóan képesek biciklizni, mind egy (Murata Girl), mind pedig két keréken (Murata Boy). Ezen felül képesek egyhelyben megállni és hátrafele haladni. A robotokban kamera található, amelyek vezeték nélküli kapcsolat segítségével össze vannak kötve egy számítógéppel.
13. ábra Murata robotok [5] A Murata Girl a fejlesztéseknek köszönhetően képes egyedül végigmenni egy S alakú pályán, illetve a Murata Boy önállóan tudja növelni a sebességét, így az emelkedőn is könnyedén felteker. Ezen funkciók mellett a robotok energiagazdálkodását is fejlesztették. Ezekben a robotokban sok más érzékelő és szenzor található, amelyek a stabilitást, a különböző biztonsági előírásokat, a zavarvédelmet hivatottak megőrizni. [5]
14
II.
Többfunkciós hobbirobot megtervezése
Szakdolgozatom során egy olyan hobbirobotot szeretnék megtervezni és megvalósítani, amely képes a helyváltoztatásra, mind önállóan, mind pedig a felhasználó által egy távirányító segítségével. Az önálló mozgásra egy labirintusból való kijutási feladatot valósítok meg. A feladat teljesítéséhez egy Arduino mikrovezérlő kártyát fogok alkalmazni, amely több szenzort és érzékelőt vezérel.
1. Arduino Board-ok és Shild-ek Az Arduino egy olyan egykártyás mikrovezérlő eszköz, amely az Atmel által gyártott AVR mikrovezérlőkre épül. Ezt a fejlesztőplatformot arra tervezték, hogy különféle elektronikai
projektekben
lévő
eszközök
könnyen
kezelhetőek
legyenek.
A
fejlesztőplatform alatt az Arduino Board-okat, valamint az integrált fejlesztői környezetet (IDE – Integrated Development Enviroment) értjük. Az Arduino kártyák legelőnyösebb tulajdonságai közé tartozik, hogy mindenki számára elérhető, olcsó, könnyen kezelhető, illetve egyszerűen programozható és csatlakoztatható más elektronikai eszközökhöz. A fejlesztői környezet segítségével programokat írhatunk különféle modulok, szenzorok vagy más alkatrészek vezérlésére. A számítógép és a kártya közötti kapcsolat USB porton keresztül valósul meg. Ennek segítségével tölthetjük fel az általunk megírt programokat. Az Arduino Board-ok több jellemzőben is különböznek egymástól. Ilyen jellemzők például a méret, az alak, a memória mérete, a processzor típusa, illetve sebessége és sok már paraméter. Többféle panel létezik, amelyek közül néhányat ma már nem gyártanak. Jelentleg használt Arduino kártyák:
Arduino ADK
Arduino Mega 2560
Arduino DUE
Arduino Nano
Arduino Ethernet
Arduino Yún
Arduino Fio
Arduino Esplora
Arduino Leonardo
Arduino Uno
Arduino LilyPad
15
A Shield-ek olyan kártyás kiegészítői az Arduino paneleknek, amelyek közvetlenül csatlakoztathatók magára az Arduino kártyára. A csatlakoztatás a Shield-eken lévő tüskesorral és a paneleken lévő tüskesor aljzattal valósul meg. Többféle kiegészítő kártya létezik, amelyek különböző funkciókat biztosítanak a felhasználó számára. Leggyakrabban használt Shield-ek:
Arduino GSM Shield, amellyel az Arduino kártya csatlakozni képes az internethez SIM kártya segítséégével, valamint küldeni és fogadni tud hanghívásokat és szöveges üzeneteket (ha az áramközben van külső hangszóró és mikrofon).
Arduino Ethernet Shield pár perc alatt csatlakozik az internethez egy RJ45 kábel (Ethernet kábel) segítségével. Ennek a kiegészítőnek egy Wiznet W5100 Ethernet chip az alapja.
Arduino Wifi Shield vezeték nélküli internet kapcsolatot biztosít a panel számára, illetve rendelkezik még egy micro SD kártya foglalattal, amely a fájlok tárolására nyújt lehetőséget.
Arduino Wireless SD Shield, amely vezeték nélküli kommunikációra alkalmas, a Digi által gyártott Xbee modulok segítségével. A beltéri hatósugara 100 méter, kültéri pedig 300 méter.
Arduino Motor Shield-et azért tervezték, hogy két híd meghajtó alkalmazásával vezéreljen induktív terheléseket, például reléket, mágnes szelepeket, DC illetve léptető motorokat. Ez a kiegészítő meg tud hajtani egyszerre két DC motort vagy egy léptetőmotort.
Arduino
Proto
Shield,
amely
az
általunk
megtervezett
áramkörök
megvalósítására alkalmas.
16
14. ábra Arduino Proto Shield Ezeken a Shield-eken kívül még rengeteg más kiegészítő létezik, amelyek teljes mértékben kielégítik a felhasználói igényeket. [6]
2. Arduino Uno R3 és fejlesztőkörnyezete Egy többfunkciós robot építése és megtervezése előtt be kell szerezni a szükséges alkatrészeket, eszközöket, szenzorokat és meg kell ismerkedni az Arduino szoftverrel. Az általam választott kártya az Arduino UNO R3, amely funkcionálisan és méretileg is megfelelő a robot megvalósításához.
2.1
Arduino Uno R3
Az Arduino Uno a legelterjedtebb kártya, amely egy AT mega328-as mikrovezérlőre épül. A panel 14 digitális I/O-val (Input/Output), amelyek közül 6 kivezetést PWM (Pulse Width Modulation - Impulzus Szélesség Moduláció) kimenetként használhatunk, és 6 analóg bemenettel rendelkezik. A kártyán találunk még USB csatlakozót, amely a számítógéppel való kapcsolatot valósítja meg, egy táp csatlakozót, illetve ICSP (In Circuit Serial Programming) csatlakozókat. A táp csatlakozó a kártya tápellátását biztosítja, de ez megvalósítható akkumulátor segítségével is. Ez a kártya annyiban különbözik a többi paneltől, hogy nem használ FTDI USB - soros meghajtó chippet. Ehelyett egy Atmega16U2-t használ, amely úgy programozható, mint egy USB - soros konverter.
17
15. ábra. Arduino Uno R3 [7] A kártya műszaki adatai: Mikrovezérlő Üzemi feszültség Bemeneti feszültség (ajánlott) Bemeneti feszültség (határ) Digitális I/O kivezetések Analóg bemenetek Egyenáram egy I/O kivezetésen Egyenáram a 3,3 V-os kivezetésen Flash memória SRAM EEPROM Órajel sebessége
Atmega328 5V 7-12V 6-20V 14 6 40mA 50mA 32KB 2KB 1KB 16MHz
Tápellátás Az Arduino kártyát vagy USB csatlakozón keresztül vagy pedig külső forrásból tápláljuk meg. A külső tápellátás történhet hálózatról egy AC/DC adapter segítségével vagy akkumulátorról. Bekötést tekintve a panelen találunk az adapternek egy tápcsatlakozót, viszont az akkumulátort a Vin és a GND lábakra kell kötni. A kártya külső forrásról 6-20V között üzemel. Ha a feszültség kisebb, mint 7V, akkor az 5V-os kivezetés feszültsége kevesebb lesz 5V-nál, és a kártya instabillá válhat, illetve ha a feszültség nagyobb, mint 12V, akkor a feszültségszabályzó túlmelegedhet és kárt okozhat a panelban. Ebből kifolyólag megállapítottak egy ajánlott feszültségtartományt (7-12V), amely a kártya védelmére szolgál.
18
A kártyán 5 különböző kivezetést találunk:
Vin : A kártya táplálására szolgáló kivezetés.
5V: A feszültségszabályzó által kiadott 5V –os kimenet.
3V3: A feszültségszabályzó által kiadott 3,3V-os kivezetés, amelyen 50mA áram folyhat.
GND: Föld pont.
IOREF: A mikrovezérlő működéséhez szükséges feszültség referencia pont. A megfelelően konfigurált Shield-ek olvasni tudják ennek a kivezetésnek a feszültségét.
Kommunikáció Az Arduino Uno R3 kártya többféle eszközzel tud kommunikálni, például egy számítógéppel, másik Arduinoval vagy pedig más mikrovezérlőkkel. Az AT mega328 mikrovezérlő lehetőséget nyújt UART TTL soros kommunikáció megvalósítására az RX (digitális 0-ás) és a TX (digitális 1-es) kivezetések által. Emellett támogatja az I2C (Inter-Integrated Circuit - Integrált Áramkörök közötti) és az SPI (Serial Peripheral Interface - Soros Perifária Illesztő) kommunikációt is. Az I2C kétvezetékes szinkron adatátviteli rendszer, az SPI pedig kétirányú szinkron soros kommunikációt valósít meg. Az ATmega16U2-öt soros kommunikáció jellemzi az USB-n keresztül, amely a számítógépen úgy jelenik meg, mint egy virtuális kommunikációs port. Szabványos USB COM meghajtókat használ, így nincs szükség külső meghajtókra. Az Arduino szoftver engedélyezi a szöveges adatok küldését oda-vissza a számítógép és a kártya között. Az RX és a TX LED-ek villogni fognak USB-soros chip-en történő adatátvitel következtében, illetve számítógéppel való USB kapcsolat létesítésekor. [7]
2.2
Fejlesztőkörnyezet
Az Arduino programozási nyelve C/C++ nyelven alapul, illetve ennek egy egyszerűsített változata, amely minden felhasználó számára könnyen elsajátítható. A felhasználó által megírt programot USB porton keresztül tölthetjük fel a számítógépről a mikrovezérlő kártyára. A kártyára feltöltött program által vezérelhetünk szenzorokat, érzékelőket, motorokat és sok már eszközt.
19
A program telepítését követően alapbeállításokat kell végezni, mint például, meg kell adni a kártya típusát és be kell állítani az általunk választott soros portot. Ezeket a beállításokat az Eszközök menüpont alatt találjuk, mint alappanel és soros port.
16. ábra. Fejlesztőkörnyezet [8]
2.2.1 Ki- és bemenetek kezelése
pinMode (pin, mode) utasítás Ezzel az utasítással a kártya kivezetéseinek típusát választhatjuk ki. Egy kivezetés bemenet vagy kimenet lehet. Mivel alapértelmezettként minden kivezetés bemenet, ezért a programban csak a kimeneteket szoktuk beállítani. Alkalmazása:
Ha egy kivezetést kimenetnek állítunk be, akkor az alacsony impedanciás kimenetként viselkedik, azaz maximum körülbelül 40mA áramot szolgáltat.
digitalRead (pin) utasítás Ez az utasítás a kártya digitális lábain lévő magas (HIGH) vagy alacsony (LOW) értéket olvassa be. Alkalmazása:
20
digital Write (pin, value) utasítás Alkalmazása:
Ezzel az utasítással a digitális kimenetek értékét állíthatjuk be. Pl.:
A példa program elején deklaráljuk a változókat, majd a setup részben az egyes kivezetések típusát állítjuk be. A program loop részében kiolvassuk az adott digitális kimenet értékét ( digitalRead() ), majd kiküldjük ( digitalWrite () ) ezt az értéket egy LED-re.
analogRead (pin) utasítás A kártya analóg kivezetéseit olvashatjuk be 0....1023-ig terjedő tartományban (10 bit). Alkalmazása:
analogWrite (pin, value) utasítás Alkalmazása:
Az analóg jelet a PWM (Pulse-Width Modulation – Impulzus-Szélesség Moduláció) segítségével ki lehet küldeni a digitális kimenetekre. A kimenet 0 vagy 5V (LOW vagy HIGH) lehet, amelyek a PWM 0 és 255 értékének felelnek meg. Ha a PWM értéke 0 és 255 között van, például 64, akkor az idő ¼-ben alacsony, ¾-ben 21
pedig magas feszültségű lesz, míg 128 esetében az idő felében alacsony, másik felében pedig magas feszültségű lesz. Pl.:
Ez egy analóg lábról történő beolvasás, amellyel utána egy digitális lábon lévő LED-et hajtunk meg. A LED az idő ¼-ben nem világít még a ¾-ben igen.
2.2.2 Egyéb utasítások
delay(msec) utasítás Ezt az utasítást késleltetésre alkalmazzuk. A zárójelben szereplő ’msec’ helyére a várakozás időtartamát kell begépelni. Alkalmazása:
A példa alapján a késleltetés időtartama 1000 msec, azaz 1 másodperc.
millis () utasítás Ezzel az utasítással a bekapcsolást követő pillanat óta eltelt időtartam kérdezhető le msec-ban. Alkalmazása:
min ( x, y ) utasítás X és Y számok közül a kisebbet adja vissza, teljesen függetlenül a számok típusától. Alkalmazása:
22
max ( x, y ) utasítás Ugyan úgy használható, mint a min ( x, y ) utasítás, csak a két érték közül a nagyobbat adja vissza. Alkalmazása:
randomSeed (seed) utasítás A random () függvényhez ezzel az utasítással tudunk kezdőértéket, kezdőpontot beállítani azért, mert így még véletlenebbé állítjuk be a generálást. Alkalmazása:
random (min, max) utasítások A megadott min és max értékek között kapunk egy véletlenszerű értéket. Alkalmazása:
Ügyelni kell arra, hogy ezt az utasítást csak a randomSeed () függvényt követően alkalmazhatjuk. Pl.:
A program loop részében a randomSeed () függvény kezdőértékének a bekapcsolást pillanatától eltelt időtartamot ( millis () ) állítjuk be. Utána beállítjuk a randNumber =random (255) sorral azt, hogy a véletlen számok 0-255 között legyenek, majd ezt kiküldjük egy PWM kimenetre ( analogWrite () ). A program végén pedig fél másodperces várakozás van. 23
Serial.begin (rate) utasítás Ezzel az utasítással a soros kommunikáció sebességét állíthatjuk be. A legelterjedtebb sebesség a 9600 bps. Alkalmazása:
Serial.println (data) utasítás Ezzel az utasítással a zárójelben szereplő ’data’ értéket kiküldhetjük a soros porton keresztül a számítógép felé. Alkalmazása:
Pl.:
A példában szereplő program alapján a setup részben beállítunk egy 9600 bps sebességet a soros kommunikációnak ( Serial.begin(9600) ), majd soros porton keresztül kiküldjük a 0. analóg kivezetés értékét a számítógépre ( Serial.println (analogRead (0)) ). Ezután a program vár 1 másodpercet. [8]
24
3. Felhasznált eszközök, szenzorok, alkatrészek A robot megjelenésére való tekintettel egy olyan alvázat választottam, amely nemcsak mutatós, hanem praktikus is a kialakítása miatt. Az alvázhoz lánctalpak csatlakoznak, amellyel a robot a legtöbb akadályon gond nélkül át tud haladni.
17. ábra. Alváz és a lánctalp A 18. ábrán jól látható, hogy egy áttételes motor szerkezetet használtam, amely lánctalpanként 1-1 DC motor hajtását fogaskerekeken keresztül vezeti el a hajtó kerékhez.
18. ábra. Az alvázon elhelyezett iker áttételes motor A DC motorok meghajtását motorvezérlő panel biztosítja, amely a mikrovezérlőre megírt program alapján vezérli a motorokat. Az általam megtervezett robothoz még szükség van ultrahangos szenzorokra, amelyek az akadályok érzékelésére, azaz az ütközés elkerülésére használható.
25
19. ábra. Ultrahang szenzor Mivel ez egy tank robot lesz, ezért szükség lesz egy toronyra, amelyet léptető motor segítségével forgatható. A motor működtetéséhez szintén szükség van egy motorvezérlő modulra, amely megkapja a mikrovezérlő által küldött jelet és továbbítja a léptető motor felé.
20. ábra. Léptető motor illetve motorvezérlő modul A torony csövének mozgatásához szükséges egy szervo motor és egy giroszkóp. Menet közben a cső, ezek segítségével, a talajjal vízszintesen fog maradni, bármilyen felület esetén. Mind a giroszkóp, mind pedig a szervo motor a toronyban fog elhelyezkedni. A giroszkóp érzékeli a robot dőlésszögét és ennek megfelelően fogja forgatni a szervo motort.
26
21. ábra. Giroszkóp és a szervo motor A fotoellenállásnak sokféle felhasználási módja lehet, például fényviszonyokat figyelembe vevő világításként, illetve szenzorként, amely a robotot segíti a tájékozódásban. Ha nincs elég fény, akkor a fényérzékelő ellenállása megnő, ellenkező esetben pedig lecsökken. Ezt a változás kell felhasználni a programozás során.
22. ábra. Fotoellenállás Mivel a robot többfunkciós, ezért készítek hozzá egy távirányítót, amelyen joystick és nyomógombok találhatók.
23. ábra. Joystick és a nyomógomb 27
A távirányítást bluetooth modulok segítségével valósítom meg. Az egyik modul magában a roboton, a másik pedig a távirányítóban került elhelyezésre. A joystick x-y koordinátája, illetve a nyomógombok 0 és 1 állapotai (Low, High - Alacsony, Magas) is ezen keresztül kommunikálnak a robot mikrovezérlőjének.
24. ábra. Bluetooth modul
4. Felhasznált eszközök, szenzorok, alkatrészek vezérlése 4.1 DC motorok vezérlése A motorvezérlő panel legfontosabb alkatrésze a L293D, amely 2 darab h-hidat tartalmazó IC. Ez az IC 2 darab DC motor meghajtására képes. A h-híd működését legjobban kapcsolókkal lehet szemléltetni, de a valóságban fel lehet építeni NPN és PNP tranzisztorokkal, illetve n és p csatornás FET-ekkel.
25. ábra. H-híd működése [9] Az „A” esetben a motor nem üzemel, mert minden kapcsoló nyitva van. A motor működtetéséhez a „B” ábrának megfelelően a K1 és a K4 kapcsolókat logikai 1-re kell állítani, így a motor jobbra fog forog. Ha a K2 és a K3 kapcsolókat zárjuk („C” eset), akkor a motor ismét üzemel, azonban a másik irányba fog forog. Ezekkel a 28
kapcsolókkal a motorra kötött feszültség polaritását változtattuk meg és ennek hatására forgott 2 különböző irányba. [9]
26. ábra. Motorvezérlő kapcsolási rajza [9]
Az IC PWM1 és PWM2 kivezetései engedélyező jelként szolgálnak. Ha ezek a lábak logikai 0-án vannak, akkor motorok nem üzemelnek, mert nincs engedélyezve a működésük. Ha logikai 1 szinten vannak, akkor a motor üzemelhet, mert megadtuk neki az indító jelet. Az L293D MV1A és MV1B kivezetéseire küldjük azt a feszültségszintet, amellyel majd a motor üzemelni fog. Ha az MV1A-ra magas, a MV1B-re pedig alacsony feszültségszintet adunk (MV1A = HIGH, MV1B = LOW), akkor az egyik irányba, ellenkező esetben pedig (MV1A = LOW, MV1B = HIGH) a másik irányba fog forogni a motor. Tulajdonképpen ezekkel a bemenetekkel vezéreljük a motorokat, hogy melyik irányba forogjanak.
29
27. ábra. Motorvezérlő bekötése Ezt a kapcsolás a motorvezérlő program tesztelésére állítottam össze, amely nagyon egyszerűen működik. A motorvezérlő kivezetéseit a mikrovezérlő megfelelő digitális kimeneteihez, a joystick-ot pedig a kártya bemenetére kötöttem. A joystick segítségével, amely egy X-Y tengelynek megfelelően működik, irányítom a két motor. A kar előre tolásával mindkét motor egy irányba, a kar hátrahúzásával pedig a motorok a másik irányba fognak forogni. Ez a módszer a megoldása az előre, illetve a hátra történő haladásnak. A jobbra és balra történő fordulásnál a két motort ellentétesen kell forgatni a helyben forduláshoz. Ez úgy valósítható meg, például balra fordulásnál, hogy a bal lánctalpat vezérlő motort hátra történő haladásnak megfelelően, a jobb lánctalpat pedig előre haladásnak megfelelően vezéreljük.
30
28. ábra. A lánctalpak vezérlési táblázata
Maga a program: int PWM1 = 11;
// PWM1 a 11-es kivezetésre kötve
int MV1A = 12;
// MV1A a 12-es kivezetésre kötve
int MV1B = 8;
// MV1B a 8-as kivezetésre kötve
int MV2A = 4;
// MV2A a 4-es kivezetésre kötve
int MV2B = 2;
// MV2B a 2-es kivezetésre kötve
int PWM2 = 10;
// PWM2 a 10-es kivezetésre kötve
int joyx = 0;
// joystick X koordinátája a 0-ás kivezetésre kötve
int joyy = 1;
// joystick Y koordinátája az 1-es kivezetésre kötve
int val1;
// a val1-es változó létrehozása
int val2;
// a val2-es változó létrehozása
A program első részében a működéshez szükséges deklarációk találhatók. void setup () { pinMode (PWM1, OUTPUT); // 11-es kivezetés kimenetként való definiálása pinMode (MV1A, OUTPUT); // 12-es kivezetés kimenetként való definiálása pinMode (MV1B, OUTPUT);
// 8-as kivezetés kimenetként való definiálása
pinMode (MV2A, OUTPUT);
// 4-es kivezetés kimenetként való definiálása
pinMode (MV2B, OUTPUT);
// 2-es kivezetés kimenetként való definiálása
pinMode (PWM2, OUTPUT); // 10-es kivezetés kimenetként való definiálása pinMode (joyx, INPUT);
// 0-án kivezetés bemenetként való definiálása
pinMode (joyy, INPUT);
// 1-es kivezetés bemenetként való definiálása
Serial.begin (9600);
// a soros port sebességének beállítása 9600 baud-ra
}
A setup részben a kimeneteket és bemeneteket definiáljuk a pinMode (pin, mode) utasítással, valamint a Serial.begin (value) függvénnyel beálltjuk a soros kommunikáció
31
sebességét. A program harmadik részében magát a mozgást biztosító utasítások sorozata található. void loop () { val1 = analogRead (joyx);
// a joyx beolvasása a val1-es változóba
val2 = analogRead (joyy);
// a joyy beolvasása a val2-es változóba
Serial.println (val1, DEC);
// val1 értékének soros monitoron való kiirítása
Serial.println (val2, DEC);
// val2 értékének soros monitoron való kiirítása
digitalWrite (MV1A, LOW); //alaphelyzetben az MV1A alacsony szintet kap digitalWrite (MV1B, LOW); //alaphelyzetben az MV1B alacsony szintet kap digitalWrite (MV2A, LOW); //alaphelyzetben az MV2A alacsony szintet kap digitalWrite (MV2B, LOW); //alaphelyzetben az MV1B alacsony szintet kap
Először beolvassuk az analogRead (pin) utasítással a joystick X-Y koordinátáját, majd a Serial.println (data) függvénnyel kiíratom a joystick X-Y értékét soros monitorra a működés ellenőrzése végett. A motor alaphelyzetben áll, ezért a digitalWrite (pin, value) utasítással az IC összes kivezetését (MV1A, MV1B, MV2A, MV2B) alacsony feszültségszintre állítom. Ezek után elkezdődhet az irányok beprogramozása. if ( val1 > 600 )
// joystick előre
{
// motor előre analogWrite (PWM1, 255);
// PWM engedélyező jel kiküldése
analogWrite (PWM2, 255);
// PWM engedélyező jel kiküldése
digitalWrite (MV1A, HIGH);
// az MV1A magas feszültségszintet kapjon
digitalWrite (MV1B, LOW);
// az MV1B alacsony feszültségszintet kapjon
digitalWrite (MV2A, HIGH);
// az MV2A magas feszültségszintet kapjon
digitalWrite (MV2B, LOW);
// az MV2B alacsony feszültségszintet kapjon
}
Az első IF utasításnál az előre haladás függvényei találhatók. Az IF feltételeként a joystick állását adtam meg, amelyet a val1 változóba tároltam. A joystick értéke mind X és mind Y irányban 0 és 1023 között változik a mozgatásától függően. A soros monitor segítségével megnéztem a joystick alaphelyzetéhez tartozó X és Y értéket, amely X irányban körülbelül 510 volt. Ennek megfelelően 600-as értéket adtam meg feltételként 32
biztonsági okokból. Ezek után a PWM1 és PWM2-es kivezetésekre az analogWrite (pin, value) utasítással magas szintnek megfelelő értéket adtam meg, amely egy engedélyező jelként szolgál a motor számára. A kártya PWM kivezetéseire magas vagy alacsony feszültségszintet adhatunk meg, amelyek 0 és 255 értékeknek felelnek meg. Ezek után már csak a lánctalpak vezérlési táblázata alapján kell a digitalWrite (pin, value) utasítással megadni az egyes digitális kimenetek (MV1A, MV1B, MV2A, MV2B) magas illetve alacsony értékét. else if ( val1 < 500 )
// joystick hárta // motor hárta
{ analogWrite (PWM1, 255);
// PWM engedélyező jel kiküldése
analogWrite (PWM2, 255);
// PWM engedélyező jel kiküldése
digitalWrite (MV1A, LOW); // az MV1A alacsony feszültségszintet kapjon digitalWrite (MV1B, HIGH); // az MV1B magas feszültségszintet kapjon digitalWrite (MV2A, LOW); // az MV2A alacsony feszültségszintet kapjon digitalWrite (MV2B, HIGH);
// az MV2B magas feszültségszintet kapjon
}
else if ( val2 < 400 ) {
// joystick balra // motor balra
analogWrite (PWM1, 255);
// PWM engedélyező jel kiküldése
analogWrite (PWM2, 255);
// PWM engedélyező jel kiküldése
digitalWrite (MV1A, LOW); // az MV1A alacsony feszültségszintet kapjon digitalWrite (MV1B, HIGH); // az MV1B magas feszültségszintet kapjon digitalWrite (MV2A, HIGH); // az MV2A magas feszültségszintet kapjon digitalWrite (MV2B, LOW);
// az MV2B alacsony feszültségszintet kapjon
}
else if ( val2 > 600 )
// joystick jobbra
{
// motor jobbra analogWrite (PWM1, 255);
// PWM engedélyező jel kiküldése
analogWrite (PWM2, 255);
// PWM engedélyező jel kiküldése
digitalWrite (MV1A, HIGH); // az MV1A magas feszültségszintet kapjon digitalWrite (MV1B, LOW);
// az MV1B alacsony feszültségszintet kapjon
digitalWrite (MV2A, LOW); // az MV2A alacsony feszültségszintet kapjon digitalWrite (MV2B, HIGH); // az MV2B magas feszültségszintet kapjon }
33
A többi irányba történő haladásnál ugyan ezeket a lépéseket kell megismételni, viszont ezek annyiban különböznek egymástól, hogy az IF utasítás feltételében hátra felé történő haladásnál a val1-es változó értéke kisebb lesz, mint 500. A balra és jobbra történő irányításnál a feltételben a joystick Y koordinátáját kell figyelembe venni. Alaphelyzetben a joystick 508-as értéknél mozgott a soros monitoron, így a balra fordulásnál a val2 kisebb lesz, mint 400, a jobbra fordulásnál pedig nagyobb lesz, mint 600. else { analogWrite (PWM1, 0);
// PWM engedélyező jel tiltása
analogWrite (PWM2, 0);
// PWM engedélyező jel tiltása
} }
A program végén pedig a PWM1 és a PWM2 motor működését engedélyező kivezetéseket letiltom, azaz ha nem mozgatom a joystick-ot, akkor ne működjön a motor. [9]
4.2 Ultrahang szenzor vezérlése Az ultrahang szenzor rendelkezik VCC, GND, Trigger, illetve Echo lábbal. A Trigger kivezetésen indítjuk el az ultrahang hullámot, majd a tárgyról visszavert visszhang pedig, az Echo lábon lesz észlelhető.
29. ábra. Ultrahang szenzor elméleti működése [10]
34
Maga a szenzor közvetlenül nem távolságot mér. A program által számlálni lehet a különböző idő intervallumokat, amelyek majd szükségesek lesznek a távolság kiszámításához. A trigger jel generálását követően a szenzor egy 8 bites „ultrahang csomagot” küld ki a hangszórón keresztül, majd ezt követően az Echo láb feszültségszintjét magasra állítja. Ez addig lesz magas állapotban, amíg a tárgyról visszavert visszhang nem érkezik vissza a szenzor mikrofonjába.
30. ábra. Ultrahang szenzor idődiagrammja [10] Az ultrahang szenzor megismeréséhez az alábbi kapcsolást raktam össze (31. ábra). Maga a szenzor 200 mm-es távolságot tud érzékelni. Ennek alapján állítottam össze ezt a kapcsolást, miszerint, ha az érzékelni kívánt tárgy 10 mm távolságon kívül van, azaz nem érzékel tárgyat az adott érzékelési tartományban, akkor a zöld LED világít. Ha a tárgy 10 mm-es vagy attól kisebb távolságon belül van, akkor pedig piros LED világít. A sárga LED azt a célt szolgálja, ha a tárgy az érzékelési távolságon kívül van, azaz nagyobb a távolság 200 mm-nél, vagy ha például letakarjuk a szenzor hangszóróját. [10]
35
31. ábra. Ultrahangos szenzor bekötése
Maga a program: int TRIG = 13; int ECHO = 12; int zold = 11; int piros = 10; int sarga = 9; long us; long cm;
// TRIG láb a 13-as kivezetésre kötve // ECHO láb a 12-es kivezetésre kötve // zöld LED a 11-es kivezetésre kötve // piros LED a 10-es kivezetésre kötve // sárga LED a 9-es kivezetésre kötve // us változó létrehozása // cm változó létrehozása
A program elején a működéshez szükséges deklarációk találhatók. void setup() { Serial.begin (9600); pinMode (TRIG, OUTPUT); pinMode (ECHO, INPUT); pinMode (zold, OUTPUT); pinMode (piros, OUTPUT); pinMode (sarga, OUTPUT);
//soros port sebességének beállítása 9600 baud-ra // 13-as kivezetés kimenetként definiálva // 12-es kivezetés bemenetként definiálva // 11-as kivezetés kimenetként definiálva // 10-as kivezetés kimenetként definiálva // 9-as kivezetés kimenetként definiálva
}
A setup részben állítjuk be az egyes kivezetések típusát, azaz, hogy bemenet vagy kimenet a pinMode (pin, Mode) függvénnyel, illetve a kommunikáció sebességét a Serial.begin (value) utasítással. void loop() { digitalWrite(TRIG, LOW); delayMicroseconds(2); digitalWrite(TRIG, HIGH); delayMicroseconds(10); digitalWrite(TRIG, LOW); us = pulseIn(ECHO, HIGH); mm = ( us / 2 ) / 29.1;
// TRIG kivezetés alacsony szintet kapjon // 2 us-ig várakozzon // TRIG kivezetés magas szintet kapjon // 10 us-ig várakozzon // TRIG kivezetés alacsony szintet kapjon // az idő számlálása // távolság kiszámítása
36
A loop részben történik a trigger impulzus létrehozása az ultrahang szenzor idődiagramja alapján, majd a pulseIn (pin, value) függvénnyel megmérjük azt az időtartamot, amíg az ECHO láb magas logikai állapotban van. Ezek után pedig a távolság kiszámítása következik az alábbi képlet alapján: á
á
á
é
ő
Az ECHO láb addig lesz magas állapotban, amíg az ultrahang elmegy a céltárgyig, majd visszaverődik. Ez a távolság a céltárgy távolságának kétszerese. Ezért szükséges a 2-vel való osztás. if ( mm < 10 ) { digitalWrite (zold, LOW); digitalWrite (piros, HIGH); digitalWrite (sarga, LOW); } else { digitalWrite (zold, HIGH); digitalWrite (piros, LOW); digitalWrite (sarga, LOW); } if (mm >= 200 || mm <= 0) { digitalWrite (sarga, HIGH); digitalWrite (zold, LOW); digitalWrite (piros, LOW);
// távolság magadása //zöld LED alacsony szintet kap // piros LED magas szintet kap // sárga LED alacsony szintet kap
//zöld LED magas szintet kap //piros LED alacsony szintet kap //sárga LED alacsony szintet kap // távolság megadása //sárga LED magas szintet kap //zöld LED alacsony szintet kap //piros LED alacsony szintet kap
Ebben a részben adjuk meg az egyes távolságokhoz tartozó LED-ek működését. Serial.println("Erzekelesi tavolsagon kivul!"); // távolság kiíratása a soros monitoron } else { Serial.print(mm); Serial.println(" mm"); }
// távolság kiíratása a soros monitoron // távolság kiíratása a soros monitoron
delay(100);
// késleltetés
}
A program végén pedig a soros monitorra történő kiíratások találhatók a Serial.print() és a Serial.println() függvényekkel.
37
4.3 Léptetőmotor vezérlése A léptetőmotorok annyiban különböznek az egyenáramú motoroktól, hogy ezeket a motorokat digitális jelekkel vezéreljük. A léptetőmotoroknak 2 fajtája van: bipoláris és unipoláris motorok.
32. ábra. Léptetőmotorok fajtái [11] Az ábrán jól látható a bipoláris és az unipoláris léptetőmotor közötti különbség. Az unipoláris motornál a tekercsek középkivezetésekkel rendelkeznek, míg a bipoláris motornál nincs ilyen kivezetés. Vezérlést tekintve 4 féle módon vezérelhetjük a léptetőmotorokat:
teljes léptetéses mód (egytekercses)
fél léptetéses mód
teljes léptetéses mód (kéttekercses)
mikro léptetéses mód.
Az általam elképzelt funkcióhoz a teljes lépéses módot (kéttekercses) választottam. Ennek a vezérlésnek az a hátránya, hogy a motor sokkal jobban melegszik, mivel egyszerre 2 tekercs kap áramot. [11] A probléma kiküszöbölésre egy egyszerű megoldást választottam. A programban meghatároztam, hogy csak akkor kapjon feszültséget a motor, ha a joystick nem alaphelyzetben van.
38
33. ábra. Léptetőmotor bekötése A léptetőmotor megismeréséhez az ábrán látható kapcsolást állítottam össze (33. ábra). A kapcsolásnak megfelelően joystick segítségével forgatom a léptetőmotort jobbra és balra. Mivel a léptetőmotor irányításához csak egy tengely szükséges, ezért a joystick Y koordinátáját használtam fel. A léptetőmotor vezérléséhez szükség van egy motorvezérlőre is, amelynek egy ULN2003APG integrált áramkör az alapja. Ez az IC 7 darab Darlington tranzisztor párt tartalmaz egyéb alkatrészekkel, amelyekkel majd a vezérlés történik. A léptető motorvezérlő panel nagy előnye, hogy 4 darab LED is található rajta, amelyek egy-egy tekercshez vannak hozzákötve. Ezek akkor világítanak, ha a tekercsek feszültséget kapnak, így vizuálisan is ellenőrizhetjük a motorvezérlő működését.
A1
B1
A2
B2
1. állapot
1
0
0
1
2. állapot
1
1
0
0
3. állapot
0
1
1
0
4. állapot
0
0
1
1
34. ábra. Működési táblázat [11]
39
Maga a program: #include <Stepper.h> int IN1 = 8; int IN2 = 9; int IN3 = 10; int IN4 = 11; int joyy = 0; int val; int lepes = 100;
// Stepper.h könyvtár használata
// motorvezérlő IN1 bemenete a 8-as kivezetésre kötve // motorvezérlő IN2 bemenete a 9-es kivezetésre kötve // motorvezérlő IN3 bemenete a 10-es kivezetésre kötve // motorvezérlő IN4 bemenete a 11-es kivezetésre kötve // joystick Y koordinátája a 0-ás kivezetésre kötve // val változó létrehozása // lépésszám megadása
Stepper lepteto (lepes, IN1, IN3, IN2, IN4);
//tekercsek vezérlési sorrendje
A program elején a működéshez szükséges deklarációk találhatók, illetve itt kell deklarálni a lépésszámot, amely azt határozza meg, hogy a léptetőmotor egy teljes fordulatot hány lépésből tegyen meg. Mivel a lépésszámot 100-ra állítottam, ezért a léptetőmotor 3,6 fokonként fog lépkedni (360 fok / 100 lépés = 3,6 fok/lépés). Itt kerül még sor a tekercsek vezérlési sorrendjének megadására a Stepper lepteto (lepes, pin1, pin2, pin3, pin4) deklarációval. A program alapján először az IN1 és az IN3, majd az IN2 és az IN4 kivezetéseket vezérlem. void setup() { } void loop() { val = analogRead (joyy);
// joystick Y koordinátájának beolvasása
if ( val > 600 ) { lepteto.setSpeed (300); lepteto.step (1); }
// joystick jobbra
else if ( val < 400 ) { lepteto.setSpeed (300); lepteto.step (-1); }
//joystick balra
else { lepteto.setSpeed (0); digitalWrite (IN1, LOW); digitalWrite (IN2, LOW); digitalWrite (IN3, LOW); digitalWrite (IN4, LOW); }
// motor sebességének beállítása // motor forgásirányának beállítása
// motor sebességének beállítása // motor forgásirányának beállítása
// a motor ne forogjon // IN1 kivezetés alacsony szintet kapjon // IN2 kivezetés alacsony szintet kapjon // IN3 kivezetés alacsony szintet kapjon // IN4 kivezetés alacsony szintet kapjon
}
40
Ennél a programnál a setup rész üresen maradhat, mivel a kártya kivezetései alapértelmezettként bemenetek. A program loop részében kerül sor a joystick Y koordinátájának beolvasására, illetve a léptetőmotor vezérlésére. A joystick állását figyelembe
véve
a
léptetőmotor
sebességét
(fordulat/perc)
lepteto.setSpeed()
függvénnyel, illetve a forgásirányát a lepteto.step() utasítással állítjuk be. A lepteto.step() utasításnál két dolgot állíthatunk be. Az egyik a forgásirány, amelyet úgy határozhatunk meg, hogy a zárójelben szereplő értéket negatív vagy pozitív előjellel írjuk. A zárójelben szereplő szám pedig az a lépésszámot adja meg, hogy vezérlés során hány lépést tegyen meg a motor. A motorral való ismerkedés során azt tapasztaltam, hogy egy teljes kört körülbelül 2000 lépéssel tesz meg. A program végén pedig a motor sebességét kinullázom, amikor nem használom a joystick-ot, illetve az IN1, IN2, IN3 és az IN4 kivezetéseket alacsony logikai szintre állítom, ezzel kiküszöbölve a teljes léptetéses vezérlési mód melegedési hátrányát.
4.4 A giroszkóp és a szervo motor vezérlése Különféle giroszkópok léteznek, amelyek általában a tengelyek számában különböznek egymástól. Léteznek olyan modulok is, amelyek nemcsak a tengelyek változását figyelik, hanem gyorsulásmérővel, illetve hőmérséklet érzékelővel is rendelkeznek. A giroszkóp paneljén egy MPU 6050-es felületszerelt érzékelő integrált áramkör található, amelyen belül egy giroszkópot és egy gyorsulásmérőt találunk. Ez nagyon pontos mérésekre alkalmas, mivel csatornánként 16 bites analóg-digitális átalakítókat tartalmaz. Ezek mérik egyszerre az X, Y és a Z koordinátákat. A modul I2C (I2C Inter-IC) buszt használ, amely egy kétvezetékes szinkron adatátviteli rendszer.
35. ábra. MPU 6050 integrált áramkör 3 tengelye [12] 41
A GY-521-es giroszkóp modul 8 kivezetéssel rendelkezik, de ebből csak 4 et használtam fel a feladat megvalósítása során. Ez a négy láb: VCC, GND, SDA, SCL. Az SDA, illetve az SCL kivezetések egy felhúzó ellenálláson keresztül csatlakoznak az I2C buszhoz. Az SDA (SDA – Serial Data) adat, az SCL (SCL – Serial Clock) pedig órajel kivezetésként szolgál. A maradék 4 kivezetés (XDA, XCL, AD0, INT) olyan feladatok megvalósításához szükséges, mint például ha egy másik I2C buszt is alkalmazunk (XDA, XCL), ha egy másik giroszkóp modult is szeretnénk a projektben (AD0) vagy ha megszakítást szeretnénk alkalmazni (INT). A szervo motorokat egy négyszögjel impulzussal vezéreljük, mégpedig úgy, hogy az impulzusok szélességét fogjuk változtatni, nem pedig a jel amplitúdóját. Ezeknek a motoroknak 3 kivezetése van: egy 5V-os, egy GND és egy jelkivezetés.
36. ábra. Giroszkóp és a szervo motor bekötése A giroszkóp és a szervo motor tanulmányozására az alábbi kapcsolást állítottam össze (36. ábra). Az általam megvalósított feladatnál a giroszkóp X koordinátájával fogom vezérelni a szervo motort, azaz az X koordináta változásának megfelelően fog mozogni a motor. Az Arduino Uno kártyánál az A4 és az A5 analóg kivezetések biztosítják az I2C kommunikációt, ezért SCL és az SDA kivezetéseket a kapcsolásnak megfelelő módon kellett bekötni. A kártya tartalmaz még másik csatlakozó pontokat is, amelyek az AREF kivezetés mellett található.
42
Maga a program: #include<Wire.h>
//I2C kommunikáció működéséhez szükséges könyvtár
#include <Servo.h>
//Szervo működéséhez szükséges könyvtár
const int I2C = 0x68;
// I2C busz címének a megadása
int X, Y, Z;
// az X, Y, Z változók létrehozása
Servo szervo;
//szervo változó létrehozása
A program elején a működéshez szükséges deklarációk találhatók. Itt kerül sor az I2C busz címének a megadására, illetve a szervo változó létrehozására.
void setup() { szervo.attach(3);
// a szervo jelvezetéke a 3-as PWM kivezetésre kötve
Wire.begin();
//inicializálja az I2C kommunikációt
Wire.beginTransmission(I2C);
// megkezdi az adattovábbítást a megadott címre
Wire.write(0x6B);
// 0x6B szám küldése a szolgának
Wire.write(0);
//0 elküldése a szolgának
Wire.endTransmission(true);
// az adattovábbítás leállítása egy stop üzenettel
Serial.begin(9600);
//kommunikáció sebességének a beállítása
}
A setup részben a szervo.attach() utasítással adjuk meg, hogy a szervo jelvezetéke melyik kivezetésre van kötve. Ez ugyan azt a funkciót látja el, mint a pinMode() utasítás.
Ebben a részben Wire.begin() függvénnyel inicializáljuk az I2C busz
kommunikációt, illetve engedélyezzük az adattovábbítást a Wire.beginTransmission() utasítással. A Wire.write() utasítással a mester eszköz a slave-nek küld adatot, ami az én esetemben az Arduino kártya, valamint Wire.endTransmission() utasítással állítjuk le az adattovábbítást. Az adattovábbítást lezáró utasítás zárójelében true vagy false érték lehet, ami a lezárás típusát határozza meg. Igaz érték esetén az adattovábbítást egy STOP üzenet, hamis érték esetén pedig egy RESET üzenet szakítja meg.
43
void loop() { Wire.beginTransmission(I2C);
// megkezdi az adattovábbítást a megadott címre
Wire.write(0x3B);
// 0x3B szám küldése a szolgának
Wire.endTransmission(false);
// az adattovábbítás leállítása egy reset üzenettel
Wire.requestFrom(I2C, 14, true);
// 14 darab bájt kérése a szolgától
X = Wire.read() << 8 | Wire.read();
// X koordináta beolvasása
Y = Wire.read() << 8 | Wire.read();
// Y koordináta beolvasása
Z = Wire.read() << 8 | Wire.read();
// Z koordináta beolvasása
X = map (X, -16000, 16000, 20, 70);
szervo.write(X);
Serial.print("X = ");
// X koordináta átváltása
//az átváltott X koordináta kiküldése a szervora // X koordináta kiíratása
Serial.println(X); }
A loop részben ismét engedélyezzük az adattovábbítást, illetve adatokat küldünk a mester eszköznek. Ezt követően egy RESET üzenettel megszakítjuk az adattovábbítást, majd Wire.requestFrom () utasítással a mester eszköz visszahívja az adatokat a szolga eszköztől. A függvény zárójelében három paraméter szerepel: az lekérdezés 7 bites címe, a lekérdezendő bájtok száma, illetve hogy STOP vagy RESET üzenettel szakítsa meg az adattovábbítást. Ezt követően beolvassuk az X, Y és Z koordinátákat a Wire.read() utasítással a szolga eszközről, majd az X koordinátát átalakítom egy kisebb számtartományra. A giroszkópot az alaphelyzetből az X tengelynek megfelelően elfordítom felfelé, illetve lefelé, akkor az alaphelyzethez tartozó 0 érték +90 foknál 16000-re, -90 foknál pedig -16000-re ugrik. Ez azt jelenti, hogy a giroszkóp X koordinátája egy -16000 és 16000, azaz egy 32000-es tartományban változik. Mivel a szervo motor működési tartománya 0 és 180 között van, ezért szükség volt a számok átalakítására. A feladatban azért választottam a 20 és 70 közötti tartományt, mert nincs szükségem a szervo teljes forgási tartományára. Az átalakítást követően az X koordinátát kiküldöm a szervo motorra a szervo.write() utasítással, majd ezt az értéket kiíratom soros monitorra is, amelyen ellenőrizni tudom a program működését. [12]
44
4.5 Bluetooth modul megtervezése és programozása A távirányítós funkcióhoz szükség van egy távirányítóra, amely bluetooth modul segítségével kommunikál a hobbirobottal. A kapcsolat létrehozásához kettő darab BTM 222-es bluetooth-t választottam, amely a Class 1-es kategóriába tartozik, azaz a hatótávolsága 100 méter. Mivel ezek a modulok 3,3V-os tápfeszültséggel működnek, ezért gondoskodni kell a megfelelő szintillesztésről a modul és az Arduino kártya között.
37. ábra. Bluetooth modul és a szintillesztő áramkör [13] A 37. ábrán a BTM 222-es modul látható egyéb kiegészítő alkatrészekkel. A két darab LED a bluetooth modulok közötti kapcsolatot és az adatforgalmat jelzik. A D1-el jelölt LED az adatforgalmat jelzi, azaz ha adatot küldünk az egyik bluetooth-ról a másikra, akkor ez folyamatosan világítani fog. A D2 jelölésű pedig a bluetooth modulok közötti kapcsolatot jelzi, azaz ha ez a LED villog, akkor keresi a másik eszközt, ha pedig folyamatosan világít, csatlakoztatva van. A BTM 222 -es IC 38-as lábára egy antennát kell kötni a kommunikáció szempontjából. Ennek meg van határozva a mérete, amely 31 milliméter. A 34. ábrán még a szintillesztő áramkör látható, amely a kártya és a modul között helyezkedik el. Működését tekintve nagyon egyszerű, ha a kártya adatot küld a bluetooth modulnak, illetve fordítva, akkor a szintillesztő áramkör gondoskodik a megfelelő feszültségekről, mivel a két eszköz logikai szintjei nem egyeznek meg.
45
BTM-222
Arduino Uno
Logikai 0
0V
0V
Logikai 1
3,3V
5V
38. ábra. Logikai feszültségszintek A kapcsolásban szereplő BC547B tranzisztorok kapcsoló üzemben vannak működtetve. A szintillesztő kapcsolás négy darab logikai NEM kaput tartalmaz a tranzisztorok által. A BTM-222 modul felől nézve a kapcsolást, ha a Tx kivezetés logikai magas szinten van, azaz 3,3V, akkor a T1-es tranzisztor kinyit, ekkor a kollektoron, illetve a T2-es tranzisztor lévő feszültség közel 0V lesz és ennek hatására a T2-es tranzisztor zárva marad. A tranzisztorok egy-egy ellenálláson keresztül tápfeszültségre vannak kötve, 5V-ra, illetve 3,3V-ra, így a T2-es tranzisztor kollektora 5V-os lesz, amely megegyezik az Arduino kártya logikai magas szintjével. Ezzel a megoldással egy 3,3V-os logikai feszültségszint lett átalakítva 5V-ra. Az alacsony logikai szintnél a T1-es tranzisztor zárva, a T2-es tranzisztor pedig a tápfeszültség miatt nyitva lesz. Ekkor a T2 es tranzisztor kollektorán közel 0V feszültség van, amely a kártya az alacsony logikai szintjének felel meg. A kártya felől nézve a szintillesztő áramkört ugyanez a helyzet áll fenn, annyi különbséggel, hogy 5V-os logikai feszültségszintet kell átalakítani 3,3V-ra. A bluetooth modul AT parancsokkal állíthatók be. Ehhez szükség van egy USB-UART konverterre és egy terminál programra, amelyben mindent beállíthatunk a parancsok segítségével. A konverter 5 darab kivezetéssel rendelkezik (5V, Tx, Rx, 3,3V, GND) és közvetlenül a megépített bluetooth modulhoz kell csatlakoztatni.
39. ábra. USB-UART konverter Az első legfontosabb dolog, hogy ellenőrizzük a kommunikációt a számítógépünk és a bluetooth modul között. Ezt úgy tehetjük meg, hogy beállítjuk azt a portort, amelyen a konverter található, illetve a terminálon belül csatlakoztatjuk a számítógépet a 46
modulhoz. Ekkor a modulon a kommunikációt jelző LED-nek villognia kell, illetve ha létrejött a kapcsolat, akkor a terminálon begépelt karaktereknek meg kell jelennie a válasz ablakban. Fontos, hogy a bluetooth modul és a terminál program kommunikációs sebessége megegyezzen. Sikeres kapcsolódást követően el lehet kezdeni az BTM 222 beállítását az AT parancsokkal. Fontos, hogy a parancsokat kizárólag kis betűkkel kell begépelni, máskülönben nem működik a beállítás, illetve ha begépeljük az AT parancsot, akkor a modulnak az OK üzenetet kell visszaküldenie.
40. ábra. A terminál kezelőfelülete Elsőként a kommunikáció sebességét állítottam be, amely az ATL paranccsal valósítható meg. Többféle sebesség közül válogathatunk, amelyek közül a 19200 baudos sebességet választottam az ATL2 paranccsal. Ezt követően beállítottam a modulokat, hogy az egyik master, a másik slave legyen a ATR0 (master), illetve az ATR1 (slave) parancsokkal. A kapcsolat nem valósulhat meg modulok címei nélkül, azaz először mindét modul címét kértem a terminál programban az ATB paranccsal, majd az ATD = „xxxxxxx” -el megadtam a címeket mindkét bluetooth-nak. Természetesen a master címét (0012-6f-6baac7) a slave-nek (ATD = 00126f6baac7), míg a slave címét (00126f-6baab9) a master-nek adtam meg (ATD = 00126f6baab9). Beállítottam még kevésbé fontosabb beállításokat is, mint például a BTM 222 nevét (hobbirobot, taviranyito) az ATN paranccsal. Az alapbeállításokat követően az ATA parancs segítségével csatlakoztatjuk a két bluetooth modult egymáshoz. Ekkor a kommunikációt jelző LEDnek folyamatosan világítania kell, amely a kapcsolat létrejöttét jelzi, illetve ekkor már a számítógéphez csatlakoztatott modul nem reagál az AT parancsokra. Ha a kapcsolat 47
létrejött, akkor bármilyen karakter küldése esetén az adatforgalmat jelző LED-nek folyamatosan világítania kell. [13]
4.6 Fotoellenállás programozása A fotoellenállás programozása nagyon egyszerű, hiszen az alkatrész ellenállását kell beolvasni egy adott kivezetésen és ennek függvényében kell feszültséget adni a példában szereplő LED-ekre.
41. ábra. A fotoellenállás és a LED-ek bekötése A fotoellenállás működésének tanulmányozására a 41. ábrán látható kapcsolást alkalmaztam. Mivel a két darab LED egyszerre működik, azaz kevés fény hatására mindkettő világít, ezért elég egy digitális kivezetés a vezérléshez.
Maga a program: int FOTO = 0; int LED = 11; int val; void setup() { pinMode(FOTO, INPUT); pinMode (LED, OUTPUT); Serial.begin(9600);
// a fotoellenállás a 0-s kivezetésre kötve // a LED-ek a 11-es kivezetésre kötve // a val változó létrehozása
// a 0-ás kivezetés bemenetként definiálva // a 11-es kivezetés kimenetként definiálva // a kommunikáció sebességének a beálltása
} void loop() { val = analogRead(FOTO); digitalWrite(LED, LOW);
// a fotoellenállás értékének a beolvasása // a LED-ek alacsony szintre történő beállítása
48
// a fotoellenállás értékének ellenőrzése soros monitoron
Serial.println(val);
if (val < 70) // a beolvasott értéknek megfelelően a feltétel meghatározása { digitalWrite(LED, HIGH); // a LED-ek magas feszültségszintet kapnak } else { digitalWrite(LED, LOW); }
// a LED-ek alacsony feszültségszintet kapnak.
}
A program elején a működéshez szükséges deklarációk találhatók, majd ezeket követi a setup rész, amelyben beállítjuk az adott kivezetések típusát a pinMode() utasítással, illetve a soros kommunikáció sebességét. A loop részben először is beolvassuk a fotoellenállás értékét az analogRead() függvénnyel, majd ezt az értéket kiíratjuk soros monitorra a Serial.println()-el. Azt az értéket, amely a feltételben fog szerepelni, tetszés szerint választjuk meg, hogy milyen fényviszonyok mellett kapcsoljanak be a világítást szolgáltató LED-ek.
5. A felhasználó általi irányítás megvalósítása A felhasználói irányításhoz szükség van 2 darab bluetooth modulra, amelyek a roboton, illetve az irányító eszközön helyezkednek el. Az irányító eszköz lehet egy távirányító vagy akár egy számítógép is, amelynek billentyűivel történik a vezérlés. A feladat megvalósításához a soros kommunikációhoz tartozó könyvtár utasításait kellett felhasználni. A sikeres kommunikációhoz a bluetooth modulok és a szintillesztő áramkörök helyes működése elengedhetetlen, hiszen ha valamelyik nem megfelelően üzemel, akkor nem valósul meg az adatátvitel. Az áramkörök ellenőrzésére a következő programot alkalmaztam: int incomingByte = 0; // beérkező adatok változója void setup() { Serial.begin(9600); }
// a soros kommunikáció sebességének beállítása
void loop() { if (Serial.available() > 0) //itt vizsgáljuk van-e adat a soros vonalon { incomingByte = Serial.read(); // ha van adat, akkor beolvassuk egy változóba
49
Serial.print("I received: "); // az adott szöveg kiíratása Serial.println(incomingByte, DEC); // a beolvasott érték kiíratása } }
Ezzel az egyszerű programmal tesztelhetők a kommunikációban részvevő áramkörök. A működése nagyon egyszerű. A bluetooth-nál említett terminál programban (40. ábra) bármilyen üzenetet küldünk a számítógépre kötött modulra, akkor a mikrovezérlőre csatlakoztatott BTM-222 érzékeli ezt és visszaküldi a Serial.print() zárójelében szereplő üzenetet válaszul. Ez csak akkor valósítható meg, ha a mikrovezérlőre kötött bluetooth modul Rx és Tx lábait összekötjük.
42. ábra. A kommunikációt tesztelő kapcsolás A sikeres tesztelést követően a Serial függvények segítségével meg lehet írni a felhasználói irányításhoz szükséges programot. A működéshez szükséges utasítások a Serial.read() és a Serial.write(), amelyekkel a soros vonal írása és olvasása történik., illetve a Serial.available(), amellyel az adatok érkezését vizsgáljuk. Először a számítógépről történő vezérlést valósítottam meg. A vezérlő program felépítése hasonló az áramkörök tesztelésénél alkalmazott kóddal, annyi különbséggel, hogy az érkező adatok beolvasása a PC billentyűzetéről történik. Maga a program: void loop() { if (Serial.available() > 0) { val = Serial.read(); }
// a soros vonal figyelése, hogy van-e adat // az adat beolvasása a val változóba
A program elején a motorok, az ultrahangszenzor, a léptetőmotor, a giroszkóp és a szervo motor működéséhez szükséges deklarációk, illetve a setup() részben a hozzájuk 50
tartozó kivezetések típusainak (pinMode ()) és a kommunikáció sebességének beállítása (Serial.begin()) található. A loop rész a soros vonal olvasásával kezdődik a Serial.available() utasítás segítségével, amely meghatározza azt, hogy van-e adat a vonalon. Ha van továbbított adat, akkor ez az érték nagyobb lesz, mint nulla. Ebben az esetben beolvassuk a vonalon lévő adatot a val változóba a Serial.read() függvény felhasználásával. if (val == 105) { analogWrite (PWM1, 200); analogWrite (PWM2, 200); digitalWrite (MV1A, LOW); digitalWrite (MV1B, HIGH); digitalWrite (MV2A, LOW); digitalWrite (MV2B, HIGH);
// robot ELŐRE // PWM engedélyező jel kiküldése // PWM engedélyező jel kiküldése // az MV1A alacsony feszültségszintet kapjon // az MV1B magas feszültségszintet kapjon // az MV2A alacsony feszültségszintet kapjon // az MV2B magas feszültségszintet kapjon
} if (val == 106) { analogWrite (PWM1, 200); analogWrite (PWM2, 200); digitalWrite (MV1A, HIGH); digitalWrite (MV1B, LOW); digitalWrite (MV2A, LOW); digitalWrite (MV2B, HIGH);
//robot BALRA // PWM engedélyező jel kiküldése // PWM engedélyező jel kiküldése // az MV1A magas feszültségszintet kapjon // az MV1B alacsony feszültségszintet kapjon // az MV2A alacsony feszültségszintet kapjon // az MV2B magas feszültségszintet kapjon
}
Az adatok beolvasását követően a négy irány programozása következik, amelyeknél a feltételben szereplő értékek a számítógép billentyűzetén található betűk kódjai. Ezeket az értékeket egy ASCII táblázatból lehet kiolvasni (6. melléklet), amelyben megtalálható minden billentyűhöz tartozó decimális érték. Az irányításhoz az i, j, k, l, m nyomógombokat használtam fel, amelyekhez tartozó decimális értékek a következők:
Billentyű
Decimális érték
i
105
j
106
k
107
l
108
m
109
43. ábra. Decimális értékek [14]
51
A jobbra, a hátra, illetve a stop funkciókat is ugyan így kell programozni, természetesen a megfelelő decimális értékekkel. Ezzel a megoldással a léptetőmotor is vezérelhető, annyi különbséggel, hogy itt három darab billentyűre van szükségünk: forgatás jobbra (a), forgatás balra (d), stop (s). if ( val == 97 ) { lepteto.setSpeed (300); lepteto.step (1); }
// motor sebességének beállítása // motor forgásirányának beállítása
if ( val == 100 ) { lepteto.setSpeed (300); lepteto.step (-1); }
// motor sebességének beállítása // motor forgásirányának beállítása
if ( val == 115 ) { lepteto.setSpeed (0); digitalWrite (IN1, LOW); digitalWrite (IN2, LOW); digitalWrite (IN3, LOW); digitalWrite (IN4, LOW);
// motor sebességének beállítása // IN1 kivezetés alacsony szintet kapjon // IN2 kivezetés alacsony szintet kapjon // IN3 kivezetés alacsony szintet kapjon // IN4 kivezetés alacsony szintet kapjon
} }
Ezzel a megoldással a felhasználó képes magát a robotot irányítani, illetve a tornyot forgatni. A programba belekerül még az ultrahangszenzor, amely az ütközés elkerülését biztosítja, valamint a giroszkóp és a szervo motor vezérlése, amelyek a cső mozgását biztosítják. [14]
6. Az önálló mozgás megvalósítása A hobbirobot önálló mozgásának megvalósítására egy labirintusból való kijutást próbáltam megvalósítani. A labirintus egy olyan folyosókból és derékszögű kanyarokból álló építmény, amelyben a robot kétféleképpen tájékozódhat. Az egyik ilyen tájékozódási lehetőség a határoló falak érzékelése. Ennek a megvalósításához három darab ultrahang szenzor szükséges, amelyek a robot előtti és melletti falakat érzékeli. Menet közben folyamatosan feltérképezi a labirintus minden útvonalát. Ezt célszerű kijelezni, vagy egy erre alkalmas programmal, vagy valamilyen kijelző segítségével. Az ultrahangszenzorok a faltól való távolságot, illetve a kereszteződéseket jelzik.
52
A labirintusban való tájékozódás másik lehetősége a padlón elhelyezett vonal érzékelése és követése. Ehhez a fotoellenállásokat használtam fel LED-ek segítségével. A működését tekintve ez a megoldás nagyon egyszerű, hiszen a robotnak csak a vonalat kell követnie a labirintusból való kijutáshoz. A vonal érzékelésére szükség van egy szenzor megtervezésére és megépítésére.
44. ábra. Vonalérzékelő szenzor [15] A 44. ábrán egy fotoellenállásból, egy LED-ből és 2 darab ellenállásból álló áramkört láthatunk, amely a padlóról visszavert fényt érzékeli. Ha a visszavert fény mértéke magas, akkor a fotoellenállás ellenállása kicsi lesz, azaz rajta nagy áram folyik keresztül és ennek következtében a kimenet és a GND között nagy feszültség mérhető (körülbelül 5V). Ha a visszavert fény mértéke alacsony, akkor nagy lesz az ellenállás, kis áram folyik rajta és a kivezetések között kis feszültség mérhető (körülbelül 0V). A feladat megvalósításához szükséges három ilyen áramkör, amelyek közül egy a vonalat, kettő pedig a vonal melletti területet érzékeli. Maga a program: void loop () { FOTO1 = analogRead (val1);
// a középső fotoellenállás értékének beolvasása
FOTO2 = analogRead (val2);
// a baloldali fotoellenállás értékének beolvasása
FOTO3 = analogRead (val3);
// a jobboldali fotoellenállás értékének beolvasása
Serial.println (FOTO1, DEC);
// a középső fotoellenállás értékének kiíratása
//Serial.println (FOTO2, DEC);
// a baloldali fotoellenállás értékének kiíratása
//Serial.println (FOTO3, DEC);
// a jobboldali fotoellenállás értékének kiíratása
digitalWrite(LED, HIGH);
// a LED-ek magas logikai szintet kapjanak
53
A program elején a DC motorok, az ultrahangszenzor, illetve a vonalérzékelő szenzor működéshez szükséges deklarációk találhatók. A setup () rész a kivezetések típusainak (pinMode()) és a soros kommunikáció beállítását (Serial.begin()) tartalmazza. A loop () elején beolvassuk a három darab fotoellenállás értékét az analogRead() segítségével, majd ezeket az értékeket egyesével kiíratjuk a soros monitorra (Serial.println()). Erre a program következő részében szereplő feltételek meghatározása miatt van szükség. A mért értékek miatt a feltételben olyan számot állítottam be, amely a két érték számtani közepe. Például a középső szenzor vonal melletti értéke 870, míg a vonalon mért értéke 735 körül mozgott, emiatt a feltételben 800 szerepel. if ( FOTO3 > 800 && FOTO2 > 890 && FOTO3 > 910 )
// robot ÁLL
{ analogWrite (PWM1, 0);
// PWM engedélyező jel kiküldése
analogWrite (PWM2, 0);
// PWM engedélyező jel kiküldése
digitalWrite (MV1A, LOW);
// az MV1A alacsony feszültségszintet kapjon
digitalWrite (MV1B, LOW);
// az MV1B alacsony feszültségszintet kapjon
digitalWrite (MV2A, LOW);
// az MV2A alacsony feszültségszintet kapjon
digitalWrite (MV2B, LOW);
// az MV2B alacsony feszültségszintet kapjon
}
Abban az esetben, ha az érzékelő nem észlel vonalat, akkor nem vezérli a motorokat, azaz a robot áll. if ( FOTO1 < 800 && FOTO2 > 890 && FOTO3 > 910 )
// robot ELŐRE
{ analogWrite (PWM1, 170);
// PWM engedélyező jel kiküldése
analogWrite (PWM2, 170);
// PWM engedélyező jel kiküldése
digitalWrite (MV1A, LOW);
// az MV1A alacsony feszültségszintet kapjon
digitalWrite (MV1B, HIGH);
// az MV1B magas feszültségszintet kapjon
digitalWrite (MV2A, LOW);
// az MV2A alacsony feszültségszintet kapjon
digitalWrite (MV2B, HIGH);
// az MV2B magas feszültségszintet kapjon
}
Mivel a DC motorok nincsen összehangolva, azaz ugyanolyan PWM hatására különböző sebességgel forognak. Többféle lehetőség van a probléma megoldására, például ha a motor tengelyre egy résekkel ellátott kereket szerelünk, akkor egy 54
optokapuval detektálhatjuk ennek a forgását és beállíthatjuk a megfelelő sebességet. Létezik egy egyszerűbb megoldás is, amely nem teljesen megbízható. A megvalósításához szükséges egy a mikrovezérlő kártya analóg kivezetésére kötött potencióméter, amellyel majd az egyik DC motorra adott PWM jel változtatható. A tesztelés során a potencióméterrel nem lehetett olyan PWM jelet beállítani, amely megoldást jelentett volna a problémára. if ( FOTO1 > 800 && FOTO2 < 890 && FOTO3 > 910 )
// robot korrigálás
{ analogWrite (PWM1, 170);
// PWM engedélyező jel kiküldése
analogWrite (PWM2, 170);
// PWM engedélyező jel kiküldése
digitalWrite (MV1A, HIGH);
// az MV1A alacsony feszültségszintet kapjon
digitalWrite (MV1B, LOW);
// az MV1A alacsony feszültségszintet kapjon
digitalWrite (MV2A, LOW);
// az MV1A alacsony feszültségszintet kapjon
digitalWrite (MV2B, HIGH);
// az MV1A alacsony feszültségszintet kapjon
}
A balra illetve a jobbra kanyarodás igazság szerint nem a robot tényleges irányváltoztatására, hanem az előre haladás következtében történő korrigálásokra szolgál a DC motorok sebességkülönbségéből adódóan, illetve ezek a programrészek a robot nagy ívű kanyarodását is lehetővé teszi. A motor sebességét a nagy ívű kanyarodás miatt lentebb kellett venni, mivel a robot kiesett az érzékelési tartományból. if ( FOTO1 < 800 && FOTO2 < 890 && FOTO3 > 910 )
// robot BALRA
{ analogWrite (PWM1, 170);
// PWM engedélyező jel kiküldése
analogWrite (PWM2, 170);
// PWM engedélyező jel kiküldése
digitalWrite (MV1A, HIGH);
// az MV1A magas feszültségszintet kapjon
digitalWrite (MV1B, LOW);
// az MV1B alacsony feszültségszintet kapjon
digitalWrite (MV2A, LOW);
// az MV2A alacsony feszültségszintet kapjon
digitalWrite (MV2B, HIGH);
// az MV2B magas feszültségszintet kapjon
delay(1000);
// 1 másodperces működés
digitalWrite (MV1A, LOW);
// az MV1A alacsony feszültségszintet kapjon
digitalWrite (MV1B, HIGH);
// az MV1B magas feszültségszintet kapjon
55
digitalWrite (MV2A, LOW);
// az MV2A alacsony feszültségszintet kapjon
digitalWrite (MV2B, HIGH);
// az MV2B magas feszültségszintet kapjon
delay(1000);
// 1 másodperces működés
digitalWrite (MV1A, HIGH);
// az MV1A magas feszültségszintet kapjon
digitalWrite (MV1B, LOW);
// az MV1B alacsony feszültségszintet kapjon
digitalWrite (MV2A, LOW);
// az MV2A alacsony feszültségszintet kapjon
digitalWrite (MV2B, HIGH);
// az MV2B magas feszültségszintet kapjon
delay(1000);
// 1 másodperces működés
digitalWrite (MV1A, LOW);
// az MV1A alacsony feszültségszintet kapjon
digitalWrite (MV1B, HIGH);
// az MV1B magas feszültségszintet kapjon
digitalWrite (MV2A, LOW);
// az MV2A alacsony feszültségszintet kapjon
digitalWrite (MV2B, HIGH);
// az MV2B magas feszültségszintet kapjon
}
A vonalérzékelő szenzor a robot elején helyezkedik el, ezért a sima jobbra és balra kanyarodást nem célszerű alkalmazni, mivel bármely oldalra, helyben történő kanyarodás következtében a robot nem a megfelelő pozícióban lesz.
45. ábra. Helyben történő balra kanyarodás A probléma megoldására olyan módszert választottam, amely több 1 másodperces mozgásokból tevődik össze. Ez azt jelenti, hogy a teljes 90 fokos kanyarodást előrebalra-előre-balra kombinációval valósítottam meg. A jobbra kanyarodást hasonlóképpen kell megoldani.
56
A kereszteződésben történő irányváltoztatáshoz szükség lenne még egy érzékelőre vagy pedig a középső érzékelő előre tolására. Ekkor a három érzékelő elhelyezkedésükkel háromszöget képezne és ezzel a megoldással már megvalósítható a kereszteződés érzékelése. Az így elhelyezett érzékelők az egyvonalban elhelyezett megoldással szemben, mindhárom irányban lévő vonalat képesek érzékelni. Ebben a helyzetben valamelyik irányt előnyben kell részesíteni. Zsákutca esetén pedig a robot megfordul. [15]
III.
Többfunkciós hobbirobot megépítése
A megépítés első lépése az alkatrészek, szenzorok és a panelek elhelyezésének megtervezése volt. Mivel az általam használt Arduino Uno kártya nem rendelkezik elég digitális kivezetéssel, mint amennyi kellene a megvalósítandó feladathoz, ezért még szükségem volt egy ATMEGA328P mikrovezérlő IC-re. Emiatt készítettem egy nyomtatott áramkört, amely tartalmazza ezt a mikrovezérlő IC-t (1), a motorvezérlő panelt (5), illetve a hozzá szükséges 5V-ot előállító L7805-ös IC-t (4). Ezek mellett a panelen található még egy szintillesztő áramkör (2), amely a bluetooth modul és a mikrovezérlő közötti kapcsolatot biztosítja, illetve tüskesorok (3), amelyek az Arduino kártya, a léptetőmotor, a giroszkóp és a szervo csatlakozási pontjai.
46. ábra. A hobbirobot panelje A mikrovezérlő IC használata előtt be kell állítani, azaz bele kell égetni a bootloadert. A bootloader olyan program, amely tapasztalataim szerint engedélyezi a programok feltöltését az IC-re, illetve például definiálja a RESET nyomógomb használatát. A bootloadert többféleképpen lehet beégetni. Azt a megoldást választottam meg, amelynél az Arduino kártya, mint programozó vesz részt az égetésben. A bootloader beégetése a 57
következőképpen történik: első lépésként az Arduino Uno kártyára feltöltjük a mintaprogramok között található ArduinoISP programot, amelynek segítségével a kártya programozóvá válik. Ezt követően a 47. ábrának megfelelően összekötjük a kártyát és az üres mikrovezérlő IC-t.
47. ábra. Bootloader beégetése [16] Ezek után kiválasztjuk a megfelelő kártyatípust és a soros portot, majd Bootloader beégetése menüponttal elkezdjük a beégetést. A bootloadert csak egyszer kell beégetni az IC-be és ezt követően bármilyen általunk írt program feltölthető. [14] A motorvezérlés tanulmányozása során megtapasztaltam, hogy az Arduino kártya 5V-os feszültsége nem elegendő az összes szenzor és érzékelő, de főként a DC motorok meghajtására. Ezért volt szükség egy L7805-ös IC (4) beépítésére az áramkörbe, amely a motorvezérlő panelt (5) látja el 0, illetve 5V-tal. Mivel ez egy tank hobbirobot lesz, ezért szükség van egy toronyra. A tornyot egy kis műanyag vödörből vágtam ki, amely átlátszó, így az ebben elhelyezett szenzorok és érzékelők jól láthatóak működés közben. A toronyban került elhelyezésre a giroszkóp, a szervo motor, a léptetőmotor vezérlő, illetve a bluetooth modul.
58
48. ábra. A hobbirobot tornya A torony elkészítéséhez felhasználtam még hurkapálcikát távtartóként, illetve lemaratott nyomtatott áramköri lapokat különböző mechanikai elemként. Ennek a megoldásnak az a hátránya, hogy a toronyban elhelyezett eszközök vezetékezése sok helyet foglal, ezért például a szervo motor működését akadályozza. Szintén gondot jelentenek a torony és az alváz között húzódó vezetékek, amelyek gátolják a torony 360 fokos forgását. A probléma egyik megoldása az lehetett volna, hogy a toronyban kerül elhelyezésre a mikrovezérlő is, amely ezeket az eszközöket vezérli. A megépítés következő lépése a bluetooth modulok elkészítése volt. Ebből az eszközből kettő szükséges, egy a távirányítóba, egy pedig magára a robotra. A modul alapja egy BTM 222-es áramkör, amely egy felületszerelt alkatrész. A nyomatott áramkör megtervezésénél ezt a szempontot figyelembe kellett venni, ezért egy vegyes szerelésű nyomtatott huzalozású lemez készült, amelyen az alkatrészek a forrasztási oldalon helyezkednek el.
49. ábra. A bluetooth modul
59
A modulok elkészítése és a bluetooth kapcsolat létrehozását követően került sor a távirányító megvalósítására. Ez egy felnyitható karton dobozból készült, amelyben egy mikrovezérlő IC, egy szintillesztő áramkör, a bluetooth modul, illetve a 3,3V-ot és az 5V-ot előállító integrált áramkörök találhatók. A távirányító tetejére került elhelyezésre a 2 darab joystick és egy kezelőpanel.
50. ábra. A hobbirobot távirányítója A bluetooth kapcsolat létrehozásához szükség volt egy mikrovezérlőre, amelynek segítségével a joystick mozgatásával generált értékeket beolvassuk, majd ezt követően írjuk az adatokat a soros vonalra.
51. ábra. A távirányító panelje
Az 51. ábrán látható kapcsolás hasonló a roboton elhelyezkedő panelhez. Ezen is találunk egy mikrovezérlő IC-t és a hozzá tartozó alkatrészeket, egy szintillesztő 60
áramkört és egy 3,3V-ot, illetve 5V-ot előállító integrált áramkörök. A panel tesztelése során az összes alkatrész megfelelően működött. Ennek ellenére a távirányítóval való vezérlés nem valósult meg ismeretlen hiba miatt. A labirintusból való kijutáshoz szükséges egy vonalérzékelő megtervezésére és megépítésére. Ez a feladat áramkörtervezést nem igényelt, mert a megvalósításhoz csak pár alkatrészre volt szükség.
52. ábra. A vonalérzékelő szenzor
A vonalérzékelő szenzor három darab érzékelőt tartalmaz. Egy ilyen részben egy fotoellenállást, egy LED-et és kettő darab ellenállást találunk. A megépítésnél ügyelni kellett arra, hogy a fotoellenállás érzékelő része magasabban legyen, mint a LED fényforrása. Ez nagyon fontos szempont, mert ha ez nem teljesül, akkor a LED közvetlenül megvilágítja a fotoellenállást és nem a visszavert fényt fogja mérni. A mérés pontosságának biztosítása érdekében az egyes részeket leárnyékoltam egy műanyag kerettel, ezzel megakadályozva a külső fény által okozott hatásokat.
53. ábra. A tank hobbirobot 61
Az 53. ábrán a teljesen felszerelt hobbi robot látható, amelynek elején a vonalérzékelő szenzor könnyedén kicserélhető egy ultrahang szenzorra. Erre a megoldásra azért van szükség, mert a felhasználó általi irányítás következtében az ultrahang szenzor megakadályozza az esetleges ütközést, illetve a vonalérzékelő szenzor a robotot akadályozná a mozgásban, mivel pár milliméterre helyezkedik el a talaj felett.
62
Következtetések Az általam megtervezett és megépített hobbirobot megvalósította a kitűzött célokat. Ennek ellenére vannak olyan kérdések, amelyek még megoldásra várnak. A megépítés során azt tapasztaltam, hogy a robot váza nem teljesen megfelelő az elképzelt feladathoz, elsősorban a sok vezetékezés miatt, például a korábban már említett torony 360 fokos forgását akadályozza. A távirányítóval való irányítás még nem működőképes valamilyen eddigi ismeretlen probléma miatt. Valószínűleg a hibát a rosszul megírt program okozza, mert a távirányító paneljén található alkatrészek működése sikeresen tesztelve lett. A felhasználói irányítás programozása során a billentyűzetről irányított DC motorokon kívül a léptetőmotor is vezérlésre kerül. Az irányítása folyamán a léptetőmotor nem forog, de a motorvezérlő panel LED-jei világítanak a vezérelt tekercseknek megfelelően. Ezt követően sikeresen újrateszteltem a motort a 33. ábrának megfelelően. A problémára nem sikerült eddig megoldást találni. A hobbirobottal kapcsolatos jövőbeli céljaim közé tartozik egy olyan szerkezeti kialakítás megvalósítása, amely a vezetékezési problémákra megoldást nyújt. További célom a programozásbeli hibák kijavítása és tökéletesítése.
63
Összefoglaló A szakdolgozatom során egy olyan tank hobbirobotot terveztem és építettem meg, amely képes az önálló és a felhasználó általi helyváltoztatásra. A robot megtervezése során az összes felhasznált alkatrészt, szenzort, érzékelőt egy-egy saját feladat segítségével tanulmányoztam és próbáltam olyan kapcsolásokat tesztelni, amely a két megvalósított funkciókhoz szorosan kapcsolódik. A felhasznált eszközök tanulmányozását követően a különböző feladatokat ellátó panelek nyomtatott áramkörének megtervezése következett egy erre alkalmas program segítségével. A nyomtatott huzalozás elkészítése során ügyelni kellett a forrszemek méretére, illetve a vezetősáv szélességére, mivel a kicsi forrszemek megnehezítik a forrasztást. A másik fontos szempont, amelyet tervezésnél figyelembe kellett venni, az a felületre szerelt alkatrészek (BTM-222), amelyek egy vegyes szerelésű nyomtatott áramkört eredményeztek, a forrasztási oldalán elhelyezett alkatrészekkel. A megtervezést követően a hobbirobot megépítése következett, amely a nyomtatott áramköri panelek elkészítésével kezdődött. A vezetősávok panelre történő felvitelét rámelegítéses technológiával valósítottam meg. A nyomtatott áramköri tervet kinyomtattam lézernyomtatóval egy fotopapírra, majd egy vasaló segítségével rávasaltam a panelen található rézfóliára. Ennek a módszernek a hátránya az, hogy a forrszemek maximum háromszori újraforrsztást bírnak ki. A panelek elkészítését követően a hobbirobot építése a toronnyal folytatódott. A torony alapját egy műanyag vödör alja képezi, amelyben különböző eszközök kerültek elhelyezésre egy mechanikai szerkezeten, amely lemaratott nyomtatott huzalozású panelekből épül fel. A torony elkészítését követően a felhasználói irányításhoz szükséges távirányító összeszerelése következetett, amelyben szintén különböző feladatokat ellátó áramkörök kerültek elhelyezésre. Ezt követően a vonalérzékelő szenzor megvalósítása következett. A megépítést a funkciók programozása követte, amely során tesztelésre került a vonalérzékelő szenzor, illetve az áramkörök működése. A szakdolgozat kidolgozása során megismerkedhettem az Arduino kártyákkal és magával a fejlesztőkörnyezettel, amelyek segítségével rengeteg tapasztalatot szereztem a mikrovezérlőkről és azok működéséről. A programozás alatt felhasznált könyvtárak mellett
sok
más
feladatra
alkalmas
függvények
találhatók,
amelyek
még
tanulmányozásra várnak.
64
Summary In my thesis I designed and built my own hobby robot, which is able to move both independently and with a user’s help.
While designing the device, I studied all of the parts and sensors with the help of tasks, and I tried to make circuits which are closely connected to two implemented functions. After that I designed printed circuit boards, which perform different tasks, with a suitable program. When designing the printed wiring I had to take care of the size of the pads and the width of the conductions, as soldering of small pads is more difficult. Another important aspect which had to be considered in designing: there are two surface mount devices (BTM-222) that resulted in a mixed-mounted printed circuit with parts on the bottom side.
After designing, the next step was building my robot, which began with the preparation of printed circuit boards. In the application of conductions I adopted the ”ironing” technology. I printed the drawing of the circuit onto photo paper with a laser printer and I ironed it to the copper foil of the board. The disadvantage of this method is that the pads are able to do re-soldering three times, but this is the maximum. Then the construction of the robot involved making a tower. The tower was made out of the bottom of a small plastic bucket, in which different tools were placed on the mechanical structure that was built from etched down board. Then the next step was to make a controller for the user, in which circuits with different tasks were placed. After this I made the line sensor. As the last stage I started to write the programme for two functions where the line sensor and circuits were tested.
During the elaboration of my thesis I got to know the Arduino boards and its software, with the help of which I got lots of experience about microcontrollers and their operation. Besides libraries that were used in programming there are a lot of other functions for different tasks, which are still to be studied in the future.
65
Források [1] http://siva.bgk.uni-obuda.hu/jegyzetek/Robotositott_anyagmozgatas/robottechnika.doc. [2] http://www.typotex.hu/upload/book/5510/kulcsar_bela_robottechnika_reszlet.pdf http://history-computer.com/Dreamers/Vaucanson.html [3] http://hobbirobot.hu/content/avr-vezerlesu-hexapod-robot-epitese [4] http://rendszerigeny.hu/rc-rayline-998-v2-quadrocopter-kameraval-teszt/2014/05/20 [5] http://cimnelkul.uni-miskolc.hu/mindenmas/7-robot/21-egyensulyozo-robot http://www.geeks.hu/blog/ceatec_2010/101007_egyensulyozo_robot_boy_es_robot_ girl
[6] http://hu.wikipedia.org/wiki/Arduino http://en.wikipedia.org/wiki/Arduino http://arduino.cc/ http://arduino.cc/en/Main/Products [7] http://arduino.cc/en/Main/ArduinoBoardUno http://esca.atomki.hu/PIC24/spi.html#Az_SPI_kommunik%C3%A1ci%C3%B3s_c satorna [8] csizmt.uw.hu/Arduino/tavir_arduino_notebook.pdf http://hobbirobot.hu/content/arduino-kezdoknek [9] http://www.hobbielektronika.hu/cikkek/willi_epitese_avagy_nullarol_a_robotokig_-_avr_mikrovezerlok.html?pg=8 http://hobbirobot.hu/content/ardu [10] http://hobbirobot.hu/content/ardu [11] http://qtp.hu/elektro/leptetomotor_mukodese.php [12] http://harsanyireka.blog.hu/2014/06/22/13_3_kommunikacios_konyvtarak_wire http://invensense.com/mems/gyro/documents/PS-MPU-6000A-00v3.4.pdf
66
[13] http://hobbirobot.hu/content/btm-222-bluetooth-modul http://www.mikrocontroller.net/wikifiles/f/fc/BTM222_DataSheet.pdf http://jkwarduino.wordpress.com/2010/12/08/arduino-mega-per-bluetooth-flashen/ http://electronics-4-fun.blogspot.hu/2012/03/bluetooth-module-btm-222.html [14] http://www.asciitable.com/ http://arduino.cc/en/reference/serial [15] http://hobbirobot.hu/content/vonalkoveto-ii-robotika-kezdoknek http://hobbirobot.hu/content/vonalkoveto-iii-robotika-kezdoknek [16] http://arduino.cc/en/Tutorial/ArduinoToBreadboard http://www.webmaster442.hu/letoltheto-irasok/mikrovezerlos-rendszerfejlesztescc-nyelven-ii-arduino-platform/ http://avr.tavir.hu/modules.php?name=Content&pa=showpage&pid=158 http://www.instructables.com/id/Burning-the-Bootloader-on-ATMega328-usingArduino-/ http://arduino.cc/en/Hacking/Bootloader?from=Tutorial.Bootloader
67
Melléklet 1. melléklet: A hobbirobot panelje
68
2. melléklet: Bluetooth modul
69
3. melléklet: A távirányító panelje
70
4. melléklet: Távirányító kezelőpanelje
71
5. melléklet: ASCII táblázat
72