(un progetto utile ed interessante: monitoraggio e trasmissione dei dati)
Qualche tempo fa mi sono dedicato alla scrittura di un libro, che ritengo essere la migliore rappresentazione del mio biglietto da visita: MMC – Misure – Monitoraggio – Controllo.
Un libro che ho scritto con passione e che spero possa essere di stimolo a chi avrà l’opportunità di leggerlo.

In questo periodo, facendo seguito a delle esigenze lavorative e prendendo spunto da quel libro, vorrei proporre un progetto didattico che ritengo possa essere utile per capire l’ambito tecnico nel quale si opera per realizzare un semplice monitoraggio, in questo caso di un parametro inerente la temperatura di un liquido stoccato all’interno di un silos.
Il valore rilevato, verrà trasmesso ad una “postazione remota”, mentre “in locale” il dato sarà reso visibile mediante un display LCD, ovviamente, da un controllo su tale dato, se messo in relazione con un parametro di riferimento, potrà essere utilizzato per generare un segnale di allarme.
Per qualcuno, questo potrebbe essere un “semplice progettino”, per altri invece questo potrebbe essere qualcosa di “complesso”, qualcosa di “non facile realizzazione”, “punti di vista” che dipendono dalla percezione dovuta a molti fattori che sono sempre soggettivi, qualcosa di individuale, che è implicito nella personalità di chi si approccia ad una esperienza operativa in questo ambito, ognuno di noi ha un modo personale di affrontare un “percorso mentale”, ma la cosa bella è che, chi inizia il percorso, anche se non è sicuro di arrivare alla meta, sicuramente lo fa mettendoci la propria volontà, la propria esperienza, le proprie facoltà intellettive e traccia, passo dopo passo, un sentiero, nel campo della “conoscenza”, qualcosa che potrà essere utile anche per altri che, come lui, affronteranno esperienze simili! Forse noi questo lo dobbiamo a chi, per primo, è riuscito ad accendere un fuoco, che ha modificato la temperatura di un ambiente nel quale sopravvivere.
Il concetto di temperatura
Va di moda utilizzare gli LLM (le intelligenze artificiali) per esprimere dei concetti, una volta si usava il vocabolario, ma tanto vale ed allora, se chiediamo ad un LLM di fornirci una descrizione del concetto di temperatura, ci potrebbe rispondere come riportato dalle seguenti righe:
“La temperatura è una grandezza fisica che misura il grado di “caldo” o “freddo” di un corpo, rappresentando l’energia cinetica media delle sue particelle.
Si distingue dal calore, che è una forma di energia termica che si trasferisce tra corpi a temperature diverse fino a raggiungere l’equilibrio termico.
La temperatura viene misurata con strumenti come il termometro, e si esprime in varie scale, le più comuni sono Celsius, Fahrenheit e Kelvin.
Concetti chiave:
Definizione fisica: La temperatura è una misura dello stato termico di un corpo, direttamente collegata all’agitazione delle sue molecole o atomi.
Più veloci sono le particelle, più alta è la temperatura.
Differenza tra temperatura e calore: Il calore è energia che si sposta da un corpo più caldo a uno più freddo; la temperatura è una misura di questa condizione, non l’energia stessa.
Equilibrio termico: Due corpi in contatto termico scambiano calore fino a quando non raggiungono la stessa temperatura, momento in cui il trasferimento di calore cessa.
Grandezza intensiva: La temperatura è una proprietà intensiva, il che significa che non dipende dalle dimensioni del corpo, ma solo dalle sue condizioni interne.
Strumenti e scale: Si misura con strumenti come il termometro.
Le scale più note includono:
Celsius (°C): Utilizzata comunemente, con (0 °C) per il punto di fusione del ghiaccio e (100 °C) per il punto di ebollizione dell’acqua a pressione atmosferica.
Kelvin (K): L’unità del Sistema Internazionale, che ha lo zero assoluto come punto di partenza (0K).
Fahrenheit (°F): Utilizzata principalmente nei paesi anglosassoni.“
Semplice no? Per misurare una temperatura, basta dotarsi di un termometro, ovvero, un qualcosa che possa modificare il proprio stato fisico, in relazione allo stato di agitazione delle particelle, molecole o atomi nel quale si trova, fornendo una indicizzazione, in base ad una scala di valori parametrizzati in relazione a delle convenzioni “culturali”. Basta avere qualcosa che funge da “sonda” e qualcosa che “indichi” un numero ed il gioco è fatto.
Il “Dizionario” a riguardo del termine, lo definisce come “Sostantivo femminile”:
sostantivo femminile
1. In fisica, grandezza che misura gli scambi di calore tra corpi in contatto termico: fluendo il calore da quelli a temperatura maggiore a quelli a temperatura minore, il confronto tra la temperatura del corpo umano e quella degli oggetti genera le sensazioni soggettive di caldo e di freddo, per cui risultano caldi quelli che, essendo a temperatura superiore, cedono calore al corpo.
Particolarmente:
- In termodinamica, una delle variabili di stato, legata, secondo la meccanica statistica, all’energia media dei costituenti elementari del sistema, e che può essere misurata in gradi Celsius, Fahrenheit, Réaumur e Kelvin.
- Temperatura assoluta, quella espressa in gradi Kelvin, così chiamata perché allo zero della scala Kelvin ( zero assoluto ) il volume e la pressione di un gas ideale si riducono a zero.
- Temperatura critica, quella alla quale avviene una transizione di fase in un sistema termodinamico.
- Temperatura critica di dissoluzione, con riferimento a una coppia di liquidi, la temperatura in corrispondenza della quale si verifica la loro completa miscibilità.
- Temperatura di colore, con riferimento a una sorgente luminosa che emette radiazione termica, la temperatura del corpo nero il cui spettro di emissione meglio approssima lo spettro della sorgente (per es. nel caso del Sole è di 5780 K).
- Temperatura di Curie, quella al di sopra della quale una sostanza ferromagnetica magnetizzata si smagnetizza perché i dipoli magnetici di cui è composta perdono l’orientamento ordinato.
- Temperatura di rugiada, vedi rugiada.
- In astronomia: temperatura di eccitazione, quella di una stella dedotta dall’intensità di varie righe spettrali.
2. com.
Il grado di calore dell’atmosfera.
“t. in diminuzione”
- Temperatura massima, temperatura minima, la temperatura rispettivamente più alta o più bassa registrata in una località o in un determinato periodo di tempo. fig.
- Tensione, situazione di latente contrasto.
- “le sue parole fecero salire la t. della riunione”
3. Il grado di calore del corpo umano: t. cutanea, interna; misurare la t.; pop. ( assol. ), lieve stato febbrile.
- “il bambino ha un po’ di t.”
- Temperatura basale, la temperatura corporea misurata al risveglio, prima dell’interferenza di altri fattori (per es. il movimento); poiché si innalza di qualche decimo di grado centigrado per influsso del progesterone, la sua misurazione è utile nella donna per rivelare i giorni fertili.
4. arcaico
Il conferimento della tempra all’acciaio.
- L’affilatura della punta della penna d’oca.
- Temperamento (nel senso di costituzione fisica).
Origine
Dal lat. temperatura ‘mescolanza in giusta misura (di caldo e freddo, umido e secco)’; nel sign. 4, der. di temperare •sec. XVI.
Fatto sta che, dal 2019, la scala termometrica assoluta viene definita a partire dalla “Costante di Boltzmann”, il cui valore è definito esatto! (per convenzione dico io)! – Questo è un argomento trattato anche nel libro.
Significato di misura della temperatura
Da notare innanzitutto che, questo parametro che in qualche modo riferisce la “Qualità” di uno “Stato energetico”, si riferisce a degli oggetti che possono assumere una diversificazione di stati esistenziali, in relazione alle loro caratteristiche “Endogene” e all’ambiente in cui si trovano: due corpi “in contatto” prima o poi assumono la stessa temperatura, il calore ceduto da un sistema viene acquistato da un altro sistema, in accordo con il principio di conservazione dell’energia, per “Conduzione”.
Tra un solido e un fluido questo fenomeno avviene per “convenzione”, ma quello che “fa pensare” è che la trasmissione del calore, da un corpo ad un altro, avviene anche per “Irraggiamento”, l’esempio più classico ce lo abbiamo ad ogni “sorgere del sole”, e tra noi (il pianeta terra) ed il Sole… Per “convenzione” assumiamo, ci sia una regione di “Spazio-tempo” “Vuoto”: la luce che noi vediamo, “Emessa” dal sole, ci impiega circa 8 minuti per arrivare. Questi sono i “Fotoni”, che viaggiano dalla superficie del Sole e colpiscono i “corpi” che ci sono su questo pianeta, ad una velocità stimata attorno ai 299.792.458 metri al secondo.
Per noi, una velocità pazzesca, ma un “Fotone”, non se ne accorge nemmeno del passare del tempo! Anche perché dalla sua “Nascita” alla fuoriuscita dal sole, possono passare migliaia di anni senza che lui se ne accorga; di più, per il “Fotone” stare “Nel Sole”, o arrivare “Sulla Terra”, probabilmente non cambia nulla: la sua esistenza potrebbe essere un fenomeno “Non locale”, per quanto io possa immaginare!
Fatto sta che, “Nel cosiddetto vuoto” è presente una radiazione cosmica, “Ci sono fotoni che “Viaggiano”, che si agitano, che “Vibrano”, per così dire, o meglio, “Ci si sono radiazioni elettromagnetiche”, (Cmb, dall’inglese cosmic microwave background), quindi, a questa minima attività energetica, di “agitazione”… corrisponde una “Temperatura”: circa 2,73 K!
Attenzione: per definizione (diremmo)… i “Fotoni” sono particelle “Senza massa”, ma possono essere identificati come “Vettori” che trasportano dei “Quantitativi di energia”… per dirla con parole semplici.
Per inciso: la massa è considerata “La misura dell’inerzia di un corpo”, cioè la misura della resistenza che il corpo oppone alla variazione del suo stato di quiete o di moto, quindi, se “un corpo” è in quiete, è “Ben definibile”, ma se invece è “in moto”, rispetto ad un sistema di coordinate, potrebbe non essere “Ben definibile”, definirne la sua velocità di spostamento in riferimento ad un sistema di coordinate arbitrario, e definirne la sua massa… potrebbe non essere cosa semplice, ci potrebbero essere dei “Limiti oggettivi”, come in effetti riferisce il “Principio di indeterminazione di Heisenberg”.
Heisenberg dimostrò che non è possibile conoscere con precisione due variabili coniugate allo stesso istante nel tempo.
Nel suo caso le due variabili erano velocità dell’elettrone (quantità di moto) e la sua posizione nell’orbita descritta: aumentando la precisione di una misura l’altra ne risentirà inevitabilmente.
Si noti che in “Meccanica classica”, la quantità di moto di un oggetto è una grandezza vettoriale definita come il “Prodotto della massa dell’oggetto per la sua velocità”.
Nel biliardo la quantità di moto di una palla viene trasmessa alle altre tramite collisione, (questo lo ho imparato nelle ore che preferivamo trascorrere fuori dalla scuola io e Umberto Cibien di cui riporto alcuni testi di matematica al sito https://www.academia.edu/).
Da notare quindi che la quantità di moto e l’energia sono correlate: se la prima è il prodotto di massa (m) per velocità (v) → (p=mv), la seconda (l’energia cinetica) è esprimibile dalla seguente relazione:

, allora, la relazione tra energia cinetica e quantità di moto può esprimersi attraverso questa relazione:

Nella teoria della relatività, la relazione è più generale e lega l’energia totale (E) alla quantità di moto (p) attraverso il teorema di Pitagora relativistico:

dove (m0 ) è la massa a riposo e (c) è la velocità della luce.
Ma la quantità di moto “Relativistica”, tiene conto di un fattore di relazione tra “Velocità di un oggetto” e “Velocità della luce”: il fattore di Lorentz, che si esprime mediante questa equazione:

per cui la quantità di moto relativistica si esprime con: pr = ɣmv
Da notare allora, che in relatività generale, l’energia di riposo (m0c2) che rappresenta l’energia posseduta da un oggetto fermo, (per il fotone, che non ha una massa questo prodotto è nullo! Dunque l’energia di un fotone E = prc ( è una radiazione, una forma d’onda!).
Quindi, quando ci sono “Urti” o anche quando ci sono “Interferenze”, si genera “Confusione”: un fotone da solo in un “Punto spaziotemporale” potrebbe esistere? Io non credo! Semmai potremmo parlare di una “Regione Spaziotemporale”, in questo caso però dovremmo far riferimento alla “Lunghezza di Planck” che, tiene conto della “Costante gravitazionale”, della “Velocità di trasferimento dei fotoni (la velocità della luce) e un valore di “Proporzionalità” tra quantitativi energetici e “Frequenze oscillatorie” di queste strane “Particelle” senza “Massa” che trasportano “Energia”, da un “punto ad un altro” di un “Ambiente” “Multidimensionale”.
Per inciso, La lunghezza di Planck è l’unità fondamentale di lunghezza nel sistema di unità di misura di Planck, con un valore pari a circa 1.6167 10-35 metri e rappresenta la scala di lunghezza più piccola possibile, al di sotto della quale le relazioni fisiche dedotte da formule matematiche, che combinano la teoria della “Meccanica quantistica” e quella della “Relatività generale”, non sarebbero più applicabili.
Per altri versi, la lunghezza di Planck è “la misura del raggio dell’orizzonte degli eventi” di una “Massa di Planck” e concorre a definire, se riferito alla lunghezza d’onda di una radiazione elettromagnetica, “la massima energia possibile per un fotone” prima che questo “collassi” in forma di massa.
Sottolineo che il volume di una sfera si ricava mediante la seguente formula:
dove con “Lp” si intende un raggio, in questo caso, potrebbe coincidere con la lunghezza di Planck.
In realtà, il volume di Planck viene definito come il valore al cubo della distanza di Plank: equivalente a circa 1,6 * 10-105.

Questo volume rappresenta dunque il “Limite della fisica”, ovvero il limite di applicabilità delle attuali leggi della fisica, come la meccanica quantistica e la relatività generale.
Quindi dentro questo volume se c’è qualcosa, forse è una radiazione, che potrebbe avere una certa temperatura (qualcosa che vibra ad una determinata frequenza), in questo universo!
Capisco che questi concetti possono generare un po’ di confusione, ma, a questi livelli, se dovessimo “Misurare” la “Confusione”, dovremmo far riferimento ad un parametro chiamato “Entropia”: ovvero, la misura del “Grado di dispersione dell’energia”… ad una data temperatura.
Si tenga ben presente che l’energia ha la naturale tendenza a migrare da un corpo caldo ad uno freddo, (fino a quel limite inferiore, dove si misurerebbe lo “Zero Assoluto”! Ed il processo inverso non è spontaneo! Inoltre, farlo, (apportando energia), ad una determinata temperatura comporta un “conto energetico” e farlo ad un’altra temperatura il conto cambia! Ed inoltre, l’energia, qualora fosse “Localizzata o concentrata” tende a disperdersi e a diffondere… anche nel vuoto!
Volendo dunque usare un gradiente di temperatura per produrre “Lavoro”, inteso come prodotto scalare tra i vettori forza e spostamento, e calcolato come L=F·s·cos(α), non si riuscirebbe a trasformare totalmente “L’energia scambiata” in “Lavoro utile”, in quanto una parte di essa si disperderà nell’ambiente circostante sotto forma di energia termica (calore).
Questo significa soltanto una cosa: le “Sostanze”, la materia che conosciamo ha una caratteristica, quella di poter accumulare energia in relazione alla proprie “geometrie molecolari” e lo fa riscaldandosi o raffreddandosi con una determinata “Inerzia”.
In questo senso, il “Calore specifico” può essere definito come l’energia necessaria per aumentare la temperatura di una determinata sostanza di un grado.
Nessun processo quindi, può raggiungere il 100% di efficienza energetica, perciò tutti i processi di scambio energetico, nell’universo contribuiscono ad aumentare la dispersione e diffusione dell’energia, in quanto, una parte di essa viene sempre dispersa nell’ambiente.
L’entropia è dunque misurabile in unità di energia su temperatura: nota definizione quantitativa data da Clausius (dS = dqrev/T).
Da notare che non esiste alcun strumento che sia in grado di misurare direttamente l’entropia, mentre termometri e calorimetri, usati per misurare la temperatura e gli scambi energetici, fanno parte della dotazione di fisici e chimici, ma sono strumenti utilizzabili anche da persone comuni.
Questa mi sembra una base abbastanza “solida” su cui iniziare a parlare di misure di “Temperatura”, poiché introduce una panoramica più vasta di quella data dal solito approccio: “Per misurare una temperatura ci sono vari metodi, che fanno riferimento a varie tipologie di strumenti”, tra i quali, in ordine storico, forse bisogna indicare il “termobaroscopio” di Galileo che prima del 1600 ideò questo strumento capace sì di indicare una variazione di temperatura, anche se molto impreciso, ma già poco tempo dopo comparvero i “fiorentini” che vennero adottati in tutta Europa, ma a quel punto, il problema erano “Le scale di misura”…
Chi non ha presente i termometri a liquido?, quelli che utilizzano la differente espansione termica fra un liquido ed il suo contenitore in vetro, io mi ricordo benissimo quelli in mercurio (sostituiti per ragioni ecologiche con quelli a Galinstan (gallio, indio e stagno) e quelli ad alcool, ma sono strumenti che hanno un range di misura limitato, rispetto allo spettro delle misurazioni possibili, basti pensare che, se da un lato il limite inferiore è dato dallo “Lo zero assoluto” ovvero la temperatura minima possibile teorica di un qualsiasi sistema termodinamico, dall’altro, la cosiddetta “temperatura di Planck“, definirebbe la massima temperatura teorica raggiungibile dalle particelle (fotoni) (≈1,41679×1032 K). (che farebbero evaporare un buco nero!).
Un termometro a liquido dunque, quando viene messo sotto l’ascella, riceve energia, sotto forma di “Urti” di particelle che passano come vibrazioni al vetro ed al liquido, che evidentemente, aumenta di volume, riscaldandosi, se la temperatura corporea è superiore a quella ambientale.
I termometri moderni però, rilevano la temperatura a distanza, sfruttando le radiazioni dei raggi di luce, che emette un corpo! Stelle e corpi celesti compresi! E la luce, “Viaggia nel vuoto”, compiendo geodetiche non lineari, in relazione alla deformazione dello “Spaziotempo”.
I Sensori di temperatura
Quelli moderni sono dei trasduttori, perché trasformano la grandezza temperatura in una grandezza elettrica (un parametro di differenza di potenziale analogico), che viene convertito solitamente in un dato digitale. Questi sensori si differenziano in sensori di temperatura a contatto o senza contatto.
Tra i sensori di temperatura a contatto, i più comuni sono le termocoppie e i termometri a resistenza, costituiti da materiali termoresistenti o RFD – Resistance Temperature Detector o termistori, conme venivano chiamati ai miei tempi.
Sensori che non hanno bisogno di contatto con la sostanza da misurare, invece, sono i termometri a infrarossi o pirometri ottici, ovvero, le termocamere a infrarossi.
Ma quelli più antichi, presero origine dagli studi di Alessandro Volta verso la fine del 1700, ripresi e da Thomas Johann Seebeck nei primi dell’1800, in particolare, per l’uso delle termocoppie che sono formate da due conduttori metallici uniti in un punto (“giunto caldo”, dove viene effettuata la misura) e collegati agli altri due estremi a una morsetteria (“giunto freddo”), legata a sua volta allo strumento di misurazione.
Semplificando, la descrizione, sul principio di funzionamento, farei solo riferimento al fatto che materiali differenti hanno una composizione molecolare diversa e quindi geometrie e dinamiche che rispondono in maniera diversificata alle “sollecitazioni degli urti”, avendo come conseguenza, una variazione sullo stato del campo elettromagnetico derivante dalla differenza di temperatura tra i loro giunti (freddo e caldo) che comporta una differenza di potenziale elettrico misurabile dell’ordine di alcuni μV per grado kelvin o Celsius.
Basandosi sempre sul fatto che, il valore della temperatura di un materiale è “funzione” di uno stato molecolare dinamico, vi sono materiali, i quali in relazione all’aumentare della temperatura alla quale sono sottoposti, assumono valori di “resistività” diversi, alcuni aumentano la loro resistenza specifica, altri invece la diminuiscono, in particolare, vi sono termoresistenze: RTD – Resistance Temperature Detector e i termistori o resistori termosensibili.
In particolare, I termistori possono essere NTC – Negative Temperature Coefficient, a coefficiente negativo, o PTC – Positive Temperature Coefficient, a coefficiente positivo.
Ma, come accennato sopra, vi sono strumenti che misurano la radiazione luminosa emessa dai corpi, come i “pirometri ottici”, che mediante una lente che direziona la radiazione dell’oggetto su un ricevitore, viene convertita in segnale elettrico prima ed elaborata digitalmente, per essere esposta su un display o su uno schermo, generando quindi un’immagine termica che rappresenta la distribuzione del calore dell’oggetto di riferimento.
Alla base di tutto vi sono le “Vibrazioni”, stati di “Particelle” che mutano posizione e caratteristiche endogene, al punto tale da essere considerabili come “Onde” o “corpuscoli”.
Per oggetti macroscopici, la “lunghezza d’onda” è così piccola da essere trascurabile, ma per le particelle subatomiche come gli elettroni, la lunghezza d’onda è di dimensioni confrontabili con le strutture atomiche, rendendo gli effetti ondulatori osservabili e misurabili.
Il datalogger
E’ un dispositivo elettronico che registra automaticamente dati come ad esempio temperatura, umidità, presenza di gas in determinate atmosfere, stati fisici di solidi o liquidi, ovviamente, valori di frequenza, ampiezza di tensione o corrente elettrica nel tempo, utilizzando sensori interni o esterni.
Questa tipologia di dispositivi dunque è utilizzata per monitorare e analizzare condizioni specifiche in vari settori, dalla industria spaziale all’agricoltura e possono variare da modelli semplici a sistemi complessi con la possibilità di allarmi, scaricamento dati in tempo reale tramite wireless e report automatici.
Sotto l’aspetto storico, ll primo strumento concettualmente simile a un datalogger è stato costruito da Charles Babbage nel 1800, che collegò un dinamometro meccanico a un vagone ferroviario per registrare diversi parametri su un rotolo di carta.
Nel 1901 la rivista “L’elettricità”, pubblicava la realizzazione di uno strumento in grado di rilevare delle scariche elettriche prodotte da un fulmine, con memorizzazione dell’ora del fenomeno, ad opera del Prof. Pietro Lancetta.
Ovviamente in commercio se ne trovano di tutti i tipi, ma credo che potrebbe essere interessante proporre la costruzione di un semplice datalogger per il monitoraggio della temperatura, poiché a livello didattico questo può essere accessibile a molte persone, sia dal punto di vista economico, che dal punto di vista didattico.
I datalogger moderni sono dei dispositivi elettronici che possono essere miniaturizzati, alcuni dei quali possono essere addirittura monouso! Utilizzati ad esempio nei trasporti a temperatura controllata.
Ovviamente, il connubio tra elettronica e informatica consente di avere una continua evoluzione tra “Hardware” e “Software”, ed in particolare vengono messi a disposizione di un vasto pubblico sia componenti a basso costo, come ad esempio schede contenenti microcontrollori, che piattaforme software, con le quali si possono produrre dei programmi in grado di elaborare e trasmettere i dati a distanza.
Quindi, in sintesi, un datalogger è composto da:
- una o più sonde o sensori per il rilievo delle grandezze fisiche
- una scheda per l’elaborazione e la trasmissione dei dati
- un display per la visione dei dati
- il software per l’elaborazione e la trasmissione dei dati
Un esempio didattico
Come sopra già accennato, supponiamo di voler misurare la temperatura di un liquido contenuto in un silos, mediante una sonda di temperatura, magari, volendo settare due parametri di soglia per detectare una temperatura minima ed una temperatura massima di stoccaggio.
I componenti hardware utilizzati per questo progetto, vengono di seguito elencati:
- Una sonda tipo DS18B20
- Un Raspberry pi pico-w (da utilizzare come client)
- Un dispaly IIC LCD1602
- Un alimentatore USB
- Una scatola di contenimento (IP55)
- viterie cavi ed accessoristica optional:
- Un raspberry da adibire come server remoto
necessario:
- un PC per la programmazione software (o un raspberry accessoriato).

Immagine generata da https://nanobanana.ai/
La sonda DS18B20
Il modulo DS18B20 è composto da un sensore in grado di misurare temperature da – 55 a +125 gradi centigradi con un’approssimazione di 0,5 gradi, e da un chip convertitore di segnale da analogico a digitale che può svolgere ulteriori funzioni.

Il modulo e’ alimentato da una fonte da 3 a 5,5 volt ed ha un suo numero seriale (ogni modulo DS18B20 ha un suo univoco numero seriale).
La sigla del numero seriale dei componenti elettronici come l’IMEI significa International Mobile Equipment Identity (Identità Internazionale dell’Apparecchiatura Mobile), un codice univoco di 15 cifre che identifica ogni dispositivo mobile. Non si deve confondere con il numero di serie (S/N) che identifica i dispositivi della stessa serie.

Questa particolare caratteristica consente di avere più moduli collegati poiché il software presente nelle librerie (c++ o micropython) è in grado di riconoscere il numero e quindi fornire la temperatura di ogni singolo ambiente in cui e’ collocato un modulo.
Il chip dispone di una memoria non volatile nella quale possono essere memorizzate due temperature (tipicamente una minima ed una massima) oltrepassate le quali lancia un segnale di allarme, sempre sottoforma di impulsi digitali, che può essere letto ed interpretato da una scheda hardware.
Il modulo può anche essere alimentato dall’energia presente sulla linea in cui scorrono i dati per cui è possibile limitare i collegamenti alla sola terra ed alla linea dati.
La risoluzione del termometro è programmabile da 9 a 12 bit con un tempo di latenza di 750ms.
Lo schema a blocchi della sonda è desumibile dalla seguente immagine:

Lo schema classico per la connessione elettrica (con la possibilità di connettere un’altra sonda sulla linea dati)

La funzionalità principale del DS18B20 è il suo sensore di temperatura digitale diretto.
La risoluzione del DS18B20 è configurabile (9, 10, 11 o 12 bit), con letture a 12 bit come impostazione predefinita di fabbrica, ciò equivale a una risoluzione di misura della temperatura di 0,5 °C, 0,25 °C, 0,125 °C o 0,0625 °C.
La conversione del dato, si identifica in due byte:


Il bus “1-Wire” è un sistema con un singolo bus master e uno o più slave: il DS18B20 si comporta come uno slave.
Il bus 1-Wire ha una sola linea per la trasmissione e la ricezione dei dati, per definizione; è fondamentale dunque, che ogni dispositivo sul bus sia in grado di pilotarla al momento opportuno.
Ogni dispositivo collegato al bus 1-Wire deve avere uscite open drain o a 3 stati. La porta 1-Wire del DS18B20 (pin DQ) è open drain con un circuito interno equivalente a quello mostrato in Figura:

Un bus multidrop è costituito da un bus 1-Wire con più slave collegati.
Il bus 1-Wire richiede una resistenza di pull-up di da 4,7kΩ.
Il DS18B20 richiede protocolli rigorosi per garantire l’integrità dei dati. Il protocollo consiste in diversi tipi di segnalazione su una linea: impulso di reset, impulso di presenza, scrittura 0, scrittura 1, lettura 0 e lettura 1.
Tutti questi segnali, ad eccezione dell’impulso di presenza, sono avviati dal bus master.
In sintesi: il bus master trasmette (TX) un impulso di reset (un segnale basso per un minimo di 480 µs).
Il bus master quindi rilascia la linea e passa in modalità di ricezione (RX).
Il bus 1-Wire viene portato allo stato alto tramite la resistenza di pull-up da 4,7k.
Dopo aver rilevato il fronte di salita sul pin DQ, il DS18B20 attende 15-60 µs e quindi trasmette l’impulso di presenza (un segnale basso per 60-240 µs).
Il comando di scrittura: [4Eh], scrive nella memoria scratchpad del DS18B20, a partire dal registro “TH”.
I successivi 3 byte scritti verranno salvati nella memoria scratchpad, nelle posizioni di indirizzo da 2 a 4. Tutti e 3 i byte devono essere scritti prima che venga eseguito un reset.
Il comando di lettura: [Beh], legge il contenuto dello scratchpad. La lettura inizierà dal byte 0 e continuerà attraverso lo scratchpad fino alla lettura del nono byte (byte 8, CRC).
Se non tutte le posizioni devono essere lette, il master può emettere un reset per terminare la lettura in qualsiasi momento.
Il comando di conversione: [44h], avvia una conversione della temperatura.
Non sono richiesti ulteriori dati.
La conversione della temperatura verrà eseguita e quindi il DS18B20 rimarrà inattivo. Se il bus master emette intervalli di tempo di lettura dopo questo comando, il DS18B20 emetterà 0 sul bus finché è impegnato a effettuare una conversione della temperatura; restituirà 1 al termine della conversione.
Se alimentato da un dispositivo parassita, il bus master deve abilitare un pull-up forte per un periodo maggiore di “tconv” immediatamente dopo l’emissione di questo comando.
Lo schema di flusso della funzionalità del dispositivo (parte1):

Lo schema di flusso della funzionalità del dispositivo (parte2):

Lo schema di flusso della funzionalità del dispositivo (parte3):

Tabella comandi:

Nota importante: la conversione della temperatura richiede fino a 750 ms. dopo aver ricevuto il protocollo Convert T, se il componente non riceve alimentazione dal pin VDD, la linea DQ per il DS18B20 deve essere mantenuta alta per almeno un periodo superiore a tconv per fornire alimentazione durante il processo di conversione, pertanto, nessuna altra attività può aver luogo sul bus 1-Wire per almeno questo periodo dopo l’emissione di un comando Convert T.
Curva errori tipici:

Il Raspberry Pi Pico-W
Il raspberry pi pico-w è un “Microcontrollore” della famiglia raspberry.
Si potrebbe definirlo come un piccolo computer, su un singolo chip che integra al suo interno una CPU, memoria (RAM e ROM/Flash) e varie periferiche di ingresso/uscita (I/O), disponendo inoltre di una porta per il collegamento WIFI.
Per inciso, è giusto specificare che la differenza principale tra un microcontrollore (MPU, Micro Processor Unit) ed un microprocessore (CPU) consiste nel fatto che l’unità di elaborazione “CPU” (il microprocessore o Central Processing Unit)) richiede componenti esterni (memoria, I/O), mentre un microcontrollore è un chip singolo che integra CPU, memoria (RAM e ROM) e periferiche di input/output.
Questo rende i microcontrollori ideali per applicazioni embedded e a basso consumo come elettrodomestici, mentre i microprocessori sono usati per compiti generici e ad alte prestazioni come nei computer.
Questo è il suo layout:

I componenti del raspberry pi pico – w si possono identificare nel seguente elenco:
RP2040 microcontroller chip designed by Raspberry Pi in the United Kingdom
- Dual-core Arm Cortex M0+ processor, flexible clock running up to 133 MHz
- 264KB of SRAM, and 2MB of on-board flash memory
- USB 1.1 with device and host support
- Low-power sleep and dormant modes
- Drag-and-drop programming using mass storage over USB
- 26 × multi-function GPIO pins
- 2 × SPI, 2 × I2C, 2 × UART, 3 × 12-bit ADC, 16 × controllable PWM channels
- Accurate clock and timer on-chip
- Temperature sensor
- Accelerated floating-point libraries on-chip
- 8 × Programmable I/O (PIO) state machines for custom peripheral support
- Wireless (802.11n), single-band (2.4 GHz)
- WPA3
- Soft access point supporting up to four clients
- Bluetooth 5.2
I dispositivi Raspberry Pi Pico serie W supportano i linguaggi di programmazione C/C++ o MicroPython.
Sui dispositivi è presente il pulsante BOOTSEL che serve a mettere l’apparecchiatura in modalità bootloader, ovvero una modalità di archiviazione di massa, quando collegato a un computer tramite USB.
In questa modalità, il Pico appare come una chiavetta USB chiamata “RPI-RP2”, consentendo di trascinare e rilasciare facilmente il firmware o il codice “uf2” per aggiornarlo o programmarlo.
Il dispaly IIC LCD1602
Questo modulo utilizza il diffusissimo display LCD ((Liquid Crystal Displays) 1602C da 16 caratteri e 2 file che contiene un convertitore al “bus I2C” consentendo il collegamento al circuito di pilotaggio con solo 2 fili.

Il diagramma a blocchi del dispositivo:

caratteristiche principali:

bus di trasmissione dati:

segnali:

Il protocollo I2C
Il protocollo di trasmissione “I2C” (Inter-Integrated Circuit) è un bus seriale a due fili sviluppato da Philips, utilizzato per la comunicazione tra più dispositivi su una stessa scheda madre o tra diversi circuiti integrati.
Si basa su un modello master-slave in cui il master controlla la comunicazione e gli slave rispondono.
Le due linee fondamentali sono SDA (Serial Data) per i dati e SCL (Serial Clock) per la sincronizzazione di trasmissione.
Come funziona:
osservando il grafico dei segnali sopra riportato, si possono evincere i seguenti processi:
Start:
- Il master segnala l’inizio di una comunicazione spostando la linea SDA da alto a basso mentre SCK è alto.
Indirizzamento:
- Il master invia l’indirizzo univoco dello slave con cui vuole comunicare.
- Lettura/scrittura:
- Il master invia un ulteriore bit che indica se deve leggere o scrivere dal/al dispositivo.
Trasferimento dati:
- I dati vengono scambiati bit per bit, sincronizzati dal segnale SCK.
- Dopo ogni byte, il ricevente invia un segnale di “ACK” (Acknowledgement) per confermare la ricezione.
Stop:
- Il master segnala la fine della comunicazione spostando la linea SDA da basso ad alto mentre SCK è alto.
Un alimentatore USB
Universal Serial Bus: comunemente noto come USB, non è altro che un’interfaccia progettata per semplificare la connessione tra computer e periferiche come tastiere, mouse, scanner, stampanti, fotocamere digitali e telefoni cellulari.
L’USB è stato inizialmente progettato da aziende americane, in particolare Intel, IBM e Microsoft Corporation, a metà degli anni ‘1990.
L’idea alla base era quella di fornire un metodo standard per collegare diverse periferiche ai computer, da allora, l’USB si è evoluto e ha sostituito molti connettori specializzati con un’interfaccia USB standard.
L’USB funge da ponte tra l’host e la periferica, svolgendo due funzioni: la trasmissione dei dati e l’alimentazione delle periferiche.
Un’interfaccia USB standard è composta da quattro pin: due per il trasferimento dei dati e due per l’alimentazione.
I pin per il trasferimento dei dati servono per l’invio e la ricezione dei dati, mentre i pin per l’alimentazione servono per l’alimentazione a +5 V e per il collegamento a massa (GND).
Ciascuno dei fili ovviamente, è contrassegnato da un colore univoco.

Un alimentatore USB viene alimentato dalla rete monofase (230V – 50Hz) per l’Italia, ed in uscita può variare da (500mA) per (USB 2.0) a (1,5A) per (USB BC 1.2), fino a raggiungere i (3A) per le porte USB-C standard.

Tipi di USB
La tecnologia USB offre una varietà di tipologie e configurazioni per soddisfare le esigenze specifiche del dispositivo. I tipi di USB più comuni sono USB Type-A, USB Type-B, Micro USB, Mini USB e USB Type-C.
1. USB di tipo A: Il tipo A è il connettore rettangolare standard comunemente presente su computer, unità flash e caricabatterie. Esistono due versioni di connettori di tipo A: maschio (spina) e femmina (presa). La femmina (presa) si trova sul controller host, mentre il maschio (spina) si trova su dispositivi periferici come tastiere, mouse e altri dispositivi.
La piedinatura USB di tipo A è composta da quattro pin, due per il trasferimento dati e due per l’alimentazione. Tuttavia, una versione più recente di USB di tipo A è composta da nove pin. I connettori USB di tipo A sono ampiamente utilizzati in personal computer, caricabatterie per cellulari, dispositivi di gioco, smart TV e impianti stereo.
2. USB di tipo B: Questi connettori sono di forma quadrata e si trovano principalmente su scanner e stampanti. Le porte di tipo B sono connettori upstream presenti solo nelle periferiche. Proprio come il connettore USB di tipo A, anche il connettore di tipo B ha quattro pin (VCC, D+, D- e GND). Le versioni USB 3.0 e successive sono dotate di nove pin con altri cinque pin per una maggiore velocità di trasferimento dati.
3. Micro USB: Con l’avanzare dell’intelligenza dei dispositivi moderni, i tradizionali connettori USB di tipo A e USB di tipo B non sono più adatti. Per questo motivo, sono nati i connettori Micro USB. A differenza dei connettori USB di tipo A e di tipo B, i connettori Micro USB sono intelligenti, compatti e più piccoli.
Il pinout del connettore Micro-USB è diverso da quello dei connettori USB di tipo A e B. Il connettore Micro-USB è composto da cinque pin: pin di alimentazione (VBUS (+5V), GND), pin di trasferimento dati (D+, D-) e pin di identificazione (ID). Il connettore Micro-USB è ampiamente utilizzato in dispositivi intelligenti come telefoni cellulari, gadget, tablet, sistemi audio, cuffie wireless e altri dispositivi portatili.
4. Mini-USB: Il connettore Mini USB è stato inizialmente progettato per fotocamere digitali e smartphone più vecchi. I connettori Mini USB sono più grandi dei Micro USB e più piccoli dei connettori Tipo A/Tipo B. La configurazione dei pin del Mini USB e del Micro USB è la stessa: pin di alimentazione (VBUS (+5V), GND), pin di trasferimento dati (D+, D-) e un pin per l’identificazione (ID).
5. USB di tipo C: Il connettore USB Type-C è un connettore reversibile, il che significa che può essere utilizzato sia per l’host che per i dispositivi. I connettori USB Type-C hanno gradualmente sostituito i connettori Type-A/Type-B. Tra tutti i tipi di connettore, il connettore USB Type-C offre la velocità di trasferimento dati più elevata (fino a 10 Gbps). Il connettore USB Type-C ha una configurazione a 24 pin, che verrà discussa nella sezione successiva.
I connettori USB di tipo C sono tra i più utilizzati in assoluto, le loro applicazioni includono, a titolo esemplificativo ma non esaustivo, fotocamere digitali, smartwatch, auricolari ricaricabili e controller di gioco, apparecchiature miniaturizzate.
I connettori USB:

Ogni pin del connettore ha una funzione specifica, in relazione alla tipologia di connettore, cosi come la potenza erogabile:

I cavi USB sono progettati per soddisfare le specifiche esigenze di connettività per il trasferimento dati e l’alimentazione.
Cavi USB da tipo A a tipo B: i cavi USB standard vengono utilizzati per collegare dispositivi come computer, scanner e stampanti. Tra le applicazioni rientrano il trasferimento di file e la ricarica di dispositivi. Lo schema elettrico da USB tipo A a tipo B presenta quattro fili (VCC, D-, D+ e GND).
Cavi mini USB: la maggior parte dei dispositivi portatili utilizza cavi mini-USB di tipo A, come fotocamere digitali, dispositivi elettronici e lettori MP3. I cavi mini-USB avevano un design compatto, ma sono stati sostituiti dai cavi micro-USB grazie al progresso tecnologico.
Micro cavi USB: la maggior parte dei dispositivi moderni, come power bank, smartphone, tablet e fotocamere digitali, utilizzava fino a poco tempo fa cavi Micro USB per il loro design compatto. Lo schema elettrico di un cavo Micro USB ne include cinque (VBUS, D-, D+, ID, GND). Le configurazioni dei pin Micro USB e Mini USB sono le stesse, ma differiscono per le dimensioni. Entrambi hanno un pin aggiuntivo per l’identificazione della modalità.
Cavi USB di tipo C: nella tecnologia moderna odierna, l’USB Type-C è il più versatile, veloce e affidabile tra tutti. I cavi Type-C sono presenti nella maggior parte dei dispositivi moderni, inclusi computer da gaming, fotocamere digitali moderne, smartwatch e auricolari. Lo schema elettrico del cavo Type-C presenta 24 pin.
Il box di contenimento
Per il contenimento delle apparecchiature è sufficiente modificare una scatola di derivazione con grado di protezione IP55:

dotandola di pressacavi adeguati:

Ovviamente la modifica farà perdere le caratteristiche di protezione della scatola, ma, con l’applicazione di una lastrina di plexiglass opportunamente dimensionata e qualche accorgimento accessoristico, sarà possibile proteggere il display LCD da polveri e anche da eventuali spruzzi di acqua.

I gradi di protezione IP
I gradi di protezione IP (International Protection o Ingress Protection) indicano la resistenza di un apparecchio a corpi solidi estranei (prima cifra) e a liquidi (seconda cifra).
La prima cifra va da 0 (nessuna protezione) a 6 (antipolvere), mentre la seconda da 0 (nessuna protezione) a 9 (resistenza a getti d’acqua ad alta pressione)
In realtà, il codice IP completo, si costituisce in questo modo:
Prima cifra: protezione delle persone contro il contatto con parti pericolose e protezione dei materiali contro l’ingresso dei corpi solidi;
Seconda cifra: protezione dei materiali contro l’ingresso dannoso dell’acqua;
Lettera aggiuntiva: da usarsi qualora la protezione delle persone contro il contatto con parti pericolose sia superiore a quella della protezione contro l’ingresso dei corpi solidi richiesta dalla prima cifra caratteristica;
Lettera supplementare: da usarsi per fornire ulteriori informazioni relative al materiale.
NOTA: quando non è richiesta una cifra caratteristica, quest’ultima è sostituita dalla lettera “X” (“XX” se sono omesse entrambe le cifre), le lettere addizionali e/o supplementari possono essere omesse senza essere sostituite.

Il Software
L’etimologia di questa parola, credo sia da riferirsi ad una “interpretazione tecnica”, derivante dalla distinzione necessaria tra parte fisica (hard-ware) di un sistema o macchina per l’elaborazione di dati e la parte “non tangibile” inerente le istruzioni a cui fanno riferimento gli algoritmi (soft-ware), “coniata” dal matematico John Tukey nel 1958.
il termine “Software” è generico e viene riferito sia ai programmi che ai dati elaborati dalle apparecchiature moderne, ma generalmente si può categorizzare in modi diversi:
- Software di sistema: il software di base che gestisce le funzioni essenziali e le risorse della macchina, come il sistema operativo (ad esempio, Windows, macOS, Android).
- Software applicativo: i programmi che gli utenti usano per svolgere attività specifiche, come i fogli di calcolo, i browser web, i videogiochi e le applicazioni per smartphone.
- Software di programmazione (linguaggi): strumenti utilizzati dagli sviluppatori per creare altri software.
Vi è quindi una parte del software strettamente legata all’hardware necessario per l’elaborazione dei dati, il software di sistema, che è composto da un sistema operativo (il suo nucleo, chiamato kernel), adibito esclusivamente a gestisce l’hardware e le risorse dello strumento, e da altri componenti essenziali come il file system per l’organizzazione dei dati, i driver per la comunicazione con le periferiche, e l’interfaccia utente che permette all’utente di interagire con il sistema. Comprende anche i programmi di utilità e il firmware (come il BIOS).
Il raspberry pi pico-w non ha un vero e proprio BIOS, ma si avvia da un “bootloader” denominato UF2 che viene montato come un’unità disco (RPI-RP2) quando si collega la scheda al PC tenendo premuto il pulsante BOOTSEL
Il file UF2 (USB Flashing Format) è un “firmware” che può essere facilmente caricato sul Raspberry Pi Pico-W, collegandolo ad un computer, in questo modo si può caricare un interprete funzionale per sistemi “Embedded”: MicroPython.

MicroPython
Come “dice il nome”, è un linguaggio di programmazione derivante dal Python(3) ed implementato appositamente per essere utilizzato su dispositivi aventi “risorse limitate” ed operare a “basso livello”, mediante moduli specifici opportunamente archittettati per interagire con dispositivi In/Out.
L’intero “core” di MicroPython è disponibile per l’uso generale con la licenza MIT, molto liberale.
La maggior parte delle librerie e dei moduli di estensione (alcuni dei quali di terze parti) sono disponibili anche con licenza MIT o simili. (OPEN SOURCE).
È possibile utilizzare e adattare liberamente MicroPython per uso personale, didattico e in prodotti commerciali.
Questo linguaggio è scritto in “C99”, un linguaggio ideato da Dennis Ritchie negli anni ’70 per sviluppare il sistema operativo UNIX, quindi un “codice” molto orientato all’hardware, alla macchina, più che all’umano.
MicroPython invece ha degli aspetti più orientati al programmatore:
Caratteristiche principali
- Leggero e efficiente: è ottimizzato per funzionare su dispositivi con risorse limitate.
- Facile da usare:
porta i vantaggi di Python, come la sintassi chiara e l’elevata produttività, nel mondo dell’embedded.
- Accesso all’hardware:
include moduli specifici che permettono al programmatore di controllare direttamente l’hardware, come sensori e pin di input/output.
- Interattività:
offre un prompt interattivo (REPL) che consente di eseguire comandi e testare il codice in tempo reale.
Vantaggi:
- Sviluppo più veloce: permette di scrivere e testare codice più rapidamente rispetto a linguaggi tradizionali come il C o il C++.
- Maggiore riutilizzo del codice:
il codice scritto in MicroPython è più portabile tra diversi dispositivi, riducendo i tempi di sviluppo.
- Accessibile ai maker:
rende la programmazione di microcontrollori più intuitiva per un pubblico ampio, come i maker.
MicroPython è sviluppato in modalità open source su GitHub e il codice sorgente è disponibile sulla pagina GitHub e sulla pagina di download.
Il programma
il codice scritto in MicroPython è sintetizzabile come di seguito esposto:
Flusso Logico Principale (Main Loop)
Il programma è essenzialmente un ciclo infinito (while True) che gestisce tre operazioni principali con cadenze temporizzate diverse:
- Controllo Connessione WiFi (ogni 60 secondi).
- Lettura Sensori e Aggiornamento Display LCD (ogni 30 secondi).
- Invio Dati al Server (ogni 240 secondi).
Pseudocodice:
INIZIO
CONFIGURAZIONE INIZIALE
1. Tenta connessione WiFi (wlan = connect_to_wifi())
2. Inizializza DS18B20 e LCD I2C
Se LCD è inizializzato:
Mostra "Pico W Client" e "Avvio..."
Imposta CONTATORI TEMPORIZZATI (last_read_time, last_send_time, last_check_time)
Imposta SOGLIE DI ALLARME (MIN_TEMP_ALARM, MAX_TEMP_ALARM)
alarm_on = FALSO
INIZIA LOOP PRINCIPALE (WHILE TRUE):
current_time = tempo attuale
# 1. Controllo Connessione (Ogni 60s)
SE current_time - last_check_time >= 60:
wlan = check_connection(wlan)
last_check_time = current_time
---
# 2. Lettura e Allarmi (Ogni 30s)
SE current_time - last_read_time >= 30:
temperature = read_temperature()
motor_on = FALSO
alarm_on = FALSO
# CHECK ALLARMI
SE temperature NON È Nullo:
SE temperature <= MIN_TEMP_ALARM O temperature >= MAX_TEMP_ALARM:
alarm_on = VERO (Allarme Temperatura)
# CHECK MIXER
SE MIX == VERO:
motor_on = read_mix() # Blocca per 3s, verifica rotazione
SE motor_on == FALSO:
alarm_on = VERO (Allarme Mixer Fermo)
# AGGIORNAMENTO LCD
SE LCD è inizializzato:
update_lcd(temperature, alarm_on) # Mostra allarme se attivo
last_read_time = current_time
---
# 3. Invio Dati (Ogni 240s)
SE WiFi connesso E current_time - last_send_time >= 240:
SE temperature NON È Nullo E temperature È disponibile:
SE send_data_to_server(temperature) È VERO:
last_send_time = current_time # Aggiorna solo in caso di successo
ALTRIMENTI:
Stampa "Invio fallito"
ALTRIMENTI:
Stampa "Dato non disponibile"
Pausa di 1 secondo (time.sleep(1))
FINE LOOP
FINE
Entrando più nel particolare:
1. connect_to_wifi(ssid, password)
Questo blocco rappresenta un flusso di inizializzazione con ciclo e timeout.
FUNZIONE connect_to_wifi(ssid, password):
Attiva la WLAN (STA_IF)
Tenta la connessione (wlan.connect)
max_wait = 20
CICLO WHILE max_wait > 0:
SE connessione Riuscita O Fallita (status < 0 O status >= 3):
ESCI DAL CICLO (break)
ALTRIMENTI:
Attendi 5 secondi
max_wait = max_wait - 1
SE wlan.isconnected() È VERO:
Stampa "Connessione riuscita" e l'IP
RITORNA Oggetto WLAN
ALTRIMENTI:
Stampa "Connessione fallita"
RITORNA Nullo
2. read_temperature()
Flusso di lettura del sensore DS18B20.
FUNZIONE read_temperature():
TENTA:
SE Nessun sensore trovato (roms vuoto):
RITORNA Nullo
Invia comando di conversione al sensore (ds_sensor.convert_temp())
Attendi 750 millisecondi
temperature = Leggi il valore dal primo sensore (roms[0])
RITORNA temperature Arrotondata a 2 decimali
ECCEZIONE (Se la lettura fallisce):
Stampa l'errore
Tenta un reset (ds_sensor.convert_temp())
RITORNA Nullo
3. read_mix()
Flusso di monitoraggio del MIX/Agitatore, basato su un ciclo limitato nel tempo.
FUNZIONE read_mix():
motor_on = FALSO
intervallo_tempo_secondi = 3
time_start = tempo attuale in ms
INIZIA CICLO (Monitoraggio di 3 secondi):
ora_attuale = tempo attuale in ms
stato_pin = mix_pin.value()
# DECISIONE: Segnale rilevato (fronte di discesa, 1 -> 0)
SE stato_pin == 0 E ultimo_segnale == 1:
motor_on = VERO
Stampa "Rotazione rilevata"
ESCI DAL CICLO (break)
# DECISIONE: Tempo Limite superato
SE ora_attuale > time_start + 3000ms:
ESCI DAL CICLO (break)
ultimo_segnale = stato_pin
Attendi 0.5 secondi
SE motor_on È VERO:
Stampa "Rotazione rilevata"
ALTRIMENTI:
Stampa "Nessuna rotazione rilevata"
RITORNA motor_on (Vero o Falso)
4. update_lcd(temp, alarm_status)
Flusso di visualizzazione condizionale sul display LCD.
FUNZIONE update_lcd(temp, alarm_status):
SE lcd È Nullo: RITORNA (uscita rapida)
Pulisci LCD
# DECISIONE: Allarme Attivo?
SE alarm_status È VERO:
Riga 1: Mostra la temperatura
# DECISIONI ALLARME SPECIFICHE
SE temp <= MIN_TEMP_ALARM:
Riga 2: "ALARM! < MIN_TEMP_ALARM"
ALTRIMENTI SE temp >= MAX_TEMP_ALARM:
Riga 2: "ALARM! > MAX_TEMP_ALARM"
Attendi 1 secondo
ALTRIMENTI SE motor_on == FALSO: # Allarme mixer
Riga 2: "ALARM MIX"
# DECISIONE: Stato Normale o Errore
ALTRIMENTI SE temp NON È Nullo:
Riga 1: Mostra la temperatura (Formato normale)
Riga 2: "CP4 TS_gr" (Messaggio standard)
ALTRIMENTI:
Riga 1: "Temp: N/A"
Riga 2: "Errore Lettura"
Questa funzione gestisce la preparazione dell'URL e l'invio della richiesta HTTP GET al server (Raspberry Pi/ o PC Ubuntu, inclusa la gestione degli errori.
FUNZIONE send_data_to_server(temp):
SE temp È Nullo:
Stampa "Dato non valido, salto l'invio."
RITORNA FALSO
url = SERVER_URL / temp
TENTA:
response = Invia richiesta HTTP GET a url
# DECISIONE: Server OK?
SE response.status_code == 200:
Stampa "Dato inviato: X°C, Server OK."
Chiudi la risposta
RITORNA VERO
ALTRIMENTI:
Stampa "Errore Server: Status Code Y"
Chiudi la risposta
RITORNA FALSO
ECCEZIONE (Errore di connessione o HTTP):
Stampa "Errore invio dati al server: E"
RITORNA FALSO
integrazione opzionale del Main Loop
Questa è una parte del blocco, nel ciclo while True che controlla la cadenza dei 240 secondi e chiama la funzione di trasmissione dei dati mediante richiesta HTTP - GET.
La logica è cruciale: aggiorna il tempo dell'ultimo invio solo se l'invio ha avuto successo.
# ... (Parte del Loop Principale) ...
# 3. Invio Dati al Server (Ogni 240 secondi)
SE wlan è connesso E current_time - last_send_time >= 240:
# DECISIONE: C'è un dato di temperatura valido da inviare?
SE temperature È stata definita E temperature NON È Nullo:
# DECISIONE: La chiamata alla funzione è riuscita?
SE send_data_to_server(temperature) È VERO:
last_send_time = current_time # Successo: aggiorna il timer per il prossimo invio
ALTRIMENTI:
Stampa "Invio dati fallito, inoltro al prossimo intervallo di invio."
# NOTA: last_send_time NON viene aggiornato, forzando un ritentativo
# appena possibile dopo la pausa (time.sleep(1))
ALTRIMENTI:
Stampa "Dato di temperatura non ancora disponibile per l'invio."
# ... (Fine Loop) …
Specifiche:
La richiesta GET è un metodo HTTP che viene utilizzata per richiedere dati da un server web, a differenza di POST, che invia dati nel corpo della richiesta, GET aggiunge i parametri direttamente nell'URL dopo un punto interrogativo (?), separati da e commerciale (&). Questo tipo di richiesta è considerato idempotente (lo stesso risultato si ottiene ripetendo la richiesta) e i suoi risultati possono essere memorizzati nella cache, rendendola adatta per recuperare risorse che non vengono modificate di frequente.
Il codice del programma:
Il programma che viene installato sul Raspberry Pi Pico W è scritto in MicroPython e rispecchia quanto sopra riportato dal tracciato in pseudocodice.
La versione proposta è una delle primissime release beta (R.beta_0.2).
Una release di un programma informatico è una “versione” di un software che ne identifica “Lo stato dell’arte”.
Le release possono essere "maggiori" (major) per cambiamenti significativi o "minori" (minor) per aggiornamenti più piccoli, come le patch.
A cosa serve una release:
- Introduzione di nuove funzionalità: Aggiunge nuove caratteristiche e opzioni per migliorare l’usabilità e il valore del software.
- Correzione di bug: Risolve errori e malfunzionamenti presenti nelle versioni precedenti.
- Miglioramento delle prestazioni: Ottimizza l’efficienza del software per renderlo più veloce e reattivo.
- Aggiornamenti di sicurezza: Introduce modifiche per proteggere il software da vulnerabilità e minacce.
- Miglioramento dell’esperienza utente: A volte può includere modifiche al design o al flusso di lavoro per rendere l’interfaccia più intuitiva.
- Supporto e compatibilità: Si assicura che il software rimanga compatibile con nuovi sistemi operativi o altri dispositiv
i.
Fase Alfa
- Test interni: Il software viene testato principalmente all’interno dell’azienda, dagli sviluppatori stessi
- Funzionalità incomplete:
Le funzionalità potrebbero non essere completamente implementate e i bug sono frequenti.
- Obiettivo:
Identificare e correggere i bug più gravi prima di renderlo disponibile agli utenti esterni.
Fase Beta
- Test esterni: La versione è resa disponibile a un gruppo selezionato di utenti esterni (chiamati beta tester) o al pubblico.
- Funzionalità complete: Il software è più stabile e completo rispetto alla versione alfa.
- Obiettivo: Raccogliere feedback sull’usabilità, prestazioni e individuare bug residui che non sono stati trovati nei test interni.
Dopo le fasi Beta:
- Dopo la fase beta, il software può passare alla fase di “Release Candidate” (RC), che è l’ultima versione prima del rilascio finale.
- Una volta che tutti i bug critici sono stati risolti, viene rilasciata la versione ufficiale e stabile del software. ( vedasi approfondimenti di letture consigliate)
main.py
# main.py (Pico-w) release Beta_0.2
# funziona e trasmette al server il dato temp
import time
import machine
import network
import urequests as requests
# DS18B20 Imports
import onewire, ds18x20
# I2C LCD Imports
from machine import I2C
# Le librerie I2C LCD (lcd_api.py e i2c_lcd.py) devono essere caricate separatamente
from LCD_API import LcdApi
from I2C_LCD import I2CLcd
# --- Configurazione Hardware e Network ---
# Impostazioni WiFi
ssid = 'SSID'
password = 'PASSWORD'
# Configurazione Server
SERVER_IP = '10.10.10.10' # Cambia con l'IP locale del PC
SERVER_PORT = 5000
SERVER_URL = f"http://{SERVER_IP}:{SERVER_PORT}/temperatura"
# Configurazione DS18B20 (Assegnato il pin GPIO 0)
DS_PIN = 0
ds_pin = machine.Pin(DS_PIN)
ds_sensor = ds18x20.DS18X20(onewire.OneWire(ds_pin))
# Cerca il dispositivo
roms = ds_sensor.scan()
print('Trovato DS18B20:', roms)
# Configurazione MIX
# MIX_PIN = xx
mix_pin = machine.Pin(14, machine.Pin.IN, machine.Pin.PULL_DOWN)
MIX = True
# Configurazione I2C LCD (I2C(0) con pin standard)
I2C_ADDR = 0x27 # Indirizzo I2C standard per PCF8574 (potrebbe essere 0x3F)
I2C_NUM = 0
I2C_SCL = 5 # GPIO 5 (Pin 7)
I2C_SDA = 4 # GPIO 4 (Pin 6)
LCD_ROWS = 2
LCD_COLS = 16
i2c = I2C(I2C_NUM, scl=machine.Pin(I2C_SCL), sda=machine.Pin(I2C_SDA), freq=400000)
try:
lcd = I2CLcd(i2c, I2C_ADDR, LCD_ROWS, LCD_COLS)
except Exception as e:
print(f"Errore inizializzazione LCD: {e}")
lcd = None
# --- Funzioni di Utility ---
def connect_to_wifi(ssid, password):
# global SSID, PASSWORD
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(ssid, password)
# Attesa connessione o timeout
max_wait = 20
while max_wait > 0:
if wlan.status() < 0 or wlan.status() >= 3:
break
max_wait -= 1
print('In attesa connessione WiFi...')
time.sleep(5)
if wlan.isconnected():
status = wlan.ifconfig()
print('Connessione WiFi riuscita! IP:', status[0])
return wlan
else:
print('Connessione WiFi fallita.')
return None
def check_connection(wlan):
if wlan is None or not wlan.isconnected():
print("Connessione persa. Riconnessione...")
return connect_to_wifi(ssid, password)
return wlan
def read_temperature():
global temperature
try:
if not roms:
print("Nessun sensore DS18B20 trovato.")
return None
ds_sensor.convert_temp() # Richiede la conversione
time.sleep_ms(750) # Attesa del tempo di conversione (max 750ms per 12-bit)
temperature = ds_sensor.read_temp(roms[0]) # Legge il primo sensore
return round(temperature, 2)
except Exception as e:
print(f"Errore lettura DS18B20: {e}")
ds_sensor.convert_temp() # Prova a resettare
return None
def read_mix():
global motor_on
# Variabili per la misurazione
ultimo_segnale = 0
stato_pin = 0
intervallo_tempo_secondi = 3 # si potrebbe anche verificare la velocità di rotazione...
motor_on = False
print("Avvio del monitoraggio di rotazione utensile...")
time_start = time.ticks_ms()
while True:
ora_attuale = time.ticks_ms() # tempo attuale in millisecondi
print("ora attuale ", ora_attuale)
stato_pin = mix_pin.value()
print("stato_pin ", stato_pin)
# variante per raffreddatore o riscaldatore
# il contatto relè (NC) o (NO) rilevela che un blocco nella apparecchiatura associata
# if stato_pin == 1:
# variante per MIXER
# Controlla se il pin è passato da LOW a HIGH (rilevando un segnale MIXER)
if stato_pin != ultimo_segnale:
motor_on = True
print("Rotazione rilevata")
# Calcola il tempo trascorso dall'ultimo segnale
tempo_trascorso = time.ticks_diff(ora_attuale, ultimo_segnale) / 1000
print("tempo trascorso ", tempo_trascorso)
break
tempo_limite = time_start + intervallo_tempo_secondi * 1000
if ora_attuale > tempo_limite:
# print("Nessuna rotazione nell'intervallo di tempo prestabilito!")
break # Esce dal loop
ultimo_segnale = stato_pin
print("ultimo segnale", ultimo_segnale)
time.sleep(0.5) # Piccola attesa per non sovraccaricare la CPU
if motor_on:
print("La rotazione meccanica e' avvenuta entro il limite di tempo")
else:
print("Nessuna rotazione meccanica rilevata nel tempo specificato.")
return motor_on
def update_lcd(temp, alarm_status):
if lcd is None:
return
lcd.clear()
lcd.putstr("Temp:")
if alarm_status:
lcd.move_to(0, 0)
line1 = f"temp= {temp:.2f} C"
lcd.putstr(line1)
if temp <= MIN_TEMP_ALARM:
line2 = f"ALARM! < {MIN_TEMP_ALARM:.2f}C"
lcd.move_to(0, 1)
lcd.putstr(line2)
elif temp >= MAX_TEMP_ALARM:
line2 = f"ALARM! > {MAX_TEMP_ALARM:.2f}C"
lcd.move_to(0, 1)
lcd.putstr(line2)
time.sleep(1)
elif motor_on == False:
line2 = f"ALARM MIX"
lcd.move_to(0, 1)
lcd.putstr(line2)
elif temp is not None:
line1 = f" {temp:.2f} C"
lcd.putstr(line1)
lcd.move_to(0, 1)
lcd.putstr("CP4 TS_gr")
else:
lcd.putstr(" N/A")
lcd.move_to(0, 1)
lcd.putstr("Errore Lettura")
def send_data_to_server(temp):
if temp is None:
print("Dato non valido, salto l'invio al server.")
return False
url = f"{SERVER_URL}/{temp}"
try:
response = requests.get(url)
if response.status_code == 200:
print(f"Dato inviato: {temp}C, Server OK.")
response.close()
return True
else:
print(f"Errore Server: Status Code {response.status_code}")
response.close()
return False
except Exception as e:
print(f"Errore invio dati al server: {e}")
return False
# --- Loop Principale ---
wlan = connect_to_wifi(ssid, password)
# Contatori per le azioni temporizzate (in secondi)
read_interval = 30
send_interval = 240
check_interval = 60
last_read_time = 0
last_send_time = 0
last_check_time = 0
MIN_TEMP_ALARM = 20.0 # Soglia di allarme inferiore
MAX_TEMP_ALARM = 30.0 # Soglia di allarme superiore
motor_on = False # Motore agitatore fermo
lcd_initialized = lcd is not None # Flag per evitare loop se l'LCD non è collegato
if lcd_initialized:
lcd.clear()
lcd.putstr("Pico W Client")
lcd.move_to(0, 1)
lcd.putstr("Avvio...")
time.sleep(3)
alarm_on = False
while True:
current_time = time.time()
print("current time", current_time)
# 1. Controllo Connessione (Ogni 60 secondi)
if current_time - last_check_time >= check_interval:
print("Controllo connessione...")
wlan = check_connection(wlan)
if wlan is None or not wlan.isconnected():
print("Nessuna connessione, riprovo al prossimo ciclo.")
last_check_time = current_time
# 2. Lettura dati temperatura, stato MIXER e Aggiornamento LCD (Ogni 30 secondi)
if current_time - last_read_time >= read_interval:
temperature = read_temperature()
if temperature is not None and temperature <= MIN_TEMP_ALARM:
alarm_on = temperature is not None and temperature <= MIN_TEMP_ALARM
print("allarme temperatura bassa")
elif temperature is not None and temperature >= MAX_TEMP_ALARM:
alarm_on = temperature is not None and temperature >= MAX_TEMP_ALARM
print("allarme temperatura alta")
else:
alarm_on = False
print ("nessun allarme di temperatura")
print(f"Temperatura letta: {temperature}C. Allarme: {alarm_on}")
motor_on = False
if MIX == True and motor_on == False:
motor_on = read_mix()
print("stato di motor_ON", motor_on)
alarm_on = MIX == True and motor_on == False
print("allarme mixer fermo", alarm_on)
if lcd_initialized:
update_lcd(temperature, alarm_on)
last_read_time = current_time
# 3. Invio Dati al Server (Ogni 240 secondi)
# Si assicura di inviare l'ultima temperatura letta (quella del ciclo read_interval)
if wlan is not None and wlan.isconnected() and current_time - last_send_time >= send_interval:
# Usa l'ultima temperatura letta
if 'temperature' in locals() and temperature is not None:
if send_data_to_server(temperature):
last_send_time = current_time
else:
# Non aggiorna last_send_time in caso di fallimento,ritenta al prossimo ciclo
print("Invio dati fallito, inoltro al prossimo intervallo di invio.")
else:
print("Dato di temperatura non ancora disponibile per l'invio.")
# Pausa principale di 1 secondo per il controllo
time.sleep(1)
Considerazioni finali
Spero che questo apporto sia utile per coloro che dedicheranno un po’ di tempo a questa lettura, nella quale ho cercato di mettere dei concetti interessanti di varia natura, mosso dalla curiosità che da sempre mi accompagna nel cercare di interpretare al meglio l’ambiente nel quale viviamo.
Spero anche che, questo “progettino didattico”, che tuttavia ha un senso pratico, possa essere condiviso da insegnanti e allievi di ogni genere e grado, ma anche da persone che per hobby o per necessità pratiche, intendano realizzarlo davvero, anche perché tutto sommato è economico e può trovare applicazioni di vario genere, con le dovute integrazioni e modifiche.
“Imparare ad imparare” è qualcosa che di solito non si insegna a scuola, bisogna avere lo spirito da “Autodidatta”, ma in questi “tempi moderni”, questa attività può essere resa gradevole anche per mezzo dell’utilizzo di “Macchine inferenziali”.
Quella che solitamente viene nominata come “Intelligenza artificiale”, se usata con le dovute maniere, può facilitare di molto l’apprendimento, può essere usata per “Stimolare la mente”, al posto di “Addormentare i neuroni”.
Anche questo testo, in parte è stato scritto con i suggerimenti di qualche agente che sfrutta gli LLM, e nel farlo, devo dire, mi sono anche divertito, d’altra parte, mi ha facilitato il compito, mi ha fatto risparmiare del tempo, ma mi ha dato opportunità anche di ampliare il contesto del discorso, senza dover andare a ricercare le informazioni che necessitavo, nei meandri della rete, ciò non toglie che, tra le righe di quanto riportato specialmente nelle prime pagine, si nascondano delle domande di enorme rilevanza scientifica che meriterebbero degli ulteriori approfondimenti, in particolar modo per quanto concerne la comprensione anti-intuitiva della “Meccanica quantistica”, ma lascio questa via a chi vorrà percorrerla con l’entusiasmo giovanile, io da “Vecchio cibernetico”, ne subisco il fascino, come un paesaggio di montagne che non saprei scalare, ma che mi ricordano i sentieri percorsi in gioventù.
Vi ringrazio per la lettura e ringrazio tutti coloro che hanno contribuito a vario titolo a divulgare la “Cultura scientifica”, scevra da orientamenti politici o religiosi, ma densa di “concetti vivi” e dinamici, che sin dall’inizio dei tempi hanno accompagnato il genere umano in un percorso affascinante, quel percorso che, partendo dai pittogrammi ci ha fatto arrivare alle icone, passando per i numeri e le parole. ;-)
Letture di approfondimento consigliate:
p.s.
Se il genere umano avesse imparato ad usare i VCS (Version Control System), forse il mono sarebbe migliore!
Romeo Ceccato