poniedziałek, 6 października 2014

Lekcja Nr 2. Robot omijający przeszkody przy pomocy ultradźwiękowego miernika odległości HC-SR04

Tym razem zajmiemy się projektem, do którego wprowadzimy platformę robota Magician Chasis oraz czujnik odległości. Na bazie tej platformy zbudujemy kilka wersji robota: z czujnikiem odległości, sterowanego pilotem na podczerwień oraz sterowanego poprzez Bluetooth i aplikację na telefon komórkowy.
Jeżeli nigdy dotąd nie miałeś styczności z ideą Arduino, to odsyłam na oficjalną stronę Arduino.cc, gdzie w dziale Getting Started with Arduino on Windows dowiesz się, krok po kroku, od czego zacząć. Również w języku ojczystym jest wiele stron, na których znajdziesz pomoc, jak np. w tym miejscu: http://majsterkowo.pl/od-czego-zaczac-zabawe-z-arduino/.
Będziesz też potrzebował bibliotekę dla Adafruit Motor Shield, pomoc znajdziesz na stronie producenta Adafruit, a samą bibliotekę tutaj >>.
W Internecie można znaleźć mnóstwo opisów podobnego robota, ale kiedy przychodziło co do czego, to efekt nie spełniał moich oczekiwań. Moim celem był jak najbardziej prosty sketch, zrozumiały nawet dla takiego laika, jak ja sam. Metodą prób i błędów doszedłem w końcu do rozwiązania, które prezentuję poniżej. 

PODZESPOŁY.

1. Magician Chassis - Platforma dla robota
2. Arduino Uno R3 (compatibile) 
3. Arduino Motor Shield L293D 
4. Pojemnik na jedną baterię 6F22 (9V) z wyłącznikiem
5. Ultradźwiękowy miernik odległości HC-SR04
6. Listwa żeńska 1x10 pin 10.5 mm 
7. Listwa żeńska 1x8 pin 10.5 mm (2 szt.) 
8. Przewody czarne 10 szt. ARE 0009
9. Listwa kołkowa 1x40 pin kątowa symetryczna

Celem, jaki sobie postawiłem, była budowa robota omijającego przeszkody przy pomocy sonaru HC-SR04. Poniżej rzut:
















Ażeby móc sterować dwoma silnikami DC potrzebny jest kontroler silników. Tu również mamy do wyboru różne rozwiązania, od podstawowych (mostek H L293D), poprzez moduły, aż do tzw. Shieldów czyli rozszerzeń, które wpina się bezpośrednio w płytkę Arduino Uno R3. Ja skorzystałem z ARDUINO MOTOR SHIELD L293D DO SILNIKÓW KROKOWYCH I DC. Powodów jest kilka, jest tani (cena ok. 30.00 PLN, dostępny w www.electropark.pl), obsługuje aż 4 silniki DC (lub 2 silniki krokowe) oraz dwa serwomechanizmy:
















W Adafruit Motor Shield ze względu na ilość obsługiwanych silników DC (4 szt. lub 2 silników krokowych) oraz dwóch serwomechanizmów, które zajmują wszystkie piny cyfrowe (poza 2 i 13), nie przewidziano "przelotek". Wiedząc, że w kolejnych projektach będę używał tego rozwiązania, dokupiłem jeszcze ScrewShield x2 - złącza śrubowe dla Arduino:

















W kolejnych projektach z pewnością się przyda.
Do całości potrzebujemy jeszcze ultradźwiękowego czujnika odległości HC-SR04.















Budowę robota zaczynamy od zmontowania platformy dla robota (poz. 1). Razem z zestawem otrzymujemy dokładną instrukcję "step by step", tak więc nie powinno to stanowić dla nas większego problemu.

Następnym krokiem jest przymocowanie płytki Arduino Uno R3 (poz. 2) do naszego podwozia, przy pomocy słupków dystansowych (poz. 10 w instrukcji - L10 spacer 4PCS), które znajdziemy w zestawie montażowym podwozia. Na zdjęciu widać koszyczek na cztery baterie 1.5 V, ale osobiście polecam taki, jak w wykazie czyli 9V, ważne żeby miał wyłącznik (poz. 4).























W omawianym przeze mnie przykładzie posłużyłem się rozwiązaniem "tańszym", ale niekoniecznie praktycznym, wykorzystałem listwy żeńskie (goldpin poz. 7 i 8) oraz listwą kołkową symetryczną (poz. 9 spisu na wstępie). Do obsługi sonara HC-SR04 potrzebujemy, poza trzema pinami wpiętymi do Servo 2 AdaFruit Motor Shield, jeszcze jeden dodatkowy pin Echo (A1) i dlatego zmuszeni jesteśmy pomóc sobie w pokazany poniżej sposób.
No, chyba że potrafisz lutować, na tę okoliczność producent przewidział miejsca, gdzie możesz wlutować Pin 2 oraz Piny od A0 do A5. Do tak przygotowanej płytki Arduino dodajemy Adafruit Motor Shield. Na fotografii poniżej znajdziesz dokładny sposób, jak podłączyć silniki (M2 i M3) do terminalblocków, oraz przewody sonara (Trigger, + i - ) do Servo2, przewód Echo łączymy z pinem wyprowadzonym wcześniej na płytce Arduino Uno R3 (Pin A1).
Uwaga: silniki mają dwa przewody: czarny (GND) i czerwony (V+), w naszym przypadku kolor czerwony skierowany jest w kierunku przodu robota.


























Opis pinów w Arduino Motor Shield:
MOTORLATCH 12
MOTORCLK 4
MOTORENABLE 7
MOTORDATA 8

MOTOR1_A 2
MOTOR1_B 3
MOTOR1_PWM 11

MOTOR2_A 1
MOTOR2_B 4
MOTOR2_PWM 3

MOTOR3_A 5
MOTOR3_B 7
MOTOR3_PWM 6

MOTOR4_A 0
MOTOR4B_ 6
MOTOR4_PWM 5

SERVO1_PWM 10
SERVO2_PWM 9
























I to właściwie już wszystko. Oczywiście pozostało jeszcze wgrać nasz sketch/program. Poniżej - pomiędzy liniami - sketch:

--------------------------------------------------------------------------------------------------------------------------
/*W sketchu wykorzystałem Demo Code ze strony:
http://www.electrodragon.com/w/index.php?title=HC-SR04_Ultrasonic_sensor
*/

#include <AFMotor.h>

AF_DCMotor motor1(3); //M3 - motor lewy
AF_DCMotor motor2(2); //M2 - motor prawy

#define echoPin A1 // Echo Pin = Analog Pin A1
#define trigPin 9 // Trigger Pin = Digital Pin 9 - Servo 2
#define LEDPin 13 // Onboard LED

long duration; // Duration used to calculate distance
long HR_dist=0; // Calculated Distance
int minimumRange=5; //Minimum Sonar range
int maximumRange=200; //Maximum Sonar Range


void setup() {

Serial.begin (9600);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(LEDPin, OUTPUT); // Use LED indicator (if required)

motor1.setSpeed(250);//prędkość silnika lewego
motor1.run(FORWARD);//silnik lewy domyślnie do przodu
motor2.setSpeed(255);//prędkość silnika prawego
motor2.run(FORWARD);//silnik prawy domyślnie do przodu

}

void loop() {

motor1.run(FORWARD); //silnik lewy M3 do przodu
motor2.run(FORWARD);//silnik prawy M2 do przodu
getDistance();
void getDistance(){ 

digitalWrite(trigPin, LOW); 
delayMicroseconds(2); 
digitalWrite(trigPin, HIGH);
delayMicroseconds(10); 
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH); 
HR_dist = duration/58.2;

if (HR_dist >= maximumRange || HR_dist <= minimumRange){

Serial.println("0");
digitalWrite(LEDPin, HIGH); 

} else {

Serial.println(HR_dist);
digitalWrite(LEDPin, LOW);


if (HR_dist <=30 ){//jeżeli robot jest w odległości od przeszkody <=30

motor1.run(RELEASE);//silnik lewy bieg jałowy
motor2.run(RELEASE);//silnik prawy bieg jałowy
delay (500);//przez pół sekundy

motor1.run(BACKWARD);//silnik lewy do tyłu
motor2.run(BACKWARD);//silnik prawy do tyłu
delay (700);//przez 0,7 sekundy

motor1.run(RELEASE);// silnik lewy bieg jałowy
motor2.run(RELEASE);// silnik prawy bieg jałowy
delay(500); //przez pół sekundy

motor1.run(FORWARD);//silnik lewy do przodu |robot skręca w prawo
motor2.run(RELEASE);//silnik prawy bieg jałowy |
delay (500);//przez pół sekundy 

}

}

}
--------------------------------------------------------------------
I gotowy robocik:






















Na bazie tego robota opiszę, jak zbudować robot sterowany pilotem na podczerwień.
UWAGA: jeżeli robot wykonuje różne dziwne ruchy, to nie wiń mnie, tylko dociśnij AFM (Adafruit Motor Shield) i listwy żeńskie do płytki Arduino. Niestety zdarza się, że ze względu na niski koszt produkcji, listwy nie łącza w sposób trwały naszych podzespołów. 

Lekcja Nr 1. Diody LED włączane pilotem.

Zamiast wstępu. To jest mój pierwszy projekt, w którym wykorzystałem nabyte umiejętności dot. platformy Arduino. W tym roku, mój wnuk, rozpoczął naukę w renomowanym liceum ogólnokształcącym i pomyślałem sobie, że byłoby dobrze, gdyby pokierować jego zainteresowaniami w kierunku robotyki i mikro kontrolerów. W międzyczasie sam połknąłem bakcyla Arduino, i stąd ten Blog. Kieruję go zatem do dziadków i ojców, którzy chcą zaszczepić w młodzieży samodzielne myślenie, kreatywność i poszerzyć ich wiedzę o tematy nieporuszane w szkole. ARDUINO ŁĄCZY POKOLENIA!

Temat: diody LED włączane pilotem. Diody LED włączane odpowiednio przyciskami na pilocie 1, 2, 3 , 4 i 5.
Ta lekcja ma przygotować do zbudowania robota sterowanego pilotem. Podzespoły wykorzystane w tym projekcie znajdą swoje zastosowanie w kolejnych projektach.

Materiały:
1. Arduino Uno R3 (lub zamiennik)
2. Diody LED 5 mm, 5 szt. (mogą być różne kolory)
3. Pilot 














4. Moduł Odbiornika podczerwieni IR VS1838B














5. Koszyczek i 4 baterie 1.5 V (najlepiej z wtykiem DC 5.5/2.1)

Przed uruchomieniem sketcha należy skopiować bibliotekę IRemotes, którą można pobrać w tym miejscu:
IRemote - https://github.com/shirriff/Arduino-IRremote

Rozpakowany plik należy skopiować do: Katalog - Arduino > libraries > katalog powinien mieć nazwę IRemotes.

Poniższy sketch należy skopiować razem z katalogiem o tej samej nazwie do np.: Pulpit > Documents > Arduino > nasz katalog pt.: "Sterowanie_diodami_LED_pilotem_na_podczerwien". Po otwarciu Arduino IDE sketch pojawi się w zakładce Plik > Szkicownik. Reszta tak, jak na załączonej grafice.
Schemat połączeń Arduino i płytki stykowej.






















Sketch: Sterowanie_diodami_LED_na_podczerwien (skopiować tekst pomiędzy liniami poziomymi i wkleić w czysty nowy projekt Arduino>Plik>Nowy).
-----------------------------------------------------------------------------------------------------------------
/*
* IRremote: IRrecvDemo - demonstrates receiving IR codes with IRrecv
* An IR detector/demodulator must be connected to the input RECV_PIN.
* Version 0.1 July, 2009
* Copyright 2009 Ken Shirriff
* http://arcfn.com
*/


#include <IRremote.h>

int RECV_PIN = 11;
IRrecv irrecv(RECV_PIN);
decode_results results;


void setup()

{

Serial.begin(9600);
irrecv.enableIRIn(); // Start the receiver
pinMode(2, OUTPUT);

pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);

}

int i1 = 0;
int i2 = 0;
int i3 = 0;
int i4 = 0;
int i5 = 0;


void loop() {

if (irrecv.decode(&results)) {
Serial.println(results.value, HEX);
Serial.println(results.value);
irrecv.resume(); // Receive the next value


//button 1
if(i1 == 0 && results.value == 16724175)

{

digitalWrite(6, HIGH);
i1 = 1;

}

else if(i1 == 1 && results.value == 16724175)

{

digitalWrite(6, LOW);
i1 = 0;

}

//button 2
else if(i2 == 0 && results.value == 16718055)

{

digitalWrite(5, HIGH);
i2 = 1;

}

else if(i2 == 1 && results.value == 16718055)

{

digitalWrite(5, LOW);
i2 = 0;

}

//button 3
else if(i3 == 0 && results.value == 16743045)

{

digitalWrite(4, HIGH);
i3 = 1;

}

else if(i3 == 1 && results.value == 16743045)

{

digitalWrite(4, LOW);
i3 = 0;

}

//button 4
else if(i4 == 0 && results.value == 16716015)

{

digitalWrite(3, HIGH);
i4 = 1;

}

else if(i4 == 1 && results.value == 16716015)

{

digitalWrite(3, LOW);
i4 = 0;

}

//button 5
else if(i5 == 0 && results.value == 16726215)

{

digitalWrite(2, HIGH);
i5 = 1;

}

else if(i5 == 1 && results.value == 16726215)

{

digitalWrite(2, LOW);
i5 = 0;

}

}

}

------------------------------------------------------------------------------------------------------
A oto efekt:

I to by było na tyle. Życzę udanego eksperymentowania.