- Mini Stazione meteo con Arduino -
- Small Weather Station with Arduino -
- 16/03/2016 -
In questo progetto si utilizza il solo sensore BMP180.
In this project you are used only BMP180 sensor.
Materiale occorrente:
Arduino UNO
LCD Keypad Shield oppure LCD 16x2.
BMP180 breakout della Sparkfun.
Si potrà utilizzare anche altro materiale apportando le modifiche allo schema ed allo sketch.
Questo progetto ed il relativo sketch, sono la semplice riduzione al solo uso del sensore BMP180, del precedente sketch Stazione Meteo v103.
Si visualizzando i risultati su LCD 16x2.
Per semplificare ulteriormente ho utilizzato "LCD Keypad Shield" ( 16 x 2) .
Dopo l'inizializzazione del sensore, si mostrano sul display Temperatura e Pressione, i dati vengono aggiornati utilizzando:
const int DELAY_LETTURE = 10000; //tempo tra le letture in millisecondi (10 secondi)
si può cambiare il valore per avere aggiornamenti più frequenti o più radi.
Nello sketch questa riga dovrà essere cambiata in base all'altitudine del luogo di misura:
#define ALTITUDINE 234.3 // Altitude del luogo dove si trova il sensore (in metri)
Questo progetto ed il relativo sketch, sono la semplice riduzione al solo uso del sensore BMP180, del precedente sketch Stazione Meteo v103.
Si visualizzando i risultati su LCD 16x2.
Per semplificare ulteriormente ho utilizzato "LCD Keypad Shield" ( 16 x 2) .
Dopo l'inizializzazione del sensore, si mostrano sul display Temperatura e Pressione, i dati vengono aggiornati utilizzando:
const int DELAY_LETTURE = 10000; //tempo tra le letture in millisecondi (10 secondi)
si può cambiare il valore per avere aggiornamenti più frequenti o più radi.
Nello sketch questa riga dovrà essere cambiata in base all'altitudine del luogo di misura:
#define ALTITUDINE 234.3 // Altitude del luogo dove si trova il sensore (in metri)
qui sotto lo schema semplificato.
non ho trovato su fritzing il Bmp180 e quindi ho utilizzato limmagine del BMP085.
Vale la pena di segnalare che il sensore BMP180 utilizza la seriale I2C, ed è alimentato a 3,3V.
Adriano ha integrato lo sketch seguendo le indicazioni del costruttore "sparkfun".
Per quanto riguarda il funzionamento ed i collegamenti alla scheda Arduino abbiamo seguito quanto indicato nel Tutorial bmp180.
Nel Tutorial si trovano le istruzioni per il collegamento, la libreria da utilizzare e lo sketch di esempio. (scaricate la libreria dal tutorial della Sparkfun.)
Qui sotto lo sketch.
************************************************
***** Sergio & Adriano Prenleloup *****
************************************************
***** Stazione meteorologica ******
***** temperatura e pressione *****
***** Si utilizza solo il BMP180 *****
***** ver. 1.03b del 3/3/2016 *****
************************************************
** modifiche proposte da Biagio Pellegrino
** allo SKETCH
** SUL BLOG http://avventurarduino.blogspot.it
**
/*
************************************************
** MiniMeteoBMP180 ********
******************** *********
*** Temperatura e ****
*** pressione atmosferica ****
******************************
**sensore BMP180 ************
* mostra i dati su display LCD
* in questa prova ho utilizzato
* "LCD Keypad Shield" 16 x 2
* i tasti non sono utilizzati
* Sensore pressione BMP180
* SDA -> A4
* SCL -> A5
*
* Ho utilizzato la breakout della Sparkfun:
* seguire il tutorial che trovate sul sito della Sparkfun, se utilizzate
* un bmp180 dovrete tener conteo che funziona a 3,3V e dovrete inserire le
* resistenze opportune sul bus I2C.
* leggere le avvertenze qui sotto !!!! Estratto dal sito Sparkfun.
*************************************************************************************
Description: This is a breakout board for the Bosch BMP180 high-precision,
low-power digital barometer.
The BMP180 offers a pressure measuring range of 300 to 1100 hPa
with an accuracy down to 0.02 hPa in advanced resolution mode.
It’s based on piezo-resistive technology for high accuracy,
ruggedness and long term stability.
These come factory-calibrated, with the calibration coefficients already stored in ROM.
What makes this sensor great is that it is nearly identical to its former rev, the BMP085!
This breadboard-friendly board breaks out every pin to a 5-pin 0.1" pitch header.
VCC can be from 1.8V to 3.6V and is I/O lines are 5V tolerant;
we typically run it on a clean, regulated 3.3V supply.
The analog and digital supplies (VDDD and VDDA) are tied to a single header pin, but are separately decoupled.
It connects to a microcontroller via I²C bus (also known as TWI, or on the Arduino, the “Wire” library).
*/
//----------------------------------------------------------------------------------------------------------
#include // libreria LCD
#include // libreria sensore pressione
#include // wire per comunicazione bus I2C
// Configurazione PIN LCD
// --------------------------------------------------------------------------------
// i pin utilizzati corrispondono a questi
// i colori si riferiscono allo schema con friz
/* Circuito
* LCD GND -> blu -> pin GND
* LCD RS -> marrone -> pin 8
* LCD ENABLE -> giallo -> pin 9
* LCD DB4 -> marrone -> pin 4
* LCD DB5 -> rosso -> pin 5
* LCD DB6 -> verde -> pin 6
* LCD DB7 -> arancio -> pin 7
* LCD 5v -> rosso -> pin 5V
*
*/
LiquidCrystal lcd(8, 9, 4, 5, 6, 7); // questi sono i pin utilizzati dalla Shield.
// è possibile collegare lcd ad altri pin in quanto si utilizza solo la I2C
// che utilizza i pin A4 ed A5 - sda, scl
//---------------------------------------------------------------------------------
#define SDA_PIN 4 // pin della I2C //giallo
#define SCL_PIN 5 // pin della I2C // verde
// questa è richiesta dal sensore
#define ALTITUDINE 234.3 // Altitude del luogo dove si trova il sensore (in metri)
// --------------------------------------------------------------------------------
// Inizializza la libreria per lettura dati pressione
SFE_BMP180 pressure;
// --------------------------------------------------------------------------------
// Variabili gestione temperatura e pressione
// --------------------------------------------------------------------------------
double temperatura = 0.0;
double pressione = 0.0;
double t_corrente = 0.0;
double p_corrente = 0.0;
// --------------------------------------------------------------------------------
// costanti e variabili gestione lettura
// --------------------------------------------------------------------------------
const int DELAY_LETTURE = 10000; //tempo tra le letture in millisecondi (10 secondi)
unsigned long ora_lettura = millis();
//-----------------------------------------------------------------------------------
// setup del sensore bmp180
// --------------------------------------------------------------------------------
void setup_BMP()
{
// Serial.print("Inizializzazione BMP...");
lcd.clear();
lcd.print("Configurazione...");
delay (1000);
// Inizializza il sensore di pressione
// in questa fase il sensore recupera dei valori memorizzati
// al suo interno che usa per la sua calibrazione
if (pressure.begin())
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.println("OK");
lcd.setCursor(0, 1);
lcd.print("Altitudine : ");
lcd.println(ALTITUDINE);
delay (2000);
}
else
{
// L'inizializzazione puo' fallire a causa di problemi di connessione con il bus
lcd.println("ERRORE!! ");
while(1); // Attesa infinita --> resettare arduino
}
}
//----------------------------------------------------------------------------------------
// questa è la procedura indicata nel tutorial Sparkfun
// legge i valori di temperatura e pressione interrogando il sensore BMP
boolean leggi_temperatura_e_pressione(double& temp, double& pres)
{
boolean res = false;
double T, P, p0, a;
// Prima di poter leggere la pressione e' necessario effettuare una lettura della
// temperatura
// Invia il comando per iniziare la lettura della temperatura
// Se il comando ha successo ritorna il numero di millisecondi da attendere prima di ricevere il dato
// In caso di errore ritorna 0
int stat = pressure.startTemperature();
if (stat != 0)
{
// Attende il completamento della lettura della temperatura
delay(stat);
// Adesso si puo' recuperare il valore, il valore è salvato in T
stat = pressure.getTemperature(T);
if (stat != 0)
{
// si ripete il procedimento per la lettura della pressione
// Il parametro 3 indica la precisione (lettura piu' lenta)
stat = pressure.startPressure(3);
if (stat != 0)
{
delay(stat);
// Si legge il valore della pressione assoluta e si salva in P
// la funzione richiede la temperatura corrente
stat = pressure.getPressure(P, T);
// calcola la pressione relativa, compensando con l'altitudine locale
p0 = pressure.sealevel(P, ALTITUDINE);
// Infine calcola l'altitudine in base alla pressione misurata e alla pressione al livello del mare
a = pressure.altitude(P, p0);
// la lettura ha avuto successo, si aggiornano le variabili
res = true;
pres = P;
temp = T;
// pr = p0;
// alt = a;
}
}
}
return res;
}
//---------------------------------------------------------------------------------
// Logica per lettura e aggiornamento dati
// Si eseguono le letture ad intervalli basterà cambiare questa costante
// const int DELAY_LETTURE = 10000; //tempo tra le letture in millisecondi
// se si desiderano letture più frequenti o meno basterà cambiare
// questa costante
// --------------------------------------------------------------------------------
// ritorna true se dall'ultima lettura è trascorso il tempo fissato
boolean check_timeout()
{
unsigned long ora_corrente = millis();
return ora_corrente > ora_lettura;
}
//-------------------------------------------------------------------------------
void effettua_lettura()
{
// si leggono i dati dal sensore di pressione e si aggiornano per la visualizzazione
//
if (leggi_temperatura_e_pressione(t_corrente,p_corrente))
{
temperatura = t_corrente;
pressione = p_corrente;
}
//imposta l'ora della prossima lettura, aggiunge "DELAY_LETTURE"
ora_lettura = millis() + DELAY_LETTURE;
}
// --------------------------------------------------
//
// SETUP E LOOP PRINCIPALE SKETCH
//
// -------------------------------------------------
void setup()
{
Serial.begin(9600);
// inizializza LCD
// si inizializzano caratteri e righe LCD
lcd.begin(16, 2);
// Messaggio di controllo
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Display ok");
delay (1000);
// inizializza il BMP180
setup_BMP();
}
void loop()
{
// si controlla se è giunto il momento di effettuare le letture
if (check_timeout())
{
// se si, allora si recuperano i dati e si imposta l'ora della prossima lettura
effettua_lettura();
// si aggiorna il display
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Temp : ");
lcd.print(temperatura, 1);
lcd.print(" C");
lcd.setCursor(0, 1);
lcd.print("Pres : ");
lcd.print(pressione, 1);
lcd.print(" mb");
}
delay(100);
}
// END
Qui sotto lo sketch.
************************************************
***** Sergio & Adriano Prenleloup *****
************************************************
***** Stazione meteorologica ******
***** temperatura e pressione *****
***** Si utilizza solo il BMP180 *****
***** ver. 1.03b del 3/3/2016 *****
************************************************
** modifiche proposte da Biagio Pellegrino
** allo SKETCH
** SUL BLOG http://avventurarduino.blogspot.it
**
/*
************************************************
** MiniMeteoBMP180 ********
******************** *********
*** Temperatura e ****
*** pressione atmosferica ****
******************************
**sensore BMP180 ************
* mostra i dati su display LCD
* in questa prova ho utilizzato
* "LCD Keypad Shield" 16 x 2
* i tasti non sono utilizzati
* Sensore pressione BMP180
* SDA -> A4
* SCL -> A5
*
* Ho utilizzato la breakout della Sparkfun:
* seguire il tutorial che trovate sul sito della Sparkfun, se utilizzate
* un bmp180 dovrete tener conteo che funziona a 3,3V e dovrete inserire le
* resistenze opportune sul bus I2C.
* leggere le avvertenze qui sotto !!!! Estratto dal sito Sparkfun.
*************************************************************************************
Description: This is a breakout board for the Bosch BMP180 high-precision,
low-power digital barometer.
The BMP180 offers a pressure measuring range of 300 to 1100 hPa
with an accuracy down to 0.02 hPa in advanced resolution mode.
It’s based on piezo-resistive technology for high accuracy,
ruggedness and long term stability.
These come factory-calibrated, with the calibration coefficients already stored in ROM.
What makes this sensor great is that it is nearly identical to its former rev, the BMP085!
This breadboard-friendly board breaks out every pin to a 5-pin 0.1" pitch header.
VCC can be from 1.8V to 3.6V and is I/O lines are 5V tolerant;
we typically run it on a clean, regulated 3.3V supply.
The analog and digital supplies (VDDD and VDDA) are tied to a single header pin, but are separately decoupled.
It connects to a microcontroller via I²C bus (also known as TWI, or on the Arduino, the “Wire” library).
*/
//----------------------------------------------------------------------------------------------------------
#include
#include
#include
// Configurazione PIN LCD
// --------------------------------------------------------------------------------
// i pin utilizzati corrispondono a questi
// i colori si riferiscono allo schema con friz
/* Circuito
* LCD GND -> blu -> pin GND
* LCD RS -> marrone -> pin 8
* LCD ENABLE -> giallo -> pin 9
* LCD DB4 -> marrone -> pin 4
* LCD DB5 -> rosso -> pin 5
* LCD DB6 -> verde -> pin 6
* LCD DB7 -> arancio -> pin 7
* LCD 5v -> rosso -> pin 5V
*
*/
LiquidCrystal lcd(8, 9, 4, 5, 6, 7); // questi sono i pin utilizzati dalla Shield.
// è possibile collegare lcd ad altri pin in quanto si utilizza solo la I2C
// che utilizza i pin A4 ed A5 - sda, scl
//---------------------------------------------------------------------------------
#define SDA_PIN 4 // pin della I2C //giallo
#define SCL_PIN 5 // pin della I2C // verde
// questa è richiesta dal sensore
#define ALTITUDINE 234.3 // Altitude del luogo dove si trova il sensore (in metri)
// --------------------------------------------------------------------------------
// Inizializza la libreria per lettura dati pressione
SFE_BMP180 pressure;
// --------------------------------------------------------------------------------
// Variabili gestione temperatura e pressione
// --------------------------------------------------------------------------------
double temperatura = 0.0;
double pressione = 0.0;
double t_corrente = 0.0;
double p_corrente = 0.0;
// --------------------------------------------------------------------------------
// costanti e variabili gestione lettura
// --------------------------------------------------------------------------------
const int DELAY_LETTURE = 10000; //tempo tra le letture in millisecondi (10 secondi)
unsigned long ora_lettura = millis();
//-----------------------------------------------------------------------------------
// setup del sensore bmp180
// --------------------------------------------------------------------------------
void setup_BMP()
{
// Serial.print("Inizializzazione BMP...");
lcd.clear();
lcd.print("Configurazione...");
delay (1000);
// Inizializza il sensore di pressione
// in questa fase il sensore recupera dei valori memorizzati
// al suo interno che usa per la sua calibrazione
if (pressure.begin())
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.println("OK");
lcd.setCursor(0, 1);
lcd.print("Altitudine : ");
lcd.println(ALTITUDINE);
delay (2000);
}
else
{
// L'inizializzazione puo' fallire a causa di problemi di connessione con il bus
lcd.println("ERRORE!! ");
while(1); // Attesa infinita --> resettare arduino
}
}
//----------------------------------------------------------------------------------------
// questa è la procedura indicata nel tutorial Sparkfun
// legge i valori di temperatura e pressione interrogando il sensore BMP
boolean leggi_temperatura_e_pressione(double& temp, double& pres)
{
boolean res = false;
double T, P, p0, a;
// Prima di poter leggere la pressione e' necessario effettuare una lettura della
// temperatura
// Invia il comando per iniziare la lettura della temperatura
// Se il comando ha successo ritorna il numero di millisecondi da attendere prima di ricevere il dato
// In caso di errore ritorna 0
int stat = pressure.startTemperature();
if (stat != 0)
{
// Attende il completamento della lettura della temperatura
delay(stat);
// Adesso si puo' recuperare il valore, il valore è salvato in T
stat = pressure.getTemperature(T);
if (stat != 0)
{
// si ripete il procedimento per la lettura della pressione
// Il parametro 3 indica la precisione (lettura piu' lenta)
stat = pressure.startPressure(3);
if (stat != 0)
{
delay(stat);
// Si legge il valore della pressione assoluta e si salva in P
// la funzione richiede la temperatura corrente
stat = pressure.getPressure(P, T);
// calcola la pressione relativa, compensando con l'altitudine locale
p0 = pressure.sealevel(P, ALTITUDINE);
// Infine calcola l'altitudine in base alla pressione misurata e alla pressione al livello del mare
a = pressure.altitude(P, p0);
// la lettura ha avuto successo, si aggiornano le variabili
res = true;
pres = P;
temp = T;
// pr = p0;
// alt = a;
}
}
}
return res;
}
//---------------------------------------------------------------------------------
// Logica per lettura e aggiornamento dati
// Si eseguono le letture ad intervalli basterà cambiare questa costante
// const int DELAY_LETTURE = 10000; //tempo tra le letture in millisecondi
// se si desiderano letture più frequenti o meno basterà cambiare
// questa costante
// --------------------------------------------------------------------------------
// ritorna true se dall'ultima lettura è trascorso il tempo fissato
boolean check_timeout()
{
unsigned long ora_corrente = millis();
return ora_corrente > ora_lettura;
}
//-------------------------------------------------------------------------------
void effettua_lettura()
{
// si leggono i dati dal sensore di pressione e si aggiornano per la visualizzazione
//
if (leggi_temperatura_e_pressione(t_corrente,p_corrente))
{
temperatura = t_corrente;
pressione = p_corrente;
}
//imposta l'ora della prossima lettura, aggiunge "DELAY_LETTURE"
ora_lettura = millis() + DELAY_LETTURE;
}
// --------------------------------------------------
//
// SETUP E LOOP PRINCIPALE SKETCH
//
// -------------------------------------------------
void setup()
{
Serial.begin(9600);
// inizializza LCD
// si inizializzano caratteri e righe LCD
lcd.begin(16, 2);
// Messaggio di controllo
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Display ok");
delay (1000);
// inizializza il BMP180
setup_BMP();
}
void loop()
{
// si controlla se è giunto il momento di effettuare le letture
if (check_timeout())
{
// se si, allora si recuperano i dati e si imposta l'ora della prossima lettura
effettua_lettura();
// si aggiorna il display
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Temp : ");
lcd.print(temperatura, 1);
lcd.print(" C");
lcd.setCursor(0, 1);
lcd.print("Pres : ");
lcd.print(pressione, 1);
lcd.print(" mb");
}
delay(100);
}
// END
Come potete leggere nei commenti dello sketch, prima si deve eseguire l'inizializzazione del sensore, successivamente si esegue la misura della temperatura, e solo dopo questa si può misurare la pressione.
Nello sketch si utilizzano le seguenti librerie:
LiquidCrystal.h // libreria LCD
SFE_BMP180.h // libreria sensore pressione
Wire.h // wire per comunicazione bus I2C.
Nel link qui sotto potete scaricare lo sketch per Arduino Uno.
Sketch Arduino MiniMeteo180
Ciao Sergio ... anche "meteorolo"
RispondiElimina:-) a presto "Buona Pasqua" GiuMa
Ciao!
RispondiEliminaCiao, complimenti per i tuoi progetti e la perizia nel descriverne le impostazioni e il funzionamento. Mi chiedo, nel caso si utilizzasse un arduino mega con più porte seriali, se fosse possibile collegare il display in modo seriale. grazie
RispondiEliminaCiao! Grazie per il commento.
EliminaSi e' sicuramente possibile con il Mega ma anche con Arduino UNO infatti la linea sda scl della I2c permette di utilizzare piu' indirizzi ricordati di inserire sulla linea le due resistenze previste, se invece vuoi utilizzare un display sulla seriale anche in questo schema con la UNO i due pin rx tx sono disponibili e con le opportune modifiche allo sketch e' possibile utilizzare un display tipo Nextion.
Saluti
Sergio