Close

Arduino robot RedBot #7: Nárazníky

Arduino robot RedBot

V dnešním článku se podíváme, jak může robot používat nárazníky. Ty ve skutečnosti nejsou nic jiného, než dva dráty, které vycházejí na obě strany na přední straně robota. Vypadají a fungují velice podobně, jako fousky koček – pokud robot najede na nějakou překážku, ta ohne drát, čímž se sepne obvod jako u vypínače a robot tak detekuje překážku.

Nárazníky jsou součástí kitu SparkFun Inventor’s Kit for RedBot. Ve standardní sadě SparkFun Inventor’s Kit for RedBot je bohužel nenajdete.

K tomu, abychom mohli na nárazy do překážek reagovat, musíme se naučit v programu říci „když se stane toto, udělej toto“. K tomu v programovacích jazycích slouží takzvané „podmínky“. Díky nim můžeme robota naučit zajímavé kousky. S podmínkami jsme se již setkali, ale nevěnovali jsme jim moc pozornosti. Nejjednodušší z nich je podmínka if().

Podívejme se teď na příklad, který naleznete v RedBot příkladech: File > Examples > SparkFun RedBot Library > Exp5_Bumpers. Tento kód nahrajeme do RedBota.

/***********************************************************************
 * Exp5_Bumpers -- RedBot Experiment 5
 * 
 * Now let's experiment with the whisker bumpers. These super-simple switches
 * let you detect a collision before it really happens- the whisker will
 * bump something before your robot crashes into it.
 * 
 * This sketch was written by SparkFun Electronics, with lots of help from 
 * the Arduino community.
 * This code is completely free for any use.
 * Visit  
 * for SIK information.
 * 
 * 8 Oct 2013 M. Hord
 * Revised 30 Oct 2014 B. Huang
 ***********************************************************************/

#include <RedBot.h>
RedBotMotors motors;

RedBotBumper lBumper = RedBotBumper(3);  // initialzes bumper object on pin 3
RedBotBumper rBumper = RedBotBumper(11); // initialzes bumper object on pin 11

int buttonPin = 12; // variable to store the button Pin 

int lBumperState;  // state variable to store the bumper value
int rBumperState;  // state variable to store the bumper value

void setup()
{
  // nothing here.
}

void loop()
{
  motors.drive(255);
  lBumperState = lBumper.read();  // default INPUT state is HIGH, it is LOW when bumped
  rBumperState = rBumper.read();  // default INPUT state is HIGH, it is LOW when bumped

    if (lBumperState == LOW) // left side is bumped/
  { 
    reverse();    // backs up
    turnRight();  // turns
  }

  if (rBumperState == LOW) // right side is bumped/
  { 
    reverse();   // backs up
    turnLeft();  // turns
  }

}

// reverse() function -- backs up at full power
void reverse()
{
  motors.drive(-255);
  delay(500);
  motors.brake();
  delay(100);  // short delay to let robot fully stop
}

// turnRight() function -- turns RedBot to the Right
void turnRight()
{
  motors.leftMotor(-150);  // spin CCW
  motors.rightMotor(-150); // spin CCW
  delay(500);
  motors.brake();
  delay(100);  // short delay to let robot fully stop
}

// turnRight() function -- turns RedBot to the Left
void turnLeft()
{
  motors.leftMotor(+150);  // spin CW
  motors.rightMotor(+150); // spin CW
  delay(500);
  motors.brake();
  delay(100);  // short delay to let robot fully stop
}

Co by se mělo stát

Po spuštění programu by se měl robot začít pohybovat dopředu, dokud jeden z nárazníků nenarazí na překážku. Pokud jako první narazí levá strana, měl by robot popojet dozadu a otočit se doprava. Pokud poprvé narazí pravá strana, robot couvne a otočí se doleva.

Můžete upravit časování ve funkcích reverse()turnRight()turnLeft(), abyste dosáhli požadovaného posunu dozadu a otočení o 90° po každém nárazu.

Důležité části kódu

Nad funkcí setup() jsme si vytvořili dva objekty nárazníků pomocí třídy RedBotBumper. Konstruktor potřebuje jeden parametr, a to pin, na kterém je nárazník připojen.

RedBotBumper lBumper = RedBotBumper(3);  // initialzes bumper object on pin 3
RedBotBumper rBumper = RedBotBumper(11); // initialzes bumper object on pin 11

Konstruktor RedBotBumper() automaticky nastaví vybrané piny jako vstupy s interním pull-up rezistorem. To mimo jiné znamená, že pokud je nárazník neaktivní, je výchozí stav vstupu HIGH. Více o vstupech s interním pull-up rezistorem si můžete přečíst ve článku Funkce input-pullup.

Stav nárazníku je možné získat pomocí metod lBumper.read() rBumper.read(). Když dojde k nárazu do nárazníku, dotkne se drát šroubu připojeného ke GND, což způsobí změnu hodnoty na LOW. V příkladu je také vidět použití proměnných, které uchovávají stav jednotlivých nárazníků.

lBumperState = lBumper.read();  // default INPUT state is HIGH, it is LOW when bumped
rBumperState = rBumper.read();  // default INPUT state is HIGH, it is LOW when bumped

Naučte se více – podmínky

Chcete se dozvědět více o logice v podmínkách? Jedna z věcí, které vám při programování pro Arduino robota RedBot přijdou vhod, je tvorba složitých podmínek, založených na různých vstupech a senzorech.

Logické hodnoty

Jsou možné jenom dvě logické hodnoty – true (pravda) a false (nepravda). Všechny logické výrazy i operace jsou vyhodnoceny buď jako true, nebo jako false. Pokud podmínka if() dostane hodnotu true, provede se, pokud ne, neprovede se. Tedy úplně nejjednodušší podmínky jsou:

if(true){
    //...    
}
if(false){
    //...    
}

To ale většinou v praxi nevyužijeme a budeme chtít trochu komplexnější chování. K tomu slouží právě logické výrazy.

Logické výrazy

Podmínky se v programovacích jazycích tvoří pomocí tzv. logických výrazů. Ty mohou obsahovat logické operace a také porovnání. Logické výrazy mohou být seskupeny pomocí závorek – například (A == B). Logické operace a operace porovnání jsou:

Symbol Co operátor zkoumá Výsledná logická hodnota
A == B Je a rovno b? true, pokud jsou A a B stejné, jinak false
A != B Je a různé od b? true, pokud jsou A a B různé, jinak false
A > B Je a větší než b? true, pokud je A větší než B, jinak false
A < B Je a menší než b? true, pokud je A menší než B, jinak false
A >= B Je a větší nebo rovno b? true, pokud je A větší nebo rovno B, jinak false
A <= B Je a menší nebo rovno b? true, pokud je A menší nebo rovno B, jinak false
if(A == B){ //... }
if(A != B){ //... }
if(A > B){ //... }
if(A < B){ //... }
if(A >= B){ //... }
if(A <= B){ //... }

Logické operace

Pomocí logických operací můžeme skládat dohromady logické výrazy a dosáhnout tak i velice komplexního chování. Můžeme tak například zkoumat platnost i více výrazů najednou a různě je kombinovat.

Symbol Jméno operace Description
X && Y AND – logické a (výraz X) && (výraz Y) je true, pokud X i Y jsou true, jinak false
X || Y OR – logické nebo (výraz X) || (výraz Y) je true, pokud alespoň jeden z výrazů X a Y je true, jinak false
!X NOT – logická negace !(výraz X) je true, pokud je výraz X false, jinak false
X Y X && Y
false false false
false true false
true false false
true true true
X Y X || Y
false false false
false true true
true false true
true true true
X !X
false true
true false

Například tedy můžeme vytvořit složenou podmínku:

if (mod == 1 && (teplota < hodnota || prepis == true)){
    digitalWrite(topeni, HIGH);
}

Tato podmínka spustí topení, pokud je mod rovno 1 a zároveň platí, že je teplota pod určitou hodnotou, nebo je hodnota prepis rovna true.

Další úpravy

Možná jste si všimli, že program neobsahuje možnost, že RedBot narazí oběma „fousky“ současně. Zkuste tuto možnost přidat a zajistěte, že se robot v tomto případě otočí o 180°.

Zbyšek Voda

One Comment on “Arduino robot RedBot #7: Nárazníky

Ondřej Tůma
9.9.2016 at 9:58

Zrovna dnes jsem viděl něco podobného na instructables.com. A říkal jsem si jak pěkné / jednoduché řešení to je. Tedy +1

Napsat komentář