Připojujeme „periférie“ k Multi-function Shield (Funduino)
Multifunkční rozšíření modulu Arduino nazvané Multi-function Shield (nebo též Funduino) se kromě zabudovaných obvodů – např. LED zobrazovač, signalizační LED, bzučák… – chlubí i tím, že jej lze využít pro řízení dalších obvodů a modulů – servo, sonar, krokový motor…
Pojďme si tedy tyto vlastnosti vyzkoušet. I když rovnou je třeba říci, že se ani tak nejedná o vlastnosti tohoto rozšiřujícího shieldu, ale samotného modulu Arduino. Neboť to, co shield v tomto případě přináší, je často jen vyvedení řídicích pinů modulu Arduino na dané konektory.
1. Teplotní čidla
1.1. Teplotní čidlo LM35
Ukážeme si, jak pomocí teplotního čidla LM35 měřit teplotu. Výhoda tohoto čidla oproti běžnému termistoru, který též můžeme použít, je především jeho linearita (oproti exponenciální závislosti odporu na teplotě u běžného termistoru).
Čidlo LM35 zasuneme do konektoru označeného na desce plošného spoje jako U5 (v našem popisu desky označen jako 7b). Piny konektoru jsou (zleva doprava): GND, A4, +5 V.
Rozpojte zkratovací spojku (jumper) J1 – tím odpojíte rezistor 10 kΩ mezi +5 V a pinem A4 (Rezistor je tam kvůli čidlu DC18B20).
- POZOR!
Na desce plošného spoje je předtištěn tvar pouzdra pro obvod DS18B20. Čidlo LM35 je třeba zasunout opačně – tj. zakulacenou částí pouzdra směrem dolů (viz obrázek č. 1 - vlevo).
1.1.1. Teploměr (LM35)
Pro jednoduchost celého ukázkového programu nebudeme zobrazovat teplotu na LED zobrazovačích, ale odesílat pomocí sériového portu do PC.
Kód:
#define LM35 A4 // kam je priveden vstup LM35
int val = 0; // nactena hodnota
float temp = 0; // teplota
void setup()
{
Serial.begin(9600); // nastaveni seriove komunikace
}
void loop()
{
val = analogRead(LM35); // nacteni A/D vstupu A4 (1023 odpovida Uin = 5 V)
temp = val * 0.48876; // vypocet teploty: Uin = 10 mV * temp (takze 0.48876 = 5/1023*100)
Serial.print("LM35 = ");
Serial.print(temp); // vypis teplotu (odesli na PC)
Serial.println(" stupnu C");
delay(1000);
}
Popis:
V části setup
nastavíme sériovou komunikaci. Mohli bychom zde i nastavit pin A4 jako vstupní analogový, ale protože takovou funkci má nastavenou jako výchozí, dovolili jsme si toto nastavení vynechat.
Výstupní hodnotu napětí odpovídající teplotě čidla LM35 (na pinu A4) načítáme jako analogovou hodnotu (analogRead) v rozmezí 0–1023. Vstupní napětí je pak dle kalibrační křivky čidla LM35 (viz datasheet obvodu LM35) přepočteno na hodnotu teploty (1 °C ≈ 10 mV). Tato hodnota je sériovou linkou odesílána do PC, či jiného modulu. Toto celé se po vteřinovém čekání cyklicky opakuje v sekci loop
.
1.2. Teplotní čidlo Maxim/Dallas DS18B20
Teplotní senzor DS18B20 (firmy Maxim/dříve Dallas) umožňuje za velmi rozumnou cenu měřit teplotu v rozsahu -55 až +125 °C. Čidlo je možné zakoupit jak v pouzdře TO-92 (podobné obyčejnému tranzistoru), tak i ve vodotěsné variantě (senzor v nerezové tyčince). Pro komunikaci s Arduino deskou je u čidla DS18B20 využita sběrnice OneWire, která využívá pouze jeden komunikační vodič (pin). Toto čidlo také podporuje takzvaný parazitní režim, kdy pro spojení čidla s Arduino deskou stačí využít pouze 2 vodiče1). Díky tomu můžete na internetu najít dva způsoby zapojení – buď s připojenými oběma napájecími vodiči GND a +5 V a vodičem datovým, nebo s připojeným vodičem GND a napájecí napětí +5 V je připojeno přes rezistor cca 5 kΩ do datového vodiče (GND a VDD pak bývá někdy spojeno).
1) Zdroj: http://
Nás však tyto „drobnosti“ v zapojování nemusí trápit, neboť připojení čidla je vyřešeno přímo na desce multifunkčního shieldu. Čidlo vsuneme do konektoru U5 (v našem popisu 7b), přesně podle vyznačeného předtisku na desce (zakulacená část pouzdra směrem nahoru).
Pro komunikaci s obvodem, musíme zapojit rezistor mezi napájecí napětí +5 V a datový pin (A4). To provedeme zkratováním zkratovací propojky (jumper) J1.
V následujícím programu použijeme pro komunikaci s čidlem dvě knihovny a to: OneWire (komunikace po jednovodičové sběrnici) a knihovnu DallasTemperature (ovládání a komunikace čidla DS18B20). Zároveň si tím způsobem ukážeme, jak můžeme přidávat potřebné knihovny do svého projektu.
Pro instalaci knihoven do svého projektu máme tyto možnosti:
a) Instalace ze ZIP souboru
Tento způsob především využijeme, pokud budeme mít knihovnu v ZIP souboru – např. staženou ze stránek nějakého vývojáře, který nám ji poskytl.
V prostředí Arduino IDE zvolíme v hlavní menu volbu Projekt→ Přidat knihovnu → Přidat ZIP Knihovnu… (viz obrázek č. 4). Poté v následném dialogu zvolíme umístění ZIP souboru, ve kterém je knihovna umístěna.
b) Instalace on-line
Pokud chceme využít nějaké standardní knihovny, které se již obecně využívají, a tedy jsou i dostupné na stránkách http://
, zvolíme právě tuto možnost.
V prostředí Arduino IDE v hlavním menu zvolíme: Projekt → Přidat knihovnu → Spravovat knihovny… (viz obrázek č. 5). Prostředí Arduino IDE se připojí k webu arduino.cc, odkud se načte seznam tam dostupných knihoven. V seznamu knihoven si pak vybereme požadovanou (lze vyhledávat pomocí zadaných klíčových slov). Zvolenou knihovnu lze stáhnout a naistalovat (popř. jen aktualizovat).
Ať již zvolíme kterýkoliv způsob instalace, oba by měly skončit stejně. To znamená, že se po úspěšném nainstalování knihoven vytvoří v pracovní složce (obvykle: Dokumenty aktuálního uživatele – podsložka Arduino) složka „libraries“ a v ní podsložky knihoven – v našem případě: DallasTemperature
a OneWire
.
Tím došlo k propojení stažených knihoven a našeho prostředí Arduino IDE. Zatím to znamená jen to, že až budeme knihovny potřebovat, dokáže je prostředí Arduino IDE najít, a tedy neskončí překlad kvůli tomu chybou. Použití kterékoliv z knihoven samozřejmě musíme též zapsat do zdrojového kódu programu. To si ukážeme v následujícím příkladu.
1.2.1. Teploměr (DS18B20)
Kód:
// připojení knihoven
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS A4 // nastaveni cisla vstupního pinu
OneWire oneWire(ONE_WIRE_BUS); // vytvoreni instance oneWire z knihovny OneWire
DallasTemperature sensors(&oneWire); // vytvoření instance senzors z knihovny DallasTemperature
void setup(void) {
Serial.begin(9600); // komunikace pres seriovou linku rychlosti 9600 baud
sensors.begin(); // zapnuti komunikace knihovny s teplotnim cidlem
}
void loop(void) {
Serial.print("Dotazuji se na teplotu…");
sensors.requestTemperatures(); // nacteni informaci ze vsech pripojenych cidel na danem pinu
Serial.println("HOTOVO");
Serial.print("Teplota cidla DS18B20: ");
// vypis teploty na seriovou linku, pri pripojeni vice cidel
// na jednom pinu muzeme postupne nacist vsechny teploty
// pomoci zmeny cisla v zavorce (0) - poradi dle unikatni adresy cidel
Serial.print(sensors.getTempCByIndex(0));
Serial.println(" stupnu Celsia");
delay(1000); // pauza 1 s
}
Popis:
První a nyní i novou částí programu je direktiva #include
, která k programu připojí zadané knihovny (jméno v ostrých závorkách). Rázem se nám instrukční sada jazyka Wiring rozšíří i o příkazy definované v těchto knihovnách. V našem případě to je využití instance objektů OneWire a DallasTemperature. Sekce setup
nastaví vše pro sériovou komunikaci s připojeným PC a také i komunikaci s teplotním čidlem DS18B20. Hlavní program ve smyčce loop
, pak probíhá velmi jednoduše:
Příkazem sensors.
se dotážeme na teploty všech připojených čidel – zatím je jen jedno, ale dále si ukážeme, jak lze tyto čidla „řetězit“. Po načtení se tato hodnota zobrazí pomocí příkazu sensors.
, kde parametr 0
udává „adresu“ čidla. Pak se získaná hodnota již může odeslat se přes sériové rozhraní – kamkoliv.
1.2.2. Teploměr DS18B20 a LED zobrazovače
Pojďme využít možností multifunkčního shieldu a vytvořit nějakou trochu sofistikovanější aplikaci. A protože si „hrajeme“ s teplotními čidly, bude to teploměr. Využijeme k tomu čidlo DS18B20 a hned si ukážeme drobné úskalí tohoto čidla.
Zapojení čidla i načítání teploty z něj je stejné jako v předchozím případě. Jediné, co do kódu doplníme, bude obsluha čtveřice LED zobrazovačů. Ale to by snad již pro nás neměl být problém!
Kód:
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS A4 // nastavení čísla vstupního pinu
OneWire oneWire(ONE_WIRE_BUS); // vytvoření instance oneWire z knihovny OneWire
DallasTemperature sensors(&oneWire); // vytvoření instance senzors z knihovny DallasTemperature
int rT=0; // pomocná promenna
int carka=0; // urci segment, kde bude des. tecka
int latchPin = 4;
int clockPin =7;
int dataPin = 8; // nastaveni vystupu pro segmentovky
unsigned char Dis_table[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90}; // data pro segmentovky
unsigned char Dis_buf[] = {0xF1,0xF2,0xF4,0xF8};
unsigned char disbuff[] = {0, 0, 0, 0};
void setup ()
{
pinMode(latchPin,OUTPUT);
pinMode(clockPin,OUTPUT);
pinMode(dataPin,OUTPUT); // piny pro segmentovku
sensors.begin();
}
void display()
{
for(char i=0; i<=3; i++) // postupne nastavuje segmentovky
{
digitalWrite(latchPin,LOW); // vybere latch pro zapis
if(carka == i) { // ma tam byt des. tecka?
shiftOut(dataPin,clockPin,MSBFIRST,Dis_table[disbuff[i]]&0x7F); // doplni des. tecku
} else {
shiftOut(dataPin,clockPin,MSBFIRST,Dis_table[disbuff[i]]); // posle hodnoty pro zobrazeni
}
shiftOut(dataPin,clockPin,MSBFIRST,Dis_buf[i] ); // nastavi cislo segmentovky
digitalWrite(latchPin,HIGH); // ukonci zapis do latch - zobrazeni
delay(2); // cekej 2 ms
}
}
void loop(void)
{
sensors.requestTemperatures(); // Send the command to get temperatures
float t = sensors.getTempCByIndex(0);
// prevod reálného des. cisla na 4-ciferne číslo (to co se zobrazi)
if (t < 10) { rT = (int)(t*1000); carka = 0; } // vyrobi 4-ciferne cislo
else {
if (t < 100) { rT = (int)(t*100); carka = 1; }
else {
if (t < 1000) { rT = (int)(t*10); carka = 2; }
else { rT = (int)(t); carka = 3; }
}
}
// priprava cisel pro LED zobrazovace
disbuff[0]= rT/1000;
disbuff[1]= rT%1000/100;
disbuff[2]= rT%1000%100/10;
disbuff[3]= rT%1000%100%10;
for(int time = 0; time < 200; time++)
{
display(); // nekolikrat zapise, aby to neblikalo a zaroven jako cekacka
}
}
Popis:
Většina kódu se podobá tomu, co zde již bylo – ať již jde o ovládání LED zobrazovačů, či načítání čidla Dallas. Zaměříme se jen na části, které jsou v kódu nové. Zejména jde o sekci složených podmínek těsně po načtení teploty do proměnné t
. Jelikož hodnota teploty je desetinné číslo, chceme vyřešit umístění desetinné tečky. Dále chceme číslo zaokrouhlit tak, aby „zaplnilo“ všechny čtyři LED zobrazovače. Je-li hodnota teploty menší než 10 vynásobíme ji číslem 1000. Tím získáme čtyřciferné číslo, které pak rozdělíme na počet tisíců, stovek, desítek a jednotek pro jednotlivé LED zobrazovače. Pochopitelně musíme na prvním zobrazovači rozsvítit desetinnou tečku – to nám zařizuje proměnná carka
a její hodnota 0 (adresa 1. zobrazovače). Je-li hodnota teploty menší než 100 (a zároveň větší než 10), vynásobíme ji číslem 100 – tím opět získáme čtyřciferné číslo a postup je stejný, jen proměnná carka
bude rovna 1. Obdobným způsobem pokračujeme pro případné teploty větší než 100 a 1000. Hodnota proměnné carka
pak v proceduře display
rozhoduje, u kterého zobrazovače se zobrazí desetinná tečka.
Teploty menší než 10 pak budou zobrazeny s 3 desetinnými místy, teploty z intervalu 10-99 s dvěma desetinnými místy, stovkové teploty s jedním desetinným místem. Teoreticky by bylo možné zobrazit i teploty řádu tisíců s nulovým počtem desetinných míst, ale je jasné, že takových teplot nejen reálně nedosáhneme, ale především by to nevydrželo použité teplotní čidlo.
Na obrázku č. 6 vidíme realizaci našeho teploměru. V patici 7b je zasunuto čidlo DC18B20. Datový pin A4 je pomocí žluté zkratovací spojky J1 propojen přes rezistor s napájecím napětím. Na čtveřici LED zobrazovačů je zobrazena aktuální teplota. Tak, kde to slibované úskalí?
Na fotografii je to hezké, ale zkuste výše uvedený kód zkompilovat a nahrát do modulu Arduino. A uvidíte!
Avizovaný problém spočívá v rychlosti načítání teplotního čidla. Možná jste si toto již všimli v minulém příkladu, kdy se teploty vypisovaly v Serial Monitoru.
Pokud jste bedlivě sledovali výpis, objevilo se „Dotazuji se na teplotu“ a po cca vteřinové pauze se objevilo „HOTOVO“ a pak se zobrazila i změřená teplota. Při výpisu teplot to je dobré, ale jakmile musíme modulem Arduino obsluhovat zobrazovače na multifunkčním shieldu, je vteřinová prodleva katastrofou! Jak se to projeví? První tři zobrazovače zhasnou – svítí jen ten čtvrtý – a po znatelné pauze se teplota opět zobrazí celá – na chvíli. Jak dlouhou? To záleží na počtu průběhů v posledním cyklu v sekci loop
.
Jste zklamaní? No, co se dá dělat, tohle čidlo je prostě pomalé… Ale tohle čidlo má zase jiné přednosti.
Více čidel:
Krásou teplotních čidel Maxim/Dallas DS18B20 je možnost jejich společného připojení na jeden datový vodič (sběrnici). Následující obrázek č. 6 ukazuje zapojení čtyř čidel, ale je jasné, že takovým způsobem lze připojit i čidel více. Hodnoty z nich načtené si pak vybíráme parametrem v příkazu sensors.
Kolik lze takto připojit čidel maximálně? Tak to bohužel nevím…
2. Sonarové čidlo
Dalším čidlem připojitelným k modulu Arduino a tedy multifunkčnímu shieldu je sonarové čidlo. Nejčastěji bývá používané čidlo označené HC-SR04, či různé jeho klony2).
2) Mimochodem, mně se klony moc nevyplatily – ze tří hned dva nefungovaly správně (cenová úspora tedy skutečně k „nezaplacení“!)
2.1. Sonar (HC-SR04)
Čidlo je osazeno čtyřmi vývody. Dva zajišťují napájení (+5 V a GND) a zbylé dva jsou pro spuštění signálu (TRIG) a pro data (ECHO). Zjištění vzdálenosti se spustí pomocí 10 μs dlouhého vysokého signálu (HIGH). Čidlo vyšle sonarový signál (osm pulzů, 40 kHz) a čeká na odpověď (odraz zvuku od překážky).
Pro určení vzdálenosti máme hned dvě možnosti. Buď vzdálenost určíme z doby mezi vysláním signálu (TRIG) a přijetí zpětného signálu (ECHO), nebo z délky trvání signálu HIGH na signálu ECHO, která odpovídá době „letu“ signálu.
Tedy:
nebo
připojené k Multi-function Shield
Na internetu najdete mnoho způsobů připojení sonarového čidla, které se liší jen tím, ke kterým pinům je modul připojen. My chceme k řízení čidla využít multifunkční shield, tak využijeme jeho univerzální konektor v pravé části dole (v našem popisu označen 10). Signál TRIG připojíme k pinu 6, signál ECHO k pinu 5. Napájení +5 V (resp. GND) je v druhém (popř. prvním) sloupci. Připojení sonarového čidla k Multi-function Shieldu vidíte na obr. 8.
2.1.1. Měřič vzdálenosti
Při stavbě jednoduchého měřiče vzdálenosti budeme postupovat přesně podle výše popsaného postupu. Pro výpočet vzdálenosti použijeme prvního postupu, tj. času mezi signály TRIG a ECHO. Pro zjištění této doby využijeme funkci pulseIn(pin, stav, [timeout])
, která má dva povinné parametry – pin
udávající číslo pinu modulu Arduino, na kterém „číháme“ na stav
(HIGH nebo LOW). Návratová hodnota funkce odpovídá počtu mikrosekund, které uběhly do okamžiku, kdy se objeví očekávaný stav na zadaném pinu. Třetí (nepovinný) parametr timeout
udává, jak dlouho se má čekat. Po uplynutí této doby funkce vrací hodnotu 0. Standardně je výchozí hodnota nastavena na dobu 1 s.
Kód:
// pripojte sonarove cidlo HC-SR04 na piny +5 V, GND, 5 (ECHO) a 6 (TRIG)
int inputPin = 5; // pin pro ECHO
int outputPin = 6; // pin pro TRIG
void setup()
{
Serial.begin(9600);
pinMode(inputPin, INPUT);
pinMode(outputPin, OUTPUT);
}
void loop()
{
digitalWrite(outputPin, LOW); // signal LOW 2 us
delayMicroseconds(2);
digitalWrite(outputPin, HIGH); // 10 us signalu HIGH
delayMicroseconds(10);
digitalWrite(outputPin, LOW); // konec start pulzu
int distance = pulseIn(inputPin, HIGH); // cekam do signalu HIGH
distance = distance/58; // prepocitani na vzdalenost
Serial.print(distance); // odesli vzdalenost
Serial.println(" cm");
delay(500);
}
Popis:
Sekce setup
opět definuje jak nastavení pinu 5 a 6 pro vstup ECHO a výstup TRIG, tak pro sériovou komunikaci s PC, popř. s jiným modulem.
Ve smyčce loop
vidíme nejdříve nastavení úrovně LOW, abychom mohli pak „vytvarovat“ startovní 10 μs HIGH pulz. Po startovním pulzu čekáme na úroveň HIGH na pinu ECHO. Vydělením hodnoty distance
(počet mikrosekund) číslem 58 dostaneme vzdálenost v centimetrech. Toto číslo odešleme sériovou linkou. Další měření opět spustíme za 0,5 s. To celé se cyklicky opakuje.
Je již na každém vývojáři, aby tento kód upravil buď na zobrazení vzdálenosti na čtveřici LED zobrazovačů, nebo přeměnil na zvukový signál bzučáku. Obojí máte na Multi-function Shieldu plně k dispozici.
3. Servo
Tak jsme si zablikali, zatroubili… a co konečně také něčím pohnout! Jednou možností– a modeláři nám jistě potvrdí, že vcelku dobrou a oblíbenou – je použití serva. Servo si můžeme představit jako motorek s převodovkou, který se umí natočit do předem stanovené polohy. Natočení serva je řízeno pulzním signálem, u kterého se mění tzv. střída (tj. poměr šířky vysoké úrovně HIGH a nízké LOW). Kontrolér serva (např. RC přijímač modelářské soupravy) posílá v pravidelném intervalu 50 Hz kladný pulz, na jehož šířce závisí natočení serva. Zpravidla při délce pulzu 1500 μs je servo v neutrální pozici (střed). Se zkracováním pulzu až někam k 500 μs se servo natáčí vlevo, s prodlužováním až k cca 2400 μs pak vpravo. Je dobré vědět, že každé servo má jiné krajní hodnoty a není vůbec dobré, pokud je budeme překračovat. Mechanika serva je pak nepříjemně zatěžovaná krouticím momentem motoru a může se v takové situaci lehce poškodit.
3.1. Otáčení servem
Pro naše pokusy použijeme malé modelářské servo SG90, které připojíme k modulu multifunkčního shieldu (Funduino) do univerzálního konektoru v pravé dolní části. Servo má tři vývody spojené do společného plochého konektoru. Vodiče mají tento význam: hnědá – GND, červená – +5 V, oranžová – řídicí signál. Multifunkční shiled je navržen tak, že lze konektor serva rovnou nastrčit na připravené piny univerzálního konektoru – my jej zapojíme hned do horní řady – díky tomu budeme servo řídit pinem č. 5.
připojené k Multi-function Shield
Servo připojené k Multi-function Shield vidíte na obrázku č. 9.
Kód:
int servopin = 5; // nastaveni rizeni serva
int myangle; // promenna pro uhel
int pulsewidth; // sirka pulzu
int val;
void setup()
{
pinMode(servopin,OUTPUT); // nastaveni vystupu pro servo
Serial.begin(9600); // nastaveni ser. komunikace
}
void servopulse(int servopin, int myangle) // ovladani serva
{
pulsewidth = (myangle*11) + 500; // vypocet pulzu (500-2480)
digitalWrite(servopin,HIGH); // zapnout na HIGH
delayMicroseconds(pulsewidth); // cekej zadany pocet mikrosekund
digitalWrite(servopin,LOW); // nastaveni LOW
delay(20-pulsewidth/1000); // doba nizke urovne
}
void loop()
{
val = Serial.read(); // nacte uhel (od 0 do 9 vcetne - tj. po 20 stupnich)
if(val>'0' && val<='9')
{
val = val-'0';
val = val*(180/9); // vypocet uhlu pootoceni
Serial.print("Natacim servo na ");
Serial.print(val, DEC);
Serial.println();
for(int i = 0; i <= 50; i++) // posle 50 pulzu, aby platily a zaroven jako cekacka
{
servopulse(servopin, val);
}
}
}
Popis:
Servo je připojeno k pinu 5, to je nastaveno v proměnné servopin
. Při přepojení serva na jiný pin (např. 6, či 9) lze tento fakt pro celý program změnit hned na první řádce. Sekce setup
opět nastavuje pin 5 pro výstup a nastavuje sériovou komunikaci s PC.
Novinkou tohoto programu bude to, že nebudeme hodnoty odesílat z modulu Arduino do PC, ale naopak budeme je modulem Arduino načítat. To zajišťuje funkce Serial.read()
v sekci loop
. Hodnoty z rozmezí 1-9 budeme zadávat v monitoru sériového portu (Serial Monitor) prostředí Arduino IDE3).
Procedura servopulse
ze zadané hodnoty natočení (úhel) vypočítá délku řídicího pulzu. Ve smyčce loop
, jak již bylo zmíněno, se načte zadaná hodnota (1-9 tj. násobek úhlu 20 stupňů). Vstupní hodnota se převede na úhel a tato hodnota úhlu je vstupním parametrem procedury servopulse
. Celé je to vykonáno celkem cca 50×, to z důvodu určité doby platnosti generovaného signálu pro servo, ale zároveň to slouží i jako zdržení programu.
3) „Fajšmekři“ si mohou naprogramovat aplikaci, která bude prostřednictvím sériového portu tuto hodnotu odesílat. Ale jak to udělat, to si třeba povíme jindy, až se začneme zabývat vzájemnou komunikací mezi PC aplikací a modulem Arduino. Pochopitelně, abychom to dotáhli k nějakému pěknému vzdáleně (internetově) řízenému experimentu.
4. Krokový motor
Další pohybovou jednotkou, která se může natáčet do zvoleného směru je krokový motor. V principu jde o motor s několika cívkami, jejichž zapínáním dochází k postupnému natáčení rotoru o předem definovaný úhel. Teoreticky bychom tedy mohli připojit jednotlivá vinutí motoru k pinům modulu Arduino a řízením stavů HIGH a LOW je zapínat v požadovaných sekvencích. To ovšem nejde! Problém spočívá v relativně velkém proudovém odběru jednotlivých vinutí krokového motoru. Zatímco proudové zatížení jednotlivých pinů modulu Arduino či Multi-function Shield nám stačilo na rozsvěcení LED, natáčení serva… atd., nyní prostě nestačí. Na piny modulu tedy musíme připojit buď řídicí tranzistory, nebo lépe rovnou obvod pro takové účely navržený. Takovým obvodem může být kupříkladu integrovaný obvod ULN2003 (ale lze nalézt i jiné).
4.1. Krokový motor 28BYJ-48 s obvodem ULN2003
Pro naše „krokové“ hrátky je možné pro modul Arduino zakoupit krokový motor 28BYJ-48 společně s obvodem ULN2003 na malém tištěném spoji. Řídící obvod je doplněn konektorem pro připojení napájecího napětí (pro obvod i krokový motor) a čtveřicí vstupních pinů pro zapnutí jednotlivých vinutí motoru. Zapnutí dané cívky motoru je na plošném spoji signalizováno čtveřicí LED.
Připojení k modulu Multi-function Shield je poměrně jednoduché – opět využijeme univerzální konektor (vpravo dole), kde ve třetím sloupci jsou přístupné piny (shora dolů): 5, 6, 9 a A5. Jednotlivá vinutí 1-4 zapojíme a piny 5, 6, 9 a A5 – viz obr. 10.
Ke krokovému motoru však ještě musíme připojit napájení. Buď bychom mohli +5 V a GND získat z patice konektoru 7, ale pevnější připojení nám poskytne konektor pro Buetooth a jiné moduly (v našem popisu označen č. 1).
Kód:
#define A 5 // nastaveni pro krokovy motor
#define B 6
#define C 9
#define D A5
void setup()
{
pinMode(A,OUTPUT); // nastaveni vystupu pro civky
pinMode(B,OUTPUT);
pinMode(C,OUTPUT);
pinMode(D,OUTPUT);
}
void Phase_A()
{
digitalWrite(A,HIGH); // A1 civky pro krok
digitalWrite(B,LOW);
digitalWrite(C,LOW);
digitalWrite(D,LOW);
}
void Phase_B()
{
digitalWrite(A,LOW);
digitalWrite(B,HIGH); // B1 civky pro krok
digitalWrite(C,LOW);
digitalWrite(D,LOW);
}
void Phase_C()
{
digitalWrite(A,LOW);
digitalWrite(B,LOW);
digitalWrite(C,HIGH); // C1 civky pro krok
digitalWrite(D,LOW);
}
void Phase_D()
{
digitalWrite(A,LOW);
digitalWrite(B,LOW);
digitalWrite(C,LOW);
digitalWrite(D,HIGH); // D1 civky pro krok
}
void loop()
{
Phase_A(); // postupne otaceni
delay(10);
Phase_B();
delay(10);
Phase_C();
delay(10);
Phase_D();
delay(10);
}
Popis:
Na začátku si nastavíme piny 5, 6, 9 a A5 (direktivou #define
si je v kódu označíme jako A, B, C a D), jako výstupní. Všimněte si, že pin A5 – jakožto člen „rodiny“ pinů A, které jsme zatím používaly jako vstupní (načítání trimru, test tlačítek…), je nyní možno nastavit i jako výstupní – to je právě to kouzlo univerzálnosti modulu Arduino!
Procedury PhaseA-D
nastavují jednotlivé konfigurace cívek krokového motoru (první, druhou, třetí, čtvrtou cívku). Při každé zadané konfiguraci se rotor motoru otočí o jeden krok.
Sekce loop
je pak velmi jednoduchá – neustále a cyklicky se zde opakují jednotlivé kroky. Protože každý krokový motor má určitou maximální frekvenci otáčení, je rychlost otáčení upravena pomocí doby čekání 10 ms mezi jednotlivými kroky.
5. Další čidla
Je asi jasné, že se zde nedá uvádět veškeré možné použití multifunkčního modulu Funduino (Multi-function Shield). Určitě bych se zde rád zmínit o doplnění modulu Arduino o možnost (skutečného) analogového výstupu, který dle mého názoru modulu chybí. Ale tomu si někdy jindy dovolím věnovat samostatný článek.
Podíváme se tedy ještě na jednu věc, kterou nalezneme na multifunkčním modulu a zatím jsme si o ní moc neřekli.
5.1. Bluetooth modul i to další…
Asi Vás napadá, že jsme se zabývali vším možným, ale zatím jsme se (až na jednu výjimku) nezmínili o možnosti připojení nějaké „periférie“ ke konektoru, který v našem popisu označujeme číslem 1. Obecně je tento konektor (dle popisu) koncipován pro připojení modulu Bluetooth a nebo modulu Voice Recognition. Konektor obsahuje kromě napájecích pinů, které jsme využili pro napájení krokového motoru, i dva piny (pin 0 a pin 1) komunikační – RxD a TxD. Je to vlastně takový univerzální sériový port pro připojování různých komunikačních modulů. Tento konektor má následující rozložení pinů – viz obr. 11.
Osobně s tímto konektorem a především moduly pro něj určenými nemám moc osobních zkušeností, protože jsem je pro vývoj svých aplikací zatím nepotřeboval. Až doposud jsem věřil, že vývojář, který bude chtít tyto moduly použít, najde na internetu spoustu inspirace – včetně potřebných knihoven, který vývoj výrazně zjednoduší.
Když se podíváte na následující obrázek č. 12 hned s několika různými moduly určenými pro tento konektor, tak to vypadá, že je stačí jen zasunout do konektoru.
Problém nastane, když se na tyto moduly podíváme podrobněji. Respektive, podíváme se na rozložení jejich pinů v porovnání s piny konektoru na multifunkčním shieldu. Dle mého názoru jsou piny zpřeházené!!! Výše uvedené fotografie na obr. 12 sice ukazují moduly zasunuté, ale nejsem si jist, že by i po zapnutí napájení modulu Arduino, ještě fungovaly.
5.1.1. Bluetooth modul JY-MCU
Výše popsaný problém si ukážeme si to na modulu Bluetooth JY-MCU. Jedná se o modul Bluetooth, který k modulu Arduino připojuje řada vývojářů. Na internetu můžete najít několik (vesměs stejných) zapojení, jak pomocí svého mobilního telefonu rozsvěcet LED připojenou k modulu Arduino.
Multi-function Shield
Ale jak ho připojit k multifunkčnímu shieldu?
Podíváme se na rozložení pinů (viz obr. č. 13) RxD, TxD, GND, VCC (+5 V). A nyní konektor multifukčního shieldu (viz obr. 11), do kterého by se měl modul zasunout (čteno shora): NC4), NC, pin 0, pin 1, NC, +5 V, GND. Už na první pohled je vidět, že pokud zasuneme do konektoru modul tak, aby si odpovídalo napájecí napětí, tak piny RxD a TxD se na piny 0 a 1 nikdy nedostanou. Podobně je to i s jinými moduly, nejen s tímto Bluetooth.
4) NC – nezapojeno
Jediné řešení, jak modul k shieldu zapojit, je pomocí propojovacích kablíků – stejně jako, když jej připojujete rovnou k modulu Arduino. Obrázek č. 13 tento způsob demonstruje. V levé části je zapojení na straně multifukčního shieldu a v pravé části zapojení na straně Bluetooth modulu. Všimněte si pořadí barev vodičů, které si odpovídají.
Jak už jsem zmínil, nemám s užitím modulů připojených k tomuto konektoru příliš praktických zkušeností, ale samotné rozmístění pinů na modulech a na shieldu pro mě hovoří jasně. Takže v tomto směru doporučuji nejvyšší opatrnost!!! Moduly do konektoru shieldu půjdou mechanicky zastrčit, ale z hlediska elektronického zapojení to něco „odnese“ S největší pravděpodobností rozšiřující modul, možná modul Aduino. Naopak s největší pravděpodobností ten, kdo to přežije, bude modul Multi-function Shield, který to kuriózně celé zaviní.
Pokud ale budete rozšiřující moduly (Bluetooth modul, modul Voice Recognition, senzor vlhkosti komunikující po sériové lince…) připojovat pomocí vodičů ke správným pinům, může Vám multifunkční shield Funduino posloužit stejně dobře jako ve všech předchozích případech.
Závěr
Ukázali jsme si příklady připojení některých základních „periférií“ k modulu Arduino přes Multi-function Shield (Funduino). Někdy příště se ještě zaměříme na možnost rozšíření modulu Arduino o čistě analogový výstup pomocí připojeného D/A převodníku, ale to již nemá nic společného s multifunkčním shieldem, na který jsme se nyní zaměřili.
Jak bylo již uvedeno v úvodu, v případě připojování „periférií“ k modulu Funduino nepřináší tento modul nic moc nového – téměř vše, co bylo zde uvedeno, bylo by možné realizovat přímo na modulu Arduino i bez daného shieldu. Určitým přínosem multifunkčního shieldu je připravenost konektorů a v případě čidla DS18B20 zkratovací spojka pro připojení rezistoru mezi datový a napájecí pin.
Pochopitelně Multi-function Shield (Funduino) umožňuje navázat na připojená čidla a kupříkladu přímo zobrazit změřenou teplotu, vzdálenost… apod. na LED zobrazovačích, či přeměnit na zvukový signál bzučáku. Též vstupní tlačítka, či trimr na vstupu A0, si v nějaké aplikaci může ve spojení s některou s výše popsanou „periférií“ využití najít.