Zdalne sterowanie za pomocą latarki testowane podczas #6 części kursu budowy robotów było bardzo proste, ale miało jednak wiele ograniczeń.
Tym razem zajmiemy się prawdziwą łącznością bezprzewodową! Zamiast światła widzialnego wykorzystamy podczerwień. Robotem będzie można więc sterować za pomocą pilota od TV.
Coraz więcej producentów wyposaża swoje urządzenia w moduły Bluetooth i WiFi. Rozwiązania te mają niewątpliwie wiele zalet, jednak nie zawsze potrzebujemy tak rozbudowanej łączności. Co więcej, korzystanie z bardziej zaawansowanych standardów komunikacji wymaga od nas często skomplikowanych urządzeń nadawczych takich jak telefon/tablet. Nie zawsze jest to wygodne.
Dlatego warto pamiętać o łączności bezprzewodowej, która od lat sprawdza się w telewizorach. Za pomocą odpowiedniego sygnału nadawanego w podczerwieni (IR) możemy komunikować się z różnymi urządzeniami. Jeśli pilot IR sprawdza się przy zmianie kanałów TV, to równie dobrze można go wykorzystywać do sterowania robotów!
Komunikacja z wykorzystaniem podczerwieni może przebiegać na wiele sposób. Zdecydowanie najpopularniejszym standardem wśród hobbystów jest RC5, który został opracowany ponad 30 lat temu przez firmę Philips. Protokół ten został przygotowany głównie z myślą o sprzęcie RTV.
Pilot nadający w standardzie RC5 wysyła wiązkę podczerwieni o częstotliwości 36 kHz. Za każdym razem przesyłane jest 14 bitów danych, które tworzą ramkę danych. Jeśli przycisk na pilocie jest wciśnięty, to ramki danych przesyłane są cały czas (co około 114 ms).
Szczegóły na temat przesyłania danych wykraczają poza podstawy omawiane
w kursie. Zainteresowanych odsyłam do haseł RC5 i kod Manchester.
Ramka danych zbudowana jest z następujących części:
Ramka danych w standardzie RC5
Dwa pierwsze bityoznaczają początek ramki i mają wartość "1" (jest to prawdą dla podstawowej wersji RC5). Trzeci bit nazywany jest po angielsku toggle i niestety ciężko znaleźć dla niego prostą nazwę w języku polskim. Na grafice posłużyliśmy się nazwą bit przełącznikowy, podpatrując ją na Wikipedii... Nazwa nie jest jednak kluczowa. Ważne, aby zapamiętać znaczenie tego bitu!
Bit toggle zmienia swój stan na przeciwny (0/1) po każdym wciśnięciu przycisku. Dzięki temu można wykryć, że na pilocie wciśnięty jest cały czas ten sam przycisk.
Wyjaśnię to później raz jeszcze na praktycznym przykładzie!
Następnie, w ramce danych, znajdziemy 5 bitów adresowych. Na ich podstawie odbiorniki mogą rozpoznawać, czy dane są wysyłane właśnie do nich. W praktyce pozwala to na korzystanie z kilku pilotów jednocześnie (np.: do telewizora i do DVD), bez wzajemnego zakłócania komunikacji.
Ostatnie 6 bitów danych zawiera komendę. Każdy klawisz na pilocie ma przypisany swój numer. Dzięki temu telewizor może rozróżnić komendy np.: "przełącz kanał", "zwiększ głośność" itd. Całość może wydawać się zawiła, jednak wszystko wyjaśni się podczas testów w praktyce!
Gotowe zestawy do kursów Forbota
Komplet elementów Gwarancja pomocy Wysyłka w 24h
Części pozwalające wykonać ćwiczenia z kursu budowy robotów dostępne są w formie gotowych zestawów! W komplecie znajdują się elementy mechaniczne (w tym koła i silniki), baterie oraz shield!
Masz już zestaw? Zarejestruj go wykorzystując dołączony do niego kod. Szczegóły »
Odbiornik i nadajnik podczerwieni
Osoby, które wykonywały zadania z kursu elektroniki (poziom 2), na pewno kojarzą ćwiczenie, podczas którego budowaliśmy tester pilotów TV. Wtedy odbiornikiem IR był układ z rodziny TSOP.
Nie inaczej będzie i tym razem. Na płytce robota znajduje się układ TSOP2236. Dwie ostatnie cyfry w jego nazwie, informują nas o tym, że układ odbiera sygnały nadawane z częstotliwością 36 kHz, czyli taką, która jest wymagana przez standard RC5.
Ważne jest, aby nie zasłaniać w żaden sposób odbiornika (np. przewodami).
Podczas kursu elektroniki budowaliśmy nadajnik IR korzystając z układu NE555. Generował on jednak stały sygnał o zadanej częstotliwości. Tym razem potrzebne jest rozbudowane rozwiązanie, które potrafi przesyłać różne informacje. W zestawie elementów do kursu znajduje się uniwersalny pilot do telewizora. Poniżej widoczne jest przykładowe zdjęcie. Dodawane piloty mogą się różnić np. kształtem i przyciskami, na pewno są one jednak zgodne ze standardem RC5!
Przykład pilota RC5.
Jak sprawdzić, czy pilot działa?
Przed programowaniem warto upewnić się, że pilot działa. Inaczej mówiąc trzeba sprawdzić czy dioda IR świeci po wciśnięciu przycisku. Oczywiście nie zobaczymy podczerwieni gołym okiem. Wystarczy jednak spojrzeć na pilot przez aparat cyfrowy (kamera w laptopie, aparat w telefonie).
Podgląd podczerwieni w praktyce.
Jeśli pilot działa poprawnie, to na zdjęciach wykonanych aparatem cyfrowym będzie widoczne, że podczas wciskania przycisku dioda "świeci na fioletowo". Efekt może być oczywiście różny w zależności od pilota i telefonu, test najlepiej przeprowadzić w ciemności.
Instalacja biblioteki RC5
Do dekodowania komend przesyłanych przez pilota wykorzystamy bibliotekę, która nazywa się RC5. Wszystkie pliki znajdują się na GitHubie jej autora, użytkownika guyc. Opis instalacji bibliotek pojawiał się już na Forbocie wielokrotnie, ale dla formalności go powtórzę.
Wchodzimy na stronę biblioteki i klikamy przycisk Clone or Download, a następnie Download ZIP.
Pobieranie biblioteki.
Pobrane archiwum rozpakowujemy. Cały folder przenosimy do katalogu bibliotek, u mnie jest to:
C:\Users\Damian\Documents\Arduino\libraries
Po ponownym uruchomieniu środowiska biblioteka będzie zainstalowana i gotowa do działania.
Koniecznie zainstaluj bibliotekę RC5 zanim przejdziesz dalej!
Pierwszy test RC5
Zaczniemy od prostego wykorzystania biblioteki, aby sprawdzić jej działanie w praktyce. Najpierw podstawowy szkic z informacją na temat biblioteki oraz podłączenia odbiornika IR:
Arduino
1
2
3
4
5
6
7
8
9
10
11
12
#define TSOP_PIN 3
#include <RC5.h>
RC5rc5(TSOP_PIN);//Informacja o podłączeniu odbiornika TSOP
voidsetup(){
Serial.begin(9600);//Start komunikacji przez UART
}
voidloop(){
}
Zgodnie z wcześniejszymi informacjami ramka standardu RC5 przekazuje 3 informacje, więc trzeba stworzyć odpowiednie zmienne. Pierwsza będzie informowała o adresie urządzenia, druga o komendzie, a trzecia o tym, czy przycisk jest cały czas wciśnięty.
Arduino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#define TSOP_PIN 3
#include <RC5.h>
RC5rc5(TSOP_PIN);//Informacja o podłączeniu odbiornika TSOP
//Zmienne dla RC5
byteaddress;
bytecommand;
bytetoggle;
voidsetup(){
Serial.begin(9600);
}
voidloop(){
}
Teraz można przejść do odczytywania komend z pilota. W tym celu skorzystamy z gotowej funkcji rc5.read(). Tutaj pojawia się jednak pewien problem. Zgodnie z informacjami, które były omawiane w kursie podstaw Arduino funkcja może zwrócić jedną wartość (za pomocą return).
Ta funkcja musi jednak zwrócić trzy wartości!
Autor biblioteki rozwiązał ten problem za pomocą wskaźników. Temat ten jest jednak dość zawiły, szczególnie dla początkujących. Dlatego tutaj pokrótce opiszę jedynie jak to działa, ale nie będę zagłębiał się w szczegóły programistyczne.
Poprawne wywołanie funkcji rc5.read() wygląda następująco:
Arduino
1
rc5.read(&toggle,&address,&command)
Jako parametry funkcji podajemy trzy wcześniej zadeklarowane zmienne. Ich nazwy poprzedzone są znakiem & (ampersand), co oznacza, że tak naprawdę jako argumenty podajemy adresy w pamięci Arduino, z których one korzystają. Dzięki temu rc5.read() może "podmienić" zawartość zmiennych i umieścić tam odczytane dane.
Na ten moment nie będę wnikał jak dokładnie się to dzieje. Temat wskaźników
zostawiam do kolejnej serii artykułów Arduino dla zaawansowanych.
Dodatkowo cała funkcja zwraca jeszcze wartość 1 (już tradycyjnie "przez return"), gdy odebrana zostanie komenda. Teraz możemy dodać fragment kodu, który wyświetli odebrane dane:
Arduino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#define TSOP_PIN 3
#include <RC5.h>
RC5rc5(TSOP_PIN);//Informacja o podłączeniu odbiornika TSOP
//Zmienne dla RC5
byteaddress;
bytecommand;
bytetoggle;
voidsetup(){
Serial.begin(9600);
}
voidloop(){
//Jeśli odebrano komendę
if(rc5.read(&toggle, &address, &command))
{
Serial.print("A:");
Serial.print(address);
Serial.print(" K:");
Serial.print(command);
Serial.print(" T:");
Serial.println(toggle);
}
}
Od teraz, po przyciśnięciu przycisku na pilocie, w monitorze portu szeregowego powinny pojawiać się różne informacje. Przypominam, że ramki powtarzane są co około 114 ms, więc nawet krótkie wciśnięcie przycisku może prowadzić do wysłania kilku komend.
Poniższy zrzut ekranu przedstawia dane odebrane przez Arduino po krótkim wciśnięciu przycisku opisanego jako "2". Jak widać układ zdążył odebrać w tym czasie 3 ramki danych.
Wyniki wciśnięcia przycisku 2.
Adres urządzenia, to 0, ponieważ tak przyjęto adresować telewizory, a mój pilot służy właśnie do sterowania TV. W związku z tym adres nigdy nie ulegnie zmianie - zawsze będzie tam 0 (chyba, że zmienimy pilot).
Komenda, to 2, ponieważ wcięliśmy przycisk opisany jako 2. Analogicznie wciśnięcie przycisku 8 spowoduje wysłanie wartości 8. Podobnie będzie dla wszystkich klawiszy od 0 do 9. Pozostałe mają przypisane mniej intuicyjne komendy.
Najlepiej sprawdzić to w praktyce. U mnie np. klawisz do
włączania TV zwraca wartość 12, a przycisk "ciszej" wartość 33.
Toggle, wskazuje wartość 0, ponieważ przycisk wciśnięty był raz. Drugie wciśnięcie przycisku spowoduję zmianę bitu na przeciwny, co widoczne jest poniżej:
Wynik ponownego wciśnięcia przycisku 2.
Jak widać adres i komenda nie uległa zmianie, jedynie bit toggle informuje nas, że przycisk został puszczony i wciśnięty raz jeszcze.
Reasumując, odebranie ciągu takich samych komend z identycznym toggle oznacza, że przycisk był wciśnięty i trzymany. Odebranie takich samych komend z różnymi wartościami toggle, oznacza, że przycisk był wciskany i puszczany wielokrotnie.
Zdalne sterowanie pojazdu
Pora przejść do najciekawszej części, czyli zdalnego sterowania naszym pojazdem. Zacznijmy od szkicu programu, który ma w sobie wszystkie niezbędne informacje:
Arduino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include <RC5.h>
#define L_PWM 5
#define L_DIR 4
#define R_PWM 6
#define R_DIR 9
#define PWM_MAX 165
#define BUZZER 10
#define LED 13
#define TSOP_PIN 3
RC5rc5(TSOP_PIN);//Informacja o podłączeniu odbiornika TSOP
byteaddress;
bytecommand;
bytetoggle;
voidsetup(){
//Konfiguracja pinow od mostka H
pinMode(L_DIR,OUTPUT);
pinMode(R_DIR,OUTPUT);
pinMode(L_PWM,OUTPUT);
pinMode(R_PWM,OUTPUT);
//Konfiguracja pozostalych elementow
pinMode(BUZZER,OUTPUT);
digitalWrite(BUZZER,0);//Wylaczenie buzzera
pinMode(LED,OUTPUT);
digitalWrite(LED,0);//Wylaczenie diody
Serial.begin(9600);
}
voidloop(){
}
voidleftMotor(intV){
if(V>0){//Jesli predkosc jest wieksza od 0 (dodatnia)
V=map(V,0,100,0,PWM_MAX);
digitalWrite(L_DIR,0);//Kierunek: do przodu
analogWrite(L_PWM,V);//Ustawienie predkosci
}else{
V=abs(V);//Funkcja abs() zwroci wartosc V bez znaku
V=map(V,0,100,0,PWM_MAX);
digitalWrite(L_DIR,1);//Kierunek: do tyłu
analogWrite(L_PWM,V);//Ustawienie predkosci
}
}
voidrightMotor(intV){
if(V>0){//Jesli predkosc jest wieksza od 0 (dodatnia)
V=map(V,0,100,0,PWM_MAX);
digitalWrite(R_DIR,0);//Kierunek: do przodu
analogWrite(R_PWM,V);//Ustawienie predkosci
}else{
V=abs(V);//Funkcja abs() zwroci wartosc V bez znaku
V=map(V,0,100,0,PWM_MAX);
digitalWrite(R_DIR,1);//Kierunek: do tyłu
analogWrite(R_PWM,V);//Ustawienie predkosci
}
}
voidstopMotors(){
analogWrite(L_PWM,0);//Wylaczenie silnika lewego
analogWrite(R_PWM,0);//Wylaczenie silnika prawego
}
Teraz w pętli loop() wystarczy sprawdzać, czy odebrano jakąś komendę i jeśli tak, to trzeba wykonać odpowiednie operacje. Przypominam, że zmienna adres w naszym wypadku zawsze będzie miała taką samą wartość, więc nie musimy jej wykorzystywać.
Działanie programu będzie uzależnione od wartości jednej zmiennej, czyli: command.
Tutaj idealnie sprawdzi się instrukcja warunkowa switch!
W ramach rozgrzewki dopiszmy obsługę buzzera, który będzie klaksonem naszego pojazdu. Niech wciśnięcie przycisku od włączania TV (u mnie adres 12) uruchamia na chwilę dźwięk:
Arduino
1
2
3
4
5
6
7
8
9
10
11
voidloop(){
if(rc5.read(&toggle, &address, &command)){
switch(command) {
case 12:
digitalWrite(BUZZER, 1);
delay(500);
digitalWrite(BUZZER,0);
break;
}
}
}
Teraz warto dopisać instrukcje odpowiadające za poruszanie się pojazdu. Najlepiej dopasować je do układu przycisków na pilocie. Podczas testów przyjąłem poniższy układ klawiszy:
2 - jazda do przodu
8 - jazda do tyłu
5 - STOP
4 - obrót w lewo
6 - obrót w prawo
Cały program wyglądał następująco:
Arduino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#include <RC5.h>
#define L_PWM 5
#define L_DIR 4
#define R_PWM 6
#define R_DIR 9
#define PWM_MAX 165
#define BUZZER 10
#define LED 13
#define TSOP_PIN 3
RC5rc5(TSOP_PIN);//Informacja o podłączeniu odbiornika TSOP
byteaddress;
bytecommand;
bytetoggle;
voidsetup(){
//Konfiguracja pinow od mostka H
pinMode(L_DIR,OUTPUT);
pinMode(R_DIR,OUTPUT);
pinMode(L_PWM,OUTPUT);
pinMode(R_PWM,OUTPUT);
//Konfiguracja pozostalych elementow
pinMode(BUZZER,OUTPUT);
digitalWrite(BUZZER,0);//Wylaczenie buzzera
pinMode(LED,OUTPUT);
digitalWrite(LED,0);//Wylaczenie diody
Serial.begin(9600);
}
voidloop(){
if(rc5.read(&toggle, &address, &command)){
switch(command) {
case 2: //Do przodu
leftMotor(40);
rightMotor(40);
break;
case8://Do tyłu
leftMotor(-40);
rightMotor(-40);
break;
case5://STOP
stopMotors();
break;
case4://Obrót w lewo
leftMotor(-30);
rightMotor(30);
break;
case6://Obrót w prawo
leftMotor(30);
rightMotor(-30);
break;
case12:
digitalWrite(BUZZER,1);
delay(500);
digitalWrite(BUZZER,0);
break;
}
}
}
voidleftMotor(intV){
if(V>0){//Jesli predkosc jest wieksza od 0 (dodatnia)
V=map(V,0,100,0,PWM_MAX);
digitalWrite(L_DIR,0);//Kierunek: do przodu
analogWrite(L_PWM,V);//Ustawienie predkosci
}else{
V=abs(V);//Funkcja abs() zwroci wartosc V bez znaku
V=map(V,0,100,0,PWM_MAX);
digitalWrite(L_DIR,1);//Kierunek: do tyłu
analogWrite(L_PWM,V);//Ustawienie predkosci
}
}
voidrightMotor(intV){
if(V>0){//Jesli predkosc jest wieksza od 0 (dodatnia)
V=map(V,0,100,0,PWM_MAX);
digitalWrite(R_DIR,0);//Kierunek: do przodu
analogWrite(R_PWM,V);//Ustawienie predkosci
}else{
V=abs(V);//Funkcja abs() zwroci wartosc V bez znaku
V=map(V,0,100,0,PWM_MAX);
digitalWrite(R_DIR,1);//Kierunek: do tyłu
analogWrite(R_PWM,V);//Ustawienie predkosci
}
}
voidstopMotors(){
analogWrite(L_PWM,0);//Wylaczenie silnika lewego
analogWrite(R_PWM,0);//Wylaczenie silnika prawego
}
Działanie programu w praktyce widoczne jest na poniższym filmie:
Oczywiście w ramach dalszej rozbudowy programu warto wykorzystać pozostałe przyciski i dodać np. funkcje jazdy po łukach:
Rozbudowana wersja klawiatury.
Wykorzystanie bitu toggle
Na zakończenie pokażę jak można wykorzystać w praktyce bit toggle, który sprawia niektórym trudność. Skupię się na jednym przykładzie - przystosowania go do innych akcji robota będzie już łatwe! Moim celem w tym zadaniu jest zmiana prędkości, z jaką pojazd się obraca.
Jednorazowe wciśnięcia przycisku powinny sprawiać, że robot będzie kręcił się ze standardową prędkością (30%). Jednak im dłużej przycisk będzie wciśnięty, tym robot powinien obracać się szybciej.
Zaczynamy od podstawowej zawartości pętli loop(). Jedyne zmiany, to usunięcie fragmentów kodu, które nas teraz nie interesują (jazda w innych kierunkach) oraz dodanie zmiennej, w której trzymana jest prędkość obrotu:
Arduino
1
2
3
4
5
6
7
8
9
10
11
12
intpredkoscObrotu=30;
voidloop(){
if(rc5.read(&toggle, &address, &command)){
switch(command) {
case 4: //Obrót w lewo
leftMotor(-predkoscObrotu);
rightMotor(predkoscObrotu);
break;
}
}
}
Aby wykryć, czy przycisk jest cały czas wciśnięty trzeba porównywać aktualną wartość toggle z tą, którą otrzymaliśmy poprzednio. Można to zrobić za pomocą dodatkowej zmiennej:
Arduino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
intpredkoscObrotu=30;
bytetogglePoprzedni=0;
voidloop(){
if(rc5.read(&toggle, &address, &command)){
switch(command) {
case 4: //Obrót w lewo
leftMotor(-predkoscObrotu);
rightMotor(predkoscObrotu);
break;
}
//Jeśli bit toggle jest taki sam jak poprzednio
if(toggle==togglePoprzedni){
}else{//Jeśli bit toggle jest taki sam jak poprzednio
}
//Zapamiętanie poprzedniej wartości toggle
togglePoprzedni=toggle;
}
}
Pod instrukcją switch dodany został warunek, który porównuje obie zmienne. Aby mógł on działać za każdym razem, gdy odbierzemy komendę, musimy zapamiętać poprzednią wartość toggle.
Teraz wystarczy uzupełnić nasz nowy warunek. Jeśli bit toggle jest taki sam, to chcemy zwiększyć prędkość o 1 - warto tutaj również sprawdzić, czy prędkość obrotu nie jest zbyt wysoka. Na koniec, jeśli bit toggle jest różny, to wystarczy przywrócić naszą prędkość obrotu do wartości początkowej. Cały program może wyglądać następująco:
Arduino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#include <RC5.h>
#define L_PWM 5
#define L_DIR 4
#define R_PWM 6
#define R_DIR 9
#define PWM_MAX 165
#define BUZZER 10
#define LED 13
#define TSOP_PIN 3
RC5rc5(TSOP_PIN);//Informacja o podłączeniu odbiornika TSOP
byteaddress;
bytecommand;
bytetoggle;
voidsetup(){
//Konfiguracja pinow od mostka H
pinMode(L_DIR,OUTPUT);
pinMode(R_DIR,OUTPUT);
pinMode(L_PWM,OUTPUT);
pinMode(R_PWM,OUTPUT);
//Konfiguracja pozostalych elementow
pinMode(BUZZER,OUTPUT);
digitalWrite(BUZZER,0);//Wylaczenie buzzera
pinMode(LED,OUTPUT);
digitalWrite(LED,0);//Wylaczenie diody
Serial.begin(9600);
}
intpredkoscObrotu=30;
bytetogglePoprzedni=0;
voidloop(){
if(rc5.read(&toggle, &address, &command)){
switch(command) {
case 4: //Obrót w lewo
leftMotor(-predkoscObrotu);
rightMotor(predkoscObrotu);
break;
}
//Jeśli bit toggle jest taki sam jak poprzednio
if(toggle==togglePoprzedni){
predkoscObrotu++;//Zwieksz predkosc obrotu o 1
//Jeśli wartość prędkości przekroczy 90
if(predkoscObrotu>=90){
predkoscObrotu=30;//To ustawiamy stadnardowe 30
}
}else{//Jeśli bit toggle jest różny
//Ustaw predkosc na standardową
predkoscObrotu=30;
}
//Zapamiętanie poprzedniej wartości toggle
togglePoprzedni=toggle;
}
}
voidleftMotor(intV){
if(V>0){//Jesli predkosc jest wieksza od 0 (dodatnia)
V=map(V,0,100,0,PWM_MAX);
digitalWrite(L_DIR,0);//Kierunek: do przodu
analogWrite(L_PWM,V);//Ustawienie predkosci
}else{
V=abs(V);//Funkcja abs() zwroci wartosc V bez znaku
V=map(V,0,100,0,PWM_MAX);
digitalWrite(L_DIR,1);//Kierunek: do tyłu
analogWrite(L_PWM,V);//Ustawienie predkosci
}
}
voidrightMotor(intV){
if(V>0){//Jesli predkosc jest wieksza od 0 (dodatnia)
V=map(V,0,100,0,PWM_MAX);
digitalWrite(R_DIR,0);//Kierunek: do przodu
analogWrite(R_PWM,V);//Ustawienie predkosci
}else{
V=abs(V);//Funkcja abs() zwroci wartosc V bez znaku
V=map(V,0,100,0,PWM_MAX);
digitalWrite(R_DIR,1);//Kierunek: do tyłu
analogWrite(R_PWM,V);//Ustawienie predkosci
}
}
voidstopMotors(){
analogWrite(L_PWM,0);//Wylaczenie silnika lewego
analogWrite(R_PWM,0);//Wylaczenie silnika prawego
}
Od teraz, w momencie przytrzymania przycisku "4", robot będzie zwiększał prędkość obrotów wraz z każdą odebraną ramką danych - czyli co około 114 ms.
Prędkość wróci do 30%, gdy:
osiągniemy limit prędkości (90%),
puścimy przycisk i wciśniemy go ponownie.
Działanie programu korzystającego z bitu toggle widoczne jest poniżej:
Podsumowanie
Zdalne sterowanie za pomocą podczerwieni oraz standard RC5 sprawdzają się naprawdę w wielu zastosowaniach. Niewielki wysiłek od strony programistycznej pozwala na przesyłanie różnych kodów do robota ze znacznej odległości. Zachęcam do eksperymentowania z IR!
W kolejnej części kursu budowy robotów omówię ekspander portów oraz złącze do podłączania serwa modelarskiego. Elementy te nie są wykorzystywane podczas budowy robotów opisanych w kursie, jednak na pewno będą przydatne podczas dalszej, samodzielniej rozbudowy robotów!
Czy wpis był pomocny? Oceń go:
Średnia ocena 4.9 / 5. Głosów łącznie: 69
Nikt jeszcze nie głosował, bądź pierwszy!
Artykuł nie był pomocny? Jak możemy go poprawić? Wpisz swoje sugestie poniżej. Jeśli masz pytanie to zadaj je w komentarzu - ten formularz jest anonimowy, nie będziemy mogli Ci odpowiedzieć!
Dołącz do 20 tysięcy osób, które otrzymują powiadomienia o nowych artykułach! Zapisz się, a otrzymasz PDF-y ze ściągami (m.in. na temat mocy, tranzystorów, diod i schematów) oraz listę inspirujących DIY na bazie Arduino i Raspberry Pi.
Dołącz do 20 tysięcy osób, które otrzymują powiadomienia o nowych artykułach! Zapisz się, a otrzymasz PDF-y ze ściągami (m.in. na temat mocy, tranzystorów, diod i schematów) oraz listę inspirujących DIY z Arduino i RPi.
Trwa ładowanie komentarzy...