Costruire un semplice server web con M5Stack ATOM S3 e ATOMIC PoE W5500
13 Feb 2025
0 Commenti
L' M5Stack ATOM S3 è un'unità microcontrollore compatta e versatile, particolarmente utile per progetti di Internet delle Cose (IoT). Combinandola con un modulo Ethernet si apre un mondo di possibilità per applicazioni connesse in rete. Questo articolo fornisce una guida completa per costruire un semplice server web sull'M5Stack ATOM S3 utilizzando il modulo Ethernet, spiegando il codice in dettaglio ed esplorando potenziali miglioramenti.
Requisiti hardware:
-
M5Stack ATOM S3
-
Modulo Ethernet M5Stack (o compatibile)
-
Cavo USB Type-C per programmazione
-
Cavo Ethernet per connessione di rete
Requisiti software:
-
Arduino IDE (con supporto per scheda ESP32)
-
Libreria M5Stack per ATOM S3
#include "M5AtomS3.h" #include#include #definisci SCK 5 #definisci MISO 7 #define MOSI 8 #definisci CS 6 byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x99}; // Indirizzo MAC (spesso sovrascritto da DHCP) IPAddress ip(192, 168, 1, 177); // Indirizzo IP statico (non utilizzato in questo esempio abilitato DHCP) EthernetServer server(80); // Crea un oggetto server sulla porta 80 (HTTP) impostazione nulla() { cfg automatico = M5.config(); AtomS3.begin(cfg); AtomS3.Display.setTextColor(VERDE); AtomS3.Display.setTextDatum(middle_center); AtomS3.Display.setFont(&fonts::Orbitron_Light_24); AtomS3.Display.setTextSize(1); SPI.begin(SCK, MISO, MOSI, -1); // Inizializza la comunicazione SPI per Ethernet Ethernet.init(CS); // Inizializza il chip Ethernet con il pin CS AtomS3.Display.drawString("Inizializza...", AtomS3.Display.width() / 2, 60); while (Ethernet.begin(mac) != 1) { // Prova a ottenere un indirizzo IP tramite DHCP Serial.println("Errore durante il recupero dell'indirizzo IP tramite DHCP, riprovando..."); ritardo(1000); } // Check for Ethernet hardware present if (Ethernet.hardwareStatus() == EthernetNoHardware) { Serial.println("Lo shield Ethernet non è stato trovato. Mi dispiace, non posso funzionare senza hardware. :("); mentre (vero) { delay(1); // non fare nulla, non ha senso eseguire senza hardware Ethernet } } if (Ethernet.linkStatus() == LinkOFF) { Serial.println("Il cavo Ethernet non è connesso."); } server.begin(); // Avvia il server Serial.print("il server è a "); Serial.println(Ethernet.localIP()); // Stampa l'indirizzo IP assegnato AtomS3.Display.setTextSize(0.5); AtomS3.Display.clear(); AtomS3.Display.drawString(Ethernet.localIP().toString().c_str(), AtomS3.Display.width() / 2, 60); // Visualizza l'IP sullo schermo } ciclo vuoto() { EthernetClient client = server.available(); // Controlla la connessione di un nuovo client if (client) { // Se un client è connesso Serial.println("nuovo cliente"); boolean currentLineIsBlank = true; while (client.connected()) { // Finché il client è ancora connesso if (client.available()) { // Se il client ha inviato dati char c = client.read(); // Leggi un carattere dal client Serial.write(c); // Stampa il carattere sul Monitor Seriale if (c == '\n' && currentLineIsBlank) { // Controlla la fine della richiesta HTTP // Send HTTP response client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println("Connessione: chiudi"); client.println("Refresh: 5"); // Aggiorna la pagina ogni 5 secondi client.println(); // Riga vuota per segnalare la fine dell'intestazione client.println(""); client.println(""); client.print("Ciao M5Stack LAN Module!"); client.println(""); break; // Esci dal ciclo while interno (richiesta elaborata) } se (c == '\n') { currentLineIsBlank = true; } else if (c != '\r') { currentLineIsBlank = false; } } } ritardo(1); client.stop(); // Chiudi la connessione del client Serial.println("client disconnesso"); } }
✔ Copiato!
Spiegazione Dettagliata:
- Include: Il codice inizia includendo le librerie necessarie: M5AtomS3.h per l'ATOM S3, SPI.h per la comunicazione SPI (utilizzata dal modulo Ethernet) e M5_Ethernet.h per la funzionalità Ethernet.
- Definisce: Le istruzioni #define definiscono i pin SPI utilizzati dal modulo Ethernet. Questi sono cruciali per una corretta comunicazione.
- Indirizzo MAC: byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x99}; dichiara un indirizzo MAC. Anche se incluso, questo viene spesso sovrascritto dal server DHCP quando il dispositivo si connette alla rete.
- Indirizzo IP: IPAddress ip(192, 168, 1, 177); definisce un indirizzo IP statico. Tuttavia, in questo esempio, viene utilizzato DHCP, quindi questo IP statico non è effettivamente assegnato al dispositivo. È un segnaposto.
- Server Ethernet: EthernetServer server(80); crea un'istanza della classe EthernetServer, che ascolta le connessioni in arrivo sulla porta 80 (la porta HTTP standard).
- funzione set up():
- auto cfg = M5.config(); AtomS3.begin(cfg);: Inizializza l'hardware M5 ATOM S3.
-
Le seguenti righe configurano la visualizzazione per l'output del testo: impostazione del colore, allineamento, font e dimensione.
-
SPI.begin(SCK, MISO, MOSI, -1); inizializza la comunicazione SPI utilizzando i pin definiti. Il -1 indica che nessun pin di selezione del chip specifico è gestito dalla libreria SPI stessa.
-
Ethernet.init(CS); inizializza il chip Ethernet utilizzando il pin di selezione chip (CS) specificato.
-
AtomS3.Display.drawString("Init...", AtomS3.Display.width() / 2, 60); visualizza "Init..." sullo schermo ATOM S3 per indicare che l'inizializzazione è in corso.
-
Il ciclo while (Ethernet.begin(mac) != 1) tenta di ottenere un indirizzo IP tramite DHCP. Continua a riprovare ogni secondo fino a quando non viene ricevuto un IP valido. È qui che l'ATOM S3 ottiene il suo indirizzo di rete.
-
Il codice verifica quindi se l'hardware Ethernet è presente e se è stabilita una connessione (cavo). In caso contrario, il programma si ferma. Questo è importante per un funzionamento robusto.
-
server.begin(); avvia il server Ethernet, rendendolo pronto ad accettare connessioni in arrivo.
-
L'indirizzo IP assegnato (ottenuto tramite DHCP) viene stampato sul Monitor Seriale e visualizzato sullo schermo dell'ATOM S3.
7. ciclo()
funzione:
- EthernetClient client = server.available(); verifica se un client si è connesso al server. server.available() restituisce un oggetto EthernetClient se un client è disponibile, o null se non lo è.
- Il blocco if (client) viene eseguito se un client è connesso.
- boolean currentLineIsBlank = true; è un flag utilizzato per rilevare la fine di una richiesta HTTP.
- Il ciclo while (client.connected()) continua finché il client rimane connesso.
- if (client.available()) controlla se il client ha inviato dei dati.
- char c = client.read(); legge un singolo carattere dalla richiesta del client.
- Serial.write(c); stampa il carattere ricevuto sul Monitor Serial per il debug.
- Il codice quindi analizza la richiesta HTTP. La condizione if (c == '\n' && currentLineIsBlank) verifica la fine della richiesta HTTP. Una riga vuota (\n\r\n o \n\n) di solito segna la fine delle intestazioni.
Se viene rilevata la fine della richiesta, il server invia una risposta HTTP:
-
HTTP/1.1 200 OK
: Una risposta HTTP standard che indica successo. *Content-Type: text/html
: Specifica che il corpo della risposta è HTML. *Connection: close
: Comunica al client che la connessione verrà chiusa dopo l'invio della risposta. Questo è un approccio semplice; le connessioni persistenti potrebbero essere utilizzate per una comunicazione più efficiente. *Refresh: 5
: Questo header istruisce il browser a ricaricare la pagina ogni 5 secondi. Questo crea un effetto dinamico. * Una riga vuota (client.println();
) è cruciale; separa gli header HTTP dal contenuto effettivo. * Il contenuto HTML viene quindi inviato:
. Questo è il semplice HTML che verrà visualizzato nel browser. *Ciao M5Stack LAN Module!
break;
esce dal ciclo internowhile (client.connected())
perché la risposta è stata inviata. * Il codice gestisce quindi la logica per rilevare la fine della richiesta HTTP.if (c == '\n')
controlla la presenza di un carattere di nuova riga, indicando l'inizio di una nuova riga nella richiesta.currentLineIsBlank
è impostato sutrue
quando viene incontrata una nuova riga.else if (c != '\r')
controlla se il carattere non è un ritorno a capo. Se non è un ritorno a capo, significa che ci sono dati sulla riga corrente, quindicurrentLineIsBlank
è impostato sufalse
. Questa logica rileva efficacemente la riga vuota che segnala la fine degli header HTTP. *delay(1);
fornisce un piccolo ritardo, dando al browser il tempo di elaborare i dati ricevuti. *client.stop();
chiude la connessione con il client. *Serial.println("client disconnected");
stampa un messaggio sul Serial Monitor che indica che il client si è disconnesso.
Miglioramenti e Ulteriore Sviluppo:
-
Contenuto Dinamico: L'HTML attuale è statico. Puoi generare contenuti dinamici utilizzando variabili e logica all'interno del tuo codice Arduino. Ad esempio, potresti visualizzare le letture dei sensori, controllare gli attuatori o mostrare l'ora corrente.
-
Gestire Richieste Diverse: Il codice attualmente risponde a qualsiasi richiesta con lo stesso HTML. Puoi implementare la logica per gestire diversi metodi HTTP (GET, POST, ecc.) e URL diversi, permettendoti di creare un'interfaccia web più complessa.
-
HTML Moduli e Input Utente: Aggiungi moduli HTML alla tua pagina web per consentire agli utenti di inserire dati. Puoi quindi elaborare questi dati su ATOM S3 e usarli per controllare i tuoi dispositivi.
-
WebSockets: Per la comunicazione in tempo reale, considera di utilizzare WebSockets invece di HTTP. I WebSockets consentono una comunicazione bidirezionale tra il client e il server, che è essenziale per le applicazioni interattive.
-
Sicurezza: Per gli ambienti di produzione, la sicurezza è fondamentale. Implementa meccanismi di autenticazione e autorizzazione per proteggere il tuo dispositivo e i tuoi dati.
-
Integrazione del File System: Memorizza file HTML, CSS e JavaScript su una scheda SD o memoria flash e servili dall'ATOM S3. Questo ti consente di creare interfacce web più sofisticate.
-
AJAX e JavaScript: Utilizza AJAX (JavaScript e XML asincroni) per aggiornare dinamicamente parti della pagina web senza richiedere un ricaricamento completo della pagina. Questo migliora l'esperienza dell'utente.
-
mDNS (DNS Multicast): Usa mDNS per dare al tuo ATOM S3 un nome leggibile dall'uomo sulla rete locale, rendendo più facile l'accesso.
-
Gestione degli errori: Implementare una gestione degli errori robusta per gestire con grazia situazioni come disconnessioni di rete o input utente non validi.
-
OTA (Over-The-Air) Aggiornamenti: Implementa aggiornamenti OTA per consentirti di aggiornare il firmware del tuo ATOM S3 da remoto.
Risoluzione dei problemi:
-
Nessun indirizzo IP: Controlla la tua connessione di rete, assicurati che il DHCP sia abilitato sul tuo router e verifica che il modulo Ethernet sia correttamente collegato all'ATOM S3.
-
Impossibile connettersi: Controlla di nuovo l'indirizzo IP dell'ATOM S3, assicurati che sia sulla stessa rete del tuo computer e verifica che non ci siano firewall che bloccano la connessione.
-
Problemi con il Monitor Seriale: Assicurati che la velocità di trasmissione nel Monitor Seriale corrisponda alla velocità di trasmissione utilizzata nel tuo codice (di solito 115200).
Questa spiegazione ampliata fornisce una comprensione più approfondita del codice e offre un punto di partenza per sviluppare applicazioni web server più avanzate sull'M5Stack ATOM S3. Ricorda di consultare la documentazione M5Stack e altre risorse online per informazioni e esempi più dettagliati.
ATOM Series: Controller Compatti e Versatili
tag:
Lascia un commento
Tutti i commenti del blog vengono controllati prima della pubblicazione