Arduino a motor 28BYJ-48 podruhé

Stáhnout jako PDF 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.

Obrázek zapojení ULN2003 s 28-BYJ-48

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

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] = {{0,0,0,1}, {0,0,1,1}, {0,0,1,0}, {0,1,1,0},
                      {0,1,0,0}, {1,1,0,0}, {1,0,0,0}, {1,0,0,1}};

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:

Štítky tohoto článku:

 


Diskuze: Arduino a motor 28BYJ-48 podruhé

  1. ISD (   http://www.isd-webspace.com   13.10.2015, 11:07)

    opravte prosim na konci kodu – namiesto ‚Krok[krok][0]‘ ma ‚byt Krok[krok][i]‘ digitalWrite(Mo­torPin[i], Krok[krok][i]);

    Reagovat na tento příspěvek
  2. vn158 (26.1.2016, 14:04)

    Místo toho harakiri s posuny by bylo lépe byte krok = bkrok && 7;

    Reagovat na tento příspěvek
  3. David (11.9.2016, 19:31)

    Dík tohle sem potřeboval :D

    Reagovat na tento příspěvek

  4.  
    Diskuze: Arduino a motor 28BYJ-48 podruhé
    Vaše jméno (povinné)
    Váš email (nebude zveřejněn, povinný)
    WEB (bude zveřejněn, pište s http://)
    Text vzkazu:
    Kolik je 3×2? (ochrana proti spamu)
 
[CNW:Counter]