Při vytváření složitějších projektů s micro:bitem se nám bude hodit si postavit dálkový ovladač dle svých potřeb a představ. Tato lekce je ukázkou, jaké máme možnosti si ovladač postavit s micro:bitem.
název: D1 Dálkový ovladač
kategorie: D zkušení programátoři
ref.číslo: D1
projekt: kurz micro:bit
verze: 01, 2017-11-07
autor: Ivo Obr, Lanškroun
Předpokládáme, že máme zařízení s micro:bitem, které chceme dálkově ovládat. V dalším budeme tomuto zařízení říkat přijímač, vlastnímu ovladači pak ovladač. Komunikace bude pomocí rádiového přenosu. Tato lekce je sice konkrétním návodem, ale umožní Vám porozumět tématu a upravit si svůj vlastní ovladač podle Vašich potřeb.
Nejdříve si řekneme, co od ovladače budeme očekávat. (v dalších lekcích připravuji návod na stavbu vozítka ovládaného micro:bitem, s ovladačem, který je v této lekci)
- komunikace mezi ovladačem a přijímačem bezdrátově
- klávesnice 4×4 (16 tlačítek: 1,2,3,4,5,6,7,8,9,0,A,B,C,D,*,#), odesílání stisknutého znaku
- odesílání hodnoty náklonu micro:bitu v ose X a oseY
- možnost přepínat mezi 4 nastavenými kanály (pro eliminaci rušení)
- odesílání signálu HEART BEAT (že ovladač je připojen)
- indikace připojení přijímače (pomocí signálu HEART BEAT z přijímače)
Co budeme ke stavbě ovladače potřebovat :
- 2 ks micro:bit (ovladač, přijímač)
- 1 ks EDGE konektor s kolíky
- 1 ks membránová klávesnice 4×4
- 1 ks žlutá LED dioda
- 1 ks RGB LED dioda
- spojovací dráty (male-female)
- 4 ks odpor 160 ohmů 0,25W
- nainstalovaný sériový monitor Tera Term (viz lekce B18) na PC
Začneme tím, že si vyzkoušíme funkčnost našeho rádiového přenosu mezi micro:bity a funkčnost sériového monitoru. Pokud máte realizovanou lekci B18, tak by to mělo fungovat na první zapojení.
Program pro ovladač :
from microbit import * import radio display.scroll("A") radio.config(length=32, group=48, power=7) radio.on() radio.send("OVLADAC") while True: radio.send("HEART BEAT") sleep(1000)
Abychom si nepopletli micro:bity, na začátku se na displeji micro:bitu ovladače vypíše “A”, na displeji micro:bitu přijímače “B”. Oproti standardním hodnotám rádia je nastaveno group=48 a power=7 a délka přenosu 32. Každou vteřinu bude ovladač odesílat text “HEART BEAT”.
Program pro přijímač :
from microbit import * import radio display.scroll("B") uart.init(9600) uart.write("PRIJIMAC \n \r") prijem = "" radio.config(length=32, group=48, power=7) radio.on() uart.write("RADIO ON \n \r") while True: prijem = radio.receive() if not(prijem is None): uart.write(prijem) uart.write("\n \r")
Po zapnutí micro:bitů a správném nastavení sériového monitoru by se měl na sériovém monitoru opakovat text “HEART BEAT”. (pokud ne, zkuste na ovladači i na přijímači tlačítko reset).
Pro ovladač použijeme membránovou klávesnici 4×4, která pro ovládání dostatečný počet tlačítek a je jednoduchá. Skládá se ze dvou vrstev, jedna vrstva má spojena tlačítka v řádcích, druhá vrstva ve sloupcích. Jestliže stiskneme některé tlačítko, pak se v průsečíku řádku a sloupce vytvoří vodivé spojení (dojde ke kontaktu vrstev).
Obrázek ukazuje princip této klávesnice. Jak program zjistí, která klávesa je stisknutá? Budeme postupně nastavovat v jednotlivých sloupcích digitálně hodnotu 1 (3V). Pokud v prvním sloupci nastavíme digitálně 1 (v ostatních sloupcích je digitálně 0), pak budeme číst hodnotu v jednotlivých řádcích. Pokud máme stisknutou například klávesu “7”, pak je ve třetím řádku na vodiči z klávesnice digitálně 1, v ostatních řádcích je 0. Ze souřadnice sloupce a řádku určíme, jaká klávesa je stisknuta.
(Náš program je postaven na vyhodnocení stisku jen jedné klávesy současně, pokud stiskne klávesy dvě najednou, pak bude vyhodnocena klávesa s vyšším pořadím.)
Pokud nebude žádná klávesa stisknuta, pak jsme nenašli žádný řádek s logickou hodnotou 1. Testování stisknuté klávesy je v programu nastaveno na interval 200ms, to je 5x za vteřinu. Držíme-li klávesu trvale, pak je znak vyhodnocen, jako bychom stiskli klávesu 5x za vteřinu.
Na obrázku jsou uvedeny čísla pinů na micro:bitu, ke kterým připojíme vývody z klávesnice. Sloupce jsou postupně od pinu 16 do pinu 13, řádky pak od pinu 9 do pinu 6. Kód pro test klávesnice je :
# OSAZENI KLAVESNICE klavesnice = ['1', '2', '3', 'A', '4', '5', '6', 'B', '7', '8', '9', 'C', '*', '0', '#', 'D'] iznak = None def klavesa(): global iznak iznak = None i = 0 for sloupec in [pin16, pin15, pin14, pin13]: sloupec.write_digital(1) j = 0 for radek in [pin9, pin8, pin7, pin6]: if radek.read_digital(): iznak = (i * 4) + j j += 1 sloupec.write_digital(0) i += 1
Každý znak, který je zjištěn je pak odesílán rádiem. Klávesy “A”, “B”, “C” a “D” jsem vyhradil pro přepínání kmitočtů a skupin rádiového přenosu. Na ovladači, pokud bychom se rušili s nějakým jiným rádiovým vysíláním, můžeme přepnout na jiný kanál a jinou skupinu. Také můžeme ovládat nezávisle dvě (tři nebo čtyři) zařízení jedním ovladačem. Znaky (“A”, “B”, “C” a “D”) se také odesílají ještě než dojde k přepnutí kanálu, aby se přijímač na druhé straně přepnul také na správné parametry vysílání (pokud ovládáme jedno zařízení).
V programu je sledován čas a po uplynutí 200ms dojde k testu klávesnice :
def klavesy44(): global CAS_KLAVESY global INT_KLAVESY global iznak if (running_time() - CAS_KLAVESY) >= INT_KLAVESY: klavesa() if not(iznak is None): znak = klavesnice[iznak] radio.send(znak) if (znak in ['A', 'B', 'C', 'D']): zap_radio(znak) CAS_KLAVESY = running_time() iznak = None
Zapínání rádia se provede funkcí “zap_radio(znak)”, kde znak je hodnota “A” nebo “B” nebo “C” nebo “D” přečtená z klávesnice.
# PARAMETRY RADIA A_CHANNEL = 51 A_GROUP = 201 B_CHANNEL = 61 B_GROUP = 211 C_CHANNEL = 71 C_GROUP = 221 D_CHANNEL = 81 D_GROUP = 231 def zap_radio(kanal): pin11.write_digital(0) pin12.write_digital(0) radio.off() if (kanal == 'A'): radio.config(length=32, channel=A_CHANNEL, group=A_GROUP, power=7) if (kanal == 'B'): radio.config(length=32, channel=B_CHANNEL, group=B_GROUP, power=7) pin11.write_digital(1) if (kanal == 'C'): radio.config(length=32, channel=C_CHANNEL, group=C_GROUP, power=7) pin12.write_digital(1) if (kanal == 'D'): radio.config(length=32, channel=D_CHANNEL, group=D_GROUP, power=7) pin11.write_digital(1) pin12.write_digital(1) radio.on()
Vysílací kanály a skupiny je možno upravit, vždy je ale třeba, aby stejné hodnoty byly i na přijímači. RGB LED diodu (červená- pin11, zelená – pin12) zapojíme do pinů 11 a 12 na microbitu přes omezovací odpor 160 ohmů. LED dioda svítí dle nastaveného kanálu takto :
A – nesvítí
B – červená
C – zelená
D – žlutá
Všechny časové intervaly jsou uvedeny v kódu :
# CASOVE INTERVALY CAS_KLAVESY = running_time() INT_KLAVESY = 200 CAS_GYRO = running_time() INT_GYRO = 97 CAS_HBS = running_time() INT_HBS = 1000 CAS_HBR = running_time() INT_HBR = 3000
Hodnoty z gyroskopu jsou přenášeny v časovém intervalu INT_GYRO = 97. Jedná se o souřadnice v ose X (náklon micro:bitu vpravo-vlevo) a v ose Y(náklon micro:bitu dopředu-dozadu). Hodnoty jsou přenášeny samostatně jako dva řetězce znaků. Před těmito řetězci je poslán znak “S”, aby přijímač měl informaci, že budou následovat dva řetězce znaků (X a Y).
def gyro(): global CAS_GYRO global INT_GYRO if (running_time() - CAS_GYRO) >= INT_GYRO: radio.send('S') radio.send(str(accelerometer.get_x())) radio.send(str(accelerometer.get_y())) CAS_GYRO = running_time()
Zbývá nám ještě signál HEART BEAT, který nám monitoruje spojení mezi ovladačem a přijímačem. Ovladač každou vteřinou vysílá na rádio znak “H”, který může být identifikován na přijímači jako že je spojení v pořádku. Také naopak přijímá signál z přijímače (ovládaného zařízení). Pokud signál z přijímače chodí, je toto indikováno LED diodou připojenou přes omezovací odpor na pin5. Takže pokud tato dioda svítí, je spojení ovladače a přijímače OK. Pokud po dobu 3 vteřin nepřijde signál (znak “H”) z přijímače, pak je tento stav vyhodnocen jako ztráta spojení a LED dioda zhasne. (Na pin5 je digital 0).
def HB(): global CAS_HBR global INT_HBR global CAS_HBS global INT_HBS # HEART BEAT SEND if (running_time() - CAS_HBS) >= INT_HBS: radio.send('H') if (running_time() - CAS_HBR) >= INT_HBR: radio.send('?') pin5.write_digital(0) # indikace LED HB off CAS_HBS = running_time() # HEART BEAT RECEIVE prijem = radio.receive() if not(prijem is None): if (prijem == 'H'): CAS_HBR = running_time() pin5.write_digital(1) # indikace LED HB on
Poznámka:
Pokud připojíte piny klávesnice a LED diod jinak než podle tohoto návodu, je možné, že Vám program ovladače nebude fungovat.
Celý program ovladače a přijímače najdete na konci této lekce. Nejdříve si vyzkoušíme, jak to funguje. Nahrajeme oba programy do micro:bitů. Pokud jsme pracovali pozorně, funguje vše na první zapojení.
K vlastní mechanické realizaci jsem použil elektrikářskou krabičku 80x80x28mm. Tato lekce není návodem na konkrétní mechanickou stavbu. Někdo si vytiskne krabičku na 3D tiskárně, někdo slepí z tvrdého kartonu.
LED diody a omezovací odpory a spojové dráty jsem připájel k destičce pro jednorázovou montáž viz obrázek. Celkový pohled na ovladač takto zhotovený je na posledním obrázku.
Pokud budete chtít experimentovat a měnit funkce ovladače, doporučuji nastavit si delší časy pro “X” a “Y”, aby jste dokázali sledovat komunikaci mezi ovladačem a přijímačem na sériovém monitoru.
A nakonec oba programy.
Program pro ovladač:
from microbit import * import radio # PARAMETRY RADIA A_CHANNEL = 51 A_GROUP = 201 B_CHANNEL = 61 B_GROUP = 211 C_CHANNEL = 71 C_GROUP = 221 D_CHANNEL = 81 D_GROUP = 231 # CASOVE INTERVALY CAS_KLAVESY = running_time() INT_KLAVESY = 200 CAS_GYRO = running_time() INT_GYRO = 97 CAS_HBS = running_time() INT_HBS = 1000 CAS_HBR = running_time() INT_HBR = 3000 # OSAZENI KLAVESNICE klavesnice = ['1', '2', '3', 'A', '4', '5', '6', 'B', '7', '8', '9', 'C', '*', '0', '#', 'D'] iznak = None def klavesa(): global iznak iznak = None i = 0 for radek in [pin16, pin15, pin14, pin13]: radek.write_digital(1) j = 0 for sloupec in [pin9, pin8, pin7, pin6]: if sloupec.read_digital(): iznak = (i * 4) + j j += 1 radek.write_digital(0) i += 1 def zap_radio(kanal): pin11.write_digital(0) pin12.write_digital(0) radio.off() if (kanal == 'A'): radio.config(length=32, channel=A_CHANNEL, group=A_GROUP, power=7) if (kanal == 'B'): radio.config(length=32, channel=B_CHANNEL, group=B_GROUP, power=7) pin11.write_digital(1) if (kanal == 'C'): radio.config(length=32, channel=C_CHANNEL, group=C_GROUP, power=7) pin12.write_digital(1) if (kanal == 'D'): radio.config(length=32, channel=D_CHANNEL, group=D_GROUP, power=7) pin11.write_digital(1) pin12.write_digital(1) radio.on() display.scroll("A") zap_radio('A') while True: # KLAVESY if (running_time() - CAS_KLAVESY) >= INT_KLAVESY: klavesa() if not(iznak is None): znak = klavesnice[iznak] radio.send(znak) if (znak in ['A', 'B', 'C', 'D']): zap_radio(znak) CAS_KLAVESY = running_time() iznak = None # GYRO if (running_time() - CAS_GYRO) >= INT_GYRO: radio.send('S') radio.send(str(accelerometer.get_x())) radio.send(str(accelerometer.get_y())) CAS_GYRO = running_time() # HEART BEAT SEND if (running_time() - CAS_HBS) >= INT_HBS: radio.send('H') if (running_time() - CAS_HBR) >= INT_HBR: radio.send('?') pin5.write_digital(0) # indikace LED HB off CAS_HBS = running_time() # HEART BEAT RECEIVE prijem = radio.receive() if not(prijem is None): if (prijem == 'H'): CAS_HBR = running_time() pin5.write_digital(1) # indikace LED HB on
Program pro přijímač (je na Vás, jak s tím naložíte, asi by něco podobného mělo být součástí Vašeho ovládaného zařízení):
from microbit import * import radio # PARAMETRY RADIA A_CHANNEL = 51 A_GROUP = 201 B_CHANNEL = 61 B_GROUP = 211 C_CHANNEL = 71 C_GROUP = 221 D_CHANNEL = 81 D_GROUP = 231 # CASOVE INTERVALY CAS_HBS = running_time() INT_HBS = 1000 CAS_HBR = running_time() INT_HBR = 3000 def zap_radio(kanal): radio.off() if (kanal == 'A'): radio.config(length=16, channel=A_CHANNEL, group=A_GROUP, power=7) if (kanal == 'B'): radio.config(length=16, channel=B_CHANNEL, group=B_GROUP, power=7) if (kanal == 'C'): radio.config(length=16, channel=C_CHANNEL, group=C_GROUP, power=7) if (kanal == 'D'): radio.config(length=16, channel=D_CHANNEL, group=D_GROUP, power=7) radio.on() display.scroll("B") uart.init(115200) uart.write("PRIJIMAC \n \r") prijem = "" radio.config(length=32, channel=A_CHANNEL, group=A_GROUP, power=7) zap_radio('A') uart.write("RADIO ON \n \r") while True: prijem = radio.receive() if not(prijem is None): uart.write(prijem) uart.write("\n \r") if (prijem == 'S'): X = radio.receive() while (X is None): X = radio.receive() uart.write(X) uart.write(' ') Y = radio.receive() while (Y is None): Y = radio.receive() uart.write(Y) uart.write("\n \r") if (prijem in ['A', 'B', 'C', 'D']): uart.write("KANAL ") uart.write(prijem) uart.write("\n \r") zap_radio(prijem) if (prijem == 'H'): # prisel signal HEART BEAT od prijimace CAS_HBR = running_time() # HEART BEAT SEND if (running_time() - CAS_HBS) >= INT_HBS: radio.send('H') if (running_time() - CAS_HBR) >= INT_HBR: uart.write("NENI OVLADAC \n \r") CAS_HBS = running_time()
Pingback: Aplikace D2 Vozítko s ovladačem – Microla