Aplikace D2 Vozítko s ovladačem

název: D2 Vozítko s ovladačem
kategorie: D zkušení programátoři
ref.číslo: D2
projekt: kurz micro:bit
verze: 01, 2017-11-27
autor: Ivo Obr, Lanškroun

Nejdříve si řekneme, co budeme od této hračky očekávat a co budeme potřebovat za materiál:

 Vozítko : – bude mít pravý a levý DC motor napojený na driver Kitronik 5602, viz lekce B19. V tomto driveru je zasunut micro:bit, který je také z tohoto modulu napájen. Napájení modulu je  6V (ze čtyř AA článků) z držáku na 4ks baterií. Vozítko má celkový vypínač s indikací zapnutého napájení (LED dioda) a s indikací stavu pomocí další LED diody. Jedná se o stav standby (pohotovostní stav, kdy vozítko jen přijímá a vysílá signál HeartBeat – dále jen HB) nebo je zapnuto.

(samozřejmě lze použít například driver L298N, pak je nutno použít jiný konektor pro micro:bit, realizovat napájení jinou cestou a pod. V návodu je použit Kitronik 5602, který Vám zjednoduší konstrukci el. obvodů.)

Ovladač : – Je realizován velice jednoduše. Je to pouze další micro:bit s originálním napájecím zdrojem, nejlépe pak v ochranném pouzdře s okénkem na displej a přístupnými tlačítky “A” a “B”.

Spojení vozítko – ovladač je indikováno na displeji blikáním srdce v periodě 1sec. Naklápění micro:bitu ve dvou osách se ovládá jízda dopředu-dozadu, vpravo-vlevo., pokud je vozítko zapnuto. To se provede tlačítkem “A” na ovladači, kterým se přepíná mezi oběma stavy vozítka. Přepnutím do standby se jízda zastaví, i když nakláníme ovladač. Tlačítko “B” je volné na další povely vozítku, já jsem zvolil provedení testovací jízdy, dopředu-dozadu, zatáčky a otočky.

Myslím si, že tento návod bude výchozím řešením pro realizaci ovládání nejen vozítek, ale i jiných zařízení.

Nejdříve si povíme o ovladači. Pokud jste si ještě nepřečetli lekci D1 – dálkový ovladač, tak to vřele doporučuji, i když její obsah nebudete realizovat. Náš ovladač nebude tolik složitý a bude  mít  navíc některé poznatky z praktického provozu.

Nejdříve si nastavíme časové intervaly a proměnné pro sledování času :

# CASOVE INTERVALY
CAS_KLAVESY = running_time()
INT_KLAVESY = 200
CAS_GYRO = running_time()
INT_GYRO = 93
CAS_HBS = running_time()
INT_HBS = 1000
CAS_HBR = running_time()
INT_HBR = 3000

Proměnné začínající CAS_ jsou časy naposledy provedené operace, proměnné začínající INT_ jsou časové intervaly mezi jednotlivými operacemi. HBS je Heart Beat Sent a HBR je Heart Beat Read. Časový interval 3000msec je limit pro nepřijetí signálu HB od vozítka (ztráta spojení).

Takže nejprve co bude umět ovladač :

a) odesílat v nastaveném časovém intervalu (93 msec) hodnotu náklonu microbitu ve dvou osách (X a Y). Bude použit posun hodnot o +5000, aby nebyly odesílány záporné hodnoty (vzhledem ke kontrole numeričnosti na straně vozítka). Takže nula bude odesílána jako hodnota 5000. Každé odeslané číslo (jako řetězec číslic) bude odesláno za odeslaným znakem “X” nebo “Y”.

b) Signál Heart Beat, že ovladač “žije”, je odesílán v časovém intervalu 1000msec. Signál Heart Beat od vozítka (že vozítko “žije”) je zpracován a znázorněn na displeji micro:bitu ovladače. Pokud signál chybí, je na displeji znázorněn Image.NO.

c) Každých 200msec jsou testovány tlačítka “A” a “B” na micro:bitu ovladače. Pokud stiskneme tlačítko “A”, je odesílán znak “*”, tlačítkem “B” pak znak “#”. ( na klávesnici 4×4, viz lekce D1, jsou tato tlačítka )

Podívejme se na program ovladače :

# ROBO OVLADAC MALY
# LISTOPAD 2017
from microbit import *
import radio

# CASOVE INTERVALY
CAS_KLAVESY = running_time()
INT_KLAVESY = 200
CAS_GYRO = running_time()
INT_GYRO = 93
CAS_HBS = running_time()
INT_HBS = 1000
CAS_HBR = running_time()
INT_HBR = 3000

display.scroll("ROBO OVLADAC")
radio.config(length=8, channel=48, group=248, power=7)
radio.on()
while True:
    # KLAVESY
    if (running_time() - CAS_KLAVESY) >= INT_KLAVESY:
        if button_a.was_pressed():
            radio.send('*')
        if button_b.was_pressed():
            radio.send('#')
        CAS_KLAVESY = running_time()
    # GYRO
    if (running_time() - CAS_GYRO) >= INT_GYRO:
        radio.send('X')
        radio.send(str(accelerometer.get_x() + 5000))
        sleep(1)
        radio.send('Y')
        radio.send(str(accelerometer.get_y() + 5000))
        CAS_GYRO = running_time()
    # HEART BEAT SEND
    if (running_time() - CAS_HBS) >= INT_HBS:
        radio.send('H')
        if (running_time() - CAS_HBR) >= INT_HBR:
            display.show(Image.NO, delay=1, wait=True)  # indikace HB off
        CAS_HBS = running_time()
    # HEART BEAT RECEIVE
    prijem = radio.receive()
    if not(prijem is None):
        if (prijem == 'H'):
            display.show(Image.HEART, delay=500, wait=False, clear=True)
            CAS_HBR = running_time()

Na začátku programu se vypíše text na displeji. Pak se aktivuje rádio, délka přenosu stačí 8bytů, kanál a skupinu si nastavte sami, aby jste se nepletli s jiným ovladačem a vozítkem. Síla vysílání je nastavena na maximum.

Po uplynutí časového limitu (200msec)pro test tlačítek “A” a “B” se provede test, zda-li byla tlačítka stisknuta a pokud ano, odesílá se znak “*” nebo “#”.

Po uplynutí časového limitu pro GYRO se odesílá hodnota načtená z gyroskopu zvětšená o hodnotu 5000. Odeslanou hodnotu předchází znak “X” nebo “Y”. Za odesláním hodnoty “X” se čeká 1msec, než se odešle hodnota “Y”. Protože se každá z hodnot na vozítku čte v jednom cyklu, musí micro:bit na vozítku udělat dva cykly k načtení obou hodnot.

Po uplynutí časového limitu pro odeslání signálu HB, odešleme znak “H”. Zároveň si otestujeme, zdali časový limit pro příjem signálu HB od vozítka nepřekročil časový limit 3000msec. Pokud se tak stalo, je na displeji vykreslen obrázek Image.NO. Tento test jsem zařadil pod “křídla” odesílání signálu HB a to z důvodů, že tento test není třeba dělat při každém průchodu základním cyklem (mnohosetkrát za sec.)

Posledním úkonem je test, zdali nepřišel signál HB od vozítka. Měl by přicházet každých 1000msec. Pokud přijde, zobrazíme na displeji obrázek srdce a to na 500msec. Parametr wait=False říká, že nebude micro:bit čekat na dokončení příkazu a ihned pokračuje dále. Parametr clear=True vykoná smazání obrázku z displeje po uplynutí doby zobrazení, to je  500msec. Jestliže nám signál HB přichází každých 1000msec, pak srdce na displeji bliká (500msec svítí, 500msec zhasnuto). Znamená to, že vozítko “žije” a posílá nám o tom zprávu. A také nastavíme novou hodnotu času, kdy signál přišel. Tím udržujeme časový limit pro signál HBR pod hranicí 3000msec.

Co bude umět vozítko :

a) Bude stále číst rádio. Pokud došla zpráva, bude zjišťovat, co je to za znak. Pokud to bude “X”, pak bude následovat řetězec číslic polohy v ose X. Tento řetězec si vozítko zkontroluje, zda-li obsahuje jen číslice (převod na numerickou hodnotu pomocí int() by vedl k chybovému stavu programu). Pokud by to tak nebylo, není možné zjistit původní hodnotu a proto se dosadí nula (s offsetem 5000). To samé pro “Y”.

Při znaku “H” si aktualizuje hodnotu času, kdy signál došel.

Pokud je to signál “*”, pak program změní stav vozítka na opačnou hodnotu (False – True). False je stav POHOTOVOSTNÍ, True je stav ZAPNUTO. Také současně s hodnotou stavu rozsvítí nebo zhasne LED diodu na panelu vozítka. LED dioda je přes omezovací odpor 160 ohm připojena  k pinu č.11.  Při přechodu do stavu pohotovostního se také vypnou motory.

b) Pokud je vozítko ve stavu zapnuto a přišly obě souřadnice, převedou se řetězce hodnot “X” a “Y” na numerické hodnoty a odečte se offset 5000. Tím by mělo mít vozítko originální hodnoty z ovladače.

Občas se stane, že ovladač vygeneruje hodnoty X nebo X zcela jiné, než by mělo být. Obvykle se jedná o jednu hodnotu, která je dost mimo. Abychom zabránily situaci, kdy by například motor dostal krátký obrácený impuls, výslednou hodnotu pro řízení motorů generujeme jako průměr z posledních tří odeslaných hodnot. Také kontrolujeme rozsah hodnot pro analogový výstup, který smí být pouze v rozsahu 0 až 1023 jinak je program ukončen abnormální chybou..

Pak už je jen sekce pro řízení motorů. Pokud je hodnota pro analogový výstup menší než 200, je energie do motorů příliš malá a motory zůstávají v klidu. Hodnotu XK (korekce motorů) nastavte až při ladění hardware vozítka (do XN dejte nulu, aby vozítko jelo jen rovně. Pokud zatáčí na nějakou stranu, pak korekcí XK vyrovnejte jízdu – dejte malou kladnou nebo zápornou hodnotu).

Jednotlivé piny pro driver Kitronik 5602 jsou :

Pin8   – motor pravý DOPŘEDU
Pin12 – motor pravý DOZADU
Pin0   – motor levý DOPŘEDU
Pin16 – motor levý DOZADU

Pokud použijete jiný driver (například HG7881 nebo L298N), doporučuji zachovat stejné číslování pinů.

Posledním úkonem je posun hodnot X a Y o jeden krok do minulosti.

Celý program vozítka je uveden v následujícím:

# ROBO VOZITKO (SLIM OVLADAC)
# VERZE 5   OK
# offset polohy 5000
# listopad 2017
from microbit import *
import radio

stav = False   # False -standby,  True -zapnuto
Y0 = 0         # aktualni hodnota Y
Y1 = 0         # hodnota o jeden krok zpet
Y2 = 0         # hodnota o dva kroky zpet
X0 = 0         # aktualni hodnota X
X1 = 0         # hodnota o jeden krok zpet
X2 = 0         # hodnota o dva kroky zpet
X = "5000"
Y = "5000"

# CASOVE INTERVALY
CAS_HBS = running_time()
INT_HBS = 1000
CAS_HBR = running_time()
INT_HBR = 3000

prijem = None
radio.config(length=8, channel=48, group=248, power=7)
radio.on()
while True:
    prijem = radio.receive()
    if not(prijem is None):             # neco doslo
        if (prijem == 'X'):             # bude nasledovat souradnice X
            X = None
            while (X is None):
                X = radio.receive()
            if (not X.isdigit()):       # pokud to nejsou jen cislice
                X = "5000"              # tak tam dame nulu
        if (prijem == 'Y'):             # bude nasledovat souradnice Y
            Y = None
            while (Y is None):
                Y = radio.receive()
            if (not Y.isdigit()):       # pokud to nejsou jen cislice
                Y = "5000"              # tak tam dame nulu

        # DOSEL SIGNAL HB OD OVLADACE
        if (prijem == 'H'):
            CAS_HBR = running_time()

        # PREPINANI STAVU VOZITKA
        if (prijem == '*'):             # prepinani stavu vozitka
            if (stav):
                stav = False
                pin11.write_digital(0)  # indikator stavu VYP
                pin8.write_analog(0)    # vypnuti motoru
                pin0.write_analog(0)
                pin12.write_analog(0)
                pin16.write_analog(0)
            else:
                stav = True
                pin11.write_digital(1)  # indikator stavu ZAP

# HEART BEAT SEND
    if (running_time() - CAS_HBS) >= INT_HBS:
        radio.send('H')
        if (running_time() - CAS_HBR) >= INT_HBR:
            stav = False
            pin11.write_digital(0)      # indikator stavu VYP
        CAS_HBS = running_time()

# =========== JEN PRI ZAPNUTI stav=True =====================
    if (stav):
        if (prijem == 'Y'):
            Y0 = int(Y) - 5000
            YN = (Y0 + Y1 + Y2) // 3
            X0 = int(X) - 5000
            XN = (X0 + X1 + X2) // 8
            RY_PM = YN + XN             # zataceni vozitka
            RY_LM = YN - XN             # zataceni vozitka
            if (RY_PM > 1020):
                RY_PM = 1020
            if (RY_LM > 1020):
                RY_LM = 1020
            if (RY_PM < -1020):
                RY_PM = -1020
            if (RY_LM < -1020): RY_LM = -1020 # MOTORY if (RY_PM >= 200):
                pin8.write_analog(RY_PM)            # PM vpred
            if (RY_LM >= 200):
                pin0.write_analog(RY_LM)            # LM vpred
            if (RY_PM <= -200):
                pin12.write_analog(abs(RY_PM))      # PM vzad
            if (RY_LM <= -200):
                pin16.write_analog(abs(RY_LM))      # LM vzad
            if ((abs(RY_PM) < 200)):
                pin8.write_analog(0)    # vypnuti motoru PRAVY
                pin12.write_analog(0)
            if ((abs(RY_LM) < 200)):
                pin0.write_analog(0)    # vypnuti motoru LEVY
                pin16.write_analog(0)
            Y2 = Y1
            Y1 = Y0
            X2 = X1
            X1 = X0

 

Realizace :

Nejdříve si elektroniku postavte samostatně se zkušební deskou. Až to bude fungovat jak má, pusťte se do vlastní stavby vozítka. Nezapomeňte na vypínač od zdroje jak na ovladači (pokud ho máte v krabičce) tak i na vozítku. Doplňte si kontrolku na zapnuté napájení, vyhnete se vybití baterií při opomenutí vypnutí el. zdroje.

Tento návod je zaměřen na programování vozítka, nikoliv na je ho mechanickou stavbu. Proto je na Vás, na co si troufnete, zdali máte doma dílnu a pod.

Nejjednodušší je si objednat podvozek na e-shopu v internetu. Nabídek je hodně, koupíte jak u nás v ČR tak například na ebay.com . Jednoduchá stavebnice podvozku je na obrázku a vyjde Vás cenově kolem 200Kč, podle toho, kde nakoupíte.

Další možností je podvozek si postavit. Použil jsem pevnou lepenku z krabice (tl. 7mm), dřevěné hranolky 10x10cm, přední kola jsou kladičky s průměrem 45mm na kovových úhelníčcích.

Základem je spodní díl 100x100mm, vnitřní výška 80mm, horní díl je přišroubovaný. Motory s koly koupíte samostatně a jsou nalepeny oboustrannou lepící páskou.

Driver  Kitronik 5602 se vejde bezpečně na dno, destička micro:bitu je na přední straně, aby se pro další vývojovou verzi mohlo umístit servo pro pohyb hlavy a rukou robůtka. Držák baterií je přišroubován na zadní straně. Na tuto stavbu není potřeba dílna, lze to realizovat doma v kuchyni.

Závěr :

Polaritu napájení motorů si musíte vyzkoušet, aby vozítko správně reagovalo na povely dopředu – dozadu. Návod je základní verzi, v roce 2018 připravím rozšířenou verzi o další funkce vozítka a ovladače.  Povel (znak vyslaný pomocí tlačítka “B” na micro:bitu) “#” je nepoužitý a můžete si doprogramovat něco, co budete chtít, aby vozítko provádělo.

Pokud použijete driver L298N, je vhodné si z držáku baterie vyvést třetí drát s napětím 3V pro napájení micro:bitu, 6V pak bude napájet driver motorů. (Budete potřebovat dvojitý vypínač.)

Na konci správné vložení micro:bitu do driveru Kitronik 5602 :

 

Posted in kat D - zkušení programátoři.