Ta strona używa ciasteczek (plików cookies), dzięki którym może działać lepiej. Dowiedz się więcejRozumiem i akceptuję

Kurs budowy robotów – #8 – zdalne sterowanie IR (RC5)

Roboty 28.02.2017 Damian (Treker)

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.

Nawigacja serii artykułów:
« poprzednia częśćnastępna część »

Kup zestaw elementów i zacznij naukę w praktyce! Przejdź do strony dystrybutora »

Różne metody łączności bezprzewodowej

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!

Dodatkowe informacje o podczerwieni (IR) w elektronice znaleźć można w artykule:
Różne zastosowania podczerwieni – przegląd rozwiązań

Standard RC5

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ł RC5kod Manchester.

Ramka danych zbudowana jest z następujących części:

Ramka danych w standardzie RC5

Dwa pierwsze bity oznaczają 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!

Zestaw elementów do budowy robota

Gwarancja pomocy na forum dla osób, które kupią poniższy zestaw!

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!


Kup w Botlandzie »

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:

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.

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:

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:

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:

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:

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:

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:

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:

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:

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!

Kup zestaw elementów i zacznij naukę w praktyce! Przejdź do strony dystrybutora »

Autor kursu: Damian (Treker) Szymański
Ilustracje: Piotr Adamczyk

Powiadomienia o nowych, darmowych artykułach!

Komentarze

Raf11

17:22, 01.03.2017

#1

Świetny artykuł jak zawsze. Troszkę się tylko czepnę do terminologii. Wiem, że w artykule został użyty skrót myślowy i mam nadzieję, że nikt nie pomyśli, że fala podczerwona ma częstotliwość 36 kHz ;-)

Pozdr.

Treker
Autor wpisu
Administrator

20:15, 01.03.2017

#2

Raf11, nie chciałem zagłębiać się zbyt mocno w terminologię. W tekście są odnośniki do kolejnych artykułów na temat podczerwieni, więc zainteresowani na pewno zaspokoją głód wiedzy ;)

robert10

18:00, 02.03.2017

#3

Problem z biblioteką RC5

zainstalowałem bibliotekę jak w instrukcji

i przy kompilacji błąd

Test_RC5.ino:3:17: fatal error: RC5.h: No such file or directory

compilation terminated.

leepa79

19:12, 02.03.2017

#4

robert10, pewnie już wcześniej instalowałeś biblioteki (we wcześniejszych lekcjach) więc powinno być ok. Próbowałeś jeszcze tego kroku: "Po ponownym uruchomieniu środowiska biblioteka będzie zainstalowana i gotowa do działania". I jeszcze taka porada. Ja zawsze dodaję tak biblioteki:

robert10

21:44, 02.03.2017

#5

Tak instalowałem już biblioteki. Mam wersje Arduino 1.7.10

Zainstalowałem bibliotekę, ponownie uruchomiłem program, ale nie działa. Próbowałem instalować jeszcze raz, ale pojawia się informacja, że biblioteka jest zainstalowana - Biblioteka RC5 już istnieje. W internecie znalazłem, że mogą być problemy z biblioteką z nazwą RC5-master.zip. Jako wskazówkę podano aby po rozpakowaniu usunąć człon nazwy w folderach -master. Próbowałem, ale i to nie działa

poniżej prezentuje zrzuty

Treker
Autor wpisu
Administrator

23:17, 02.03.2017

#6

robert10, czy w katalogu RC5 (z powyższego zrzutu) są już pliki biblioteki, czy jest tam może jeszcze jeden folder? Restartowałeś środowisko? Ta biblioteka nie ma w sobie nic nadzwyczajnego, skoro inne działały, to ta również powinna :)

robert10

10:36, 03.03.2017

#7

W folderze RC5 jest podfolder RC5 a w nim pliki

Poniżej załączam zrzut ze ścieżką dostępu

Tak restartowałem środowisko

Spróbuję przenieść pliki do folderu RC5 z podfolderu

Pozdrawiam

[ Dodano: 03-03-2017, 10:59 ]

Chyba rozwiązane tak jak podawałem we wcześniejszej wiadomość przeniosłem pliki z podfolderu RC5 do folderu RC5 i przeszedł proces kompilacji prawidłowo.

Niem mam możliwości wgrania kodu na Arduino ponieważ jestem w pracy, ale proces kompilacji przeszedł prawidłowo

Serdecznie pozdrawiam i dziękuję serdecznie użytkownikom Treker i leepa79

Treker
Autor wpisu
Administrator

14:35, 03.03.2017

#8

robert10, super, cieszę się, że już działa ;)

jessej

17:23, 18.03.2017

#9

Witam,

niestety program testujący rc5 nie działa w moim przypadku.

Biblioteka zaimportowana prawidłowo, program się kompiluje, dla pewności kod skopiowany ze strony, próbowałam z różnymi pilotami, prędkość transmisji w monitorze jest taka sama jak w programie i wyświetla komunikaty jeżeli nie są w warunku if(rc5.read ...), piloty "sprawdzone" aparatem cyfrowym.

W jaki sposób mogę jeszcze sprawdzić, czy odbiornik ir na shieldzie działa prawidłowo?

Treker
Autor wpisu
Administrator

17:54, 18.03.2017

#10

jessej, witam na forum :) Czy testowałaś z tym pilotem, który jest w zestawie? Wklej proszę dla pewności kod, który wgrywasz do robota.

jessej

20:19, 18.03.2017

#11

Dzięki.

Kod poniżej.

Zastanawiam sie dlaczego w tym przypadku nie konfigurujemy pinu 3 w funkcji Setup.

Używam pilot dołączonego do zestawu "Pilot zdalnego sterowania for Philips TV/DVR/VCR 3939#" w momencie naciśnięcia przycisku ma dodatkowo podświetlany przycisk POWER więc widać że działa.

Arduino z shieldem podpięte do komputera, zasilanie z baterii odłączone. Zdjęłam dodatkowo koszyk z bateriami z podstawy robota, żeby nie zasłaniać odbiornika :)

#define TSOP_PIN 3

#include <RC5.h>

RC5 rc5(TSOP_PIN); //Informacja o podłączeniu odbiornika TSOP

//Zmienne dla RC5

byte address;

byte command;

byte toggle;

void setup() {

Serial.begin(9600);

}

void loop() {

Serial.println("test");

//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);

}

}

[ Dodano: 18-03-2017, 20:33 ]

Sam pin 3 w arduino działa poprawnie (sprawdzone po zdjęciu shield).

Treker
Autor wpisu
Administrator

22:46, 18.03.2017

#12

jessej, taki program nie zadziała - nie umieszczałem go w kursie ;)

W tej chwili wysyłasz do komputera napis "test" w każdym obiegu pętli. Arduino jest całkiem szybkie, więc ilość wysyłanych danych jest olbrzymia. Powoduje to zapchanie wszystkich buforów i zwyczajnie w monitorze portu szeregowego nie widać informacji o RC5. Po usunięciu tej zbędnej linijki (poniższy fragment) całość działa dobrze - sprawdzone przed chwilą na dwóch shieldach i dwóch pilotach.

Serial.println("test");

jessej napisał/a:

wyświetla komunikaty jeżeli nie są w warunku if(rc5.read ...)

Wklejony program, nie mówi nic o wysyłaniu żadnych danych, gdy brak sygnału od RC5 - do tego należałoby skorzystać z polecenia else w warunku. Jednak nawet z else bombardowania PC informacjami bez żadnych odstępów zakończy się problemem ;) Daj znać, czy bez tej dodatkowej linijki działa dobrze.

jessej

0:55, 19.03.2017

#13

Przepraszam za zamieszanie, linię Serial.print("test") dorzuciłam już w procesie eliminowania kolejnych możliwych przyczyn problemu...

Program nie działa na oryginalnym kodzie (poniżej).

Jak wspomniałam sprawdziłam dodatkowo sam pin 3 w arduino (bez nakładki) i działa.

Stąd pytanie czy można w jakiś sposób jeszcze sprawdzić sam odbiornik.

#define TSOP_PIN 3

#include <RC5.h>

RC5 rc5(TSOP_PIN); //Informacja o podłączeniu odbiornika TSOP

//Zmienne dla RC5

byte address;

byte command;

byte toggle;

void setup() {

Serial.begin(9600);

}

void loop() {

//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);

}

}

Treker
Autor wpisu
Administrator

15:12, 19.03.2017

#14

jessej, ok rozumiem. Do tej pory nikt nie zgłaszał podobnego problemu, więc nie mam gotowego rozwiązania ;) Wyślij proszę do mnie przez prywatne wiadomości nr zamówienia w Botlandzie (lub imię i nazwisko osoby zamawiającej), to sprawdzimy inny shield z tej serii. Jeśli okaże się, że to problem sprzętowy, to wymienimy płytkę :)

Treker
Autor wpisu
Administrator

23:17, 27.03.2017

#15

Sprawa problemu z kodami RC5 rozwiązana. W niektórych zestawach znalazły się piloty potrafiące nadawać w kilku różnych standardach. Jeśli Wasz pilot ma przycisk Select, który podświetla różne tryby pracy, to pamiętajcie o ustawieniu TV1. Przykład pilota z taką opcją: https://botland.com.pl/piloty/7395-pilot-uniwersalny-z-kodowaniem-rc5.html Po odpowiednim ustawieniu pilota wszystko działa poprawnie :)

Zobacz powyższe komentarze na forum

FORBOT Damian Szymański © 2006 - 2017 Zakaz kopiowania treści oraz grafik bez zgody autora. vPRsLH.