Arduino a motor 28BYJ-48 podruhé
autor: Johny, arduino, dne 17.11.2014
Nedalo mi to, a s motorem si stále hraji. Navíc jsem objednal dalších 5 kousků. Tolik věcí, co by to mohlo dělat – automaticky stahovat žaluzie, mohu si postavit vlastní robotický podvozek, kamerový motorový slider atd atd. Prostě super ;-)
Pro začátek jsem zkusil zapojení, aby bylo jasnější, jak to funguje. Obvod ULN2003 je vlastně jenom pole tranzistorů a jediný efekt je ten, že nám pomocí 5V z arduina sepne GND (zem) z baterky do daného vývodu motoru. Motor je nastálo připojen k +5V, a právě tím, že se různě přepojuje zem se zapínají a vypínají jednotlivé cívky.
zapojení ULN2003 s 28-BYJ-48
Celé odpoledne jsem trávil tím, že jsem kreslil a vytvářel krokový motor 28BYJ-48 jako novou komponentu. O tvorbě napíšu jinde, stejně to stále není ideální. Jak obrázek, tak funkčnost ;-)
Jen upozorním, že já mám obvod ULN2003A na maličkém plošném spoji s konektorem pro motor a navíc – praktické – každý výstup do motoru má u sebe ještě LEDku kterou signalizuje, že je sepnutý. Člověk má pak krásně vizuálně přehled o tom, co se děje. Bohužel plošný spoj pro ULN2003A nemám, tak jsem to nakreslil podle datasheetu. Snad to zapojení není špatné! Pro jistotu, kdyby někdo zkoušel, se do datasheetu podívejte a překontrolujte ;-)
Nový kód na ovládání motoru
Zásadním důvodem, proč píšu je to, že jsem přepsal ovládací kód. Zatím je to spíš nástřel, nicméně už to běhá hezky. Cíl je, vyhnout se fixním zápisům a kód seskupit do funkcí které motor budou ovládat. Jednotlivé kroky mám uložené jako dvourozměrné pole, PINy motoru jsou také pole. Co šlo, je cyklus.
Abych nemusel řešit to, že po sedmém kroku se má jít na nultý pomocí podmínky (viz předchozí článek), rozhodl jsem se nechat proměnou _step běžet od nuly do maxima a přetéct, to znamená, že maximum je 255 a když se přičte 1, tak jsem zase na nule, přičtu dva a budu na jedničce atd atd. Problém je, že motor má ale kroků 8, a já mám takhle proměnou která stále dokola běhá v intervalu 0–255. Zde mě napadl fígl.
Bitový posun
Číslo BYTE v intervalu 0–255 je v paměti uloženo jako 8 jedniček a nul, tedy například 10101010. Jenže já potřebuji číslo v intervalo 0–7 → jak na to? Když neexistuje datový typ, co by toto uměl, tak jako druhé řešení je, pracuvat s proměnou typu byte ale brát jen poslední tři bity. A to se dá pomocí bitového posunu:
na začátku máme například:
promnena = „11111010“
promnena = promnena<<5
vše se nám posune o 5 pozic, tedy poslední tři hodnoty na začátek „010“ a zbytek se doplní nulama, vznikne nám tedy 01000000
No, a teď posunem zpět
promnena = promnena>>5
Nulama se doplní začátek a nám tak vznikne 0000010 – a to je náš krok!
A teď už můžeme krokovat od 0 do 255 a ničemu to nevadí!
Díky bitovému posunu získám poslední 3 bity a z nich znovu sestavím číslo kroku. Pak není třeba pomocí podmínek řešit, zda nám _step neleze přes 8 ale zkrátka dokolečka přičítáme nebo odčítáme kroky. Když se dostaneme na maximální hodnotu 255, tak po přičtení např. pěti jsme zase na začátku – tedy 0–1–2–3–4–5 :-)
A nakonec zdroják
Snad to bude pochopitelné. Pro jistotu jsem to ještě hodně okomentoval.
int _step = 0; //Piny, kam je připojen motor byte MotorPin[4] = {8,9,10,11}; //Defunuje kroky - celkem 8 kroků které se při běhu motoru postupně střídají byte Krok[][4] = ; void setup() { //Cyklem se všechny 4 piny motoru nastaví na výstup s hodnotou LOW for(int i=0;i<4;i++){ pinMode(MotorPin[i], OUTPUT); digitalWrite(MotorPin[i], LOW); } } void loop() { //Zavolá se funkce, která motor posune o 4096 kroků ve směru hod. ručiček //(měla by být jedna otáčka) NekolikKroku(4096, true); //O půl otáčky proti směru hod. ručiček NekolikKroku(2048, false); delay(3000); } //Funkce, která udělá několik kroků s motorem v daném směru void NekolikKroku(int pocet, byte smer){ //cyklus projede daný počet kroků for(int i = 0; i < pocet;i++){ //v každém kroku bud pricte nebo odecte 1 k promene _step, zavisi na smeru //promnena _step muze pretect, s tim se pocita. //pokud je smed kladny (true) - pricitame, pokud zaporny (false) - odecitame _step+=smer==true?1:-1; //vzdy kdyz se zmeni pocet kroku o 1, je třeba zmenit vystupni piny do motoru //o aktualizaci stavu pinů se stará funkce MotorUdelejKrok MotorUdelejKrok(_step); //cekame, aby motor krok stihl udelat delayMicroseconds(1000); } } //Funkce, která nastaví výstupní piny do stavu dle zvoleného kroku void MotorUdelejKrok(int bkrok) { //zde je takovy figl - bytovy posun byte krok = bkrok<<5; krok = krok>>5; //zde do 4 pinu zapiseme hodnoty dle aktualniho kroku for(int i=0;i<4;i++){ digitalWrite(MotorPin[i], Krok[krok][i]); } }Připojená fotogalerie: 2014/2014_11_11_Stepper/
Podobné články:
- Řízení Brushless DC motoru 57BLF03 s driverem BLDC-8015A pomocí Arduina 1.1.2020
- Arduino a RC vysílačka 9.12.2014
- Arduino a krokový motor potřetí 20.11.2014
- Arduino - řízení krokového motoru 11.11.2014
- Implementace ICMP Pingu v PHP 10.1.2013
Štítky tohoto článku:
Diskuze: Arduino a motor 28BYJ-48 podruhé
- ISD (13.10.2015 11:07)
opravte prosim na konci kodu - namiesto 'Krok[krok][0]' ma 'byt Krok[krok][i]'
digitalWrite(MotorPin[i], Krok[krok][i]); - vn158 (26.1.2016 14:04)
Místo toho harakiri s posuny by bylo lépe byte krok = bkrok && 7;
- David (11.9.2016 19:31)
Dík tohle sem potřeboval :D
Původní diskuze je zachována jako archiv.