In questo esercizio Arduino viene usato come un vero e proprio host IPv4 collegato a una LAN Ethernet. La configurazione è pensata per mostrare cosa succede “dietro le quinte” di un ping ICMP, usando componenti semplici e facilmente reperibili.
La shield Ethernet si occupa della parte fisica e di collegamento (livello 1–2), mentre lo sketch
implementa la parte logica di rete usando lo stack TCP/IP della libreria Ethernet e le
funzioni ICMP fornite da EthernetICMP.
Lo sketch si appoggia a tre librerie principali:
EthernetICMPPing e
EthernetICMPEchoReply.
Le librerie Ethernet ed EthernetICMP devono essere installate nella cartella delle librerie dell’IDE Arduino; la loro versione deve essere compatibile con il chip montato sulla shield (W5100/W5200/W5500).
Per compilare lo sketch sono necessarie la libreria Ethernet.h (ufficiale Arduino) e la libreria EthernetICMP.h per il ping ICMP. Devono essere installate nella cartella delle librerie dell’IDE Arduino.
Cosa fa: implementa lo stack TCP/IP per le shield/board basate su Wiznet; gestisce IP statico/DHCP, DNS, client/server TCP e UDP. Versione consigliata: usa l’ultima compatibile con il tuo chip (W5100/W5200/W5500).
Installazione: scarica l’archivio ZIP della libreria da questo link:
quindi estrai la cartella nella directory:
C:\Users\tuonome\AppData\Local\Arduino15\libraries\Ethernet
Note: alcune varianti (ad esempio “Ethernet2”, “Ethernet3”) sono pensate per il chip W5500: verifica quale chip è montato sulla tua shield prima di scegliere la libreria.
Cosa fa: estende la libreria Ethernet con ICMP Echo (ping), permettendo
l’uso delle classi EthernetICMPPing ed EthernetICMPEchoReply.
Installazione: scarica l’archivio ZIP della libreria da questo link:
quindi estrai la cartella nella directory:
C:\Users\tuonome\AppData\Local\Arduino15\libraries\EthernetICMP
Compatibilità: richiede una libreria Ethernet funzionante e un chip Wiznet
compatibile. È consigliabile dedicare un SOCKET esclusivo all’ICMP per evitare
conflitti con altre connessioni.
Lo sketch seguente configura Arduino con un indirizzo IP statico e invia periodicamente una Echo Request ICMP verso un host di destinazione, stampando il risultato sul monitor seriale.
#include <SPI.h> // Interfaccia SPI per comunicare con il chip Ethernet
#include <Ethernet.h> // Stack TCP/IP per IP, gateway, DNS, ecc.
#include <EthernetICMP.h> // Supporto ICMP Echo (ping)
// Configurazione di base
const uint8_t ETH_CS_PIN = 10; // Pin di chip select del controller Ethernet
byte mac[] = { // Indirizzo MAC (univoco sulla LAN)
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress ip = IPAddress(192, 168, 1, 100); // Indirizzo IP locale di Arduino
IPAddress dns = IPAddress(1, 1, 1, 1); // Server DNS
IPAddress gw = IPAddress(192, 168, 1, 1); // Gateway predefinito
IPAddress mask = IPAddress(255, 255, 255, 0); // Subnet mask
IPAddress target= IPAddress(192, 168, 1, 101); // Host di destinazione da pingare
// Socket ICMP e istanza del pinger
SOCKET pingSocket = 0; // Indice del socket hardware usato per ICMP
EthernetICMPPing ping(pingSocket, (uint16_t)42); // Oggetto che invia le Echo Request (ID ICMP 42)
void setup() {
Serial.begin(9600); // Inizializza la porta seriale
while (!Serial) { ; } // Attende che il monitor seriale sia pronto (sulle board con USB nativa)
Ethernet.init(ETH_CS_PIN); // Imposta il pin CS del controller Ethernet
Ethernet.begin(mac, ip, dns, gw, mask); // Avvia lo stack Ethernet con IP statico
delay(500); // Breve pausa per stabilizzare il link
Serial.print(F("IP locale: "));
Serial.println(Ethernet.localIP()); // Mostra l’indirizzo IP assegnato
Serial.print(F("Ping verso: "));
Serial.println(target); // Mostra l’IP di destinazione
}
void loop() {
// Invia una Echo Request ICMP con 4 byte di payload
EthernetICMPEchoReply r = ping(target, 4);
if (r.status == SUCCESS) { // Controlla che sia arrivata una Echo Reply valida
unsigned long rtt = millis() - r.data.time; // Calcola il round-trip time
Serial.print(F("Reply da "));
Serial.print(r.addr[0]); Serial.print('.');
Serial.print(r.addr[1]); Serial.print('.');
Serial.print(r.addr[2]); Serial.print('.');
Serial.print(r.addr[3]);
Serial.print(F(": bytes="));
Serial.print(REQ_DATASIZE); // Dimensione del payload ICMP
Serial.print(F(" time="));
Serial.print(rtt); // Tempo di andata e ritorno in ms
Serial.print(F("ms TTL="));
Serial.println(r.ttl); // Time To Live della risposta
} else {
Serial.print(F("Ping fallito; status="));
Serial.println(r.status); // Codice di errore (timeout, risposta errata, ecc.)
}
delay(1000); // Attende 1 secondo prima del prossimo ping
}
Di seguito una sintesi delle variabili più importanti usate nello sketch:
| Nome | Tipo | Ruolo |
|---|---|---|
ETH_CS_PIN |
const uint8_t |
Numero di pin usato come chip select per il controller Ethernet. |
mac[] |
byte[6] |
Indirizzo MAC della shield, necessario per il livello 2 Ethernet. |
ip, dns, gw, mask |
IPAddress |
Parametri di configurazione IPv4 (indirizzo locale, DNS, gateway, subnet mask). |
target |
IPAddress |
Indirizzo dell’host verso cui vengono inviate le Echo Request. |
pingSocket |
SOCKET |
Indice del socket hardware riservato all’uso di ICMP. |
ping |
EthernetICMPPing |
Oggetto che incapsula l’invio delle richieste ICMP Echo. |
r |
EthernetICMPEchoReply |
Struttura che contiene esito, IP sorgente, TTL e timestamp della risposta. |
192.168.1.100) e quello del gateway devono essere
coerenti con la LAN reale o simulata.target va impostato a un host raggiungibile che risponda al ping
(ad esempio un PC della stessa rete).mac[].