Registratore di pressione (datalogger)
Mi è stato chiesto un aiuto per sviluppare un programma che controllasse la pressione e la registrasse su file.
Il progetto è un assemblaggio di qualche modulo di arduino per dimostrare il corretto risultato del programma, come richiesto.
Descrizione
Questo non ha la pretesa di essere progetto completo, direi solo una prova di un programma. Ho messo insieme quattro moduli che possono essere collegati a un Arduino Nano oppure un Arduino UNO, come quello del mio amico.
I moduli sono un display a cristalli liquidi, un lettore per memoria SD, un modulo orologio con DS3231 e uno per il bluetooth. Nel programma si prevede anche una diversa configurazione con uno shield che contiene il lettore SD card e l’RTC DS1307.
Inoltre è incluso un partitore per l’ ingresso di comunicazione del modulo HC-06, per compatibilità ai 3,3 Volts usati dal modulo bluetooth.
Il programma permette un ampio grado di configurabilità, che viene determinato all’ inizio del sorgente alle linee dei #define, che spiegherò i dettagli di seguito.
Ci sono state varie difficoltà, una molto particolare è stato di capire perché non scriveva il file sulla memoria. Infatti come citato dal sito, il nome è rimasto nel formato 8.3. Per questo il nome del file è un numero sequenziale composto nel formato ggmmaiii, del quale
gg sono il giorno della data
mm è riferito al mese
a è per l’ anno
iii è per un numero sequenziale, in caso un file esistesse già si aggiunge uno nuovo
Il progetto include alcune peculiarità:
-
Controllo automatico della luminosità del display.
-
La registrazione dei file prevede un periodo programmabile, sia per la cadenza di scrittura dei campioni e anche la frequenza di cambio nome del file.
-
Lettura del rapporto tramite seriale o tramite bluetooth. Ovviamente dipende dai collegamenti disposti.
-
I files sono mantenuti e non vengono sovrascritti. Questo per evitare la perdita di registrazioni precedenti.
-
Il programma consente due versioni di hardware, una per il display collegato in parallelo e una per il collegamento tramite I2C. Quest’ultimo perché il mio amico ha quel tipo e uno shield che contiene l’ orologio e il lettore SD. Come da immagine.
-
Semplice implementazione di comunicazione tramite seriale. Tipo classico con il monitor di Arduino o al piedino TX coi livelli dei 5 V, oppure con un partiore per collegare il modulo bluetooth.
![]() |
Come si può notare qui di fianco con un collegamento tramite smartphone, con il programma Serial Bluetooth Terminal. Beh, la data non è quella che invia il programma, è piuttosto incluso nel programma di Android. |
Schema Elettrico
Lo schema descrive la connessione al piedino del controllo della luminosità che va collegato al piedino 15 del display. Dato che la libreria del display non ha tale rappresentazione ho fatto qualche ragguaglio. Anche con l’ interfaccia I2C il collegamento al piedino 15 viene preso da questo schema. La libreria per quel display, prevede solo un semplice controllo acceso o spento della retroilluminazione.
Descrizione del programma
Il programma è stato compilato con la IDE Arduino versione 1.8.7. Il file contiene anche le librerie, per evitare disguidi e possibili cambi di versioni in futuro.
Le variabili che permettono di configurare sono le seguenti:
#define RS 7
#define EN 6
#define D7 2
#define D6 3
#define D5 4
#define D4 5
Normali definizioni per le connessioni del display tipo parallelo.
#define CH1 9
Piedino assegnato per la regolazione della luminosità.
#define SENSOR A1
Permette di scegliere il canale analogico di lettura del sensore.
#define LDR A3
Definisce il canale analogico da dove prendere il segnale della fotoresistenza.
#define PARMODEL
Questo permette di scegliere la compilazione a secondo della configurazione hardware disponibile.
Quando si toglie il segno di commento, allora si opta per il modello parallelo (compatibile con il driver Hitachi HD44780) e l’ orologio è quello con il DS3231. Nel caso opposto si usa una interfaccia I2C con un PCF8574 per lo stesso tipo di display, tanto da risparmiare piedini per altre funzioni. Con questa configurazione si usa un orologio DS1307 a bordo di uno shield sopracitato.
#define DEBUG 0~1~2
Si imposta se si vuole usare la comunicazione seriale. Ci possono essere 2 livelli di debug che danno l’ occasione di determinare quali messaggi presentare alla seriale e al display.
Se venisse scritto 0 al posto di uno, allora tutta la parte della seriale non è inclusa nella compilazione del programma.
#define LCD_ROWS 2
#define LCD_COLUMNS 16
Si definisce le dimensioni del display. Variando questo implicherebbe anche altre modifiche nel programma che prevede solo la rappresentazione sulle dimensioni attuali definite da queste due righe.
#define LOG_INTERVAL 10
Questo determina la frequenza di campionamento del sensore, espresso in secondi. Quello del programma lo fa a ogni 10 secondi.
#define chipSelect 10
Si determina dove viene controllata l’ attivazione della scheda SD. Sebbene la libreria pretende di avere il piedino 10 come uscita. Quindi variando questo non implica di avere il piedino 10 liberato.
#define VMIN 102
#define VMAX 921
#define MINSCALE 0
#define MAXSCALE 160
Queste definizioni determinano i valori di lettura e conversione del canale. Nel caso specifico il sensore ha il valore di 0,5 V per lo zero e 4,5 V per quello di misura massima.
Quindi si converte in punti del convertitore ADC con la formula
V / 5 * 1024 per il minimo sarebbe 102 e per il massimo 921, arrotondati
come quelli sopra impostati.
Gli altri due sono i valori da presentare al display dopo la conversione con la funzione di Arduino map(). Minimo e massimo rispettivamente.
#define CHANGEFILE (14400 – LOG_INTERVAL)
Questo definisce il periodo di quanti secondi scrivere su un solo file. In caso d’interruzione della alimentazione, il programma prevede di non sovrascrivere un file già presente. Per questo c’è una routine che verifica se ci sono files presenti.
in tal modo si calcola le ore correttamente in multipli di 3600.
#define BGTVMIN 0
#define BGTVMAX 1024
#define BGTMINSCALE 20
#define BGTMAXSCALE 255
Queste linee, determinano i valori del controllo del PWM della luminosità del display. Sempre con la conversione della funzione map(). Ovvero il valore letto dall’ ingresso analogico del partitore di tensione viene convertito per una scala del PWM da un minimo di 20 a 255. Volendo fare le cose raffinate, si può fare la prova quando la fotoresistenza è completamente oscurata e mettere quello a BGTVMAX, viceversa anche per quando è fortemente illuminata si rileva il valore da mettere BGTVMIN.
Una piccola descrizione della funzione sprintf():
%0?d si determina di scrivere un numero decimale con riempimento con zeri per le cifre mancanti. Con ? Si determina il numero di cifre da rappresentare.
La funzione newFile() controlla se un file esiste già e quindi si aumenta il contatore.
Per questo si prova un nome nuovo e si verifica se questo è già assegnato a un file. Per esempio se il sistema viene riavviato di frequente, l’ ultimo file non viene sovrascritto ma si aggiunge uno con un valore di incremento che va da 0 a 255. Avrei voluto mettere il numero in esadecimale, ma forse non ho ancora capito bene come si scrive per la sprintf(), anche perché diventa più complicato da interpretare.
Ho considerato di usare solo una cifra per descivere il periodo annuale, in modo da garantire comunque di scrivere dati per 10 anni, senza rimuovere i files dalla memoria.
Nel programma ci sono due condizioni che limitano la rappresentazione entro i suoi estremi:
sensorVal = (sensorVal > VMIN) ? sensorVal : VMIN;
sensorVal = (sensorVal < VMAX) ? sensorVal : VMAX;
Che condizionano la rappresentazione oltre i limiti. Significa che valori oltre i limiti non vengono accettati e quindi viene rappresentato solo il minimo o il massimo, a secondo del caso.
Ultima nota:
Quando il programma incontra un errore nel rilevamento di SD o dell’ orologio, allora non procede e si blocca. Se per caso non s’è attivata la seriale possono notare i messaggi.
Quando viene rilevato che l’ orario del modulo è stato perso, con la connessione seriale si può avere un ulteriore controllo per poter impostare direttamente un orario oppure permettere di caricare quello del computer collegato.
Questa opzione presenta una richiesta con 3 scelte:
Y permette di immettere la data e l’ ora nel formato aa/mm/dd hh:mm:ss. Non c’è
una vera costrizione nel formato, una o 2 cifre fa differenza, solo che si rispetti
i delimitatori dei campi che sono / : e un spazio tra la data e l’ ora.
Z permette di saltare l’ attesa e continuare il programma con l’ orario invariato.
H consente di arrestare il procedimento del programma. Tanto da facilitare il riavvio con il tasto di reset.
Qualsiasi altro tasto o una attesa di di 3 secondi, permette di caricare l’ orario del
computer.
Per questo la scelta deve esser eseguita nel periodo di 3 secondo, altrimenti il programma decide automaticamente di aggiornare l’ orario. Tenuto conto che dal monitor seriale della IDE bisogna anche immettere il tasto d’ invio, per far prendere il comando.
Pertanto si deve abilitarla per questa operazione o poter vedere la causa di un malfunzionamento. Per questo consiglierei di mantenere la seriale attiva durante le prove iniziali e solo quando s’è sicuri del funzionamento allora disattivare tale opzione se lo si desidera. Del resto non occupa tanto del periodo di lavoro di Arduino.
Il display viene aggiornato una volta al secondo, per questo anche la procedura di scrittura del campionamento rientra a quel limite minimo di periodicità. Del resto per i periodi della scrittura si usa la funzione dell’ RTC che mi riporta il valore minimo in secondi.
Il campionamento ha una funzione di prendere almeno 10 letture e fare una media. Il massimo può essere di 64, ma bisogna intervenire direttamente alla linea del sorgente. Dato che si usa una variabile di 2 bytes allora 64 è il limite massimo.
Il qui programma viene utilizzato per la conversione di pressione, comunque non è limitato a quel solo caso specifico. Infatti i valori che si possono configurare permettono la lettura di tanti tipi sensori che abbiano una risposta analogica in tensione che si potrà leggere con il convertitore ADC di arduino.
Il pacchetto si potrà scaricare dal mio drive.
Ho messo un video su youtube.
Il bluetooth è collegato direttamente sulla seriale hardware di Arduicoso, che si nota nello schema. Si potrebbe creare un piccolo disturbo quando si vuole scrivere un nuovo firmware. Per quello si consiglia di mettere un ponticello rimovibile durante la scrittura di uno sketch.
Non sono molto convinto o forse ho letto male: chi gestisce il bluetooh ? Nello sketch non mi sembra di vederlo.
Per il resto mi riservo di leggere meglio lo sketch: alla prima lettura non mi ha convinto.
Saluti