WiFi - Serwer WWW cz15

Na tym etapie przedstawię ci w jaki sposób zbudować prosty serwer HTTP na Arduino z wykorzystaniem WiFiNINA. Pełną dokumentację i możliwości możesz zobaczyć na stronie producenta biblioteki.

Zadanie

Stwórz serwer http na Arduino z wykorzystaniem biblioteki WiFiNINA. Serwer powinien wyświetlać jakieś dane (np. z czujnika temperatury) i obsługiwać zapytania (np. gaszące i zapalające diodę led) .

Do zbudowania użyję:
  • Diodę Led
  • Rezystor 56Ω
  • Czujnik BMP180
  • Arduino MKR1010 wifi
Schemat połączenia:

schemat

Kod programu:
#include <WiFiNINA.h>
#include <Wire.h>
#include <Adafruit_BMP085.h>

char ssid[] = "Siec";    // SSID Twojej sieci WiFi
char pass[] = "Haslo";  // Hasło Twojej sieci WiFi
int status = WL_IDLE_STATUS;   // status połączenia
WiFiServer server(80);         // Port serwera

Adafruit_BMP085 bmp; // Definicja zmiennej bmp
float temp = 0;      // Zmienna przechowująca temperaturę

WiFiClient client = server.available();

int ledPin = 2; // Pin diody led

void setup() {
  Serial.begin(9600); 
  pinMode(ledPin, OUTPUT);
  while (!Serial);

  bmp.begin();  // Rozpoczęcie pracy czujnika bmp
  
  enable_WiFi();
  connect_WiFi();

  server.begin();
  printWifiStatus();

}

void loop() {
  client = server.available(); // Pobiera dane klienta połączonego

  if (client) {
    temp = bmp.readTemperature(); // Pobranie temperatury i przypisanie do zmiennej temp
    printWEB();
  }
}

void printWifiStatus() {
  // Wyświetl identyfikator SSID sieci, do której jesteś podłączony:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // Wyświetl adres IP adres:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Adres: ");
  Serial.println(ip);

  // Wyświetl siłę sygnału:
  long rssi = WiFi.RSSI();
  Serial.print("Sila sygnalu (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");

  Serial.print("Aby wyswietlic strone otworz http://");
  Serial.println(ip);
}

void enable_WiFi() {
  // Sprawdź moduł WiFi:
  if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("Komunikacja z modułem WiFi sie nie powiodła!");
    // Nie kontynuuj
    while (true);
  }

  // Sprawdź wersje
  String fv = WiFi.firmwareVersion();
  if (fv < "1.0.0") {
    Serial.println("Zaktualizuj oprogramowanie");
  }
}

void connect_WiFi() {
  // Próba połączenia z siecią Wi-Fi:
  while (status != WL_CONNECTED) {
    Serial.print("Proba połaczenia z SSID: ");
    Serial.println(ssid);
    // Połącz się z siecią WPA/WPA2. Zmień tę linię, jeśli używasz sieci otwartej lub WEP:
    status = WiFi.begin(ssid, pass);
    // Poczekaj 10 sekund na połączenie:
    delay(10000);
  }
}

void printWEB() {

  if (client) {                       // Jeśli klient wykona zapytanie GET
    Serial.println("Nowy klient");    // Wyświetl wiadomość z portu szeregowego
    // Utwórz ciąg do przechowywania danych przychodzących od klienta
    String currentLine = ""; 
    while (client.connected()) {      // Pętla, gdy klient jest podłączony
      if (client.available()) {       // Czy są bajty do odczytania z klienta,
        char c = client.read();       // Przeczytaj bajt do zmiennej c
        Serial.write(c);              // Wyświetl go na monitorze szeregowym;
        if (c == '\n') {              // Jeśli bajt jest znakiem nowej linii

          // Jeśli bieżąca linia jest pusta, otrzymasz dwa znaki nowej linii z rzędu.
          // Co oznacza koniec żądania HTTP klienta, więc wyślij odpowiedź:
          if (currentLine.length() == 0) {

            // Nagłówki HTTP zawsze zaczynają się od kodu odpowiedzi (np. HTTP/1.1 200 OK)
            // i typ treści aby klient wiedział co nadchodzi. Następnie pusta linia:
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println();
           
            // Utwórz dwa przyciski
            client.print("Kliknij <a href=\"/On\">TU</a> Aby zapalic diode led<br>");
            client.print("Kliknij <a href=\"/Off\">TU</a> Aby zgasic diode led<br><br>");

            // Wyświetl temperaturę
            client.print("Temperatura w pomieszczeniu: ");
            client.print(temp);
            client.print(" *C");

            // Odpowiedź HTTP kończy się kolejną pustą linią:
            client.println();
            // wyjdz z pętli while
            break;
          }
          else {  // Jeśli masz znak nowej linii, wyczyść bieżący wiersz:
            currentLine = "";
          }
        }
        else if (c != '\r') {  // Jeśli masz cokolwiek innego niż znak r,
          currentLine += c;    // Dodaj go na koniec bieżącej linii
        }

        if (currentLine.endsWith("GET /On")) {
        digitalWrite(ledPin, HIGH); // Zapal diodę       
        }
        if (currentLine.endsWith("GET /Off")) {
        digitalWrite(ledPin, LOW); // Zgaś diodę
        }

      }
    }
    // Zamknij połączenie:
    client.stop();
    Serial.println("klient rozłaczony");
  }
}

Po wgraniu programu obserwujemy monitor portu szeregowego, gdzie będą się wyświetlać komunikaty z naszej płytki. Pierwszym komunikatem jest próba połączenia się do sieci. Gdy już połączenie zostanie poprawnie nawiązane to dostaniemy informacje na temat połączenia i przydzielonego adresu ip przez router.

connection

Otwierając stronę otrzymujemy okno, w którym mamy dwa przyciski i informację o temperaturze w pomieszczeniu:

Site

Dostajemy również informacje w monitorze portu szeregowego o nawiązaniu nowego połączenia przez klienta, któremu zwróciliśmy stronę.

Monitor portu szeregowego

Klikając w przyciski klient (przeglądarka w naszym przypadku) wysyła zapytania GET do serwera. Poniżej możemy zobaczyć zapytanie zapalające diodę led, w którym otrzymaliśmy w zwrocie stronę html:

zapytanie

W ten oto sposób stworzyliśmy prosty serwer obsługujący zapytania dla zapalania i gaszenia diody led. Informacje o temperaturze są aktualizowane po przeładowaniu strony.