L’idea
Una semplice stazione meteo realizzata con un microcontrollore: ho scelto un Arduino Nano, ma si può usare anche un altro modello. Ci sono due sensori, un DHT11 e un BME280, e un display IPS a colori da 240×240 punti con controller ST7789.
Come ambiente di sviluppo ho usato Visual Studio Code, ma il codice funziona con qualsiasi IDE per Arduino.
Hardware
I componenti
- Arduino Nano (scheda con microcontrollore);
- DHT11: sensore di temperatura e umidità. Ha tre pin: due per l’alimentazione e uno di uscita, che si può collegare a un ingresso a scelta della scheda (io ho usato il pin 8);
- BME280: sensore di temperatura, umidità, pressione e altitudine. Ha quattro pin: due per l’alimentazione e due di comunicazione I²C, SCL e SDA;
- Display IPS 240×240 con ST7789, interfaccia SPI, a 7 pin, scelto perché economico;
- tre interruttori (SW1 accensione, SW2 scelta del sensore, SW3 schermata) con due resistenze da 5 kΩ, e una batteria con due celle 18650.
I collegamenti
| Componente | Pin del componente | Pin dell’Arduino Nano |
|---|---|---|
| DHT11 | Uscita dati | D8 |
| BME280 | SDA | A4 |
| BME280 | SCL | A5 |
| Display ST7789 | SCL (clock) | D13 |
| Display ST7789 | SDA (dati) | D11 |
| Display ST7789 | RES (reset) | D6 |
| Display ST7789 | DC | D7 |
| Display ST7789 | VCC | +5 V |
| Display ST7789 | BLK | non collegato |
| Interruttore SW2 «Sensore» | Contatto | D2 |
| Interruttore SW3 «Display» | Contatto | D10 |
I pin 13 e 11 sono quelli dell’interfaccia SPI dell’Arduino Nano (rispettivamente SCK e MOSI), mentre A4 e A5 sono quelli dell’I²C: per questo non si possono scegliere a piacere come l’uscita del DHT11.
Codice
Le librerie
Il programma usa queste librerie (si installano dal gestore librerie dell’IDE, oppure dai link qui sotto):
- DHT sensor library di Adafruit, per il DHT11 (
DHT.heDHT_U.h); - Grove – Barometer Sensor BME280 di Seeed Studio, per il BME280 (
Seeed_BME280.h); - Arduino_ST7789_Fast, per il display;
- RREFont, per i caratteri grandi sul display (i file
rre_…dei caratteri sono forniti con la libreria); - Adafruit GFX e il supporto ai display monocromatici di Adafruit, richiamati dal codice.
La struttura del programma
Il sorgente (StazioneMeteo.cpp, scaricabile qui sotto) si legge in blocchi. I numeri delle righe sono quelli del file scaricabile.
| Righe | Che cosa contengono |
|---|---|
| 4-25 | Le librerie incluse e i caratteri scelti per il display. |
| 28-37 | I pin e le impostazioni: TFT_DC 7, TFT_RST 6, PINSELEZIONE 2, PINSOLO 10, DHTPIN 8, display 240×240 e tipo di sensore (DHT11). |
| 47-54 | I colori dei riquadri e dei valori, creati con RGBto565 (formato a 16 bit del display). |
| 59-65 | Gli oggetti (display, BME280, DHT11, font) e le variabili di stato. |
| 78-136 | setup(): configura i pin, prova a leggere i due sensori, inizializza il display e disegna la schermata iniziale. |
| 138-164 | loop(): legge i due interruttori, sceglie quale sensore mostrare e aggiorna lo schermo. |
| 170-253 | sensdht11(): legge e mostra temperatura, umidità e temperatura percepita dal DHT11. |
| 256-389 | sensBME280(): legge e mostra temperatura, umidità, pressione e altitudine dal BME280. |
| 391-444 | Le funzioni di disegno: drawField() (i riquadri), showVal() (i numeri), setBigNumFont() e soloTemperatura() (la schermata con la sola temperatura). |
setup(): partenza e controllo dei sensori
All’accensione il programma imposta il pin 2 come ingresso con resistenza interna di pull-up e il pin 10 come ingresso, poi prova a leggere umidità e temperatura dal DHT11. Se una lettura non è un numero (isnan), memorizza errore = 1; se il BME280 non risponde a bme280.init(), memorizza errore = 2. Questi codici servono dopo: invece di mostrare valori inventati, il display scrive «Errore DHT11» o «Errore BME280».
loop(): la scelta del sensore e della schermata
void loop() {
boolean shift, solo;
shift = digitalRead(PINSELEZIONE); // pin 2: quale sensore
solo = digitalRead(PINSOLO); // pin 10: schermata normale o solo temperatura
...
if (shift) { sensBME280(solo); } // pin 2 alto: BME280
else { sensdht11(solo); } // pin 2 basso: DHT11
delay(18000); // un aggiornamento ogni 18 secondi
}
Il programma confronta lo stato attuale degli interruttori con quello precedente: quando cambia, ridisegna i riquadri. Con solo basso mostra la schermata completa (temperatura, umidità, pressione e altitudine, oppure temperatura percepita per il DHT11); con solo alto mostra la sola temperatura, a caratteri molto grandi. Tra un aggiornamento e il successivo passano circa 18 secondi (delay(18000)).
Le grandezze calcolate
pressure = bme280.getPressure(); // in pascal
altitudine = bme280.calcAltitude(pressure); // in metri
pressure1 = pressure * 0.00001; // in bar (1 Pa = 0,00001 bar)
...
ele = (7.5 * temp) / (237.7 + temp);
e = (6.112 * pow(10, ele) * um / 100);
H = temp + 0.5555 * (e - 10); // valore in basso a destra
La pressione arriva in pascal e viene mostrata in bar. L’altitudine è calcolata dalla libreria a partire dalla pressione. Le ultime tre righe calcolano un valore di temperatura percepita (la formula è quella dell’humidex) a partire da temperatura e umidità: è il numero piccolo in basso a destra nella schermata del BME280. Per il DHT11 la temperatura percepita è calcolata dalla libreria con computeHeatIndex().
Altre note sul codice
- Nel sorgente è lasciata anche una sezione, commentata, che si può usare con un display SSD1306 al posto dell’ST7789.
- Per capire meglio il funzionamento conviene guardare i file di descrizione e gli esempi delle librerie usate.
Prova
Nella foto il prototipo funziona con il BME280: il display mostra temperatura, umidità, pressione e altitudine, e in basso il nome «QuinciSoft». Il montaggio è fatto su basetta millefori, con il portabatterie sotto la scheda.
Scarica
- Schema dei collegamenti Schema PDF · 22 KB
- Codice sorgente (StazioneMeteo.cpp) Sorgente C++ · 10 KB
Link utili
Questi link portano a siti esterni, che si aprono in una nuova scheda.
Hai domande su questo progetto?
Scrivimi dalla pagina Contatti: ti rispondo appena possibile.