Torna al catalogo
Season 46 7 Episodi 26 min 2026

MicroPython

Edizione 2026. Una guida completa a MicroPython per microcontrollori. Scopri come eseguire un interprete Python 3 completo su hardware bare-metal.

Sistemi Embedded Microcontrollori Python Core
MicroPython
In Riproduzione
Click play to start
0:00
0:00
1
Il Python che sta in 256K
Scopri come MicroPython comprime un interprete Python 3 completo in microcontrollori bare-metal. Esploriamo la sua identità principale, le sue differenze rispetto a CPython e come riesce a funzionare in ambienti altamente vincolati.
3m 48s
2
Il ponte hardware: Il modulo machine
Impara a controllare le periferiche del microcontrollore direttamente da Python. Ci immergiamo nel modulo machine, esplorando come interagire con Pin, PWM e memoria raw.
3m 37s
3
Live Coding sull'MCU: REPL e mpremote
Rivoluziona il tuo flusso di lavoro di sviluppo embedded. Trattiamo il REPL di MicroPython e lo strumento a riga di comando mpremote per automatizzare le connessioni seriali e l'esecuzione live.
3m 53s
4
Tre righe per il WiFi: Il modulo network
Trasforma un microcontrollore in un nodo IoT connesso. Esploriamo il modulo network, spiegando in dettaglio come connettersi al WiFi come station o ospitare il tuo Access Point.
3m 42s
5
Sopravvivere ai vincoli: RAM e GC
Padroneggia l'arte di scrivere codice Python efficiente in termini di memoria. Discutiamo della frammentazione dell'heap, della pre-allocazione dei buffer e della garbage collection manuale per mantenere il tuo microcontrollore in funzione senza problemi.
3m 41s
6
Compilato vs. Frozen: Deploy in produzione
Impara a fare il deploy di applicazioni enormi senza esaurire la RAM. Esploriamo i file .mpy precompilati e il freezing del bytecode direttamente nella memoria flash del microcontrollore.
3m 46s
7
Determinismo in Python: Timer e Interrupt
Ottieni un comportamento real-time in MicroPython utilizzando timer hardware e interrupt service routine. Trattiamo le rigide regole per scrivere ISR ed evitare l'allocazione di memoria.
4m 06s

Episodi

1

Il Python che sta in 256K

3m 48s

Scopri come MicroPython comprime un interprete Python 3 completo in microcontrollori bare-metal. Esploriamo la sua identità principale, le sue differenze rispetto a CPython e come riesce a funzionare in ambienti altamente vincolati.

Download
Ciao, sono Alex di DEV STORIES DOT EU. MicroPython, episodio 1 di 7. Il Python per desktop normalmente consuma megabyte di memoria solo per avviarsi. Prova a metterlo su un minuscolo chip da due dollari e il sistema esaurirà immediatamente le risorse. Per scrivere in Python sui microcontrollori, hai bisogno di un interprete che occupi una frazione di quello spazio senza perdere le feature fondamentali del linguaggio su cui fai affidamento. Questo è esattamente ciò che offre MicroPython. MicroPython è un'implementazione snella ed estremamente efficiente del linguaggio di programmazione Python 3. È progettato specificamente per funzionare in ambienti con risorse limitate. Il Python standard, spesso chiamato CPython, presuppone di girare su un sistema operativo completo come Linux o Windows, con gigabyte di storage e RAM in abbondanza. MicroPython ribalta questo presupposto. È progettato per girare bare metal. Non c'è un sistema operativo sottostante che gestisce l'hardware. Invece, MicroPython funge da sistema operativo. Si interfaccia direttamente con l'hardware, così puoi scrivere script di alto livello per controllare dispositivi fisici. L'ingegneria dietro a tutto questo si concentra interamente sui severi limiti di risorse. MicroPython può girare interamente in soli 256 kilobyte di spazio per il codice compilato. Cosa ancora più impressionante, richiede appena 16 kilobyte di RAM per funzionare. Entro questi limiti ristretti, offre un ambiente Python completo e funzionale. Il Python standard include un'enorme standard library, famosa per l'approccio batteries included. MicroPython la riduce a un sottoinsieme di moduli scelto con cura, mantenendo solo ciò che ha senso per un sistema embedded. Nonostante queste pesanti ottimizzazioni, il linguaggio in sé rimane autentico Python 3. Questo significa che il codice che scrivi sul tuo desktop si traduce direttamente sul dispositivo embedded. MicroPython supporta feature avanzate del linguaggio come closure, list comprehension, generatori e l'exception handling standard. Gestisce persino numeri interi a precisione arbitraria. Se la tua logica richiede di moltiplicare numeri enormi, MicroPython scala la memoria dinamicamente per darti la risposta corretta senza schiantarsi contro un limite architetturale rigido, esattamente come il Python per desktop. Ecco il punto chiave. Dato che l'intero engine Python ci sta sul chip, hai a disposizione un prompt interattivo live direttamente sull'hardware. Questo read-eval-print loop cambia il modo in cui scrivi codice embedded. Normalmente, programmare un microcontrollore significa scrivere codice in C, compilarlo sul tuo desktop, flasharlo sulla scheda e aspettare che giri. Con MicroPython, colleghi la scheda al computer, apri un terminale seriale e digiti comandi Python direttamente nel chip. Puoi testare la logica, leggere i valori dei sensori o attivare azioni istantaneamente. Per rendere tutto questo possibile, MicroPython include specifici moduli built-in che vanno oltre il Python standard. Dato che il Python standard non sa nulla su come leggere pin fisici o configurare timer hardware, MicroPython fornisce interfacce specializzate e altamente ottimizzate per questi task. Queste sono integrate direttamente nel firmware per il tuo specifico chip, dandoti un controllo raw sul mondo fisico senza appesantire il memory footprint. Eliminando il sistema operativo e rimpicciolendo l'interprete per farlo stare in 256 kilobyte, MicroPython trasforma hardware economico e a corto di risorse in un ambiente di sviluppo dinamico e interattivo. Se vuoi supportare lo show, puoi trovarci cercando DevStoriesEU su Patreon. Grazie per l'ascolto. Alla prossima!
2

Il ponte hardware: Il modulo machine

3m 37s

Impara a controllare le periferiche del microcontrollore direttamente da Python. Ci immergiamo nel modulo machine, esplorando come interagire con Pin, PWM e memoria raw.

Download
Ciao, sono Alex di DEV STORIES DOT EU. MicroPython, episodio 2 di 7. Smetti di ricompilare il codice C e di flashare il firmware solo per testare un sensore o azionare un interruttore. Vuoi avere il controllo diretto del tuo microcontrollore senza boilerplate, ed è esattamente ciò che offre il modulo machine. Il modulo machine è il tuo ponte hardware. Traduce il codice Python nei segnali elettrici che pilotano i pin fisici sulla tua scheda. Fornisce l'accesso alle funzionalità hardware principali come la frequenza della CPU, le sleep mode e gli input e output digitali. Ma dato che lavora così a basso livello, porta con sé un avvertimento. Questo modulo non ti tiene per mano. Se configuri il registro hardware sbagliato o scrivi in un indirizzo di memoria protetto, la tua scheda andrà in crash e si riavvierà. La base di questo modulo è la classe Pin. Un pin è una connessione fisica sul microcontrollore che può inviare o ricevere tensioni elettriche. Per controllare un componente di base come un LED, devi inviare tensione a un pin specifico. Lo fai importando il modulo machine e creando un oggetto Pin. Fornisci il numero del pin fisico e definisci se il pin deve funzionare come input o come output. Per un LED, lo configuri come output passando una costante di output. Una volta creato l'oggetto, lo usi per impostare lo stato. Applicando un valore pari a uno, porti la linea hardware a livello alto e accendi il LED. Applicando un valore pari a zero, la porti a livello basso e lo spegni. Stai manipolando lo stato digitale dell'hardware in tempo reale da un prompt Python. A volte, i semplici stati di on e off non bastano. Se vuoi attenuare quel LED o controllare la velocità di un motore, ti serve la Pulse Width Modulation, o PWM. Il modulo machine ha una classe PWM dedicata a questo. Invece di un flusso costante di tensione, il PWM accende e spegne il pin in modo estremamente veloce. Crei un oggetto PWM passandogli l'oggetto Pin che hai già configurato. Poi, imposti due parametri hardware: frequenza e duty cycle. Ecco il punto chiave. La frequenza stabilisce quante volte al secondo il segnale compie un ciclo, mentre il duty cycle stabilisce per quale percentuale di quel tempo il segnale è effettivamente su on. Se imposti il duty cycle al cinquanta percento, il LED riceve corrente solo per metà del tempo, facendolo apparire luminoso la metà all'occhio umano. Cambiando gradualmente quel valore di duty cycle all'interno di un loop, istruisci l'hardware a creare un effetto di fading fluido. Per casi d'uso avanzati, il modulo machine offre l'accesso diretto ai registri hardware sottostanti tramite oggetti chiamati mem8, mem16 e mem32. Questi ti permettono di leggere e scrivere raw byte, half-word o word a 32 bit direttamente in specifici indirizzi di memoria. Non usi un oggetto Pin per questo. Usi la notazione standard con parentesi quadre, passando l'indirizzo di memoria fisico a cui vuoi accedere, esattamente come quando cerchi una chiave in un dizionario. Assegnare un valore a un indirizzo mem32 sovrascrive istantaneamente quel registro hardware. È così che interagisci con funzionalità oscure del microcontrollore che MicroPython non ha ancora esplicitamente wrappato in una classe. Ti dà un'autorità assoluta sul silicio. Il vero potere del modulo machine non è solo che rende l'hardware accessibile, ma che rimuove completamente la barriera tra lo scrivere logica software ad alto livello e il manipolare la tensione fisica. Grazie per l'ascolto. Statemi bene, tutti.
3

Live Coding sull'MCU: REPL e mpremote

3m 53s

Rivoluziona il tuo flusso di lavoro di sviluppo embedded. Trattiamo il REPL di MicroPython e lo strumento a riga di comando mpremote per automatizzare le connessioni seriali e l'esecuzione live.

Download
Ciao, sono Alex di DEV STORIES DOT EU. MicroPython, episodio 3 di 7. Dimentica il noioso ciclo di compile, flash e reboot. In un tipico progetto embedded, cambi una variabile, aspetti minuti per una build, scrivi sulla memoria flash e speri che funzioni. MicroPython bypassa completamente tutto questo, permettendoti di parlare direttamente con il chip in tempo reale. Questo episodio parla del Live Coding sull'MCU usando il REPL e mpremote. REPL sta per Read-Eval-Print Loop. È un prompt interattivo che gira direttamente sul tuo microcontrollore. Colleghi la tua board via USB, apri un terminale seriale, scrivi codice Python e il chip lo esegue all'istante. Il REPL standard è pensato per gli umani. Offre auto-indentation, command history e un auto-completion di base. È perfetto per testare un rapido toggle di un pin hardware. Tuttavia, esiste una seconda modalità chiamata raw REPL. Spesso la si confonde con una versione limitata di MicroPython, ma in realtà è solo una diversa modalità di input attivata inviando uno specifico carattere di controllo via seriale. Il raw REPL disabilita il character echo e l'auto-indentation. I tool usano il raw REPL per iniettare programmaticamente grandi blocchi di codice nel microcontrollore. Se uno script provasse a incollare del testo nel REPL standard, l'auto-indentation pensata per gli umani si applicherebbe a cascata e distruggerebbe completamente la formattazione Python. Il raw REPL garantisce che il codice entri esattamente come è stato scritto. Questo ci porta a mpremote. È il tool da command-line ufficiale per interagire con i device MicroPython, e pilota il raw REPL dietro le quinte per fare il lavoro pesante. Per il live coding, mpremote offre due potenti comandi: run e mount. Usi il comando run per eseguire uno script locale dal tuo computer direttamente sulla board. Scrivi il tuo codice nel tuo text editor preferito, apri il terminale e invochi mpremote run seguito dal nome del tuo file. Ecco il punto chiave. Il codice viene inviato sulla linea seriale ed eseguito interamente nella RAM del microcontrollore. Non viene mai scritto nella memoria flash del device. Se scrivi un loop sbagliato e fai crashare la board, fai semplicemente un hard reset del chip. La flash rimane intatta, risparmiando cicli di scrittura, e il tuo development loop richiede solo pochi secondi. Quando il tuo progetto cresce oltre un singolo script, usi il comando mount. Questo comando dice a mpremote di prendere una directory locale sul tuo PC e mapparla sulla connessione seriale. Il microcontrollore fa temporaneamente l'override del proprio storage e tratta quella cartella sul tuo computer come se fosse il suo filesystem interno. Immagina uno scenario in cui stai scrivendo un display driver complesso. Di solito, dovresti copiare il file del driver sulla board, eseguire il tuo script principale, notare un glitch sullo schermo, editare il file sul tuo PC e copiarlo di nuovo. Con il comando mount, il microcontrollore esegue il driver direttamente dallo storage del tuo PC. Premi salva nel tuo text editor sul laptop, riavvii lo script sulla board e le modifiche si applicano immediatamente. Iteri alla stessa velocità con cui scrivi, eliminando completamente lo step di flash dal tuo workflow. La vera potenza di MicroPython non è solo la sintassi Python in sé, ma come tool come mpremote cancellano il confine tra il tuo development environment locale e l'hardware embedded fisico. Questo è tutto per questo episodio. Grazie per l'ascolto, e continua a sviluppare!
4

Tre righe per il WiFi: Il modulo network

3m 42s

Trasforma un microcontrollore in un nodo IoT connesso. Esploriamo il modulo network, spiegando in dettaglio come connettersi al WiFi come station o ospitare il tuo Access Point.

Download
Ciao, sono Alex di DEV STORIES DOT EU. MicroPython, episodio 4 di 7. Connettere un microcontrollore a una rete Wi-Fi usando il tradizionale codice C di solito richiede centinaia di righe di boilerplate solo per inizializzare la radio e gestire l'handshake. È noioso e soggetto a errori. In MicroPython, puoi stabilire una connessione wireless in letteralmente tre righe. Questo è il compito del modulo network, in particolare della classe WLAN. Il modulo network astrae le interfacce di rete hardware sottostanti. Per le operazioni Wi-Fi, ti affidi alla classe network dot WLAN. Un chip Wi-Fi standard può operare in due ruoli distinti. Devi definire esplicitamente quale ruolo vuoi quando crei l'oggetto WLAN. Il primo ruolo è la modalità Station, specificata usando la costante STA underscore IF. Usi la modalità Station quando il tuo hardware deve connettersi come client a un router upstream, proprio come uno smartphone che si unisce a una rete domestica. Il secondo ruolo è la modalità Access Point, specificata usando AP underscore IF. In questa modalità, il microcontrollore funge lui stesso da router, trasmettendo la propria rete wireless in modo che i dispositivi esterni possano connettersi direttamente. La modalità Access Point è incredibilmente utile quando fai il deploy di hardware in posizioni remote dove non esiste una rete esterna, permettendoti di connetterti localmente per la configurazione. Mettere la tua board online richiede una sequenza specifica. Per prima cosa, crei l'oggetto WLAN usando la costante della modalità Station. Di default, la radio Wi-Fi fisica è spenta per risparmiare energia. Devi accenderla passando True al metodo active sul tuo oggetto WLAN. Una volta che l'interfaccia è attiva, invochi il metodo connect con il nome e la password della tua rete wireless. Ecco il punto chiave. Il metodo connect è strettamente non-blocking. Quando lo invochi, MicroPython passa le credenziali al processore di rete e continua immediatamente a eseguire il tuo script. Deliberatamente non aspetta che l'autenticazione di rete finisca. Questo design permette alla tua applicazione principale di aggiornare un display o leggere un sensore mentre la radio negozia con il router in background. Tuttavia, se il tuo codice tenta di inviare dati immediatamente dopo aver chiamato connect, l'operazione andrà in crash perché la board non ha ancora una connessione effettiva. Gestisci questo problema facendo polling sull'interfaccia. L'oggetto WLAN fornisce un metodo chiamato isconnected, che restituisce un semplice valore booleano. Il pattern standard è scrivere un ciclo while che valuta se isconnected è false. All'interno di questo ciclo, introduci un breve ritardo, come uno sleep di mezzo secondo. L'esecuzione va in pausa qui, controllando ripetutamente lo stato dell'hardware finché il router finalmente accetta la connessione e isconnected restituisce true. Una volta che il ciclo termina, l'hardware è ufficialmente online. Per verificare i dettagli della rete, chiami il metodo ifconfig sul tuo oggetto WLAN. Questo metodo restituisce una collection di quattro elementi specifici: l'indirizzo IP assegnato, la subnet mask, il gateway e il server DNS primario. Puoi estrarre il primo elemento da questa collection e stamparlo sulla console per vedere esattamente quale indirizzo IP il router ha assegnato alla tua board. La natura non-blocking del metodo connect significa che sei sempre responsabile di verificare lo stato dell'hardware prima di provare a instradare dati sulla rete. Per oggi è tutto. Grazie per l'ascolto — vai a costruire qualcosa di fantastico.
5

Sopravvivere ai vincoli: RAM e GC

3m 41s

Padroneggia l'arte di scrivere codice Python efficiente in termini di memoria. Discutiamo della frammentazione dell'heap, della pre-allocazione dei buffer e della garbage collection manuale per mantenere il tuo microcontrollore in funzione senza problemi.

Download
Ciao, sono Alex di DEV STORIES DOT EU. MicroPython, episodio 5 di 7. Python ama allocare la memoria dinamicamente, creando nuovi oggetti per ogni calcolo. Questo funziona perfettamente su un server, ma su un microcontrollore, questa abitudine finirà per mandare in crash la scheda, lasciandoti a fissare un errore di memoria anche quando apparentemente hai RAM a sufficienza. Oggi ci concentriamo su come Sopravvivere ai Vincoli: RAM e il GC. La memoria in cui risiedono i tuoi oggetti Python si chiama heap. In MicroPython, l'heap è incredibilmente piccolo. Quando crei degli oggetti, questi occupano blocchi di spazio. Quando quegli oggetti non sono più necessari, vengono eliminati. Questo lascia dei buchi nella tua memoria. Col tempo, man mano che oggetti di dimensioni diverse vengono creati e distrutti, il tuo heap diventa un groviera. Questa è la frammentazione dell'heap. Ecco il punto chiave. Quando devi allocare un nuovo oggetto, MicroPython ha bisogno di un singolo blocco di memoria contiguo per ospitarlo. Se il tuo heap è fortemente frammentato, potresti avere venti kilobyte di RAM libera in totale, ma nessun singolo spazio vuoto più grande di un kilobyte. Se chiedi due kilobyte, il tuo programma va in crash. Devi smettere di sprecare RAM, iniziando dalle tue variabili globali. Se hai valori interi che non cambiano mai, come i numeri di pin o gli indirizzi hardware, non assegnarli normalmente. MicroPython fornisce una dichiarazione speciale chiamata const. Se racchiudi il tuo intero in questa dichiarazione const, il compilatore sostituisce il nome della variabile con il numero effettivo ovunque nel tuo codice durante la compilazione. Questo impedisce del tutto la creazione di una variabile nella RAM. Poi, dai un'occhiata ai tuoi loop. La creazione dinamica di oggetti all'interno di un loop molto veloce è la causa principale della frammentazione. Stai leggendo un sensore tramite un bus SPI cento volte al secondo. Se usi un comando read standard, MicroPython crea una sequenza di byte completamente nuova in memoria per ogni singola lettura. Quegli oggetti si accumulano rapidamente, riempiendo i buchi e distruggendo il tuo spazio contiguo. Invece di creare nuovi oggetti, riutilizza quelli che hai. Prima che inizi il tuo loop, crea un bytearray della dimensione corretta. Un bytearray è un blocco di memoria mutabile. Poi, all'interno del tuo loop, usa un metodo hardware chiamato readinto. Passi il tuo bytearray preesistente a readinto. L'hardware scarica i dati del sensore direttamente in quello stesso blocco di memoria, sovrascrivendo i vecchi dati. Elabori i dati, il loop si ripete e non viene allocata nuova memoria. Anche scrivendo codice con attenzione, la creazione di alcuni oggetti è inevitabile, il che ci porta al garbage collector. Di default, il garbage collector viene eseguito automaticamente quando l'allocazione di memoria fallisce. Cerca gli oggetti non utilizzati e libera il loro spazio. Tuttavia, questo processo richiede tempo. Se si innesca automaticamente durante un'operazione time-sensitive, il tuo codice andrà in pausa in modo imprevedibile. Per risolvere questo problema, prendi tu il controllo. Chiama esplicitamente la funzione collect dal modulo gc. Trova un punto sicuro nel tuo codice, come la fine del tuo main loop, e avvia la collection lì. Questo mantiene l'heap pulito secondo le tue tempistiche, prevenendo ritardi imprevisti. Nel Python per desktop, la memoria è qualcosa che il linguaggio gestisce per te, ma in MicroPython, la memoria è un contenitore fisico che devi riempire a mano. Questo è tutto per questo episodio. Grazie per aver ascoltato, e continua a sviluppare!
6

Compilato vs. Frozen: Deploy in produzione

3m 46s

Impara a fare il deploy di applicazioni enormi senza esaurire la RAM. Esploriamo i file .mpy precompilati e il freezing del bytecode direttamente nella memoria flash del microcontrollore.

Download
Ciao, sono Alex di DEV STORIES DOT EU. MicroPython, episodio 6 di 7. Carichi un file Python perfettamente valido sul tuo microcontrollore, digiti import e la scheda va subito in crash con un errore di out-of-memory. Il codice in sé va bene, ma il processo di caricamento ha appena consumato tutta la tua memoria disponibile. Per risolvere questo problema devi bypassare il compiler sul dispositivo, il che ci porta al codice compilato rispetto al codice frozen per i deploy in produzione. Quando esegui uno script Python standard su un desktop, la memoria è praticamente infinita. Su un microcontrollore, la memoria è strettamente limitata. Quando trascini un file sorgente Python standard sul tuo dispositivo ed esegui il comando import, MicroPython non si limita a leggere il file. Il compiler si avvia direttamente lì, sul microcontrollore. Fa il parsing del testo, costruisce un abstract syntax tree e genera il bytecode. Ogni singolo passaggio alloca memoria in RAM. Considera un grande framework IoT che gestisce networking, security e dati dei sensori. Se provi a importare questo modulo enorme da un file sorgente standard, è probabile che il compiler esaurisca la memoria heap disponibile prima ancora che venga eseguita la prima riga della tua applicazione. Il picco di utilizzo della RAM durante la fase di compilazione uccide il processo. Per bypassare questo problema, devi rimuovere la fase di compilazione dal microcontrollore. Lo fai precompilando il tuo codice usando un tool desktop chiamato cross-compiler, o mpy-cross. Esegui questo tool sul tuo computer principale. Acquisisce il tuo file sorgente Python e genera in output un file compilato con estensione M-P-Y. Questo file contiene il bytecode pre-generato. Quando trasferisci questo file compilato sul microcontrollore e lo importi, MicroPython riconosce il formato e salta completamente la fase di compilazione. Eviti completamente il picco di memoria causato dal compiler. Ed è qui che la cosa si fa interessante. Anche se la precompilazione ti salva dal picco di memoria della compilazione, il microcontrollore carica comunque il bytecode effettivo dal file system in RAM per poterlo eseguire. Se il tuo framework IoT è abbastanza grande, il solo bytecode consumerà comunque troppa RAM, lasciandoti con pochissimo spazio per le variabili e i dati della tua applicazione. Quando i file precompilati non bastano, il passaggio finale è il freezing del bytecode. Il freezing significa integrare il codice compilato direttamente nel firmware di MicroPython. Invece di copiare il file compilato nel file system della scheda, lo metti in una directory modules specifica all'interno del codice sorgente di MicroPython sul tuo computer. Dopodiché, ricostruisci l'intera immagine del firmware MicroPython da zero e flashi questo firmware custom sulla tua scheda. Questo cambia esattamente il modo in cui il codice viene eseguito. Quando importi un modulo frozen, MicroPython non copia affatto il bytecode in RAM. Dato che il codice è integrato nel firmware, risiede permanentemente nella memoria flash del microcontrollore. MicroPython esegue il bytecode direttamente dalla flash. Eseguendo dalla flash, il footprint in RAM per l'import di quell'enorme framework IoT scende quasi a zero. Tutta la tua RAM rimane completamente libera per processare dati in real-time. La differenza fondamentale si riduce a dove risiede il tuo codice mentre è in esecuzione. La precompilazione fa risparmiare memoria durante la fase di import, ma il freezing fa risparmiare memoria per l'intera vita del programma, forzando l'esecuzione interamente nella memoria flash. Se ti va di supportare lo show, puoi cercare DevStoriesEU su Patreon. Questo è tutto per questo episodio. Grazie per l'ascolto, e continua a sviluppare!
7

Determinismo in Python: Timer e Interrupt

4m 06s

Ottieni un comportamento real-time in MicroPython utilizzando timer hardware e interrupt service routine. Trattiamo le rigide regole per scrivere ISR ed evitare l'allocazione di memoria.

Download
Ciao, sono Alex di DEV STORIES DOT EU. MicroPython, episodio 7 di 7. Scrivere una hardware interrupt service routine in un linguaggio ad alto livello con garbage collection sembra un invito a un crash immediato del sistema. Ma MicroPython in realtà lo permette, a patto di rispettare una regola imprescindibile: zero allocazioni di memoria. Questo episodio parla del determinismo in Python: Timer e Interrupt. Quando devi leggere un sensore esattamente mille volte al secondo, un loop standard con una funzione di sleep fallirà. La garbage collection e i task in background introducono ritardi casuali, distruggendo il tuo timing. Per ottenere un comportamento deterministico, ti serve un timer hardware. Usando il modulo machine, configuri un oggetto Timer per scattare periodicamente ed eseguire una specifica callback. Questa callback è la tua Interrupt Service Routine, o ISR. I timer scatenano interrupt soft o hard. Un soft interrupt viene schedulato dalla virtual machine di MicroPython quando è sicuro farlo. Scrivi una soft ISR esattamente come del normale codice Python. Può creare oggetti, fare append alle liste e gestire numeri floating-point. Lo svantaggio è la latenza. Se il garbage collector è in esecuzione quando il timer scatta, il tuo soft interrupt si mette semplicemente in coda. Se ti serve una precisione di timing rigorosa, configuri il timer per scatenare un hard interrupt. Un hard interrupt ferma immediatamente il processore. Bypassa la virtual machine ed esegue la tua callback all'istante. Ecco il punto chiave. Poiché un hard interrupt fa preemption sullo stato corrente del sistema, potrebbe interrompere il memory manager stesso. Se la tua ISR cerca di allocare memoria sull'heap mentre l'heap è nel mezzo di una modifica, il microcontrollore andrà in crash. Questo vincolo detta esattamente come devi scrivere le hard ISR. Non puoi allocare alcuna memoria. Niente creazione di liste. Niente costruzione di dizionari. Niente manipolazione di string. Persino la matematica floating-point è severamente vietata, perché in Python ogni float è un nuovo oggetto allocato sull'heap. Il tuo codice deve essere eseguito velocemente, basarsi sulla matematica integer e usare strutture di memoria preesistenti. Considera uno scenario in cui un timer hardware scatta a 1000 Hertz. Ogni millisecondo, la hard ISR legge il valore di un sensore. Dato che non puoi fare l'append della lettura a una lista, devi pre-allocare il tuo storage prima di avviare il timer. Crei un bytearray di mille byte nel tuo programma principale. Definisci anche una variabile indice globale. Quando il timer scatta, la ISR legge il sensore. Aggiorna l'indice globale, salva il raw integer nel bytearray in quella posizione ed esce. Lo spazio di memoria è stato riservato interamente in anticipo. L'interrupt si limita ad aggiornarlo in place, garantendo un'esecuzione senza jitter. Una volta che il buffer è pieno, la ISR deve passare i dati al programma principale. Non puoi triggerare una funzione complessa di elaborazione dati direttamente dalla hard ISR. Invece, usi micropython dot schedule. Questa funzione prende una reference a una callback e la mette in coda per essere eseguita non appena il sistema torna a uno stato di esecuzione soft e sicuro. Gestire gli interrupt hardware ti obbliga a smettere di pensare a Python come a un pool di risorse infinito e a iniziare a tracciare esattamente quando e dove viene assegnata la tua memoria. Consulta la documentazione ufficiale di MicroPython per i comportamenti specifici degli interrupt del tuo hardware port, e prova a infrangere intenzionalmente le regole di memoria sulla tua board per vedere come reagisce il sistema. Se vuoi suggerire argomenti per la nostra prossima serie, fai un salto su devstories dot eu. Vorrei prendermi un momento per ringraziarti per l'ascolto: ci aiuta tantissimo. Alla prossima!