Pro netrpělivé je na konci video tohoto projektu v akci - ať víte, co vás čeká.
Náš první projekt bude trochu složitější a bude zahrnovat reakci výstupu na změnu vstupu. Vstupem je typicky nějaký senzor (světelný, tepelný, pohybový apod.), výstupem bude v našem případě pohyb serva. Konkrétní senzor závisí na vás (já jsem si zvolil ultrazvukový měřič vzdálenosti), pokud nemáte vůbec žádný, můžete senzor nahradit otočným či tahovým potenciometrem a vstupy simulovat.
Budeme tedy potřebovat následující (s uvedením možného projce, na konci článku jsou linky na další):
- Arduino - arduino.cz
- Nepájivé kontaktní pole (anglicky breadboard) - Conrad
- Ultrazvukový senzor Maxbotix LV-EZ1 - Sparkfun
- 100 uF kondenzátor - Conrad
- Standardní modelářské servo - Peckamodel
- Pár propovacích drátků - Conrad
- Pájku pro připájení konektorů k senzoru, není nutné při použití senzoru či potenciometru s hotovými konektory
- Externí zdroj, pokud chcete provozovat projekt nepřipojený k PC
Cílem našeho projektu je postavit číselník (rozsah 90 stupňů, čtvrt kruhu), kde ručička (řízená servem) bude ukazovat vzdálenost předmětu (naměřenou senzorem) od číselníku.
K ovládání standardního serva nám plně postačí dodávaná Arduino knihovna Servo. Naším hlavní výzvou bude v tomto případě načtení údajů z ultrazvukové senzoru. Na stránkách výrobce tedy dohledáme datasheet. Najdeme tam technické parametry senzoru, operační napětí a odběr, konfiguraci pinů apod. Zjistíme, že náš senzor umí předávat informace třemi různými způsoby:
- Sériovou komunikací
- Analogový výstup s proměnným napětím
- PWM výstup
PWM výstup Arduino není schopné pořádně zpracovat a seriovou linku si necháme volnou pro kumikaci s PC při debuggování. Zvolíme si tedy načítání hodnot z analogového výstupu. Datasheet prozradí, že na každý naměřený palec stoupne napětí o 1/512 vstupního napětí senzoru. Arduino má 10bitovou rozlišovací schopnost na vstupu, rozezná tedy 1/1024 napětí (Senzor je napájen z Arduina, nezáleží tedy na konkrétním napětí, je shodné v obou přístrojích).
Každý palec (cca 2,5cm) naměřené vzdálenosti k překážce zvýší hodnotu analogového vstupu (bezjednotková veličina) o 2. Senzor vidí až 6,5 metrů daleko, nám bude stačit měřit do 1,5 metru (cca 60 palců). Senzor také vše bližší 5 palců určí jako 5 palců. Budeme tedy mapovat přicházející hodnoty 10 - 120 na 90 stupňů našeho číselníku.
Před samotným programem můžeme rychle připojit senzor a prohlédnout si naměřené hodnoty pomocí seriové komunikace. Testovací schéma:
Náš testovací program bude vypadat takto:
void setup()
{
Serial.begin(9600); // start seriove komunikace
}
void loop()
{
int distance = analogRead(0); // nacteme hodnotu senzoru (pin0)
Serial.println(distance); // hodnoty posleme po seriove lince
delay(50); // mala pauza
}
|
Arduino IDE má zabudovaný jednoduchý terminál seriové komunikace, kterým si můžeme posílané hodnoty prohlédnout. Pokud vše vypadá v pořádku, můžeme pokračovat. Přidáme odkaz na Servo knihovnu (není nutné psát ručně, Arduino IDE stačí ukázat knihovnu a instrukci vloží sám) a upravíme program aby reagoval na naměřené hodnoty pohybem serva.
Servo připojíme velmi jednoduše. Přívodní kabel serva má tři žíly - černou, červenou a žlutou. Červená a černá je napájení (+5V) a zem (GND). Žlutým kabelem je servo řízeno (pomocí PWM), připojíme ho na jeden z PWM výstupů - například pin9. Detaily řízení serva pro nás nejsou důležité, obstará ho knihovna. Nás zajímá její API a hlavně pak metoda servo.write(positionInDegrees), která nastaví žádanou pozici serva.
Po připojení rychle zjistíme, že metoda loop() cykluje velmi rychle a pohyb serva je tudíž trochu "panický". Zvolíme tedy vhodnou dobu zpoždění na každý cyklus naměř-nastav, v mém případě bylo vhodných 200ms. Je také vhodné přidat mezi +5V a GND pin senzoru uvedený 100uF kondenzátor, který odstraní špičky a jiné kolísání vstupního napětí, čímž vyhladí a zpřesní měření.
Náš finální program tedy bude vypadat takto:
#include <Servo.h> // knihovna pro ovladani serv
Servo servo; // deklarace objektu servo
void setup()
{
Serial.begin(9600); // start seriove komunikace
servo.attach(9); // servo na pinu 9
}
void loop()
{
// na nas kvadrant (90 stupnu) se ma vejit cca 1,5 metru (60 palcu)
// senzor vse bliz nez cca 5 palcu urci jako 5 palcu
// tedy hodnoty 10-120 mapujeme na 0-90 stupnu
int minDistance = 10;
int maxDistance = 120;
int spread = maxDistance - minDistance;
int kvadrant = 90;
int distance = analogRead(0); // nacteme hodnotu senzoru
// urcime pozici serva
int position = (float)kvadrant / (float)spread * (float)distance;
// limity kvadrantu (90 stupnu)
position = min(position, 90);
position = max(position, 0);
// nastavime pozici serva
servo.write(position);
// hodnoty posleme po seriove lince
Serial.print(distance);
Serial.print(":");
Serial.println(position);
// pockame 1/5 sekundy do dalsiho mereni
// rucicka bude mene skakat
delay(200);
}
|
Zapojení schematicky:
Veškerá propojení realizujeme pomocí drátových propojek a nepájivého kontaktního pole, takže nás nečeká žádné pájení a zdlouhavé testování. Pokud vše funguje jak má, můžeme si připravit pozadí číselníku (např. z kartonu). Ručičku protáhneme středem, zezadu servo přilepíme, uděláme otvor pro senzor a připevníme. Ještě jednou zkontrolujeme všechna propojení a spustíme. V evýsledku to může vypadat nějak takhle (přední a zadní pohled):
A na závěr jedno video našeho projektu v akci:
Pár odkazů na prodejny:
- Conrad (ČR) - skladem není nic, jen na objednávku
- GM Electronic (ČR) - mají kamennou prodejnu, kde je vše skladem, obsluha vám ale neporadí
- Sparfkun Electronics (USA) - špičkový obchod se spoustou zajímavého zboží pro domácího "robotika". Nízké poštovné a od 1.12.2008 se zvedá limit bezcelního dovozu na 150 Euro :)
- Adafruit industries (USA) - množství hotových projektů, jen spájet a zapojit
- Nuelectronics (UK) - prodej Arduino shieldů (jakýchsi nadstaveb rozšiřujících funkcí), např. ethernet, LCD, protyping,...