Arduino WiFi - Kurs Arduino cz. 4

Arduino WiFi - Kurs Arduino cz. 4

Nakładka Ethernet błyskawicznie podłączy Twoją płytę Arduino do sieci, ale w niektórych sytuacjach przydaje się łączność bezprzewodowa. Na przykład gdy musisz odbierać na bieżąco dane z samobieżnego robota własnej konstrukcji albo gdy Twój
układ musi być podłączony do sieci, a w pobliżu nie ma łącza ani routera przewodowego. Sięgnij wtedy po nakładkę WiFi, eleganckie rozwiązanie umożliwiające podłączenie Arduino do sieci bezprzewodowej i przesyłanie danych.

UWAGA: Jeżeli posiadasz nakładkę SparkFun WiFly (popularny odpowiednik oficjalnej nakładki Arduino WiFi) albo z jakiegoś powodu musisz ją wykorzystać w projekcie, na stronie internetowej oryginalnego wydania książki znajdziesz odpowiednio zmienioną wersję tego podrozdziału (w języku angielskim). Odnośnik do niego zamieściliśmy w dodatku E.

Nakładka Arduino WiFi

Nakładka Arduino WiFi umożliwia podłączenie płyty do dowolnej sieci bezprzewodowej typu 802.11b/g. Wykorzystuje moduł bezprzewodowy H&D Wireless HDG104, oferujący uzyskanie zoptymalizowanego, energooszczędnego połączenia radiowego.
Nakładka umożliwia komunikację za pomocą protokołów TCP i UDP, a jej użycie jest bardzo proste i polega na zamontowaniu na płycie Arduino i wpisaniu w szkicu kilku wierszy kodu wykorzystującego bibliotekę WiFi. Łączówki nakładki posiadają w górnej części gniazda, umożliwiające łatwe wykorzystanie pinów Arduino albo założenie dodatkowych nakładek.

Oprócz obsługi sieci bezprzewodowych w standardzie 802.11b/g nakładka WiFi oferuje szyfrowanie WEP oraz WPA2. Po załadowaniu szkicu i skonfigurowaniu płyty Arduino można ją odłączyć od komputera, zasilić z zewnętrznego źródła i zestawić
dwukierunkową komunikację z dowolnego miejsca w zasięgu routera bezprzewodowego.

Ale to nie wszystko. Nakładka WiFi zawiera również slot na kartę microSD, który może być wykorzystany zarówno przez płytę Arduino Uno, jak i Mega, dzięki prostej w użyciu bibliotece SD. Jest to bardzo przydatna funkcjonalność, jeżeli zamierzasz
zapisać dane, a następnie przesłać je przez sieć. W podrozdziale 8.7 dowiesz się dokładnie, jak korzystać z biblioteki SD.

 

Arduino piny wejścia/wyjścia


Ważna informacja na temat pinów wejścia/wyjścia

Nakładka Arduino WiFi oraz czytnik kart SD komunikują się z Arduino za pomocą szyny SPI (opisanej niżej w podrozdziale 8.6), którą cechuje kilka istotnych szczegółów związanych z wykorzystaniem pinów wejścia/wyjścia. 

W płycie Arduino Uno komunikacja jest realizowana na pinach nr 11, 12 i 13, natomiast w płycie Mega na pinach nr 50, 51 i 52. W obu płytach pin nr 10 jest używany do wybrania do komunikacji układu HDG104, natomiast pin nr 4 do wybrania czytnika karty
SD. Sprzętowy pin SS w płycie Mega (pin cyfrowy nr 53) nie jest używany ani przez czytnik kart, ani przez układ HDG104, ale musi być skonfigurowany jako wyjście, aby interfejs SPI działał prawidłowo. Pin cyfrowy nr 7 jest używany do przesyłania danych
pomiędzy nakładką WiFi a Arduino. Bardzo ważne jest więc, aby żaden z wymienionych wyżej pinów nie był wykorzystywany do innych operacji wejścia/ wyjścia. 

I wreszcie ponieważ zarówno układ HDG104 w nakładce WiFi, jak również czytnik kart SD korzystają z tej samej szyny SPI, tylko jeden z komponentów może być aktywny w danej chwili. Jeżeli wykorzystywane są oba, biblioteki SD oraz WiFi realizują ich obsługę
automatycznie. Ale jeżeli jest wykorzystywany tylko jeden z nich, należy jawnie odseparować drugi (jeżeli nie jest używany czytnik kard SD, należy go ręcznie odseparować), jak pokazuje przykładowy kod.


 

Konstrukcja nakładki WiFi jest starannie przemyślana i oprócz nawiązywania połączeń bezprzewodowych oferuje szereg przydatnych funkcjonalności. Jej budowa jest całkowicie otwarta. Nakładka jest wyposażona w port Micro-USB na potrzeby przyszłych aktualizacji wbudowanego oprogramowania. Zawiera również serię diod LED dostarczających przydatnych informacji, takich jak status połączenia (zielona dioda LINK), błędy transmisji (czerwona dioda ERROR) i wysyłanie lub odbieranie danych (niebieska dioda DATA).

 

JAK UŻYWAĆ NAKŁADKI WIFI ZE STARSZYMI PŁYTAMI ARDUINO?

Nakładka WiFi wykorzystuje pin IOREF, dostępny w nowszych wersjach płyty Arduino, do wykrywania napięcia odniesienia dla pinów wejścia/wyjścia, do których jest podłączona. Oznacza to, że w przypadku zastosowania płyty Arduino Uno lub Mega2560
w wersji wcześniejszej niż REV3 trzeba koniecznie zewrzeć piny nakładki IOREF oraz 3.3V (pokazane na rysunku 8.4).

Arduino WiFi
Rysunek 8.4. Układ pinów nakładki WiFi

 

Biblioteka WiFi i jej funkcje - Kurs Arduino

Biblioteka WiFi realizuje niskopoziomową komunikację bezprzewodową i obsługuje wiele poleceń i funkcjonalności oferowanych przez nakładkę. W tym miejscu warto zapoznać się z tabelą 8.5, zawierającą przegląd najważniejszych funkcji z biblioteki WiFi.
Po przejrzeniu tabeli 8.5 możesz przejść do opisu przykładowego projektu, w którym przez sieć bezprzewodową będą przesyłane dane z czujnika gestów.

Funkcja Opis
WiFi.begin() Inicjuje bibliotekę WiFi i rozpoczyna komunikację z urządzeniem.
WiFi.begin(char[] ssid)
WiFi.begin(char[] ssid,
char[] haslo)
WiFi.begin(char[] ssid, int
iindeksKlucza, char[] klucz)
Umożliwia podłączenie do dowolnej otwartej sieci, jak również
do sieci zabezpieczonej z szyfrowaniem WPA po podaniu
identyfikatora SSID i hasła oraz sieci z szyfrowaniem WEP po podaniu
indeksu i klucza (w szyfrowaniu WEP mogą być zastosowane cztery
klucze, dlatego trzeba podać jego indeks). Funkcja zwraca status
połączenia z siecią WiFi.
WiFi.disconnect() Odłącza się od bieżącej sieci.
WiFi.SSID() Odczytuje identyfikator SSID bieżącej sieci i zwraca go jako ciąg
znaków typu String.
WiFi.BSSID(bssid) Odczytuje adres MAC routera, z którym jest nawiązane połączenie,
i umieszcza go w 6-bajtowej tabeli przekazanej jako argument
(na przykład byte bssid[6]).
WiFi.RSSI() Zwraca siłę sygnału połączenia jako liczbę typu Long.
WiFi.encryptionType()
WiFi.encryptionType
(wifiAccessPoint)
Zwraca rodzaj szyfrowania bieżącego (lub wskazanego) punktu
dostępowego. Zwracana wartość jest typu byte. W przypadku
szyfrowania TKIP (WPA) = 2, WEP = 5, CCMP (WPA) = 4,
NONE = 7, AUTO = 8.
WiFi.scanNetworks() Zwraca wartość typu byte zawierającą liczbę wykrytych sieci
bezprzewodowych.
WiFi.getSocket() Zwraca pierwsze dostępne gniazdo połączenia.
WiFi.macAddress() Zwraca 6-bajtową tabelę zawierającą adres MAC nakładki WiFi.
WiFi.localIP() Zwraca adres IP nakładki (jako obiekt typu IPAddress).
WiFi.subnetMask() Zwraca maskę podsieci nakładki (jako obiekt typu IPAddress).
WiFi.gatewayIP() Zwraca adres IP bramy (jako obiekt typu IPAddress).
WiFiServer(int port) Tworzy serwer nasłuchujący na zadanym porcie.
WiFiServer.begin() Uruchamia serwer oczekujący na komunikaty.
WiFiServer.available() Zwraca obiekt klienta, jeżeli są już odebrane od niego dane.
WiFiServer.write(data) Wysyła dane (typu byte lub char) do wszystkich dołączonych klientów.
WiFiServer.print() Wysyła dane do wszystkich klientów. Liczby są wysyłane jako ciągi
znaków ASCII, na przykład liczba 123 jest wysyłana jako ciąg trzech
znaków: ‘1’, ‘2’ i ‘3’.
WiFiServer.println() Działa podobnie jak WiFiServer.print(), ale dodatkowo wysyła znak
nowego wiersza na końcu każdego komunikatu.
WiFiClient() Tworzy obiekt klienta, który może łączyć się z określonym adresem
IP i portem określonym w funkcji connect().
WiFiClient.connected() Zwraca informację, czy klient jest połączony z serwerem. Jeżeli
połączenie jest zamknięte, a jakieś dane wciąż nie są odczytane,
funkcja zwróci wartość true.
WiFiClient.connect(ip, port)
WiFiClient.connect(URL, port)
Nawiązuje połączenie z określonym adresem IP i portem. Adres URL
jest zamieniany na adres IP.
WiFiClient.write(data) Wysyła dane (typu byte lub char) do serwera.
WiFiClient.print() Wysyła dane do klienta. Liczby są wysyłane jako ciągi znaków ASCII,
na przykład liczba 123 jest wysyłana jako ciąg trzech znaków: ‘1’,
‘2’ i ‘3’.
WiFiClient.println() Działa podobnie jak WiFiClient.print(), ale dodatkowo wysyła
znak nowego wiersza na końcu każdego komunikatu.
WiFiClient.available() Zwraca liczbę bajtów gotowych do odczytania (liczbę bajtów
wysłanych przez serwer).
WiFiClient.read() Odczytuje następny bajt odebrany z serwera.
WiFiClient.flush() Usuwa wszystkie bajty wysłane do klienta, ale jeszcze przez niego
nieodczytane.
WiFiClient.stop() Zamyka połączenie z serwerem.

 

Ruchy ciała i bezprzewodowe przyspieszeniomierze - Arduino

W tym przykładzie zastosujesz Arduino z funkcją WiFi do bezprzewodowego przesyłania danych z przyspieszeniomierza. Przyspieszeniomierze to czujniki znakomicie nadające się do realizacji wszelkiego rodzaju interakcji za pomocą ruchów ciała. Można
dzięki nim testować nowe scenariusze gier (jak w popularnych konsolach Nintendo Wii) lub po umieszczeniu ich na ciele tancerza wykorzystywać jego ruchy do sterowania efektami wizualnymi i dźwiękowymi. Przyspieszeniomierzy można również używać do wspomagania osób niepełnosprawnych fizycznie. Jak widzisz, jest mnóstwo praktycznych zastosowań przyspieszeniomierzy i na pewno przychodzą Ci do głowy kolejne.

W tym przykładzie będą Ci potrzebne:

  • płyta Arduino,
  • nakładka Arduino WiFi,
  • przynajmniej jeden przyspieszeniomierz.

W przykładzie użyjesz języka Processing do utworzenia serwera, za pomocą którego będziesz przesyłać i analizować dane z bezprzewodowych przyspieszeniomierzy. 

 

Łączenie komponentów - Kurs Arduino

Podłączenie nakładki WiFi jest bardzo proste i polega na założeniu jej bezpośrednio na płytę Arduino od jej wierzchniej strony. Sposób podłączenia przyspieszeniomierza jest różny i zależy od zastosowanego modelu.

Jeżeli korzystasz z trójosiowego przyspieszeniomierza ADXL335 posiadającego niezależne wyjścia analogowe dla każdej osi (x, y, z), połącz go zgodnie z rysunkiem 8.5. Jeżeli posiadasz inny model, połączenia mogą być podobne albo zamiast wejściowych
pinów analogowych mogą być zastosowane piny PWM. W przypadku zastosowania innego rodzaju przyspieszeniomierza zajrzyj do jego danych technicznych lub dokumentacji, jak go poprawnie podłączyć. Po podłączeniu nakładki WiFi i przyspieszeniomierza możesz zacząć tańczyć rockand- rolla.

Arduino WiFi
Rysunek 8.5. Schemat podłączenia przyspieszeniomierza analogowego do Arduino

Szkic do komunikacji Bluetooth - Arduino

Do bezprzewodowego przesyłania z Arduino danych z przyspieszeniomierza do serwera działającego na Twoim komputerze użyjesz biblioteki WiFi. Zaraz, serwer na Twoim komputerze? Jak to zrobić?

Zastosujesz środowisko programistyczne o nazwie Processing. Jeżeli nie masz go zainstalowanego na swoim komputerze, otwórz stronę www.processing.org i pobierz najnowszą wersję oprogramowania. Jeżeli nie korzystałeś wcześniej z tego środowiska,
nie przejmuj się. Kod z listingu 8.4 wygląda znajomo i jest podobny do tego, który pisałeś już wcześniej. 

Ale najpierw zajmijmy się stroną Arduino i poniższym kodem (listing 8.3).

Listing 8.3. Kod klienta dla Arduino obsługującego przyspieszeniomierz

#include
char ssid[] = "nazwa_sieci"; // Ustawienie nazwy sieci
char pass[] = "klucz_sieci"; //  Ustawienie klucza sieci
IPAddress server_address(192,168,0,1); // Ustawienie adresu serwera
int server_port = 10000; // Ustawienie portu serwera
int status = WL_IDLE_STATUS;
WiFiClient client; // Obiekt klienta WiFi
void setup() {
    Serial.begin(9600); // Zestawienie połączenia szeregowego
    connectToNetwork(); // Próba połączenia z siecią
}
void connectToNetwork(){
    while ( status != WL_CONNECTED) {
        Serial.print("Proba polaczenia z SSID: ");
        Serial.println(ssid);
        status = WiFi.begin(ssid, pass); // Połączenie z siecią
        delay(10000); // Oczekiwanie na połączenie z siecią
    }
    printWifiStatus();
}
void loop() {
    if(status == WL_CONNECTED){ // Sprawdzenie, czy jest połączenie z siecią
        if(!client.connected())
    {
        client.connect(server_address, server_port); // Połączenie z serwerem
        delay(1000);
    }
    else
    {
        Serial.print("Polaczony, przesylanie danych do "); // Odczyt i wysłanie bieżących danych z przyspieszeniomierza
        Serial.println(server_address);
        client.print("x: ");
        client.print(analogRead(0));
        client.print(" y: ");
        client.print(analogRead(1));
        client.print(" z: ");
        client.println(analogRead(2));
    }
    delay(20); // Zwłoka 20 ms przed następną próbą połączenia
}
else{
    Serial.println("Siec WiFi niedostepna");
    connectToNetwork();
    }
}
void printWifiStatus() {
    Serial.print("SSID: ");
    Serial.println(WiFi.SSID());
    IPAddress ip = WiFi.localIP();
    Serial.print("Adres IP: ");
    Serial.println(ip);
    long rssi = WiFi.RSSI();
    Serial.print("Sila sygnalu (RSSI): ");
    Serial.print(rssi);
    Serial.println(" dBm");
}

Po zaimportowaniu potrzebnych bibliotek i określeniu kilku szczegółów dotyczących konfiguracji sieci i serwera tworzony jest obiekt WiFiClient . Następnie w funkcji setup inicjowana jest biblioteka obsługująca transmisję szeregową na potrzeby diagnostyki
, po czym podejmowana jest próba nawiązania połączenia sieciowego za pomocą utworzonej funkcji connectToNetwork . Później kod próbuje wybrać sieci WiFi za pomocą funkcji WiFi.begin i przez 10 sekund oczekuje na połączenie . Potem następuje wejście do głównej pętli. Jeżeli udało się połączyć z siecią , ale nie ma jeszcze połączenia z serwerem , podejmowana jest próba połączenia się z nim. Jeżeli połączenie z serwerem już jest nawiązane, z przyspieszeniomierza odczytywane są bieżące dane i wysyłane do serwera .

W listingu 8.4 przejdziemy do środowiska Processing i utworzymy serwer, który będzie przyjmował połączenia przychodzące od klientów (Arduino) i wyświetlał na ekranie odbierane komunikaty. 

Listing 8.4. Szkic Processing odbierający od klienta Arduino dane z przyspieszeniomierza

import processing.net.*; // Import biblioteki sieciowej Processing
int direction = 1; // Ustawienie kierunku tekstu
boolean serverRunning = false; // Utworzenie ciągu dla danych z przyspieszeniomierza
String currentData = "";
Server myServer; // Utworzenie obiektu serwera
void setup()
{
    size(400, 400); // Ustawienie wielkości okna
    textFont(createFont("SansSerif", 16));
    myServer = new Server(this, 10000); // Inicjalizacja serwera
    serverRunning = true;
    printData();
}
void printData() {
    background(0);
    text("Dane z bezprzewodowego przyspieszeniomierza: ", 15, 25);
    text(currentData, 15, 60);
}
void draw()
{
    Client thisClient = myServer.available(); // Sprawdzenie komunikatów od klienta
    if (thisClient != null) {
        if (thisClient.available() > 0) {
            currentData = "komunikat od: " + thisClient.ip() + " : " + // Rozpakowanie i wyświetlenie danych
                thisClient.readString();
            printData();
        }
    }
}

Po skonfigurowaniu w funkcji setup okna i czcionki do wyświetlania danych tworzona jest instancja serwera oczekującego na połączenia przychodzące od klientów . Funkcja draw, podobna do funkcji loop Arduino, bez przerwy sprawdza, czy nadeszły połączenia od klientów . Jeżeli tak, wyodrębnia komunikat (funkcja thisClient.readString()), dołącza do niego dodatkowe informacje, na przykład adres IP klienta, i wyświetla w oknie .

Załadowanie i test szkicu

To wszystko, co trzeba zrobić w tym projekcie. Kliknij przycisk Run w środowisku Processing. Na ekranie pojawi się okno i uruchomi serwer. Załaduj szkic do Arduino. Jeżeli Twoja sieć jest skonfigurowana prawidłowo (Arduino i komputer znajdują się
w tej samej sieci WiFi i w szkicu podałeś jako adres serwera adres IP swojego komputera), w oknie programu Processing powinny zacząć pojawiać się wartości odbierane z przyspieszeniomierza.

Jeżeli masz ochotę na więcej, dobrym początkiem może być wyodrębnienie z odebranego ciągu znaków poszczególnych danych z przyspieszeniomierza i przedstawienie ich w trójwymiarowym (x, y, z) widoku na ekranie.

 

Arduino w akcji Autorzy: Martin Evans, Joshua Noble, Jordan Hochenbaum Wydawnictwo: Helion

Podobne artykuły

Podziel się ze znajomymi tym artykułem - udostępnij na FB lub wyślij e-maila korzystając z poniższych opcji:

wszystkie oferty