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ší):

  1. Arduino - arduino.cz
  2. Nepájivé kontaktní pole (anglicky breadboard) - Conrad
  3. Ultrazvukový senzor Maxbotix LV-EZ1 - Sparkfun
  4. 100 uF kondenzátor - Conrad
  5. Standardní modelářské servo - Peckamodel
  6. Pár propovacích drátků - Conrad
  7. Pájku pro připájení konektorů k senzoru, není nutné při použití senzoru či potenciometru s hotovými konektory
  8. Externí zdroj, pokud chcete provozovat projekt nepřipojený k PC

Part list

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:

  1. Sériovou komunikací
  2. Analogový výstup s proměnným napětím
  3. 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:

Test

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:

Final wirin

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):

Front side Back side

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,...