Arduino – Ping ICMP sulla rete locale

Scheda Arduino con shield Ethernet e libreria ICMP

Utilizzo di una board Arduino come host di rete che esegue ping verso un altro nodo
Hardware utilizzato

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.

  • Scheda Arduino (es. Arduino Uno o compatibile).
  • Shield Ethernet basata su chip Wiznet (W5100, W5200 o W5500) collegata ai pin SPI.
  • Cavo Ethernet per collegare Arduino allo switch o direttamente al router.
  • Host di destinazione nella stessa rete (un PC o altro dispositivo con IP statico).
  • PC di programmazione con IDE Arduino e librerie installate.

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.

Librerie di rete utilizzate

Lo sketch si appoggia a tre librerie principali:

  • SPI.h – gestisce il bus SPI hardware, usato per parlare con il chip Wiznet montato sulla shield.
  • Ethernet.h – fornisce lo stack TCP/IP per IPv4, con gestione di indirizzo IP, subnet mask, gateway e DNS.
  • EthernetICMP.h – aggiunge il supporto per ICMP Echo Request/Echo Reply (ping) sopra la libreria Ethernet, tramite le classi 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).

Installazione librerie Ethernet ed EthernetICMP

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.

Ethernet.h (libreria Ethernet ufficiale)

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.

EthernetICMP.h (ping ICMP)

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.

Sketch Arduino – Ping ICMP

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
}
Variabili principali e significato

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.
Note operative per il laboratorio
  • L’indirizzo IP di Arduino (192.168.1.100) e quello del gateway devono essere coerenti con la LAN reale o simulata.
  • Il valore di target va impostato a un host raggiungibile che risponda al ping (ad esempio un PC della stessa rete).
  • È importante evitare indirizzi MAC duplicati; se ci sono più board, modificare l’array mac[].
  • Per leggere correttamente i messaggi occorre aprire il monitor seriale a 9600 baud.