Dal 1° all’11 ottobre 2026 Bergamo diventa il palcoscenico di BergamoScienza, giunta alla XXIV edizione: oltre 180 eventi gratuiti tra conferenze, laboratori e mostre attorno al tema di quest’anno, le Convergenze, l’incontro tra discipline diverse da cui nasce qualcosa di nuovo. Il FabLab Bergamo parteciperà con Open FabLab – Entra nella fabbrica digitale delle idee, visita guidata gratuita (su prenotazione)in programma sabato 3 e sabato 10 ottobre 2026. E il progetto che raccontiamo oggi è una convergenza nel senso più letterale del termine: fisica quantistica, matematica, elettronica embedded e un trucco ottico ottocentesco, uniti per far levitare un atomo sopra uno schermo.
In un video di pochi secondi si vede una nuvola arancione e blu che ruota sospesa sopra un piccolo schermo, come se galleggiasse nel nulla. Non è un montaggio: è una rappresentazione reale – calcolata, non disegnata – degli orbitali elettronici di un atomo, generata in tempo reale su un ESP32 da poche decine di euro. Dietro c’è un prisma di vetro e un progetto nato al FabLab Bergamo, che oggi raccontiamo per intero: come funzionano gli orbitali elettronici, che fisica c’è dentro e come puoi vederli, o costruirli, di persona.
Il progetto si chiama Electron Orbital 3D ed è open source: tutto il codice, con gli appunti dalla matematica quantistica al firmware, è pubblico su GitHub. La parte interessante non è solo che funziona, ma come è stato reso possibile farlo girare su un microcontrollore che sta in una mano, e come chi l’ha costruito si sia assicurato che quello che vedi non sia solo scenografico, ma fisicamente corretto.
Cos’è davvero un elettrone (e perché è difficile disegnarlo)
A scuola si impara a disegnare l’atomo come un piccolo sistema solare: un nucleo al centro, elettroni che gli girano intorno su orbite precise. È un’immagine comoda, ma sbagliata.
Un elettrone non ha una posizione fissa finché qualcosa non la misura: la meccanica quantistica non ti dà un punto, ti dà una probabilità, più densa dove è probabile trovarlo, più rada dove non lo è.
Quei lobi e trifogli che i libri di chimica disegnano per gli orbitali atomici – la forma a manubrio del 2p, quella a quadrifoglio del 3d – sono esattamente questa densità di probabilità, espressa come |ψ|² (psi al quadrato, il quadrato della funzione d’onda). Il progetto del FabLab prende quella densità e la trasforma in qualcosa che si può guardare davvero: migliaia di puntini, ciascuno una posizione possibile dell’elettrone campionata secondo le leggi della fisica, fatti ruotare in tre dimensioni.
Il trucco ottico: uno specchio vittoriano
L’effetto “in sospensione” non usa nessuna tecnologia futuristica. È una tecnica ottica ottocentesca chiamata Pepper’s Ghost, la stessa usata per far apparire fantasmi negli spettacoli teatrali vittoriani. Un piccolo prisma di vetro a quattro facce rimanda l’immagine dello schermo verso l’occhio dell’osservatore, dando l’impressione che l’oggetto galleggi a mezz’aria invece di essere semplicemente disegnato su un display piatto.
Il cuore elettronico è un ESP32-S3 dual-core da 240 MHz con 8 MB di PSRAM e 16 MB di flash, uno schermo a colori ST7789 da 1,3 pollici e 240×240 pixel, e un sensore IMU (accelerometro più giroscopio) che rileva quando inclini la scheda. Non ci sono pulsanti né cavi da collegare a un computer: basta dare un colpetto al dispositivo per passare da un orbitale all’altro, o per sfogliare gli elementi della tavola periodica uno a uno.
Simulare orbitali elettronici con un chip da pochi euro
Qui sta la parte più interessante dal punto di vista tecnico, ed è anche quella che rende questo progetto diverso da una semplice animazione 3D: ogni punto della nuvola deve rispettare esattamente la distribuzione di probabilità prevista dall’equazione di Schrödinger, non una sua approssimazione grafica.
Il problema è che un microcontrollore da 240 MHz non ha la potenza di calcolo di un laptop. Un primo approccio, generare punti a caso e scartare quelli che non rispettano la densità voluta (tecnica nota come rejection sampling), funziona ma è imprevedibile: non sai mai in anticipo quanti tentativi servano per ottenere un punto valido. Su un chip con poco margine di calcolo, quell’incertezza si paga cara.
La matematica aiuta
La soluzione sfrutta una proprietà matematica della funzione d’onda: la densità di probabilità si scompone in tre fattori indipendenti, uno per ciascuna coordinata (raggio, angolo verticale, angolo orizzontale). Ognuno può essere pre-calcolato una volta sola in una tabella, all’avvio (o dal compilatore stesso in C++ grazie a constexpr). Queste tabelle sono poi campionate casualmente per generare i punti (usa un’altra proprietà statistica chiamata inverse-LDF) senza tentativi o interazioni.
Nella pratica, la parte radiale è un polinomio di Laguerre associato moltiplicato per un esponenziale decrescente, quella “verticale” un polinomio di Legendre associato, quella “orizzontale” un semplice seno o coseno: tre famiglie di funzioni che compaiono in ogni libro di meccanica quantistica, qui ridotte a tabelle di numeri che l’ESP32 può solo leggere invece di ricalcolare ogni volta. Il procedimento completo, dai coefficienti dei polinomi alle tabelle di campionamento, è documentato passo passo in Coefficients to Tables.
Il codice deve fare la sua parte
A questo si aggiungono altri accorgimenti pensati apposta per l’hardware:
- Il campionamento avviene una sola volta, all’avvio: durante l’animazione il dispositivo si limita a ruotare punti già pronti, non li ricalcola a ogni fotogramma. Nella versione C++, per rendere la nuvola più vibrante, ci possiamo permettere di decimare e ricalcolare punti ogni tanto.
- Le rotazioni della nuvola usano aritmetica a virgola fissa (formato Q8) dentro il compilatore nativo
viperdi MicroPython, eliminando l’overhead dei calcoli in floating point nel ciclo più critico. - Il framebuffer viene scritto in un unico blocco via SPI a 80 MHz: il solo trasferimento verso lo schermo costa, misurato su hardware reale, circa 13 millisecondi a fotogramma. Nella configurazione di produzione (8.000 punti) questo porta il dispositivo a 31-34 fps in C++ e a circa 29 fps nella versione MicroPython semplificata.
- Non c’è nessuna allocazione di memoria durante l’animazione: tutti i buffer sono preallocati una volta sola.
Le tabelle vere e proprie, però, non nascono sul microcontrollore: un generatore Python le precalcola sul PC e le scrive in due file binari che finiscono nella memoria flash dell’ESP32, pronti per essere letti all’avvio. Il dettaglio di questo passaggio, e di come le tabelle dell’idrogeno puro convivono con quelle degli atomi multi-elettronici, è nella pagina Tables to BIN.
Il risultato è una nuvola che sembra viva, con un leggero “respiro” dello zoom pur girando su un chip pensato per l’elettronica di consumo e non per il calcolo scientifico.
Un’alternativa con una board economica
La versione C++ con PlatformIO è stata testata anche su una Cheap Yellow Display con processore ESP32, che ha caratteristiche più limitate.
È stato piuttosto soddisfacente cercare e applicare ottimizzazioni specifiche (sembra retrocomputing): il framebuffer deve essere allocato in più blocchi, è necessario ricalcolare alcune tabelle per evitare di consumare troppa memoria (trade off classico) e infine il numero di punti è limitato a circa 3500.
ESP32 in C++ o MicroPython? I benchmark
Il progetto esiste per intero, dal firmware sul dispositivo al simulatore desktop, anche in puro Python: nessuna delle tre versioni ha davvero bisogno del C++ per funzionare. Sul microcontrollore, però, la scelta del linguaggio si sente, ed è proprio questo confronto, misurato e non stimato, a rendere il progetto un buon terreno per un dibattito più ampio su quanto costi, in prestazioni reali, un linguaggio interpretato rispetto a uno compilato sullo stesso hardware — lo stesso tema affrontato nel nostro articolo su Fab-O-Matic: sviluppo embedded con C++ moderno.
A parità di condizioni, con 8.000 punti, sul dispositivo reale si misurano questi fotogrammi al secondo:
| Rendering | C++ (con dissolvenza) | MicroPython (ottimizzato ma senza dissolvenza) | MicroPython (a parità grafica C++) |
|---|---|---|---|
| Nuvola atomica (Fe) | 33 fps | 29 fps | 15 fps |
| Orbitale (2pz) | 31 fps | 29 fps | 11 fps |
Questo risultato finale nasconde però un passaggio intermedio istruttivo. Con un rendering identico in tutto e per tutto a quello C++, stessa dissolvenza (fade) tra un fotogramma e l’altro, stessa trasparenza dei punti, MicroPython si fermava tra gli 11 e i 15 fps a seconda del numero di punti, quasi tre volte più lento del C++ a parità di lavoro svolto.
Ottimizzazioni in Micropython
Per chiudere buona parte di quel divario, senza riscrivere il progetto in un altro linguaggio, sono bastate alcune ottimizzazioni mirate:
- Il ciclo di rendering critico, rotazione, proiezione, disegno dei punti, usa il compilatore
viperdi MicroPython e aritmetica a virgola fissa Q8, la stessa tecnica descritta più sopra. Basta inserire@micropython.viperdavanti alla funzione, e seguire le regole in Maximising MicroPython speed. - Le funzioni di campionamento più pesanti sono marcate
@micropython.native, con la codifica del colore inserita “in linea” invece che richiamata a parte, per non perdere l’accelerazione nativa dentro cicli annidati. - La dissolvenza tra un fotogramma, usata per creare una scia durante la rotazione, è disattivata di default: è l’effetto visivo più costoso da calcolare su un interprete, e rinunciarvi ha permesso di passare da un distacco di circa 3 volte dal C++ a uno di appena 1,16 volte.
Nessuna di queste tecniche cambia il linguaggio: resta MicroPython, non C++ travestito da MicroPython. Dimostra piuttosto che un microcontrollore da pochi euro può eseguire calcoli di meccanica quantistica in tempo reale anche partendo da un linguaggio interpretato, a patto di sapere dove concentrare il lavoro di ottimizzazione — se non hai mai provato MicroPython su ESP32, trovi un’introduzione nel nostro recap di Arduino Day 2025: MicroPython e Arduino. Che si preferisca il C++ per la velocità pura o il Python per la leggibilità, è una scelta su cui vale la pena confrontarsi: il codice di entrambe le versioni, benchmark incluso, è pubblico per chi vuole verificarlo di persona.
Non basta che sia bello: deve essere anche giusto
Qualunque animazione 3D può sembrare convincente a occhio. La matematica degli orbitali dell’idrogeno è stata confrontata punto per punto con Quantum Physics Online, l’implementazione pubblica di riferimento realizzata da Manuel Joffre per l’École Polytechnique, usata come oracolo indipendente. Le tre versioni del software, quella per il dispositivo, quella per il simulatore desktop e quella in C++, condividono lo stesso generatore di numeri casuali: con lo stesso seme producono esattamente la stessa sequenza di punti, un controllo molto più severo del semplice confronto tra istogrammi, perché individua anche errori sottili che un confronto puramente statistico lascerebbe passare.
Per gli atomi con più elettroni, il modello è stato messo a confronto con i dati di riferimento del NIST (l’istituto statunitense di metrologia): i livelli energetici calcolati corrispondono a quelli di riferimento con uno scarto inferiore a 7×10⁻⁶ Hartree su 915 sottolivelli energetici, per tutti gli elementi da idrogeno a uranio, e le configurazioni elettroniche calcolate coincidono con quelle sperimentali in 92 casi su 92.
Eh sì, i fisici nucleari usano molte unità diverse.
Per un atomo con più di un elettrone l’equazione di Schrödinger esatta non ha soluzione in forma chiusa: ogni elettrone respinge tutti gli altri, e il problema smette di essere risolvibile a mano. Il progetto approssima questa complessità con una carica nucleare “efficace”, più bassa di quella reale, che tiene conto di quanto gli elettroni più interni schermano il nucleo da quelli più esterni (il metodo di Clementi-Raimondi, anni ’60), oppure — nella modalità di default — con un calcolo a tutti gli elettroni basato sulla teoria del funzionale della densità, lo stesso approccio usato in chimica computazionale: sono proprio le sue funzioni radiali tabulate, validate contro NIST, quelle citate qui sopra.
Un dettaglio verificabile a occhio: la regola di Hund prevede che gli elettroni riempiano prima tutti gli orbitali di un sottoguscio uno alla volta, prima di accoppiarsi. Il carbonio (due elettroni nel sottoguscio 2p) mostra così una nuvola visibilmente allungata, l’azoto (tre elettroni, uno per ciascun orbitale 2p) torna quasi perfettamente sferico, e il neon, con il sottoguscio pieno, è sferico in modo esatto: prova a confrontarli nella versione web. Il modello completo, comprese le approssimazioni esplicite e i suoi limiti dichiarati, è descritto in ATOMS.md.
Provalo tu stesso, prima ancora di costruirlo
Non serve avere un ESP32 in mano per vedere il progetto in azione: esiste una versione che gira direttamente nel browser, con la stessa identica matematica del dispositivo fisico, dove puoi scegliere un orbitale dell’idrogeno o un elemento qualsiasi della tavola periodica e osservarlo ruotare in tempo reale.
Il codice sorgente completo è pubblico, con tre percorsi paralleli a seconda delle proprie preferenze: un firmware in MicroPython per il dispositivo fisico, il simulatore desktop in Python appena visto, e una versione C++/PlatformIO per chi preferisce lavorare più vicino al silicio.
Perché è un progetto pedagogico?
Ci sono alcuni accorgimenti nel progetto per poter accenare alla fisica fondamentale:
- È visualizzata in tempo reale una scala in picometri della scena
- Il nome dell’elemento in italiano e il suo numero atomico sono visualizzati in animazione, prima del calcolo della nuvola.
- Gli orbitali dell’idrogeno specificano i numeri quantistici che le determinano (n, l, m).
- Gli orbitali dell’idrogeno seguono le convenzioni di rappresentazione della chimica (segno della parte reale di ψ)
- La rotazione consente di capire le simmetrie e le similitudini fra orbitali diversi
- I gusci elettronici di un atomo sono colorati dalla minor energia (rosso, elettroni lontani dal nucleo) a massima energia (viola).
- I gusci elettronici possono essere “esplosi” con un’animazione graduale, dalla fascia orbitale più lontana a quella più vicina.
- L’animazione dei gusci elettronici specifica il numero di elettroni in ogni guscio, il nome del guscio
- La nuvola di punti sullo schermo rispecchia le proporzioni di elettroni in ogni guscio.
- La navigazione fra atomi segue l’ordine della tabella periodica degli elementi.
La scala fissa in picometri non è solo un dettaglio estetico: è calibrata sul litio, che nell’intervallo di elementi supportati risulta empiricamente l’atomo con il raggio maggiore (coerente con la chimica reale, dove i metalli alcalini sono i più “grandi” del loro periodo). Il risultato è che scorrendo la tavola periodica si vede una cosa contro-intuitiva ma vera: gli atomi non crescono man mano che aumentano gli elettroni, anzi spesso si contraggono, perché la carica nucleare via via più alta tira gli elettroni più vicino al nucleo.
AI Disclaimer
Tra chi programma sta prendendo piede l’abitudine di dichiarare apertamente quanto di un progetto sia stato scritto con l’aiuto dell’intelligenza artificiale: una sorta di etichetta degli ingredienti applicata al codice, ancora poco diffusa ma che qui vogliamo condividere volentieri. Per questo progetto la risposta è: molto. L’autore non ha competenze sufficienti in fisica quantistica per garantire personalmente la correttezza dei risultati, e ha scritto meno del 5% del codice complessivo. Ha però costruito un processo di validazione solido, descritto più sopra, per assicurarsi che la simulazione fosse verificata e coerente, e preferisce raccontare qui gli strumenti e il metodo usati.
Strumenti AI utilizzati
- Ricerca di fonti autorevoli: Claude Web (piano Pro) e ChatGPT (versione gratuita)
- Codice sorgente C++: generato principalmente con Claude Code (Sonnet 4, livello di ragionamento “High”)
- Codice sorgente Python: generato principalmente con DeepSeek Harness, con modello DeepSeek-V4-Flash (“High”)
- Analisi della fisica e documentazione : DeepSeek Harness con modello DeepSeek-V4-Flash (“High”)
- Costo in tokens complessivo: circa 4-5 $ di crediti DeepSeek, un paio di settimane di abbonamento Claude Pro (equivalenti a circa 10 €)
Strategia AI usata
Per ottenere buoni risultati dalla programmazione automatica, con pochi interventi manuali sul codice, è importante che il modello di AI possa testare da solo le proprie modifiche e confrontarle con i risultati precedenti, senza bisogno di supervisione continua: in gergo, togliere il “man-in-the-loop”.
Il progetto è partito da una fase di ricerca: individuare simulatori autorevoli e corsi universitari di riferimento, scaricarli in locale per darli in pasto agli agenti AI (l’equivalente di una ricerca bibliografica), e far generare a Claude Code delle tabelle di dati dalle implementazioni autorevoli, da usare come base di test.
È seguita la fase di porting: chiedere a Claude Code di tradurre le implementazioni in Python, un compito in cui le AI eccellono, e convalidare i calcoli ottenuti confrontandoli con Claude e DeepSeek. A quest’ultimo l’autore ha anche chiesto di spiegare e documentare l’implementazione realizzata, per poi dedicare del tempo a capire davvero le tecniche usate e i modelli fisici: una delle fasi più lunghe del progetto, perché qui il controllo umano resta indispensabile.
Una volta ottenuta un’implementazione corretta e completa in Python su PC, con tanto di animazioni e colori messi a punto iterando direttamente lì, è arrivato il momento di chiedere all’AI la conversione in MicroPython e C++, applicando le best practice del linguaggio con un misto di esempi generati ed editing manuale. Le ottimizzazioni sono state poi testate su diverse board, e infine sono arrivati gli effetti grafici: un’altra fase lunga, ancora una volta con il controllo umano al centro.
In questo progetto, due tecniche sono state usate per la prima volta dall’autore: chiedere all’AI di redigere documenti di sintesi del codice e studiare su quelli (invece che partire dai sorgenti), e generare GIF animate o catturare screenshot dello schermo dell’ESP32 per velocizzare il controllo visivo del progetto e le scelte di interfaccia grafica.
Vieni a scoprire progetti come questo al FabLab Bergamo
Se questo tipo di progetti ti incuriosisce, che tu sia un insegnante in cerca di uno strumento didattico originale, un appassionato di elettronica o semplicemente qualcuno a cui piace vedere la fisica prendere forma davanti agli occhi, vieni a trovarci in laboratorio: scopri cos’è il FabLab Bergamo e come si diventa soci nella pagina associarsi. È lo stesso principio su cui si fonda l’idea di FabLab fin dall’inizio: gli strumenti di prototipazione digitale, un tempo riservati a laboratori universitari o industrie, oggi stanno su una scrivania e permettono a chiunque di trasformare un’idea, anche complessa come la meccanica quantistica, in qualcosa di tangibile. Un piccolo prisma, uno schermo economico, e un atomo che fluttua davvero nell’aria.

