Come sfruttare MicroPython per la realizzazione di applicazioni embedded con XBee3

Il connubio tra hardware a basso livello e linguaggio di programmazione ad alto livello potrebbe rivelarsi una delle mosse vincenti per lo sviluppo di sistemi embedded. In questo articolo vedremo come il linguaggio di programmazione orientato agli oggetti come quello di Python può affacciarsi, grazie alla sua implementazione MicroPython, a contesti di sviluppo di applicazioni embedded. Continueremo a lavorare con i nostri moduli XBee3 e finalmente scopriremo come scrivere un programma che può consentire al modulo di lavorare in maniera autonoma per la gestione di applicazioni custom.

Introduzione

Nello scorso appuntamento abbiamo iniziato ad apprezzare le potenzialità fornite da XCTU, il tool gratuito offerto dalla DIGI per la programmazione dei moduli XBee3. In particolare, dopo una rapida analisi delle caratteristiche dei nuovi moduli, abbiamo realizzato una nostra prima applicazione che sfrutta il protocollo ZigBee. L’applicazione in questione consentiva la creazione di una rete PAN con annessa configurazione di un Coordinator e di un Router, nodi fondamentali per il rispetto delle caratteristiche del protocollo. Conclusa la fase di configurazione ci siamo accertati del loro funzionamento verificando in un primo momento la costruzione della rete e successivamente ci siamo sincerati che i due moduli comunichino. Al fine di testare il corretto trasferimento dei messaggi ci siamo preoccupati di come eseguire una valida costruzione di un frame e abbiamo visto come la modalità API mode ci consente di ricavare diverse informazioni sulla qualità del messaggio inviato.

In questo articolo continueremo con la nostra pratica ed entreremo sempre più nel vivo delle potenzialità offerte dai nuovi moduli. Come già accennato nell’appuntamento “Alla scoperta degli Xbee3” una delle principali features che rende questi nuovi moduli degni di nota è l’introduzione al linguaggio di programmazione orientato agli oggetti che consente di realizzare applicazioni ancora più custom e in particolare ci permette di svincolarci dalla necessità di microcontrollori esterni come accadeva nelle precedenti serie di XBee. Il focus di oggi sarà proprio MicroPython e la programmabilità dei moduli XBee3. Ma abbandoniamo le parole e iniziamo con la pratica!

MicroPython

Ma cos’è MicroPython? E perché proprio lui? Come viene riportato nella documentazione ufficiale offerta da micropython.org : "MicroPython è un’implementazione snella ed efficace del linguaggio di programmazione Python3 che include un piccolo sottoinsieme delle librerie standard Python ed è ottimizzato per l’esecuzione su microcontrollori".

È proprio partendo dall’ottimizzazione per i microcontrollori che nel 2013 questo progetto ha avuto inizio, ponendosi l’obbiettivo di consegnare agli sviluppatori un ambiente che gode delle potenzialità di un linguaggio di programmazione orientato agli oggetti come il Python, ma al tempo stesso risulta compatto e adatto per la realizzazione di applicazioni embedded con risorse limitate. La leggerezza di questa implementazione può essere apprezzata osservando che il MicroPython è pensato per lavorare in condizioni limite come 16kB di RAM. Anticipiamo che nei moduli XBee3 RF è integrato il microcontrollore HCS08 con circa 1MB di memoria disponibile di cui è allocato uno spazio pari a 32kB per l’Heap di memoria destinata all’utilizzo di variabili, oggetti e moduli importati. Abbiamo detto che MicroPython è un’implementazione del linguaggio di programmazione Python3 ma allo stesso tempo, visto il suo scopo, presenta distinzioni con tale linguaggio. Le principali differenze che si hanno tra il MicroPython e CPython3, considerata l’implementazione di riferimento del linguaggio Python3, sono le seguenti:

  • in MicroPython non è supportata l’intera libreria standard del linguaggio di programmazione Python;
  • MicroPython utilizza come mezzo principale per la gestione della memoria il garbage collection;
  • con MicroPython le metaclassi non sono supportate;
  • usi avanzati del linguaggio come ereditarietà multipla potrebbero non funzionare.

Per avere una lista più dettagliata delle differenze potete dare un'occhiata qui. Siccome lo scopo di questo articolo non è quello di entrare nel dettaglio del linguaggio di programmazione Python3, ci limiteremo a menzionare le sue strutture dati e statement solo al momento del loro utilizzo.

MicroPython terminal

Prima di analizzare l’ambiente di sviluppo dobbiamo abilitare le API di MicroPython per consentire il corretto funzionamento. Per fare questo dobbiamo tornare nell’area Configuration Working di XCTU e abilitare nella sezione UART Interface la API Enable: MicroPython REPL[4]. Questo passaggio viene riportato in Figura 1.

Figura 1: enable MicroPython da XCTU

Entriamo ora nel vivo della programmazione dei moduli XBee3, in particolare vediamo come programmarli grazie ad XCTU. Per fare questo, XCTU ci mette a disposizione in Tools un MicroPython Terminal, si veda Figura 2, con il quale sarà possibile interfacciarsi con il modulo e rendere interattiva la programmazione.

Figura 2: Accesso a MicroPython Terminal tramite XCTU

Una volta entrati in MicroPython Terminal e chiusa la connessione seriale possiamo eseguire subito un test per accertarci della comunicazione digitando la sequenza di caratteri +++. Nel caso di un esito positivo otterremo un messaggio di ritorno ‘ok’ come quello riportato in Figura 3, in caso contrario accertatevi che sia garantita una buona comunicazione con il modulo.

Figura 3: messaggio di ritorno per il check della comunicazione con il modulo XBee3

Per accedere al prompt useremo quello che viene chiamato con l’acronimo REPL(Read-Eval-Print-Loop), un linguaggio di shell che accetta un input dell’utente, lo valuta e restituisce un risultato come output. I principali comandi REPL che utilizzeremo sono:

  • CTRL+B, consente di accedere all’ambiente di MicroPython;
  • CTRL+D, effettua il reboot del REPL ripulendolo da ogni variabile e funzione dichiarati in precedenza;
  • CTRL+E, permette l’accesso alla modalità paste mode dov'è consentito testare righe di codice senza scriverle nella memoria flash del dispositivo;
  • CTRL+F, permette l'accesso alla modalità flash mode dov’è consentito compilare e salvare il nostro codice nella flash del device.

Una volta che ci siamo accertati della comunicazione possiamo entrare nell’ambiente di sviluppo di MicroPython utilizzando il comando REPL CTRL+B e se tutti i passaggi sono andati a buon fine saremo nella situazione riportata in Figura 4.

Figura 4: accesso effettuato alla shell di MicroPython

Siamo ora dentro l’ambiente! Per accertarci di quanto detto inizialmente sulle specifiche hardware e sui moduli software disponibili eseguiamo il comando:

>>help('modules')

Grazie a questo comando otterremo una lista dei moduli software resi disponibili da MicroPython. È lecito chiedersi che cosa sono per Python i moduli, pertanto prima di continuare diamo una rapida definizione a questo concetto. In Python i moduli sono semplicemente dei files usati per raggruppare costanti, funzioni e classi, nulla di più. In altri linguaggi di programmazione vengono chiamati librerie. Al fine di utilizzare specifiche classi o funzioni di un modulo viene utilizzato lo statement import, vedremo in seguito come utilizzarlo. Inoltre, aggiungiamo a scopo informativo che nel momento in cui il progetto cresce ed insieme ad esso aumentano anche i moduli, è preferibile aggiungere un ulteriore livello di astrazione per evitare di mettere moduli dentro altri moduli. Per rendere concreto questo livello di astrazione ci viene in aiuto il package. Con questo termine ci riferiamo ad una collezione di moduli presenti in una cartella dove il nome della cartella corrisponde al nome del package. Non allarmatevi se non avete confidenza con questi termini, nei prossimi appuntamenti vedremo come usarli. Definito questo concetto possiamo tornare al nostro ambiente di MicroPython. In Figura 5 è riportato l’elenco completo dei moduli disponibili ma i principali che useremo in questa prima fase di avvicinamento sono:

  • gc, modulo per il controllo del garbage collector. A differenza del modulo in CPython implementa il metodo mem_alloc() che ritorna un numero di byte di Heap che sono allocati e il metodo mem_free() che ritorna il numero di byte di Heap disponibili;
  • builtins, racchiude tutte le funzioni di bult-in;
  • sys, ci permette di avere informazioni sul sistema;
  • machine, questo modulo contiene funzioni specifiche per la gestione della parte hardware del relativo device.

All’interno del modulo machine sono presenti classi come la Pin Class, ADC class, SPI class e altre classi per la gestione della parte hardware. È bene prestare attenzione all’utilizzo di questo modulo in quanto, se usato in maniera scorretta, può portare a malfunzionamenti, blocchi, arresti della scheda e in casi estremi danni all’hardware. In questa prima fase ci limitiamo a trascurare gli altri moduli disponibili ma torneremo ad analizzarli al momento del loro utilizzo. Evidenziamo che nel caso in cui ci fosse la necessità di un modulo specifico, ad esempio per la gestione di un particolare sensore, potremmo tranquillamente realizzarlo e aggiungerlo al file system. Presa ormai consapevolezza di cosa sono i moduli, quali sono disponibili e come importarli, vediamoli subito all’opera. Abbiamo detto inizialmente che nei moduli XBee3 viene riservata una Heap di memoria per MicroPython pari a 32 kB, accertiamoci di questo dato. Per questo test, riportato in Figura 5, utilizziamo il modulo relativo al garbage collector importandolo nell'ambiente e invocando prima il metodo mem_free() e successivamente il metodo mem_alloc().

Figura 5: test per il controllo della memoria disponibile con il modulo garbage collector

Accertati che abbiamo a nostra disposizione uno spazio complessivo pari a 32 kB procediamo con le prossime verifiche. Grazie al modulo sys possiamo ottenere diverse informazioni, riportate in Figura 6, relative al device XBee3 come la versione, la piattaforma che stiamo utilizzando, l’implementazione e molto altro.

Figura 6: test con il modulo sys

Ottimo! Abbiamo a questo punto già visto diversi nodi fondamentali, siamo ora in grado di accedere all’ambiente di sviluppo tramite terminale, sappiamo cosa sono in Python i moduli, come utilizzarli e abbiamo verificato alcune specifiche dichiarate inizialmente. Questo non è ancora niente di quello che seguirà, stiamo per scrivere il nostro primo firmware per consentire al modulo XBee3 la gestione dei pin digitali. Prima però dovete prestare ancora un pò di pazienza in quanto esamineremo ora un aspetto che ci risulterà comodo. [...]

ATTENZIONE: quello che hai appena letto è solo un estratto, l'Articolo Tecnico completo è composto da ben 3235 parole ed è riservato agli ABBONATI. Con l'Abbonamento avrai anche accesso a tutti gli altri Articoli Tecnici e potrai fare il download in formato PDF eBook e Mobi per un anno. ABBONATI ORA, è semplice e sicuro.

Scarica subito una copia gratis

Scrivi un commento

Seguici anche sul tuo Social Network preferito!

Send this to a friend