Utilizzare UDP per creare una semplice comunicazione via lan

Il protocollo UDP(User Datagram Protocol) è molto utilizzato per trasmettere dati in maniera molto veloce ed efficiente tra applicazioni semplici. Anche Arduino supporta questo protocollo ed è quindi consigliato per permettere connessioni rapide e semplici tra le schede. Se ci troviamo nella situazione in cui abbiamo delle schede collegate in una LAN e abbiamo il bisogno di scambiare dati tra loro, il protocollo UDP è sicuramente il metodo più veloce e rapido da semplice da usare.

Arduno cavo UDP

Possiamo utilizzare delle schede Arduino UNO con Ethernet shield, Arduino Ethernet o schede della serie MKR con shield MKR ETH.

Le libreria da utilizzare è quella ufficiale Arduino che supporta sia schede con chip Wiz5100 sia quelle con chip Wiz5500.

#include<Ethernet.h> 
#include<EthernetUdp.h>

Nel blocco setup() dobbiamo inizializzare la classe Ethernet, creare un oggetto dalla classe EthernetUDP:

//Indirizzo mac della board
byte mac[] = { 0xD5, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
//indirizzo ip della board
IPAddress ip(10, 192, 1, 177);
//porta utilizzata per udp
unsigned int localPort = 7878;

//definisco un array di char per memorizzare i
//dati in ricezione
char DatiRX[20];

//Creo un oggetto
EthernetUDP Udp;

void setup()
{
  //Init modulo Ethernet
  Ethernet.begin(mac, ip);
  //Init oggetto EthernetUdp
  Udp.begin(localPort);
  //inizializzo la seriale per inviare
  //informazioni di debug al Serial Monitor
  Serial.begin(19200);
}

La classe Ethernet viene inizializzata con il metodo begin() passandogli come parametri il mac address e l’indirizzo ip che vogliamo assegnare alla scheda.

Il metodo begin() dell’oggetto Udp accetta come parametro il numero della porta dove saranno trasmessi e ricevuti i dati.

Nel blocco loop() scriviamo il codice che ci permette di ricevere i dati che vengono inviati alla scheda. Utilizzando il metodo parsePacket() dell’oggetto Udp verifichiamo se nel buffer di ricezione della scheda sono disponibili dei dati da leggere.

parsePacket() restituisce il numero di byte presenti nel buffer di ricezione. Usando una istruzione if possiamo gestire la lettura dei dati presenti nel buffer:

void loop()
{
  //Controlla se sono presenti dati da leggere
  int NumDataRx = Udp.parsePacket();

  if (NumDataRX > 0)
  {
    //leggi i dati
  }
}

All’interno del blocco if effettuiamo la lettura dei dati presenti nel buffer di ricezione con il metodo read()

void loop()
{
  //Controlla se sono presenti dati da leggere
  int NumDataRx = Udp.parsePacket();

  if (NumDataRX > 0)
  {
    //Invio al serial monitor il numero di byte presenti nel buffer
    Serial.print("Numero di byte da leggere: ");
    Serial.println(NumDataRx);

    //leggo i dati e li memorizzo in un array
    Udp.read(DatiRX, NumDataRx);

    for (int i = 0; i < numByteRX; i++)
      Serial.print(DatiRX[i], DEC);
  }
}

Al metodo read() dobbiamo passare un array di char dove verranno memorizzati i dati letti dal buffer di ricezione. Il ciclo for invia i singoli byte al serial monitor, utile per verificare il contenuto dei dati.

Inviare dati

Per quanto riguarda l’invio di un pacchetto UDP vengono impiegate tre istruzioni, beginPacket(), che permette di specificare l’indirizzo ip e la porta a cui vogliamo spedire il pacchetto, write() che scrive i dati all’interno del pacchetto e endPacket() che chiude e spedisce il pacchetto dati UDP. Le istruzioni da utilizzare sono le seguenti

void loop()
{
  //Controlla se sono presenti dati da leggere
  int NumDataRx = Udp.parsePacket();

  if (NumDataRX > 0)
  {
    //Invio al serial monitor il numero di byte presenti nel buffer
    Serial.print("Numero di byte da leggere: ");
    Serial.println(NumDataRx);

    //leggo i dati e li memorizzo in un array
    Udp.read(DatiRX, 20);

    for (int i = 0; i < numByteRX; i++)
      Serial.print(DatiRX[i], DEC);

    //Una volta ricevuti i dati invio una stringa di
    //conferma all'indirizzo e alla porta che hanno
    //instaurato un collegamento con l'Arduino

    //preparo il pacchetto con l'indirizzo e la porta
    //che mi hanno inviato dati precedentemente
    Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
    //scrivo nel pacchetto i dati da inviare
    Udp.write("RX_OK");
    //spedisco il pacchetto
    Udp.endPacket();

  }
}

Il metodo write() accetta sia una stringa di caratteri sia un array di char.

Impiego questo protocollo quando non ho bisogno di avere una connessione stabile con la scheda Arduino (come accade utilizzando il protocollo TCP/IP) ma quando ho bisogno di un metodo semplice, e veloce che mi permette di scambiare dati tra il computer e la scheda o far comunicare due schede tra loro.

Come avete visto per usare il protocollo Udp con Arduino sono sufficienti solo alcune righe di codice quasi quanto utilizzare le istruzioni per l’uso della seriale!