Programmiamo il WiFi su Arduino con la libreria WiFi101

Programmiamo il Wifi su Arduino con la Libreria WiFi101

Introduzione

La libreria WiFi101 permette di poter utilizzare in maniera programmatica la tecnologia WiFi su sistemi Arduino potenziati con Arduino WiFi Shield 101 o utilizzando direttamente la scheda Arduino MKR1000 che ha il WiFi integrato. Inutile dire che questa libreria è uno dei mattoncini fondamentali per lo sviluppo e l’utilizzo di Arduino come soluzioni IoT.

In questo articolo vedremo come è strutturata la libreria WiFi101, i suoi comandi e le sue funzioni, attraverso la realizzazione di semplici programmi. Questi esempi pratici metteranno in risalto i concetti base della libreria in maniera graduale permettendo così di prendere familiarità con questa libreria.

Arduino and the WiFi101 Library

Utilizzare il WiFi su Arduino

Al momento corrente, in cui l’Internetet of Things (IoT) si sta facendo sempre più una realtà incalzante a cui non è possibile astenersi, sembra impossibile continuare a lavorare con le schede Arduino senza sfruttare la tecnologia WiFi e tutto ciò che ne comporta.

Il potersi connettere a reti WiFi non solo permette lo scambio di dati tra i vari dispositivi che compongono il nostro progetto senza far uso di fili o cavi, ma rende il nostro progetto più consono e in linea con le prerogative attuali. Quindi per non venir meno a tale proposito si sono sviluppati dei moduli che permettano la facile integrazione della tecnologia WiFi su tutti i sistemi Arduino.

Arduino WiFi Schield 101

Arduino WiFi Schield 101

Per i sistemi già presenti ed affermati sul mercato, come Arduino UNO e Arduino MEGA, è stato sviluppato un apposito shield che si integra perfettamente con esse: Arduino WiFi Shield 101. Mentre le schede Arduino di nuovissima generazione, tipo  Arduino MKR1000 e Arduino YUN che vengono prodotte già con il sistema WiFi Integrato.

Arduino MKR1000 dimensioni

Arduino MKR1000

Ma per poter utilizzare la tecnologia WiFi non basta solo la parte hardware, ma anche una serie di tool che ci permettano di poterla sfruttare programmaticamente all’interno dei nostri sketch nell’ambiente di sviluppo Arduino IDE.

A tale proposito è stata quindi rilasciata la libreria WiFi101 che permette di sfruttare e gestire appieno il WiFi attraverso una serie di comandi e funzioni da inserire nei nostri programmi.

Arduino Shield WiFi101

Abbiamo detto che le schede Arduino possono utilizzare le potenzialità delle reti Wifi, utilizzando l’Arduino WiFi shield 101. Questo shield viene montato direttamente sopra le schede Arduino utilizzando lo SPI bus.

Nelle schede Arduino UNO e simili i pin utilizzati sono i PIN digitali 11,12,13 mentre su Arduino Mega ai PIN 50,51,52. Mentre come SSI abbiamo su Arduino Uno e similari il PIN 10 mentre sul Mega il PIN 53 dovrà essere mantenuto come output altrimenti si avranno problemi di mal funzionamento del sistema.

Arduino WiFi101 shield - pinout

Arduino WiFi101 shield – pinout

Oltre ai PIN che abbiamo appena indicato, altri PIN coprono altre funzionalità necessarie e quindi non possono essere utilizzati ad altri scopi.

  • PIN 7 viene utilizzato come handshake pin tra la scheda Arduino e lo shield WiFi
  • PIN 6 viene collegato al pulsante integrato sulla scheda
  • PIN 5 corrisponde alla linea di RESET del modulo WINC1500 integrato sul modulo.

WiFi101 e le configurazioni di rete

Prima di cominciare a vedere in dettaglio la libreria è necessario fare una piccola precisazione sulle configurazioni di rete Wifi. Esistono infatti diverse tipologie di rete WiFi. La loro tipologia varia a seconda del sistema di criptografia utilizzato. Per quanto riguarda la libreria WiFi101 e quindi tutti i sistemi Arduino in generale, sono possibili tutte le connessioni WiFi che fanno uso di sistemi di criptazione WEP e WPA2 Personal. Non si potranno effettuare connessioni che fanno uso di WPA2 Enterprise come sistema di criptgrafia.

Indipendentemente dalla tipologia di WiFi utilizzata, lo scopo della libreria WiFi101 è quello di rendere qualsiasi tipo di connessione il più semplice possibile. E’ richiesto comunque un minimo di configurazione in cui verranno specificati sia il SSID che la password. Se la connessione è di tipo WEP allora come password darà necessario passare una stringa esadecimale che equivale alla key. Una rete WEP può avere fino a 4 diverse key, ciascuna di esse assegnata ad un valore Key Index corrispondente. Quindi in questo caso sarà necessario specificare nella configurazione non solo il SSID e la key (password) ma anche il key number.

La libreria WiFi101

La libreria WiFi101 è molto simile alle librerie Ethernet e WiFi anch’esse presenti come librerie standard negli ambienti di sviluppo Arduino IDE. Infatti molte funzioni che svolgono le stesse operazioni su queste ultime due librerie hanno conservato il nome, in modo da rendere più semplice e coerente lo sviluppo di sketch con Arduino.

Requisiti

La libreria WiFi101 richiede che il firmware installato sulle schede o sullo shield sia in linea con essa. Quando si aggiorna la libreria ad una versione più recente anche il corrispondente firmware dovrà essere aggiornato. A tale scopo, si consiglia vivamente di utilizzare il Library Manager presente nell’Arduino IDE per tenere sotto controllo entrambe le versioni ed eventualmente aggiornarle.

WiFi101 Arduino IDE library Manager and firmware version

Le classi della libreria WiFi

La libreria WiFi101 ha le seguenti classi:

  • WiFi – inizializza la libreria Ethernet e le impostazioni di rete
  • IPAddress – fornisce informazioni sulla configurazione di rete
  • Server – crea server WiFi che inviano e gestiscono i pacchetti di dati provenienti dai client
  • Client – si connette ad un server Wifi per inviare i pacchetti di dati
  • UPD – gestiste i messaggi UPD da inviare e ricevere

La classe WiFi

La classe WiFi è la classe principale della libreria e ne svolge il ruolo base. Infatti ogni oggetto della classe WiFi corrisponde ad una connessione WiFi.

La libreria quindi fornirà tutta una serie di funzioni che ci permettano di gestire una connessione. Per esempio le funzioni

  • begin()
  • end()

corrispondono all’apertura e alla chiusura di una connessione WiFi. La funzione begin() inizializza la classe WiFi e può avere diversi argomenti a seconda della tipologia di rete WiFi a cui vogliamo connetterci.

WiFi.begin();
WiFi.begin(ssid);
WiFi.begin(ssid, pass);
WiFi.begin(ssid, keyIndex, key);

Per comprendere al meglio questa funzione, vediamo come si inserisce all’interno di uno sketch di Arduino con un piccolo esempio.

In questo caso vogliamo connettere il nostro Arduino ad una rete WiFi con criptazione WPA e quindi abbiamo bisogno di specificare una SSID network (il nome della rete) e la password. Poi andremo ad utilizzare la funzione begin() della classe WiFi dentro setup(), perchè si utilizza una volta sola: una volta aperta la connessione (inizializzazione) si passa al suo utilizzo (dentro loop() ).

Un’altra funzione interessante della classe WiFi è config().

Questa funzione ci permette di specificare la configurazione da utilizzare definendo un indirizzo IP statico, e gli indirizzi di DNS, gateway e di subnet del modulo WiFi (sia shield che integrato) su Arduino. Generalmente si dovrebbe utilizzare prima di chiamare la funzione begin().

WiFi.config(ip);
WiFi.config(ip, dns);
WiFi.config(ip, dns, gateway);
WiFi.config(ip, dns, gateway, subnet);

Vediamo l’utilizzo di questa funzione con uno sketch di esempio. Per prima cosa si deve definire un indirizzo IP statico e questo lo possiamo fare istanziando un oggetto della classe IPAddress, sempre appartenente alla libreria WiFi.

In questo esempio, dopo aver effettuato la connessione (se tutto è andato correttamente), sul terminale verrà visualizzato l’indirizzo IP statico del modulo WiFi di Arduino. Questa informazione si ottiene mediante la funzione localIP() che restituisce un valore della classe IPAddress. Per poterlo visualizzare in maniera classica, cioè tipo “192.168.1.77” è necessario aggiungere una funzione IpAddress2String() non presente nella libreria. Il codice di implementazione di questa funzione è nella parte finale dello sketch.

Esiste inoltre un set di funzioni molto utili, in particoalre quando si vuole fare una scansione delle reti WiFi disponibili.

  • scanNetworks()
  • SSID()
  • RSSI()
  • encryptionType()

La funzione scanNetworks() effettua la scansione delle reti WiFi disponibili e ne restituisce il numero. Quindi mettiamo conto che siano state rilevate 7 reti, ad ogni rete rilevata verrà assegnato uno di questi numeri. Le funzioni SSID(), RSSI() e encryptionType() fornendo come argomento questo numero, forniranno rispettivamente il nome della rete, la potenza del segnale e il tipo di criptografia utilizzata.

Non c’è metodo migliore per imparare queste funzioni che utilizzarle in un esempio. Vediamo uno sketch che le utilizza tutte quante.

Altre funzioni che possono essere utili:

  • ping()
  • status()
  • macAddress()
  • BSSID()

La funzione ping() permette di verificare la presenza sulla rete di un dispositivo con un determinato indirizzo IP.

La funzione status() verifica e restituisce lo stato corrente della connessione WiFi. Questa funzione viene sp.esso utilizzata dato che risulta molto utile all’interno delle condizioni durante la programmazione. Gli stati possibili sono i seguenti

  • WL_CONNECTED: assigned when connected to a WiFi network;
  • WL_AP_CONNECTED : assigned when a device is connected in Access Point mode;
  •  WL_AP_LISTENING : assigned when the listening for connections in Access Point mode;
  • WL_NO_SHIELD: assigned when no WiFi shield is present;
  • WL_IDLE_STATUS: it is a temporary status assigned when WiFi.begin() is called and remains active until the number of attempts expires (resulting in WL_CONNECT_FAILED) or a connection is established (resulting in WL_CONNECTED);
  • WL_NO_SSID_AVAIL: assigned when no SSID are available;
  • WL_SCAN_COMPLETED: assigned when the scan networks is completed;
  • WL_CONNECT_FAILED: assigned when the connection fails for all the attempts;
  • WL_CONNECTION_LOST: assigned when the connection is lost;
  • WL_DISCONNECTED: assigned when disconnected from a network;

Infine la funzione macAddress() restituisce il valore di MacAddress del modulo WiFi presente su Arduino.

WiFi.macAddress(mac);

come argomento accetta un array di 6 byte che viene valorizzato dalla funzione.

La funzione BSSID() infine restituisce il mac address del router a cui sei connesso.

Esiste online uno sketch di esempio davvero molto interessante che include tutte le funzioni precedenti ed è molto rappresentativo dell’uso di questa libreria. Vi riporto qui il codice.

La classe IPAddress

La classe IPAddress, che abbiamo già utilizzato negli esempi precedenti, è strettamente connessa alla classe precedente e le sue funzioni hanno solo lo scopo di restituire gli indirizzi IP impostati nella configurazione corrente:

  • localIP()
  • subnetMask()
  • gatewayIP()

La classe Server

Questa classe permette di gestire il modulo Arduino come un server WiFi. Quindi fornirà una serie di funzioni atte allo scopo di inviare e ricevere dati dai diversi client connessi.

Vediamo un breve esempio di avvio di un Server WiFi in ascolto sulla porta 80.

Come possiamo vedere dall’esempio dopo l’avvio della connessione WiFi, si attiva il server WiFi tramite la funzione begin().

Per la scrittura e l’invio dei dati, la classe mette a disposizione queste funzioni:

  • write()
  • print()
  • println()

Estendiamo l’esempio precedente facendo in modo che i messaggi ricevuti da un client e letti vengano reinviati a tutti i client in ascolto.

La classe Client

Allo stesso modo della classe Server esiste una classe Client che gestisce l’invio e la ricezione di pacchetti dati.

Anche qui le funzioni di lettura e scrittura dei dati vengono svolte da un set di funzioni:

  • write()
  • println()
  • print()
  • read()
  • flush()

La funzione flush() cancella tutti i dati che sono stati ricevuti dal Client ma che non sono stati ancora letti.

La classe UDP

Per quanto riguarda l’invio e la ricezione dei dati, questi possono essere inviati tramite il protocollo UDP (User Datagram Protocol) che a differenza dei pacchetti TCP, questi funzionano in modalità connectionless. Cioè i pacchetti vengono inviati senza controllo della loro corretta ricezione dall’altra parte (non c’è un reinvio in caso di errore) ed inoltre non esiste alcun sistema di ordinazione dei pacchetti. In compenso questo protocollo è molto veloce.

La classe UDP si occupa proprio della gestione dei messaggi UDP da inviare o ricevuti. La funzione beginPacket() inizializza una connessione per l’invio di un pacchetto UDP

WiFiUDP.beginPacket(hostName, port);
WiFiUDP.beginPacket(hostIp, port);

mentre la funzione endPacket() termina il pacchetto UPD e lo invia.

La classe mette a disposizione una serie di funzioni per la scrittura, lettura e gestione dei dati da inviare.

  • write()
  • peek()
  • read()
  • flush()

Vediamo un esempio in cui viene inviata e ricevuta una stringa tramite messaggi UDP

Connettersi ad una rete di tipo WEP

Questa tipologia di rete richiede una chiave esadecimale di lunghezza variabile (da 40 a 128 bit) associata ad un numero di chiave.
Lo sketch di esempio mostrerà come connettersi ad una rete WEP chiamata “yourNetword” che per chiave “ABBADEAF01” e come key index “0”.

Conclusioni

In questo articolo abbiamo visto come la libreria WiFi101 ci permetta di sfruttare appieno le capacità dei sistemi Arduino di interfacciarsi ad una rete WiFi. Abbiamo analizzato a fondo la libreria vedendo in dettaglio le classi di cui è composta e le loro relativi funzioni, insieme ad alcuni piccoli esempi. Infine alcuni sketch hanno dato una panoramica generale su come possa essere utilizzata questa libreria e su come si possa integrare Arduino nello sviluppo di progetti IoT.

Lascia un commento