Modem komunikacji radiowej XBee XB24B

W życiu każdego entuzjasty elektroniki i programowania (zwanego z angielska geekiem) najwięcej radości dają gadgety, mające potencjalnie ogromne możliwości, których wykorzystanie zależy tylko od nas.
Po godzinach spędzonych na zabawie i testowaniu możliwości XBee, mogę szczerze powiedzieć, że jest on jednym z takich urządzeń.

Czym jest XBee?

XBee to modem radiowy z interfejsem szeregowym i dodatkowymi pinami, które możesz wykorzystać we własnym zakresie. Modem taki pozwala przesyłać dane bez pomocy kabla z prędkościami od 1200 do 230400 bitów na sekundę w paśmie 2.4 Ghz (czyli tym samym co WiFi). Modem zasilany jest napięciem 3.3 V. Dostarczany jest w postaci małej płytki drukowanej.

Sygnały potrzebne do działania dostarczane są do niej za pomocą goldpinów rozmieszczonych na 2 bokach.

Niestety goldpiny z racji wielkości modułu mają gęściej rozmieszczone wyprowadzenia niż standardowe 2.54 mm (0.1″). Na szczęście można dokupić różne adaptery dopasowujące XBee do płytki stykowej, jednocześnie dostosowujące napięcie działania do 5 V.

Zestaw XBee z Nettigo

Całość dotarła do mnie w trzech opakowaniach.

W pierwszym znajdował się „XBee Adapter Kit”, opakowany w folię antystatyczną. Jest to zestaw do samodzielnego montażu pozwalający podłączyć XBee do dowolnego urządzenia wyposażonego w interfejs szeregowy RS-232 w standardzie TTL (o stanach 0, +5V).

W drugim opakowaniu (tzw. „narkotykowym” ;-)) Znajdował się moduł XBee XB24-B na gąbce antystatycznej.

W trzecim była nakładka na Arduino „Arduino XBee Shield” z osadzonym już drugim modułem XBee XB24-B.

Ostatnim elementem nie mieszczącym się na zdjęciu zestawu jest przewód USB-FTDI. Przewód ten ma wbudowany we wtyczce układ FTDI zamieniający sygnały USB na standard RS-232 TTL. Będzie służył do podłączenia adaptera XBee z komputerem.

Montaż adaptera XBee

Jak pisałem wyżej, adapter XBee dotarł w postaci kitu do samodzielnego montażu. Zawiera on niewiele części (3 rezystory, 2 kondensatory, dwie diody LED, układ scalony, stabilizator 3.3 V, drabinkę goldpinów, 2 gniazda podstawki pod XBee, oraz samą płytkę drukowaną).

Do kitu nie było dołączonej żadnej instrukcji, ani schematu. Postanowiłem odwiedzić stronę, której adres widniał na naklejce opakowania. Tam też nie było schematu, tylko zdjęcie zmontowanego układu. Rzeczywiście to wystarczyło by go złożyć.

Przed złożeniem układu należy zastanowić się z której strony płytki drukowanej wkłada się elementy, a z której je lutuje. W tym przypadku górna część płytki do której wkładamy elementy to ta, gdzie nadrukowane są oznaczenia elementów (R1, C1 itp), a dolna to ta z mniejszą ilością nadruków, tą część lutujemy.

Montaż należy rozpocząć od wlutowania elementów najniższych do najwyższych. Ze względu na blisko leżące wyprowadzenia najlepiej zastosować lutownicę z ostrym długim grotem, tak aby cyna nie rozpłynęła się na kilka styków. Jak dokładnie wykonywać lutowanie możesz się dowiedzieć z jednego z poprzednich artykułów.

Na początek radzę wlutować rezystory. Umieszczamy je w płytce, wcześniej odpowiednio zaginając wyprowadzenia, tak aby pasowały do otworów, a rezystor przylegał płasko do płytki.

Aby element nie wysuwał się podczas lutowania, zaleca się lekko odgiąć do zewnątrz jego wyprowadzenia.

Po wlutowaniu rezystorów,

proponuję wlutować następny, nieco wyższy element – kondensator ceramiczny.

Po nim wlutowujemy układ scalony, pamiętając o odpowiednim kierunku wlutowania – wcięcie w kształcie litery „U” musi pokrywać się z wcięciem nadrukowanym na płytce.

Układ scalony jest szczególnie wrażliwy na ciepło i ładunki elektrostatyczne. Dlatego lepiej nie podgrzewać zbyt długo jego wyprowadzeń i za każdym razem odczekać, aż układ wystygnie. Ładunków elektrostatycznych możesz pozbyć się dotykając jakiegoś uziemionego przedmiotu np. kaloryfera lub rury wodociągowej.

Następną czynnością jest wlutowanie kondensatora elektrolitycznego, stabilizatora i podstawek pod XBee. W przypadku kondensatora i stabilizatora ważne jest by odpowiednie nogi trafiły w odpowiednie miejsca. Stabilizator należy umieścić zgodnie z rysunkiem na płytce, płaską krawędzią do wewnątrz. Oczywiście nie trzeba go wciskać do końca jak inne elementy. Można zostawić małą odległość około 5 mm między jego obudową i płytką.
Kondensator ma wyprowadzenia spolaryzowane „+” i „-„. „+” to dłuższa noga, którą należy umieścić w płytce w miejscu pod kondensator oznaczonym „+”.

Na koniec wlutowujemy diody LED. Czerwona oznaczona „RSS” po lewej (świeci, kiedy modem odbiera dane). Zielona oznaczona jako „ASC” po prawej (świeci kiedy modem pracuje, mruga kiedy modem jest zalogowany do sieci). Diody LED też mają polaryzację i tak jak w przypadku kondensatora, dłuższe wyprowadzenia wchodzą w otwór oznaczony „+”.

Ostatecznym elementem do wlutowania są goldpiny. W zależności od zastosowania, można wlutować je w dość dowolny sposób (skierowane w górę, w dół – wlutowane od spodu, lub równolegle do płytki – skierowane w tył). Ja wlutowałem je w górę.

Opcjonalnie można jeszcze wlutować dodatkowe goldpiny skierowane do dołu, podłączone do pól lutowniczych po bokach układu scalonego. Są na nich sygnały pochodzące z samego XBee (kilka pinów cyfrowych, PWM i wejść analogowych [wszystkie w standardzie 3.3 V, które można wykorzystać do własnych dowolnych celów).

Oznaczenia wyprowadzeń goldpina licząc od lewej

  1. +3 V – wyjście zasilania 3 V ze stabilizatora na płytce
  2. DTR – wejście sygnału informującego działaniu urządzenia wysyłającego do modemu (opcjonalne)
  3. RST – wejście sygnału resetowania modemu
  4. GND – masa
  5. CTS – wyjście sygnału informującego, że można wysyłać dane do modemu
  6. +5 V – wejście zasilania modemu 5 V
  7. RX – wejście szeregowych danych asynchronicznych
  8. TX – wyjście szeregowych danych asynchronicznych
  9. RTS – wejście informujące, że możemy odbierać dane z modemu
  10. +3 V – wyjście zasilania 3 V ze stabilizatora na płytce

Schemat płytki adaptera ze strony Adafruit.

Dzięki uważnemu ^Imrahilowi okazało się, że istnieje oryginalny opis montażu adaptera Dziękujemy!

Przewód FTDI

Przewód FTDI wtykamy (licząc od lewej) od 4 do 9 pinu – tak, aby do 4 pinu wchodził przewód czarny oznaczony jako GND, a do 9 piu zielony oznaczony jako RTS.
Oto oznaczenia poszczególnych pinów przewodu FTDI

  • Czarny – GND
  • Brązowy – CTS
  • Czerwony +5 V
  • Pomarańczowy – RX
  • Żółty – TX
  • Zielony – RTS

Przewód FTDI jest zgodny programowo z układem zastosowanym w Arduino. Komputer wykrywa go jako kolejne urządzenie szeregowe w Windows „COMn:”, w Linuksie „/dev/ttyUSBn”.

Nakładka na Arduino „Arduino XBee Shield”

Jest to nakładka, która wchodzi w gniazda Arduino „Analog In 0 – 5”, „Digital 0 – 7” oraz ICSP. Nakładka jest przelotowa, co oznacza, że od górnej strony płytki wystają takie same gniazda, z których można normalnie korzystać.

XBee Shield wykorzystuje cyfrowe piny 0 i 1 (do komunikacji szeregowej) oraz sygnały +5 V, GND i RESET ze złącza programatora ICSP.

Nakładka posiada także dodatkowe pola lutownicze, w które można wlutować goldpiny, gniazda lub przewody. Dodatkowe pola dotyczą pinów cyfrowych i analogowych Arduino, zasilania, oraz wyprowadzeń modułu XBee.

Dodatkowo w nakładce znajdują się dwie zworki oznaczone jako XBEE/USB. Ustawienie zworek w pozycji XBEE pozwala na komunikacje procesora Arduino przez XBee. Ustawienie USB pozwala na wykorzystanie płytki Arduino jako adaptera XBee i komunikację z XBee przez port USB w Arduino.
Jeśli korzystasz z Arduino jako adaptera XBee powinieneś wyjąć procesor z podstawki i ustawić zworki na pozycję USB. Zworki w pozycji „XBee” pozwalają na komunikację z procesorem Arduino. Podłączenie z komputerem może służy wtedy do „podsłuchiwania” komunikacji.

Płytka wyposażona jest też w przycisk RESET, odpowiadający temu z płytki Arduino, oraz diodę LED oznaczoną jako ASSOCIATE informującą o działaniu XBee (świecenie) i zalogowaniu się do sieci (mruganie).

Sygnał RESET podłączony jest również przez tranzystor do sygnału CTS modułu. Powoduje to automatyczne resetowanie Arduino po wysłaniu zbyt dużej ilości danych, których nie ma kto odebrać.

Sieć ZIGBEE

Sieci Zigbee składają się z trzech głównych elementów:

  • Coordinator (Koordynatora): Jest to główny element sieci zajmuje się jej konfiguracją i to od niego zaczyna działanie każda sieć Zigbee (w której musi się znajdować dokładnie jeden koordynator)
  • Router (Ruter): Jest to element sieci przekazujący dane do dalszych jej elementów. Dzięki niemu nie trzeba komunikować się bezpośrednio z odbiornikiem. Można to zrobić właśnie przez pośrednictwo ruterów – co zwiększa zasięg
  • End Device (Urządzenie Końcowe): Jest to ostatni element sieci – jakieś urządzenie korzystające z jej dobrodziejstw.

Każdy modem XBee można skonfigurować do pracy jako jeden z wymienionych elementów sieci Zigbee. W przypadku XB24-B do wyboru są 3 role:

  • „ZIGBEE COORDINATOR”: Zwykły koordynator sieci
  • „ZIGBEE ROUTER SENSOR”: Ruter sieci pełniący jednocześnie funkcje transmisji danych o stanie własnych pinów pomiarowych. Dzięki temu można stworzyć bezprzewodowy czujnik korzystając z samego modemu XBee
  • „ZIGBEE ROUTER/END DEVICE”: Ruter sieci, pełniący jednocześnie funkcje urządzenia końcowego

Oczywiście każdy element sieci pełni normalne funkcje modemu i jest zdolny transmitować dane.

Podstawowe parametry sieci Zigbee

ID – Numer sieci. Ponieważ na tym samym obszarze może istnieć wiele sieci Zigbee (wiele Koordynatorów), dlatego każda powinna mieć inny niezależny numer. Każde urządzenie chcące przynależeć do tej samej sieci musi mieć skonfigurowany jej numer.

CH – Kanał. Modem może pracować z różnymi częstotliwościami, które wybiera się właśnie za pomocą kanału. Zwykle wyboru dokonuje koordynator, przeszukując pasmo w celu znalezienia najmniej zatłoczonego kanału i rozgłasza go podległym urządzeniom.

SH/SL – Jest to numer seryjny urządzenia w sieci Zigbee. Numer ten służy do adresowania urządzeń w sieci. Numer ten podzielony jest na dwie 32-bitowe połowy.

DH/DL – W tym parametrze ustalony jest odbiorca danych naszego modemu. Przypisujemy im numery SH/SL urządzenia do którego chcemy wysyłać dane.

BD – Parametr ustalający prędkość interfejsu szeregowego. Domyślne prędkości to 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200 i 230400.

Konfiguracja modemu

Do konfiguracji modemów służy program „X-CTU”, który można pobrać ze strony digi.com.
Program napisany jest dla Windows, ale część jego elementów działa również pod innymi systemami na których działa Wine.

Po podłączeniu modemu do komputera, uruchamiamy program i naszym oczom ukazuje się las… ;-)

W tej zakładce należy wybrać odpowiedni port do którego podłączony jest modem.
Prawidłowość połączenia możemy zbadać klikając przycisk „Test / Query”, w wyniku czego otrzymamy okno potwierdzające prawidłowość połączenia, typ modemu i wersje firmware w nim zakodowanego.

Ostatnia zakładka „Modem Configuration” służy do przeglądania, edytowania i zapisywania konfiguracji modemu oraz wybranego firmware (oprogramowania dla procesora w modemie).

Po kliknięciu przycisku „Read” informacje o XBee zostaną automatycznie wczytane i wyświetlone.

Następną czynnością jest wybór roli modemu w menu „Function Set”.

W przypadku dwóch modemów jakie testowałem jednemu przydzieliłem funkcję „ZIGBEE COORDINATOR AT”, a drugiemu „ZIGBEE ROUTER/END DEVICE AT”.

Kolejnymi czynnościami będzie skonfigurowanie parametrów sieci obydwu modemów. Najpierw wybieramy numer identyfikacyjny sieci ID.

Możesz wybrać dowolną liczbę szesnastkową z zakresu 0 – 3FFF. Jeśli wybierzesz liczbę FFFF, koordynator sam wybierze losowy numer sieci.

U siebie ustawiłem na 3333.

Teraz trzeba ustawić odbiorcę danych w parametrach DL/DH. Oczywiście przepisujemy je z SL/SH drugiego modemu. Również DL/DH drugiego modemu ustawiamy na SL/SH pierwszego modemu.

Na koniec ustalamy wybraną prędkość transmisji w parametrze BD.

Po kliknięciu przycisku „Write”, firmware i parametry powinny zapisać się w modemie.

Jeśli dobrze wszystko zaprogramowałeś obydwa modemy po włączeniu powinny się zachować jak kabel „nullmodem”. Czyli to co wyślemy do pierwszego, automatycznie odbierze drugi i na odwrót.

Należy się jeszcze mała uwaga. Odkryłem błąd w modemie. Jeśli zaczniesz wysyłać dane wcześniej niż 5 s po uruchomieniu, modem przestanie wysyłać dane aż do chwili zresetowania go lub ponownego włączenia zasilania.

Konfiguracja X-CTU dla Wine

Na początku należy stworzyć link symboliczny dowiązujący port szeregowy „/dev/ttyUSBn” do katalogu urządzeń Wine.

ln -s /dev/ttyUSB0 ~/.wine/dosdevices/com10

Następnie po uruchomieniu programu przechodzimy do zakładki „User Com Ports”. Teraz w pole „Com Port Number” należy wpisać nazwę dowiązania „COM10” i kliknąć przycisk „Add”. Port powinien pojawić się na liście interfejsów, które można użyć do komunikacji.

Na Ubuntu 10.10 z Wine 1.3.5 program działał dość topornie i nie potrafił zaktualizować swojej bazy firmware-u modemów. Po swoim działaniu rozwalał też system obsługi portów szeregowych tak, że wymagane było ponowne uruchomienie systemu.
W Ubuntu 11.04 z Linux 2.6.37 praca programu wydaje się bardziej stabilna.

Komendy AT

Oczywiście konfiguracji modemu nie trzeba przeprowadzać tylko i wyłącznie z poziomu X-CTU. Można np. posiadając wielu odbiorców pakietów rozsyłać je do różnych modemów w sieci. Jak to zrobić? W odpowiedzi przychodzą nam komendy AT, znane ze starych modemów telefonicznych albo z niektórych dzisiejszych telefonów GSM.

Ponieważ normalnie modemy przesyłają dane, nie można wysyłać im komend, bo dane podobne do rozkazów mieszałyby ustawienia modemu. Modem XBee posiada zatem dwa tryby pracy – wysyłania danych i wykonywania rozkazów. Przejście z trybu danych do rozkazów następuje po wysłaniu do modemu ciągu „+++” i odczekaniu sekundy (gdy nie odczekasz sekundy i zaczniesz wysyłać dalsze bajty modem uzna „+++” jako część danych i je wyśle). Po sekundzie modem powinien odpowiedzieć ciągiem „OKr”. Domyślnie modem używa znaku ‚r’ (CR) o numerze 13 – jako znaku zakończenia linii i tak należy się z nim komunikować. Rozkazy można ćwiczyć ręcznie w zakładce „Terminal” programu X-CTU.

Każdy rozkaz zaczyna się od liter „AT”. AT to też jeden z podstawowych rozkazów informujący, że mamy doczynienia z tym standardem. Wydając rozkaz „AT” (oczywiście w trybie rozkazów) powinniśmy otrzymać w odpowiedzi znane już „OK”. Jeśli jest inaczej powinieneś sprawdzić czy modem ma ustawiony odpowiedni „Function Set”. Prawidłowe to te zakończone na „AT”.

Bardziej złożone komendy AT

Wcześniej pisałem o parametrach modemu jako dwuliterowych symbolach (np. „ID” lub „CH”). Symbole te występowały również w menu programu do konfiguracji. Ma to takie znaczenie, że te symbole są częścią rozkazów. Jeśli np. chcemy odczytać numer sieci (parametr ID), używamy komendy „ATID”. Modem powinien w jej odpowiedzi odesłać numer sieci.

Przypominam na wszelki wypadek, o przejściu w tryb komend za pomocą „+++” i kończeniu każdej linii rozkazu za pomocą znaku „r”.
Z trybu rozkazów można wyjść do trybu wysyłania danych na 2 sposoby. Gdy upłynie ustalony czas od ostatniego rozkazu (domyślnie 10 s), modem sam przejdzie w tryb transmisji danych. Drugim sposobem jest wydanie polecenia „ATCN”.

Jest jeszcze jedna forma rozkazów – rozkazy z parametrem. Są one potrzebne wtedy, kiedy chcemy zmienić jakiś parametr modemu. Są one podobne do rozkazów odczytu z tym, że zamiast kończyć się na symbolu parametru mają za nim liczbę w postaci szesnastkowej (hex).
Np. gdybyś chciał ustawić numer sieci na 0x3333 należy wydać rozkaz „ATID3333”.

Poniżej przedstawiam opis najważniejszych rozkazów modemu. Po więcej odsyłam do dokumentacji lub programu konfiguracyjnego, który po kliknięciu w parametr przedstawia jego dość dokładny opis.

ATID – numer sieci – wszystkie modemy należące do sieci muszą mieć ten sam numer w jej obrębie

ATCH – numer kanału – domyślnie przydziela go koordynator, jednak może się przydać sprawdzenie w razie problemów

ATSL i ATSH – zawierają 32 bitowe połówki adresu modemu

ATDL i ATDH – zawierają 32 bitowe połówki adresata danych

ATBD – steruje prędkością transmisji interfejsu szeregowego jego parametr to cyfra od 0 do 8 oznaczająca:

  • 0 – 1200bps
  • 1 – 2400bps
  • 2 – 4800bps
  • 3 – 9600bps
  • 4 – 19200bps
  • 5 – 38400bps
  • 6 – 57600bps
  • 7 – 115200bps
  • 8 – 230400bps

ATAI – podaje stan sieci, jeśli zwraca wartość 0 to wszystko OK, jeśli inną to błąd sieci lub nie znaleziono koordynatora.

ATWR – zapisuje zmienione parametry w pamięci modemu, tak by po ponownym uruchomieniu nie trzeba było ich znowu ustawiać

ATRE – przywraca fabryczne parametry modemu

ATCN – wychodzi z trybu rozkazów do trybu danych

ATVR – podaje wersję oprogramowania modemu

ATHV – podaje wersję sprzętu

ATPL – ustawia moc nadawania od 0 – najsłabsza do 4 – najsilniejsza

ATPM – ustawia dodatkowe wzmocnienie nadawania 0 – wyłączone, 1 – włączone

ATDB – odczytuje siłę odebranego sygnału

AT%V – odczytuje napięcie zasilania modemu – wynik należy podzielić przez 1023 i pomnożyć przez 1200 (np. jeśli wynikiem jest B0C czyli 0xb0c/1024.0*1200 = 3314.0625 mV = 3.314 V)

Te podstawowe parametry pozwolą ustawić transmisję danych. Przykład z użyciem sieci o numerze 1234, prędkością transmisji 19200 i dwoma modemami jeden o adresie 13A230403AB2ED, a drugi 13A230433AB2FD.

[modem 1]
+++
OK
ATID1234
OK
ATBD4
OK
ATDH13A230
OK
ATDL403AB2ED
OK
ATWR
OK
ATSL
433AB2FD
ATSH
13A230

[modem 2]
+++
OK
ATID1234
OK
ATBD4
OK
ATDH13A230
OK
ATDL433AB2FD
OK
ATWR
OK
ATSH
13A230
ATSL
403AB2ED

dynamiczne adresowanie

Jeśli w sieci istnieje kilka urządzeń z modemami XBee, czasem istnieje potrzeba odwoływania się do kilku z nich. Pierwsze prawidło takich sieci mówi, że koordynator oprócz swojego własnego sprzętowego adresu ma też adres 0, 0 [H, L].
Kolejnym prawidłem jest to, że wysyłając dane na adres 0, FFFF – wyślemy je do wszystkich urządzeń w sieci na raz. Pewnym ograniczeniem/zabezpieczeniem takiego nadawania jest to, że co 8 bajtów następuje ograniczona losowym czasem przerwa w transmisji. Przerwa ma zapobiec zbyt dużemu blokowaniu całej sieci.

Każdemu modemowi można nadać nazwę, składającą się z 20 (widzialnych [czyli np. nie spacja, nie tab itp.]) znaków ASCII. Odpowiada za to parametr „NI”, czyli polecenie „ATNI”.

ATNIrobot1

Od chwili wydania tego polecenia modem będzie widziany w sieci również jako urządzenie o nazwie „robot1”.
Aby inny modem mógł się z nim połączyć za pośrednictwem nazwy, należy ustawić parametr „DN” za pomocą polecenia „ATDN”.

ATDNrobot1

Polecenie to zwróci „OK” w przypadku znalezienia nazwy lub „ERROR” w przypadku jej nieznalezienia. Jeśli znaleziono nazwę to automatycznie zostaną ustawione parametry „DL” i „DH” na adres właściciela nazwy.

Istnieje również możliwość wygenerowania listy wszystkich modemów w dostępnych w sieci (wraz z ich parametrami) za pomocą polecenia „ATND”. Każdy modem to kilka linii tekstu na końcu którego jest pusta linia z samym znakiem ‚r’. Ostatni element listy zakończony jest dwiema pustymi liniami. Pojedynczy element listy wygląda tak:

861F
13A230433AB2FD - adres modemu
ROBOT1 - nazwa modemu
FFFE
01
00
C105
101E
 - pusta linia 1
 - pusta linia 2 (koniec listy)

Programowe wydawanie poleceń AT w Arduino

Żeby było wam wygodnie, napisałem kilka prostych funkcji do wykorzystania w komunikacji z XBee.

once_at

Podstawową i najprostszą funkcją jest „once_at”. Posiada ona 2 argumenty. Pierwszym jest nazwa komendy AT, a drugim jej parametr.
Funkcja ta przechodzi do trybu komend wysyła komendę, wraca do trybu danych i zwraca nam wynik działania komendy.
np.

once_at("ATID", "3333");

zmienia adres sieci na 3333.

get_message_type

Argumentem tej funkcji jest typ String zawierający dane zwrócone w wyniku działania komendy AT. Funkcja ta sprawdza rodzaj zwróconych danych i zwraca jedną ze stałych:

MESSAGE_ERROR – Funkcja nie wykonała się prawidłowo

MESSAGE_OK – Funkcja wykonała się prawidłowo

MESSAGE_VALUE – Funkcja zwróciła jakąś wartość

MESSAGE_STRUCT_ERROR – Funkcja zwróciła nieprawidłowe dane

np.

String msg = once_at("ATID", "3333");
if (get_message_type(msg) == MESSAGE_OK)
{
    // Funkcja wykonała się prawidłowo
}

command_mode

Funkcja nie posiada argumentów i pozwala przejść w tryb wydawania komend AT. Funkcja zwraca stałą tak jak „get_message_type”.
np.

if (command_mode() == MESSAGE_OK)
{
    // Tu wpisz co ma się dziać po przejściu w tryb komend AT
}

data_mode

Funkcja nie posiada argumentów i pozwala przejść w tryb wysyłania danych. Funkcja zwraca stałą tak jak „get_message_type”.
np,

if (data_mode() == MESSAGE_OK)
{
    // Tu wpisz co ma się dziać po przejściu w tryb wysyłania danych
}

AT

Funkcja posiada 2 argumenty. Pierwszym jest nazwa komendy AT, drugim jej parametr.
Funkcja wysyła komendę AT do modemu i zwraca wynik jej działania jako String.
np.

String id = "";
if (command_mode() == MESSAGE_OK) // Przejście w tryb komend
{
    id = AT("ATID"); // Pobranie adresu sieci
    if (data_mode() == MESSAGE_OK) // Przejście w tryb danych
    {
        Serial.print(id); // Wysłanie adresu sieci do odbiornika
    }
}

W tym przykładzie zostanie pobrany adres sieci z modemu i wysłany do odbiornika.

read_message

Funkcja ta nie posiada argumentów. Funkcja zwraca jedną linię danych z modemu zakończoną znakiem „r” (czyli wynik działania komendy AT). Funkcja może być przydatna przy czytaniu wieloliniowych odpowiedzi na komendy AT.

Programowe wydawanie poleceń AT w Pythonie

Napisałem też moduł do języka Python. Moduł składa się z 2 klas. Najważniejszą z nich jest klasa „ATXBee”. Służy ona do wysyłania poleceń do modemu i odbierania odpowiedzi. Konstruktor klasy wymaga argumentu, którym jest obiekt komunikacji z modemem typu „Serial”.

import atxbee
import serial

xbee = serial.Serial('/dev/ttyUSB0', 9600) # obiekt komunikacji z modemem
at = atxbee.ATXBee(xbee) # obiekt do wydawania polecen AT do modemu

Metody klasy „ATXBee” niewiele się różnią od funkcji w bibliotece z poprzedniego rozdziału. Główną metodą jest „once_at”, która automatycznie przechodzi w tryb poleceń modemu, wykonuje polecenie i wraca do trybu danych, jednocześnie zwracając odpowiedź na polecenie.
Odpowiedzią na polecenia klasy „ATXBee” jest obiekt drugiej klasy o nazwie „Response”. Obiekt ten informuje jakiego typu jest zwrot, oraz zawiera pole przechowujące string zwrotu.
Do badania typu zwrotu służą metody „is_ok” (odpowiedź typu OK), „is_error”(odpowiedź typu ERROR), „is_value” (odpowiedź zwraca wartość), „is_struct_error” (błędna odpowiedź). Każda metoda zwraca wartość „True” jeśli modem zwrócił odpowiedź odpowiadającą wybranej metodzie. Jeśli odpowiedź jest typu „VALUE”, to jej treść znajduje się w polu „message”.

Poniżej przykład na zmianę adresu sieci:

response = at.once_at("ATID", "3333")
if response.is_ok():
    # Tu umieszczamy program, który się wykona jeśli polecenie zakończy się sukcesem

Kolejnymi metodami oferowanymi przez klasę „ATXBee” są „command_mode” (przechodzi do trybu poleceń), „data_mode” (przechodzenie do trybu danych) i „AT” (wydanie pojedynczego polecenia AT).
Za przykład posłuży nam program do odczytu adresu sieci modemu:

if at.command_mode().is_ok(): # przejście do trybu poleceń
    response = at.AT("ATID") # wydanie polecenia ATID
    if response.is_value(): # sprawdzenie czy zwrócona wartość jest odpowiedniego typu
        if at.data_mode().is_ok(): # przejście do trybu wysyłania danych
            print response.message # wyświetlenie adresu sieci

Komunikacja z XBee za pomocą API

Przeglądając menu funkcji modemu zapewne dostrzegłeś, że oprócz firmware-ów dla koordynatora i rutera/end point z końcówką „AT”, są jeszcze takie z końcówką API. API to inny format wydawania rozkazów dla modemów XBee, opierający się na wysyłaniu binarnych struktur danych.
Ponieważ temat przekracza objętość tego artykułu, a do komunikacji przez API istnieje mnóstwo bibliotek, polecam skorzystanie z nich i zaznajomienie się z ich dokumentacją.

Elektroniczny gwizdek

Z punktu widzenia dzisiejszego dizajnu, czajnik nie jest niczym niezwykłym. Stawiamy go na palniku i po jakimś czasie znienacka zaczyna piszczeć, dokładnie wtedy, kiedy najmniej się tego spodziewamy. Zbyt długie gwizdanie często denerwuje współlokatorów i nas, szczególnie jak mamy zbyt daleko do kuchni, a robiliśmy właśnie coś ciekawszego.
Wg standardów dobrego projektanta, najlepszymi rozwiązaniami są produkty przewidywalne. Pozwala to łatwiej zagospodarować czas od początku do końca przedsięwzięcia, bez niespodzianek i zaskoczenia. Skoro dzisiejsze nowoczesne pralki mają takie właściwości to czemu nie czajnik?
Postanowiłem rozwiązać to tak, aby czajnik komunikował się z komputerem i podawał swoją aktualną temperaturę. W komputerze będzie działał program wyświetlający pasek postępu (ciągle jeszcze mnie to śmieszy, bo kojarzy mi się z download-em wody przez internet) i czas pozostały do zagotowania. Gdy temperatura osiągnie 100 °C, pasek dojdzie do końca i spokojnie będziesz mógł się udać zaparzyć kawę, herbatę czy (jak w moim przypadku) nową porcję kompotu (takiego owocowego oczywiście).
Jeśli jesteś bardziej „obrotny” takie urządzenie może ci pomóc zdalnie kontrolować proces destylacji alkoholowej, ważenia piwa czy lutowania w piecu.

Czujnik temperatury

Jako czujnik temperatury zastosowałem zwykłą diodę krzemową (popularną 1N4148). Jak się okazuje, złącze PN w półprzewodnikach w kierunku zaporowym przepuszcza określoną ilość elektronów zależnie od temperatury. Najlepsze w tym wszystkim jest to, że ilość przepuszczanego prądu jest liniowa w stosunku do temperatury, co szalenie upraszcza program. Dioda 1N4148 wytrzymuje temperatury od -65 do 200 &degC. Użyłem jej głównie dlatego, gdyż była pod ręką, a nie chciałem narażać się na koszty jakiś cyfrowych czujników Dallas-a lub czujnika analogowego dostępnego w Nettigo, które mógłbym zepsuć do czasu gdy zdobędę odpowiednie doświadczenie. Oczywiście ich również można z powodzeniem użyć (polecam o ile wiesz jak zapewnić im wodoodporność) (wytrzymują do 125 °C).

Najważniejszym jest zapewnienie, aby do czujnika i między wyprowadzenia nie dostała się woda.
W trakcie prototypownia sondy pomiarowej, udało się ją zrobić dopiero za trzecim razem poświęcając dwie diody zatopione w koszulkach termokurczliwych.
W pierwszym egzemplarzu wyprowadzenia diody przylutowałem do przewodów, potem Nałożyłem koszulkę termokurczliwą i podgrzewając ją, eksplodowała cyna robiąc dziurę. Zatem nie polecam lutowania wyprowadzeń.
W drugim egzemplarzu umieściłem diodę w koszulce termokurczliwej tak, że z jednej strony wychodziły 2 przewody i w samej koszulce były ściśnięte ze sobą. Ten układ działał… prawie. Okazało się, że powyżej 80 °C izolacja przewodów robi się mniej wytrzymała i przewody ściśnięte ze sobą połączyły swoje druty, przez co pokazała mi się jakaś ekstremalna temperatura XD.
Trzeci prototyp działa prawidłowo (do trzech razy sztuka!). Jego budowa jest prosta. W środku koszulki jest dioda i przewody wychodzą z jej obydwu końców.
Taki układ wytrzymał najdłużej.

Elektronika pomiarowa

W sieci można znaleźć wiele schematów układów do pomiaru za pomocą diody krzemowej opartych na mostkach pomiarowych lub wzmacniaczach operacyjnych. Ja nie miałem czasu na przesadne eksperymenty. Hołdując tradycji „więcej kodu niż elektroniki” zastosowałem prosty układ dzielnika napięcia. Wystarczy połączyć szeregowo diodę z rezystorem. Jej katodę z GND, rezystor z 5V (na schemacie podłączyłem rezystor do pinu „Vin”, gdyż zasilam Arduino zasilaczem 5V. Jeśli używasz zasilacza o wyższym napięciu podłącz rezystor do pinu „5V”), a anodę z Analog Input 0.

Zastosowałem dość „ryzykowny” rezystor 330 Ω, który zapewnił w tym układzie dokładność 2..3 °C.

Czujnik MCP9700-E-TO można podłączyć w sposób podany w jednym z poprzednich artykułów Jak mierzyc temperaturę z Arduino.

Natomiast cyfrowe czujniki Dallas podłączamy tak jak przedstawiono tu Dallas Temperature Control Library

Za system zbierania i przekazywania pomiarów posłużyło Arduino z odpowiednio zaprogramowanym XBee Shield.

Program na Arduino

Ponieważ czujnik był na dość długim przewodzie, wprowadzającym zakłócenia, wynik pomiaru nie był wystarczająco stabilny (wahania +/- 2 jednostki). Do jego wygładzenia użyłem filtru uśredniającego. To prosty algorytm przechowujący w tablicy 10 ostatnich pomiarów i wyliczający z nich średnią.

Potem wbudowana w Arduino funkcja „map” konwertuje jednostki przetwornika A/C z Arduino na stopnie Celsjusza. Stopnie przekazywane są przez wyjście szeregowe do XBee, który transmituje je do komputera.

Program nadaje się również do układu MCP9700, do którego wymaga oczywiście korekcji skali.

Skale wyznaczamy mierząc znane temperatury i sprawdzając jaką wartość zwraca przy nich funkcja „analogRead”. Potrzebne są dwie wartości – im bardziej skrajne tym lepiej. Najprościej zmierzyć temperaturę w domu, a potem na dworze lub temperaturę ciała. Nieco trudniej byłoby zmierzyć temperaturę wrzącej wody i wody z lodem. Wartości i temperatury należy wprowadzić odpowiednie pola „define” programu.

#define VALUE1 173
#define TEMP1 24
#define VALUE2 167
#define TEMP2 37

Jeśli masz układ termometru z układem Dallas prawdopodobnie nie będzie potrzebna korekcja skali. Ważne, aby program Arduino wysyłał przez „Serial” linie tekstu zawierającą temperaturę w postaci liczby całkowitej najlepiej o możliwie stałych wartościach wzrastających.

Program na PC

Program na PC napisałem w Pythonie z użyciem PyGTK, PySerial i PyGlib. Pierwotnie napisany jest na Linuxa (platforma Ubuntu >= 10.04), jednak po kilku drobnych przeróbkach (zmianie nazwy portu szeregowego z ‚/dev/ttyUSB0’ na właściwą) i zainstalowaniu odpowiednich plików działa na większości platform.

Program wygląda jak proste okno dialogowe z informacją w postaci paska postępu o stopniu nagrzania wody. W pasku jest informacja o czasie jaki pozostał do zagotowania. Po najechaniu wskaźnikiem myszy na pasek pojawia się informacja o temperaturze.

Program wyposażyłem w coś co nazwałem „filtr krańcowy”. Jego działanie polega na tym, że temperatura przy przejściu między kolejnymi wartościami potrafi przeskakiwać kilka razy do przodu i do tyłu (32, 33, 32, 32, 33, 33). Filtr ma to wyeliminować i sprawić, że zmiana temperatury nastąpi dopiero wtedy, kiedy 5 ostatnich wartości będzie takich samych.

Badanie zasięgu

Wg. danych technicznych zasięg modułu wynosi 30 m w pomieszczeniu lub 100 m na terenie otwartym. Oczywiście zasięg może zostać zwiększony jeśli między krańcowymi modemami znajdują się inne pracujące jako rutery. Jeśli chcesz uzyskać większy zasięg możesz zaopatrzyć się w modemy większej mocy serii „XBee Pro” i/lub takie z lepszą anteną lub wyjściem antenowym. Te z wyjściem antenowym można wyposażyć w antenę kierunkową. Ponieważ najpopularniejsze XBee pracuje z częstotliwością 2.4 GHz, można podłączyć do niego osprzęt stosowany w sieciach WiFi. Amatorów „Zrób to sam” zainteresuje projekt własnej anteny kierunkowej typu „biquad”, którą można wykonać z kawałka miedzianego drutu i laminatu niewytrawionej płytki drukowanej.

OK. Zanim zaczniesz zwiększać zasięg warto najpierw sprawdzić, czy to co oferuje obecnie XBee jest wystarczające. Jak podałem wcześniej, do regulacji mocy nadawania służą 2 parametry.
Pierwszy PL (rozkaz ATPL) [Power Level] określa moc nadajnika. Argumentem tego parametru jest liczba od 0 (minimalna) do 4 (maksymalna). Wymyślono go po to, aby móc dobrać moc do warunków w jakich znajduje się urządzenie. Zbyt duża moc to oczywiście większe zużycie prądu i większa możliwość „podsłuchu”.
Kolejny parametr to PM (rozkaz ATPM) [Power Mode]. Parametr ten pozwala włączyć dodatkowe wzmocnienie sygnału (kosztem poboru prądu). Jego argument to 0 – wyłączone wzmocnienie, 1 – włączone wzmocnienie.

Do badania siły odbieranego sygnału służy rozkaz ATDB. Zwraca on wartość zwaną RSSI [Received signal strength indication] ostatnich odebranych danych. Wartość zwracana przez rozkaz ma wartość szesnastkową od 0 do FF czyli 0 – 255. Im wyższą wartość zwraca rozkaz, tym mniejsza moc sygnału dociera do odbiornika.
U mnie modemy ustawione na maksymalną możliwą moc przy sobie zwracały wartość 27 (39), a oddalone od siebie o 8 metrów i 3 ściany zwracały wartość 50 (80). Mogę zatem przyjąć, że nie wykorzystałem nawet 50% ich mocy.

Do badania mocy napisałem dwa programy wykorzystujące wyżej przedstawione biblioteki. Działanie programu polega na tym, że modem podłączony do komputera wysyła testowe dane, modem podłączony do Arduino je odbiera, dołącza do nich wynik działania rozkazu ATDB i odsyła z powrotem.
Komputer je odbiera, sprawdza poprawność danych i wyświetla wartość RSSI.

Podsumowanie

To koniec pierwszej części opisu XBee. Na podstawie tych informacji możesz zacząć konstruować rzeczy wymagające radiowej kontroli poczynając od systemów alarmowych poprzez zdalną kontrolę procesów, aż po grupy robotów i zdalne modele latające.
W kolejnej części dowiesz się czy udało mi się radiowo programować Arduino oraz o nieco bardziej zaawansowanym firmware do XBee XB-24B.

Pliki

21 myśli nt. „Modem komunikacji radiowej XBee XB24B

  1. Imrahil

    Mała prośba – mógłbyś wrzucić zdjęcia tego udanie zaizolowanego czujnika temperatury? No i te nieudane też – tak dla porównania

    Odpowiedz
  2. Sebastian

    Super opis, muszę się za to zabrać, ale mam pytanie. Jak rozumiem w trybie danych co puszcze na uarta to zostanie wysłane do adresata. W trybie rozkazów mogę konfigurować modem. A co mam zrobić jeśli mam np 5 modemów, i chce wysłać np z 2 do 5, potem zaraz do 3, itd. Chciałbym taką sieć każdy z każdym. Muszę za każdym razie wejść w tryb komend(opóźninie ponad sekunda), ustawić nowego adresata, przejść do trybu danych, wysłać dane, znowu tryb komend, zmienić adresata(znowu sekunda) itd? To będzie trochę wolno działać. Jest jakiś inny sposób?

    Odpowiedz
  3. sprae

    Marcin: Dziękuję za uznanie :)

    Sebastian: Również dziękuję.
    Można wybrać jeszcze inny typ firmware (ten z końcówką API), w którym dane wysyła się pakietowo. Polega to na tym, że wysyła się do modemu struktury danych. Część tej struktury to adres docelowego modemu, a część to dane, które chcesz mu przekazać. Wszystko jest opisane w dokumentacji modemu. Jest też wiele bibliotek do obsługi API do Arduino, Pythona, Javy itp. Dodatkowym bonusem jest to, że API pozwala także na zdalne zarządzanie modemami.
    Jeśli byłby jakiś problem chętnie opiszę jak to wszystko wygląda.
    Pozdrawiam i powodzenia :)

    Odpowiedz
  4. 7ymekk

    Witaj sprae.

    dzięki za świetny artykuł.
    ostatnio coraz częściej zastanawiam się nad kupnem takiego zestawiku w celu budowania własnych urządzeń (pracuję obecnie w systemach BMS i bardzo mi się podoba idea kontroli takich urządzeń z poziomu PC). czy zestaw wykorzystany do napisania tego artykułu zbuduję z poniższych produktów?:
    http://nettigo.pl/product/Arduino-Xbee-Shield,ard-xbee-shld#
    http://nettigo.pl/product/Starter-Kit-dla-Arduino,starter-kit#

    chciałbym się też dowiedzieć czy ten moduł XBee na “Arduino XBee Shield” jest wlutowany czy może bez problemu będzie go można w przyszłości wymienić na XBee Pro 900(6km zasięgu)?

    Odpowiedz
  5. netmaniac

    @7ymekk:
    Co do produktów to potrzeba jeszcze czegoś, bo sam shield + Starter Kit da możliwość podpięcia do sieci XBee samego Arduino. Potrzeba jeszcze czegoś co umożliwi podłączenie do sieci XBee komputera. W tym artykule Sprae korzystał z adapteru XBee http://nettigo.pl/product/XBee-adapter-kit,xbee-adapter – obecnie jest on dostępny tylko na zamówienie, natomiast do podłączenia XBee do komputera szczerze polecam http://nettigo.pl/product/Adapter-XBee-Explorer-ze-zlaczem-USB,xbee-usb-explorer – wystarczy zwykły kabel USB i już mamy XBee dostępne.

    Co do XBee Pro – shield nie ma wlutowanego modemu – modem jest wsadzany w gniazdo na shieldzie. Formatem nóżek się zgadza z modemami S1 i S2, więc powinien działać bez problemu w shieldzie (ale nigdy nie próbowałem).

    Odpowiedz
  6. Tomek

    Witam,
    mam takie pytanie, ponieważ chciałem zrobić komunikację pomiędzy dwoma zestawami Arduino Dueminalove.
    Czy jest możliwość wykonania tego za pomocą dwóch zestawów XBee zamocowanych za pomocą Arduino Xbee Shield i bez dodatkowego modułu np. Adapter XBee Explorer ze złączem USB? Czy da się zaprogramować moduły XBee za pomocą programu „X-CTU” gdy są one podłączone do Arduino tak ja napisałem powyżej?

    Może, znacie jakieś prostsze rozwiązanie do komunikacji pomiędzy dwoma zestawami Arduino?

    Odpowiedz
  7. sprae Autor wpisu

    Można używać 2 modułów 2.0 z tym, że jeden musi być koordynatorem, a drugi urządzeniem końcowym/ruterem.
    W trybie API koordynator może wydawać zdalne polecenia podrzędnym modułom.
    Co do innych metod to można je połączyć przewodowo za pomocą SPI lub Serial.
    Istnieją też inne moduły radiowe pasujące do podstawki XBee np Bluetooth lub WiFi.

    Odpowiedz
  8. Tomek

    Dzięki za odpowiedź.
    Jeszcze interesuje mnie sprawa tego zaprogramowania, tak aby jeden był kordynatorem a drugi urządzeniem końcowym.
    Czy jak mam moduł XBee podpięty za pomoacą podstawki do arduino i połączony do komputera to mogę go w tedy programować programem „X-CTU”.
    A i jeszcze czy można wtedy zaprogramować inne porty do komunikacji szeregowej np. z innym urządzeniem?

    Odpowiedz
  9. sprae Autor wpisu

    XBee Shield, który opisałem ma specjalne zworki (XBEE/USB). Od ich ustawienia zależy czy XBee będzie czytało dane z procesora Arduino czy z portu USB. W tym drugim przypadku polecam wyjąć, jeśli można procesor z podstawki, żeby sygnały nie wpadły w konflikt i nie uszkodziły któregoś z urządzeń (kiedy na jednym pojawi się stan niski a na drugim wysoki).
    Inne piny Arduino mogą służyć jako programowy port szeregowy. Służy do tego biblioteka „SoftwareSerial.h”.
    W Arduino MEGA są 3 sprzętowe porty szeregowe.

    Odpowiedz
  10. Tomek

    Ok, czyli jak dobrze rozumiem to:
    Do komunikacji bezprzewodowej pomiędzy dwoma zestawami Arduino Dueminalove potrzebne będą 2 zestawy XBee i dwie podstawki Arduino Xbee Shield.
    Jeden musi być zaprogramowany jako koordynator, a drugi jako urządzenie końcowe/ruter.
    Programować XBee można za pomocą Arduino i podstawki. wtedy najlepiej wyjąć procesor z Arduino i odpowiednio ustawić zworki.
    Natomiast do komunikacji pomiędzy dwoma Arduino należy przestawić zworki i wstawić z powrotem procesor.
    Czy dobrze to napisałem i tyle wystarczy?

    Odpowiedz
  11. Tomek

    Czy aby XBee czytało dane z portu USB zamiast wyjmować procesor można go trzymać w stanie reset, czyli połączyć reset z GND?

    Druga sprawa to, ponieważ moduł ten wykorzystuje te same piny do komunikacji z Arduino co Arduino z komputerem (piny 0 i 1). Czy można w porgramie wykorzystywać pin RX do odczytania z komputera, a pinem TX wysyłać do drugiego Arduino, który ma podpięty XBee?

    Odpowiedz
  12. sprae

    Nie wiem w jakim stanie są piny jak podtrzymujesz Reset. Jeśli są w nieustalonym to prawdopodobnie można.

    Teoretycznie można, ale stracisz możliwość potwierdzania tego co wysłałeś.
    Chyba łatwiej by było podłączyć XBee do innych pinów i użyć SoftwareSerial. Albo użyć Arduino Mega w którym są 3 porty szeregowe.

    Odpowiedz
  13. Tomek

    Dzięki za odpowiedź.

    Tylko, żeby użyć innych pinów do komunikacji z XBee wtedy musiałbym nie korzystać z nakładki do Arduino, a piny łączyć z Arduino przewodami.

    Odpowiedz
  14. sprae

    To niestety prawda. Myślę, że najłatwiej by było te 2 piny lekko odgiąć, tak by nie wchodziły w otwory w płytce Arduino. Następnie od góry podłączyć te 2 piny z jakimś innym pinem :-). Oczywiście pamiętając o kierunku sygnału.

    Odpowiedz
  15. Tomek

    Dzięki, więc będę musiał te dwa piny do transmisji podłączyć do innych wejść.
    Natomiast, aby nie wyjmować procesora Atmegi, wystarczy wgrać do niego pusty program:
    void setup() {
    }
    void loop() {
    }

    Odpowiedz
  16. sprae

    Można dla pewności dodać w setup
    pinMode(0, INPUT);
    pinMode(1, INPUT);

    Ale ja tam wole mniej ryzykowne rozwiązania podawać ;)

    Odpowiedz
  17. Tomek

    Jeszcze pytanie o zasilanie, ponieważ podpinam zewnętrzne zasilanie. Gdy podpinam pod 5V i GND na płytce Arduino to ZigBee sie w momencie bardzo nagrzewa, ponieważ dla niego napięcie wynosi 3,3V. Stąd moje pytanie czy to zewnętrzne zasilanie mogę podpiąć w miejsce oznaczone na nakładce 5V i GND?

    Odpowiedz

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *