Bygning af en simpel webserver med M5Stack ATOM S3 og ATOMIC PoE W5500

M5Stack ATOM S3 er en kompakt og alsidig mikrokontrollerenhed, særligt nyttig til Internet of Things (IoT) projekter. Kombinationen med et Ethernet-modul åbner op for mange muligheder for netværksforbundne applikationer. Denne artikel giver en omfattende guide til at bygge en simpel webserver på M5Stack ATOM S3 ved hjælp af Ethernet-modulet, forklarer koden i detaljer og udforsker potentielle forbedringer.

Hardwarekrav:

  • M5Stack ATOM S3
  • M5Stack Ethernet-modul (eller kompatibelt)
  • USB Type-C-kabel til programmering
  • Ethernet-kabel til netværksforbindelse
M5Stack ATOMIC PoE Base W5500

M5Stack ATOMIC PoE Base W5500

Se produkt
M5Stack ATOMS3

M5Stack ATOMS3

Se produkt

Softwarekrav:

  • Arduino IDE (med ESP32 board support)
  • M5Stack-bibliotek til 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}; // MAC-adresse (ofte overskrevet af DHCP)
IPAddress ip(192, 168, 1, 177); // Statisk IP-adresse (ubrugt i dette DHCP-aktiverede eksempel)

EthernetServer server(80); // Opret en serverobjekt på port 80 (HTTP)

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

    AtomS3.Display.setTextColor(GREEN);
    AtomS3.Display.setTextDatum(middle_center);
    AtomS3.Display.setFont(&fonts::Orbitron_Light_24);
    AtomS3.Display.setTextSize(1);

    SPI.begin(SCK, MISO, MOSI, -1); // Initialiser SPI-kommunikation til Ethernet
    Ethernet.init(CS); // Initialiser Ethernet-chippen med CS-pinnen

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

    while (Ethernet.begin(mac) != 1) { // Forsøg at få en IP-adresse via DHCP
        Serial.println("Fejl ved hentning af IP-adresse via DHCP, prøver igen...");
        delay(1000);
    }

    // Check for Ethernet hardware present
    if (Ethernet.hardwareStatus() == EthernetNoHardware) {
        Serial.println("Ethernet-shieldet blev ikke fundet. Beklager, kan ikke køre uden hardware. :(");
        while (true) {
            delay(1); // gør ingenting, det er meningsløst at køre uden Ethernet-hardware
        }
    }
    if (Ethernet.linkStatus() == LinkOFF) {
        Serial.println("Ethernet-kablet er ikke tilsluttet.");
    }


    server.begin(); // Start serveren
    Serial.print("serveren er på ");
    Serial.println(Ethernet.localIP()); // Udskriv den tildelte IP-adresse
    AtomS3.Display.setTextSize(0.5);
    AtomS3.Display.clear();
    AtomS3.Display.drawString(Ethernet.localIP().toString().c_str(), AtomS3.Display.width() / 2, 60); // Vis IP på skærmen
}


void loop() {
    EthernetClient client = server.available(); // Tjek for en ny klientforbindelse
    if (client) { // Hvis en klient er forbundet
        Serial.println("ny klient");
        boolean currentLineIsBlank = true;
        mens (client.connected()) { // Mens klienten stadig er forbundet
            hvis (client.available()) { // Hvis klienten har sendt data
                char c = client.read(); // Læs et tegn fra klienten
                Serial.write(c); // Udskriv tegnet til Serial Monitor

                hvis (c == '\\n' && currentLineIsBlank) { // Tjek for slutningen af HTTP-anmodningen
                    // Send HTTP response
                    client.println("HTTP/1.1 200 OK");
                    client.println("Indholdstype: text/html");
                    client.println("Forbindelse: luk");
                    client.println("Opdater: 5"); // Opdater siden hvert 5. sekund
                    client.println(); // Tom linje for at signalere slutningen af headeren
                    client.println("");
                    client.println("");
                    client.print("Hej M5Stack LAN Modul!");
                    client.println("");
                    break; // Afslut den indre while-løkke (anmodning behandlet)
                }
                hvis (c == '\\n') {
                    currentLineIsBlank = true;
                } ellers hvis (c != '\\r') {
                    currentLineIsBlank = false;
                }
            }
        }
        delay(1);
        client.stop(); // Luk klientforbindelsen
        Serial.println("client disconnected");
    }
}

✔ Kopieret!

Detaljeret forklaring:

  1. Includes: Koden starter med at inkludere nødvendige biblioteker: M5AtomS3.h til ATOM S3, SPI.h til SPI-kommunikation (brugt af Ethernet-modulet) og M5_Ethernet.h til Ethernet-funktionalitet.
  1. Defines: #define-sætningerne definerer SPI-pins, der bruges af Ethernet-modulet. Disse er afgørende for korrekt kommunikation.
  1. MAC-adresse: byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x99}; erklærer en MAC-adresse. Selvom den er inkluderet, bliver den ofte overskrevet af DHCP-serveren, når enheden opretter forbindelse til netværket.
  1. IP-adresse: IPAddress ip(192, 168, 1, 177); definerer en statisk IP-adresse. I dette eksempel bruges DHCP dog, så denne statiske IP tildeles ikke faktisk enheden. Det er en pladsholder.
  1. Ethernet Server: EthernetServer server(80); opretter en instans af EthernetServer-klassen, som lytter efter indkommende forbindelser på port 80 (standard HTTP-porten).
  2. opsæt setup()-funktionen:
  • auto cfg = M5.config(); AtomS3.begin(cfg);: Initialiserer M5 ATOM S3 hardwaren.
  • Følgende linjer konfigurerer displayet til at vise tekst: indstilling af farve, justering, skrifttype og størrelse.
  • SPI.begin(SCK, MISO, MOSI, -1); initialiserer SPI-kommunikationen ved hjælp af de definerede pins. -1 angiver, at der ikke er nogen specifik chip select-pin, som SPI-biblioteket selv styrer.
  • Ethernet.init(CS); initialiserer Ethernet-chippen ved hjælp af den angivne chip select (CS) pin.
  • AtomS3.Display.drawString("Init...", AtomS3.Display.width() / 2, 60); viser "Init..." på ATOM S3-skærmen for at indikere, at initialisering er i gang.
  • while (Ethernet.begin(mac) != 1) løkken forsøger at opnå en IP-adresse via DHCP. Den fortsætter med at prøve hvert sekund, indtil en gyldig IP modtages. Her får ATOM S3 sin netværksadresse.
  • Koden tjekker derefter, om Ethernet-hardware er til stede, og om der er etableret et link (kabel forbindelse). Hvis ikke, stopper programmet. Dette er vigtigt for robust drift.
  • server.begin(); starter Ethernet-serveren, så den er klar til at acceptere indkommende forbindelser.
  • Den tildelte IP-adresse (opnået via DHCP) udskrives til Serial Monitor og vises på ATOM S3's skærm.

7. loop() funktion:
  • EthernetClient client = server.available(); tjekker, om en klient har oprettet forbindelse til serveren. server.available() returnerer et EthernetClient-objekt, hvis en klient er tilgængelig, ellers null.
  • if (client) blokken udføres, hvis en klient er forbundet.
  • boolean currentLineIsBlank = true; er et flag, der bruges til at opdage slutningen på en HTTP-anmodning.
  • while (client.connected()) løkken fortsætter, så længe klienten forbliver forbundet.
  • if (client.available()) tjekker, om klienten har sendt data.
  • char c = client.read(); læser et enkelt tegn fra klientens anmodning.
  • Serial.write(c); udskriver det modtagne tegn til Serial Monitor for fejlfinding.
  • Koden parser derefter HTTP-anmodningen. Betingelsen if (c == '\n' && currentLineIsBlank) tjekker for slutningen af HTTP-anmodningen. En tom linje (\n\r\n eller \n\n) angiver typisk slutningen på headerne.
Hvis slutningen af forespørgslen opdages, sender serveren et HTTP-svar:
  • HTTP/1.1 200 OK: Et standard HTTP-svar, der angiver succes. * Content-Type: text/html: Angiver, at svarindholdet er HTML. * Connection: close: Fortæller klienten, at forbindelsen lukkes efter svaret er sendt. Dette er en simpel tilgang; vedvarende forbindelser kunne bruges for mere effektiv kommunikation. * Refresh: 5: Denne header instruerer browseren i at opdatere siden hvert 5. sekund. Dette skaber en dynamisk effekt. * En tom linje (client.println();) er afgørende; den adskiller HTTP-headers fra det faktiske indhold. * HTML-indholdet sendes derefter:

    Hello M5Stack LAN Module!

    . Dette er den simple HTML, der vises i browseren. * break; afslutter den indre while (client.connected())-løkke, fordi svaret er sendt. * Koden håndterer derefter logikken for at opdage slutningen af HTTP-forespørgslen. if (c == '\n') tjekker for et linjeskift, som indikerer starten på en ny linje i forespørgslen. currentLineIsBlank sættes til true, når et linjeskift optræder. else if (c != '\r') tjekker, om tegnet ikke er et carriage return. Hvis det ikke er et carriage return, betyder det, at der er data på den aktuelle linje, så currentLineIsBlank sættes til false. Denne logik opdager effektivt den tomme linje, der signalerer slutningen på HTTP-headers. * delay(1); giver en lille forsinkelse, så browseren får tid til at behandle de modtagne data. * client.stop(); lukker forbindelsen med klienten. * Serial.println("client disconnected"); udskriver en besked til Serial Monitor, der angiver, at klienten er afbrudt.

Forbedringer og videre udvikling:

  • Dynamisk indhold: Den nuværende HTML er statisk. Du kan generere dynamisk indhold ved hjælp af variabler og logik i din Arduino-kode. For eksempel kan du vise sensoraflæsninger, styre aktuatorer eller vise det aktuelle tidspunkt.
  • Håndtering af forskellige forespørgsler: Koden svarer i øjeblikket på alle forespørgsler med den samme HTML. Du kan implementere logik til at håndtere forskellige HTTP-metoder (GET, POST osv.) og forskellige URL'er, så du kan skabe en mere kompleks webgrænseflade.
  • HTML Formularer og Brugerinput: Tilføj HTML-formularer til din webside for at lade brugere indtaste data. Du kan derefter behandle disse data på ATOM S3 og bruge dem til at styre dine enheder.
  • WebSockets: Til realtidskommunikation bør du overveje at bruge WebSockets i stedet for HTTP. WebSockets tillader tovejskommunikation mellem klienten og serveren, hvilket er essentielt for interaktive applikationer.
  • Sikkerhed: For produktionsmiljøer er sikkerhed afgørende. Implementer autentificerings- og autorisationsmekanismer for at beskytte din enhed og data.
  • Filssystem integration: Gem HTML-, CSS- og JavaScript-filer på et SD-kort eller flashhukommelse og server dem fra ATOM S3. Dette giver dig mulighed for at skabe mere sofistikerede webgrænseflader.
  • AJAX og JavaScript: Brug AJAX (Asynchronous JavaScript and XML) til dynamisk at opdatere dele af websiden uden at kræve en fuld sideopdatering. Dette forbedrer brugeroplevelsen.
  • mDNS (Multicast DNS): Brug mDNS til at give din ATOM S3 et menneskeligt læsbart navn på det lokale netværk, hvilket gør det nemmere at få adgang til.
  • Fejlhåndtering: Implementer robust fejlhåndtering for elegant at håndtere situationer som netværksafbrydelser eller ugyldig brugerinput.
  • OTA (Over-The-Air) opdateringer: Implementer OTA-opdateringer, så du kan opdatere firmwaren på din ATOM S3 eksternt.

Fejlfinding:

  • Ingen IP adresse: Tjek din netværksforbindelse, sørg for, at DHCP er aktiveret på din router, og verificer, at Ethernet-modulet er korrekt tilsluttet ATOM S3.
  • Kan ikke oprette forbindelse: Dobbelttjek IP-adressen på ATOM S3, sørg for, at den er på samme netværk som din computer, og verificer, at der ikke er nogen firewalls, der blokerer forbindelsen.
  • Problemer med Serial Monitor: Sørg for, at baudraten i Serial Monitor matcher baudraten, der bruges i din kode (normalt 115200).
Denne udvidede forklaring giver en mere grundig forståelse af koden og tilbyder et udgangspunkt for at udvikle mere avancerede webserverapplikationer på M5Stack ATOM S3. Husk at konsultere M5Stack-dokumentationen og andre online ressourcer for mere detaljeret information og eksempler.

Efterlad en kommentar

Din e-mailadresse vil ikke blive offentliggjort. Obligatoriske felter er markeret med *

Sidebjælke

Seneste indlæg

Denne sektion indeholder i øjeblikket ikke noget indhold. Tilføj indhold til denne sektion ved hjælp af sidepanelet.

Tilmeld dig vores nyhedsbrev

Få de seneste oplysninger om vores produkter og særlige tilbud.