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
- +3 V – wyjście zasilania 3 V ze stabilizatora na płytce
- DTR – wejście sygnału informującego działaniu urządzenia wysyłającego do modemu (opcjonalne)
- RST – wejście sygnału resetowania modemu
- GND – masa
- CTS – wyjście sygnału informującego, że można wysyłać dane do modemu
- +5 V – wejście zasilania modemu 5 V
- RX – wejście szeregowych danych asynchronicznych
- TX – wyjście szeregowych danych asynchronicznych
- RTS – wejście informujące, że możemy odbierać dane z modemu
- +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ą.
- Biblioteka XBee API do Arduino
- Biblioteka XBee API do języka Python
- Biblioteka XBee API do Processing
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 °C. 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.
Mała prośba – mógłbyś wrzucić zdjęcia tego udanie zaizolowanego czujnika temperatury? No i te nieudane też – tak dla porównania
swietny opis!
swietna strona, juz zamawiam xbee;]
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?
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 :)
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)?
@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).
Czy ma ktoś wiedzę praktyczną, Jak to spiąć z esp8266. Esp8266 już wysyła sms serialem do modułu A6. Jak stworzyć drugi serial do obsługi pary ZigBee-Esp8266. Ponieważ moduły ZigBee//XBee mają własne piny I/O jak z nich korzystać. Chciałbym wiedzieć jak ich wartości przekazywane są serialem dalej
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?
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.
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?
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.
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?
Doskonale :-)
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?
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.
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.
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.
…z jakimiś innymi pinami (liczba mnoga)
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() {
}
Można dla pewności dodać w setup
pinMode(0, INPUT);
pinMode(1, INPUT);
Ale ja tam wole mniej ryzykowne rozwiązania podawać ;)
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?
Powinno być OK, bo płytka ma własny stabilizator 5V->3.3V i konwertery.
Nagrzewa się moduł, czy stabilizator?