Impariamo come utilizzare il microcontroller Wio dev board RP2040 distribuito da Seeed Studio per attività di monitoraggio della rete wireless.
Abbiamo recentemente presentato la scheda Wio Dev Board RP2040 distribuita da Seeed Studio, un microcontrollore ad alte prestazioni basato su processore ARM Cortex M0+ dual core. Oggi impareremo a programmarne le attivbità attraverso il linguaggio Python.
Il progetto che presenteremo consentirà di mantenere sotto controllo le caratteristiche di trasmissione della nostra rete wireless.
Il programma base
Per prima cosa occorre definire un programma in grado di acquisire le informazioni attraverso l’antenna wifi del microcontrollore.
Apriamo il nostro fido Thonny, e dopo aver installato l’ultima versione del firmware della scheda, scriviamo quanto segue:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
import network import usocket from machine import Pin, I2C, ADC, UART, SPI, PWM from time import sleep N1 = network.WLAN_SPI(network.STA_IF) N1.active(True) print("API list:") dir(N1) print("wifi list:") lis = N1.scan() for q in lis: print(q) N1.connect("FASTWEB-3CZFU9","KHDSNUK69G") if N1.isconnected(): print(" ip gateway netmask MAC ssid") print(N1.ifconfig()) |
Dopo aver importato le librerie micropython necessarie alla connessione, creiamo la connessione N1 come WLAN_SPI, ed attiviamola. Quindi richiediamo la lista delle reti presenti nelle vicinanze (N1.scan) e stampiamo il risultato. Infine,se la connessione funziona, stampiamo la configurazione della scheda.
Il risultato è il seguente:
Interessante… ma come può tornarci utile?
Python is your friend
Il metodo isconnected() restituisce una lista di oggetti. Possiamo accedere a ciascuno di essi attraverso una notazione posizionale in questo modo:
1 2 3 4 5 6 |
l = N1.ifconfig() print ("IP = ", l[0]) print ("gateway = ", l[1]) print ("netmask = ", l[2]) print ("MAC = ", l[3]) print ("ssid = ", l[4]) |
Allo stesso modo possiamo eseguiire la scansione di lis, che contiene i valori della scansione (come indicato a riga 13-15 del precedente listato). Ciascun elemento della lista è una stringa, quindi è possibile estrarre i parametri necessari attraverso le funzioni di Python. Poniamo di voler gestire un piccolo db contenente nome della rete e potenza del segnale in dB: sarà sufficiente creare una semplice funzione per acquisire i valori attraverso il metodo .split() e salvare i parametri posti in posizzione 1 e 2.
1 2 3 4 5 6 |
reti = list() potenza = list() for testo in lis: lista2 = testo.split(",") reti.append(lista2[1]) potenza.append(lista2[2]) |
A questo punto non ci resta che salvare i dati acquisiti in un database per gestirne in seguito la serie temporale.
Ma siamo su un microcontrollore, e la memoria a disposizione potrebbe non essere sufficiente… come fare?
Socket programming
L’idea è quella di utilizzare un sistema client-server basato su socket programming, in cui il client è rappresentato dal mistro Wio RP2040 ed il server da un PC in rete.
Il sorgente del client verrà modificato in questo modo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
import network import usocket from machine import Pin, I2C, ADC, UART, SPI, PWM from time import sleep reti = list() potenza = list() N1 = network.WLAN_SPI(network.STA_IF) N1.active(True) print("Preparazione dati:") dir(N1) # Creiamo la lista dei risultati lis = N1.scan() # Estraiamo gli elementi da monitorare for testo in lis: lista2 = testo.split(",") reti.append(lista2[1]) potenza.append(lista2[2]) N1.connect("FASTWEB-3XXXX0","XXXXXXX00X") if N1.isconnected(): s = usocket.socket() addr=('192.168.1.50',20000) s.connect(addr) for i in range(len(reti)): comando = "" comando = "Elemento " + str(i) + " Rete = " + reti[i] + " " + " - potenza = " + potenza[i] s.send(comando.encode()) s.close() |
Stavolta il client, anziché stampare la lista di dati a terminale, provvederà a formattarli ed inserirli nelle liste reti e potenza.
A riga 28 verrà effettuata la connessione al socket server, mentre il loop alle righe 30-33 provvederà a creare le stringhe di informazioni da inviare.
L’ultimo comando chiude la connessione.
Lato server, la situazione è ancora più semplice:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
import socket def ricevi_comandi(conn): while True: richiesta = conn.recv(4096) risposta = richiesta.decode() print(risposta) def sub_server(indirizzo, backlog=1): try: s = socket.socket() s.bind(indirizzo) s.listen(backlog) print("Server Inizializzato. In ascolto...") except socket.error as errore: print(f"Qualcosa è andato storto... \n{errore}") print(f"Sto tentando di reinizializzare il server...") sub_server(indirizzo, backlog=1) conn, indirizzo_client = s.accept() #conn = socket_client print(f"Connessione Server - Client Stabilita: {indirizzo_client}") ricevi_comandi(conn) if __name__ == '__main__': sub_server(("192.168.1.50", 20000)) |
Il codice definisce le impostazioni di ascolto del server (righe 13-16), quindi, se tutto è andato bene, si appresta a ricevere l’indirizzo del client per stampare un messaggio di avvenuta connessione.
Quindi si pone in configurazione di ascolto (ricevi_comandi(), riga 3), ricevendo le stringhe trasmesse dal client, decodificandone il contenuto e stampando a video il risultato.
Note di implementazione:
Il sistema è nato per valutare le caratteristiche della scheda Wio RP2040 di SeeedStudio (reperibile sul loro sito). I programmi presentati sono stati scritti cercando di valutare se, con l’ultima release del firmware, il prodotto fosse “compliant” con le librerie di programmazione di MicroPython. I test che abbiamo effettuato mostrano che il sistema client server funziona come previsto, anche se l’implementazione dei sorgenti non è a prova di errore.
Un possibile sviluppo successivo potrebbe essere rappresentato da una modifica al server: a riga 7, anziché limitarci a stampare una stringa, potremmo inviare le informazioni verso un database. Magari dopo aver estratto i componenti come abbiamo visto sul client. Utilizzando il modulo RTC presente sulla scheda, potremmo temporizzare gli invii ogni tot minuti, ed avere sul database l’insieme dei valori di copertura della rete nel medio periodo. Oppure lanciare un allarme in caso di calo della potenza del segnale. Con un po’ di fantasia è facile rendertsi conto delle infinite possibilità di applicazionie della scheda.
Considerazioni finali
Dopo un nutrito scambio di informazioni e messaggi con Seeed Studio, siamo riusciti a mettere le mani su un firmware della scheda sufficientemente stabile, che rende la board perfettamente utilizzabile. Abbiamo tenuto la scheda in funzione per diverse ore, senza riscontrare alcun surriscaldamento o blocco del funzionamento. Riteniamo pertanto di poter concludere i test con un voto più che sufficiente: anche se limitata a 2.4G, la scheda RP2040 in accoppiata con il sistema WiFi risulta vincente in tutte quelle situazioni in cui abbiamo un sistema di controllo distribuito, basato su sensori e pilotato da una MCU, ma desideriamo centralizzarne le informazioni.
Iscrivetevi ai nostri gruppi Telegram…