Budowanie prostego serwera internetowego z M5Stack ATOM S3 i ATOMIC PoE W5500

M5Stack ATOM S3 to kompaktowa i wszechstronna jednostka mikrokontrolera, szczególnie przydatna w projektach Internetu Rzeczy (IoT). Połączenie jej z modułem Ethernet otwiera świat możliwości dla aplikacji podłączonych do sieci. Ten artykuł zawiera kompleksowy przewodnik po budowie prostego serwera WWW na M5Stack ATOM S3 z użyciem modułu Ethernet, szczegółowo wyjaśniając kod i badając potencjalne ulepszenia.

Wymagania sprzętowe:

  • M5Stack ATOM S3
  • Moduł Ethernet M5Stack (lub kompatybilny)
  • Kabel USB Type-C do programowania
  • Kabel Ethernet do połączenia sieciowego
M5Stack ATOMIC PoE Podstawa W5500

M5Stack ATOMIC PoE Podstawa W5500

Zobacz produkt
M5Stack ATOMS3

M5Stack ATOMS3

Zobacz produkt

Wymagania dotyczące oprogramowania:

  • Arduino IDE (z obsługą płytek ESP32)
  • Biblioteka M5Stack dla ATOM S3
#include "M5AtomS3.h"
#include 
#include 

#define SCK   5
#define MISO 7
#define MOSI 8
#define CS    6

byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x99}; // adres MAC (często nadpisywany przez DHCP)
IPAddress ip(192, 168, 1, 177); // Statyczny adres IP (nieużywany w tym przykładzie z włączonym DHCP)

EthernetServer server(80); // Utwórz obiekt serwera na porcie 80 (HTTP)

void setup() {
    auto cfg = M5.config();
    AtomS3.begin(cfg);

    AtomS3.Display.setTextColor(ZIELONY);
    AtomS3.Display.setTextDatum(środek_środek);
    AtomS3.Display.setFont(&fonts::Orbitron_Light_24);
    AtomS3.Display.setTextSize(1);

    SPI.begin(SCK, MISO, MOSI, -1); // Inicjalizuj komunikację SPI dla Ethernetu
    Ethernet.init(CS); // Inicjalizuj chip Ethernet za pomocą pinu CS

    AtomS3.Display.drawString("Inicjalizacja...", AtomS3.Display.width() / 2, 60);

    while (Ethernet.begin(mac) != 1) { // Próba uzyskania adresu IP przez DHCP
        Serial.println("Błąd pobierania adresu IP przez DHCP, ponawianie próby...");
        opóźnienie(1000);
    }

    // Check for Ethernet hardware present
    if (Ethernet.hardwareStatus() == EthernetNoHardware) {
        Serial.println("Nie znaleziono osłony Ethernet. Przepraszam, nie można uruchomić bez sprzętu. :(");
        while (true) {
            delay(1); // nic nie rób, nie ma sensu uruchamiać bez sprzętu Ethernet
        }
    }
    if (Ethernet.linkStatus() == LinkOFF) {
        Serial.println("Kabel Ethernet nie jest podłączony.");
    }


    server.begin(); // Uruchom serwer
    Serial.print("serwer jest na ");
    Serial.println(Ethernet.localIP()); // Wydrukuj przypisany adres IP
    AtomS3.Display.setTextSize(0.5);
    AtomS3.Display.clear();
    AtomS3.Display.drawString(Ethernet.localIP().toString().c_str(), AtomS3.Display.width() / 2, 60); // Wyświetl IP na ekranie
}


void loop() {
    EthernetClient client = server.available(); // Sprawdź, czy jest nowe połączenie klienta
    if (client) { // Jeśli klient jest połączony
        Serial.println("nowy klient");
        boolean currentLineIsBlank = true;
        while (client.connected()) { // Dopóki klient jest nadal połączony
            if (client.available()) { // Jeśli klient wysłał dane
                char c = client.read(); // Odczytaj znak od klienta
                Serial.write(c); // Wydrukuj znak w Monitorze portu szeregowego

                if (c == '\n' && currentLineIsBlank) { // Sprawdź koniec żądania HTTP
                    // Send HTTP response
                    client.println("HTTP/1.1 200 OK");
                    client.println("Content-Type: text/html");
                    client.println("Połączenie: zamknij");
                    client.println("Odśwież: 5"); // Odśwież stronę co 5 sekund
                    client.println(); // Pusta linia sygnalizująca koniec nagłówka
                    client.println("");
                    client.println("");
                    client.print("Witaj, moduł LAN M5Stack!");
                    client.println("");
                    break; // Wyjście z wewnętrznej pętli while (żądanie przetworzone)
                }
                if (c == '\n') {
                    currentLineIsBlank = true;
                } else if (c != '\r') {
                    currentLineIsBlank = false;
                }
            }
        }
        opóźnienie(1);
        client.stop(); // Zamknij połączenie klienta
        Serial.println("klient rozłączony");
    }
}

✔ Skopiowano!

Szczegółowe wyjaśnienie:

  1. Zawiera: Kod zaczyna się od dołączenia niezbędnych bibliotek: M5AtomS3.h dla ATOM S3, SPI.h do komunikacji SPI (używanej przez moduł Ethernet), oraz M5_Ethernet.h dla funkcji Ethernet.
  1. Definiuje: Instrukcje #define definiują piny SPI używane przez moduł Ethernet. Są one kluczowe dla prawidłowej komunikacji.
  1. Adres MAC: byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x99}; deklaruje adres MAC. Chociaż jest uwzględniony, jest on często nadpisywany przez serwer DHCP, gdy urządzenie łączy się z siecią.
  1. Adres IP: IPAddress ip(192, 168, 1, 177); definiuje statyczny adres IP. Jednak w tym przykładzie używany jest DHCP, więc ten statyczny adres IP nie jest faktycznie przypisany do urządzenia. To jest symbol zastępczy.
  1. Serwer Ethernet: EthernetServer server(80); tworzy instancję klasy EthernetServer, która nasłuchuje przychodzących połączeń na porcie 80 (standardowy port HTTP).
  2. funkcja set up():
  • auto cfg = M5.config(); AtomS3.begin(cfg);: Inicjalizuje sprzęt M5 ATOM S3.
  • Następujące linie konfigurują wyświetlanie tekstu: ustawianie koloru, wyrównania, czcionki i rozmiaru.
  • SPI.begin(SCK, MISO, MOSI, -1); inicjalizuje komunikację SPI przy użyciu zdefiniowanych pinów. -1 oznacza, że biblioteka SPI nie zarządza żadnym konkretnym pinem wyboru układu.
  • Ethernet.init(CS); inicjalizuje chip Ethernet za pomocą określonego pinu wyboru chipu (CS).
  • AtomS3.Display.drawString("Inicjalizacja...", AtomS3.Display.width() / 2, 60); wyświetla "Inicjalizacja..." na ekranie ATOM S3, aby wskazać, że inicjalizacja jest w toku.
  • Pętla while (Ethernet.begin(mac) != 1) próbuje uzyskać adres IP za pomocą DHCP. Kontynuuje ponawianie próby co sekundę, aż zostanie otrzymany ważny adres IP. To właśnie tutaj ATOM S3 otrzymuje swój adres sieciowy.
  • Kod następnie sprawdza, czy sprzęt Ethernet jest obecny oraz czy nawiązano połączenie (kabel). Jeśli nie, program zatrzymuje się. Jest to ważne dla niezawodnej pracy.
  • server.begin(); uruchamia serwer Ethernet, przygotowując go do akceptowania nadchodzących połączeń.
  • Przypisany adres IP (uzyskany przez DHCP) jest wyświetlany w Monitorze Szeregowym oraz na ekranie ATOM S3.

7. pętla() funkcja:
  • EthernetClient client = server.available(); sprawdza, czy jakiś klient połączył się z serwerem. server.available() zwraca obiekt EthernetClient, jeśli klient jest dostępny, lub null, jeśli nie.
  • Blok if (client) wykonuje się, jeśli klient jest połączony.
  • boolean currentLineIsBlank = true; to flaga używana do wykrywania końca żądania HTTP.
  • Pętla while (client.connected()) trwa tak długo, jak klient pozostaje połączony.
  • if (client.available()) sprawdza, czy klient wysłał jakieś dane.
  • char c = client.read(); odczytuje pojedynczy znak z żądania klienta.
  • Serial.write(c); wyświetla odebrany znak w Monitorze portu szeregowego do celów debugowania.
  • Kod następnie analizuje żądanie HTTP. Warunek if (c == '\n' && currentLineIsBlank) sprawdza koniec żądania HTTP. Pusta linia (\n\r\n lub \n\n) zazwyczaj oznacza koniec nagłówków.
Jeśli wykryto koniec żądania, serwer wysyła odpowiedź HTTP:
  • HTTP/1.1 200 OK: Standardowa odpowiedź HTTP wskazująca sukces. * Content-Type: text/html: Określa, że ciało odpowiedzi jest w formacie HTML. * Connection: close: Informuje klienta, że po wysłaniu odpowiedzi połączenie zostanie zamknięte. To proste podejście; można użyć połączeń trwałych dla bardziej efektywnej komunikacji. * Refresh: 5: Ten nagłówek nakazuje przeglądarce odświeżać stronę co 5 sekund. Tworzy to efekt dynamiczny. * Pusta linia (client.println();) jest kluczowa; oddziela nagłówki HTTP od właściwej treści. * Następnie wysyłana jest zawartość HTML:

    Hello M5Stack LAN Module!

    . To prosty HTML, który zostanie wyświetlony w przeglądarce. * break; wychodzi z wewnętrznej pętli while (client.connected()), ponieważ odpowiedź została wysłana. * Kod następnie obsługuje logikę wykrywania końca żądania HTTP. if (c == '\n') sprawdza znak nowej linii, wskazujący początek nowej linii w żądaniu. currentLineIsBlank jest ustawiane na true, gdy napotkany zostanie znak nowej linii. else if (c != '\r') sprawdza, czy znak nie jest powrotem karetki. Jeśli nie jest powrotem karetki, oznacza to, że na bieżącej linii są dane, więc currentLineIsBlank jest ustawiane na false. Ta logika skutecznie wykrywa pustą linię sygnalizującą koniec nagłówków HTTP. * delay(1); zapewnia krótkie opóźnienie, dając przeglądarce czas na przetworzenie odebranych danych. * client.stop(); zamyka połączenie z klientem. * Serial.println("client disconnected"); wyświetla komunikat w Monitorze Szeregowego, wskazujący, że klient się rozłączył.

Ulepszenia i dalszy rozwój:

  • Dynamiczna zawartość: Obecny HTML jest statyczny. Możesz generować dynamiczną zawartość, używając zmiennych i logiki w swoim kodzie Arduino. Na przykład, możesz wyświetlać odczyty czujników, sterować siłownikami lub pokazywać aktualny czas.
  • Obsługa różnych żądań: Kod obecnie odpowiada na każde żądanie tym samym HTML-em. Możesz zaimplementować logikę obsługi różnych metod HTTP (GET, POST itp.) oraz różnych adresów URL, co pozwoli Ci stworzyć bardziej złożony interfejs sieciowy.
  • HTML Formularze i dane użytkownika: Dodaj formularze HTML do swojej strony internetowej, aby umożliwić użytkownikom wprowadzanie danych. Następnie możesz przetwarzać te dane na ATOM S3 i używać ich do sterowania swoimi urządzeniami.
  • WebSockets: Do komunikacji w czasie rzeczywistym rozważ użycie WebSockets zamiast HTTP. WebSockets umożliwiają dwukierunkową komunikację między klientem a serwerem, co jest niezbędne dla interaktywnych aplikacji.
  • Bezpieczeństwo: W środowiskach produkcyjnych bezpieczeństwo jest kluczowe. Wdroż mechanizmy uwierzytelniania i autoryzacji, aby chronić swoje urządzenie i dane.
  • Integracja systemu plików: Przechowuj pliki HTML, CSS i JavaScript na karcie SD lub pamięci flash i udostępniaj je z ATOM S3. Pozwala to na tworzenie bardziej zaawansowanych interfejsów internetowych.
  • AJAX i JavaScript: Użyj AJAX (Asynchroniczny JavaScript i XML), aby dynamicznie aktualizować części strony internetowej bez konieczności pełnego przeładowania strony. To poprawia doświadczenie użytkownika.
  • mDNS (Multicast DNS): Użyj mDNS, aby nadać swojemu ATOM S3 czytelną nazwę w sieci lokalnej, co ułatwi dostęp.
  • Obsługa błędów: Wdrożenie solidnej obsługi błędów, aby łagodnie zarządzać sytuacjami takimi jak rozłączenia sieci lub nieprawidłowe dane wejściowe użytkownika.
  • OTA (Over-The-Air) Aktualizacje: Wdrażaj aktualizacje OTA, aby umożliwić zdalną aktualizację oprogramowania układowego Twojego ATOM S3.

Rozwiązywanie problemów:

  • Brak adresu IP: Sprawdź swoje połączenie sieciowe, upewnij się, że DHCP jest włączone na routerze oraz zweryfikuj, czy moduł Ethernet jest prawidłowo podłączony do ATOM S3.
  • Nie można połączyć: Sprawdź dwukrotnie adres IP ATOM S3, upewnij się, że jest w tej samej sieci co twój komputer, i zweryfikuj, czy nie ma zapór sieciowych blokujących połączenie.
  • Problemy z monitorem szeregowym: Upewnij się, że prędkość transmisji w Monitorze szeregowym odpowiada prędkości transmisji użytej w twoim kodzie (zazwyczaj 115200).
To rozszerzone wyjaśnienie zapewnia bardziej szczegółowe zrozumienie kodu i oferuje punkt wyjścia do tworzenia bardziej zaawansowanych aplikacji serwera internetowego na M5Stack ATOM S3. Pamiętaj, aby konsultować się z dokumentacją M5Stack oraz innymi zasobami online w celu uzyskania bardziej szczegółowych informacji i przykładów.

Zostaw komentarz

Twój adres e-mail nie zostanie opublikowany. Pola wymagane są oznaczone *

Pasek boczny

Najnowszy post

Ta sekcja nie zawiera obecnie żadnych treści. Dodaj treść do tej sekcji, korzystając z paska bocznego.

Zarejestruj się do naszego newslettera

Uzyskaj najnowsze informacje o naszych produktach i specjalnych ofertach.