PitClimaDataLogger Ext
Datalogger del Pit per Esterno
PitClimaDataLoggerExt è un datalogger che consente la registrazione dei dati climatici ambientali esterni.
Si tratta dell'evoluzione del PitClimaDataLogger .
Sono infatti registrati temperatura, umidità, luminosità e pressione. Nella prossima versione integreremo anche la velocità del vento.
E' stato utilizzato Arduino Mega in quanto su Arduino uno lo spazio occupato dalle variabili non è sufficiente e occorre fare una ottimizzazione del software o delle funzioni......
Cosa serve:
- Arduino Mega
- Sensore temperatura umidità
- Sensore luminosità
- Sensore pressionee temperatura
- Scheda di memoria SD
- led
- resistenze
Download:
- Datasheet DHT22 Sensore Temperatura Umidità
- Datasheet BH1750 sensore Luminosità
- Datasheet BMP180 Sensore Pressione Temperatura
Codice sorgente:
/*
ZappocoJ - ZappocoS - PitClimaDataLogger01 26/01/2015 -- Temperatura e umidità
ZappocoJ - ZappocoS - PitClimaDataLogger02 28/02/2015 -- aggiunta luminosità
ZappocoS - PitClimaDataLogger03 11/04/2015 -- aggiunta sensore pressione e passaggio a Arduino Mega
NB: su arduino uno non si riesce per mancanza di spazio (variabili) a caricare tutte le librerie
in particolare la libreria per la scheda SD manda in tilt il tutto.
PitClimaDataLogger --> Stazione Climatica - Termo Igrometro Data Logger del PIT
//----------------------------------------------------------------------------------------
Settaggi:
Set TimeDelay --> 1 (3) 5 10 15 20 30 60 minuti () default
Set Start Log --> fa partire la registrazione
Set Stop Log --> ferma la registrazione
Status:
1) Error --> no card present
2) running --> registrazione in corso (permette stop)
3) stop --> permette settaggio time e start
//----------------------------------------------------------------------------------------
DHT22 ---- Connection
pin 1 VCC-5v
pin 2 dati --> digital pin 7
pin 3 none
pin 4 GND-GND
BH1750 ---- Connection
VCC-5v
GND-GND
SCL-SCL(analog pin 5)
SDA-SDA(analog pin 4)
ADD-NC or GND
----------------------------------------------------
SD card datalogger
This example shows how to log data from three analog sensors
to an SD card using the SD library.
The circuit:
* SD card attached to SPI bus as follows:
** MOSI - pin 11 51
** MISO - pin 12 50
** SCK - pin 13 52
** CS - pin 10 53
created 24 Nov 2010
modified 9 Apr 2012
by Tom Igoe
*/
//----------------------------------------------------------------------------------------
// librerie sensore di temperatura e umidità DHT22
//----------------------------------------------------------------------------------------
#include <DHT22.h>
// Data wire is plugged into port 7 on the Arduino
// Connect a 4.7K resistor between VCC and the data pin (strong pullup)
#define DHT22_PIN 7
// Setup a DHT22 instance
DHT22 myDHT22(DHT22_PIN);
//----------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------
// libreria sensore di pressione BMP180
//----------------------------------------------------------------------------------------
#include <Wire.h>
#include <SFE_BMP180.h>
SFE_BMP180 pressure;
#define ALTITUDE 205.0 // Altitude of Rovereto Italy
//----------------------------------------------------------------------------------------
// libreria sensore di luminosità BH1750
//----------------------------------------------------------------------------------------
#include <BH1750.h>
BH1750 lightMeter;
//----------------------------------------------------------------------------------------
// librerie SD card
//----------------------------------------------------------------------------------------
#include <SD.h>
#include <SPI.h>
File dataFile;
// On the Ethernet Shield, CS is pin 4. Note that even if it's not
// used as the CS pin, the hardware CS pin (10 on most Arduino boards,
// 53 on the Mega) must be left as an output or the SD library
// functions will not work.
const int chipSelect = 53;
//----------------------------------------------------------------------------------------
// Variabili temporali
//----------------------------------------------------------------------------------------
unsigned long TimeDelay = 3000; // setta a 3 minuti (180000 millisecondi) il tempo di delay tra le letture
unsigned long TimeStart = 0; // tempo di partenza
unsigned long TimeUltima = 0; // tempo ultima lettura
unsigned long TimeAdesso = 0; // tempo della lettura
long TimeDelta = 0; // differenza
unsigned long tempo;
unsigned long Counter = 0; // contatore delle letture
//----------------------------------------------------------------------------------------
// Variabili per errori
//----------------------------------------------------------------------------------------
int ledPin = 8;
int flagSts = 0;
int stsDelay = 1000;
int flagDHT22 = 0;
float Temperatura;
float Umidita;
float Luminosita;
float Temperatura2;
float Pressione;
//----------------------------------------------------------------------------------------
// Settaggio flag per stampa su seriale di dati per debug
//----------------------------------------------------------------------------------------
boolean OnDebug = false;
void setup(){
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
Serial.println("Running...");
Serial.println("---------------------------");
Serial.print("Initializing SD card ...");
pinMode(chipSelect, OUTPUT);
//----------------------------------------------------------------------------------------
// see if the card is present and can be initialized:
//----------------------------------------------------------------------------------------
if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not present");
// don't do anything more:
flagSts = 1;
return;
}
Serial.println("SD card initialized.");
Serial.println("---------------------------");
InitializeSensor ();
dataFile = SD.open("datalog.txt", FILE_WRITE);
// if the file is available, write to it:
Serial.print("dataFile ");
Serial.println(dataFile);
Serial.print("availableMemory : ");
Serial.println(availableMemory ());
Serial.println("---------------------------");
if (dataFile) {
dataFile.println("----------------------------------------------");
dataFile.println("-------- Inizializzazione terminata ----------");
dataFile.println("-------- sostituire . con , ----------");
dataFile.println("----------------------------------------------");
dataFile.println("");
dataFile.print("N.");
dataFile.print(" ; ");
dataFile.print("Tempo [ore]");
dataFile.print(" ; ");
dataFile.print("Temperatura [gC]");
dataFile.print(" ; ");
dataFile.print("Umidita' [%]");
dataFile.print(" ; ");
dataFile.print("Luminosita' [lx]");
dataFile.print(" ; ");
dataFile.print("Pressione [mb]");
dataFile.print(" ; ");
dataFile.println("Temperatura2 [gC]");
dataFile.close();
}
Serial.println("");
Serial.print("N.");
Serial.print(" ; ");
Serial.print("Tempo [ore]");
Serial.print(" ; ");
Serial.print("Temperatura [gC]");
Serial.print(" ; ");
Serial.print("Umidita' [%]");
Serial.print(" ; ");
Serial.print("Luminosita' [lx]");
Serial.print(" ; ");
Serial.print("Pressione [mb]");
Serial.print(" ; ");
Serial.println("Temperatura2 [gC]");
}
void loop() {
//Serial.print("flagSts ");
//Serial.println(flagSts);
switch(flagSts)
{
// Errore inizializzazione SD CARD
case 1:
Serial.println(" Error ");
digitalWrite(ledPin, HIGH);
delay(200);
digitalWrite(ledPin, LOW);
delay(200);
break;
// Inizializzazione parametri
case 0:
TimeStart = millis();
TimeAdesso = TimeStart;
TimeUltima = TimeStart;
if(OnDebug == true) {
Serial.println("---------------------------");
Serial.println("Tempi iniziali");
Serial.println("---------------------------");
Serial.print("TimeDelay ");
Serial.println(TimeDelay);
Serial.print("TimeStart ");
Serial.println(TimeStart);
Serial.print("TimeUltima ");
Serial.println(TimeUltima);
Serial.print("TimeAdesso ");
Serial.println(TimeAdesso);
Serial.print("TimeDelta ");
Serial.println(TimeDelta);
Serial.println("---------------------------");
Serial.println("Fine Tempi iniziali");
Serial.println("---------------------------");
Serial.println("---------------------------");
Serial.println("Apertura file datalog.txt per scrittura titoli colonne");
Serial.println("---------------------------");
}
flagSts = 2;
break;
// Ciclo di lettura normale
case 2:
if (TimeDelta >= 0) {
tempo =(TimeAdesso-TimeStart);
TimeUltima = millis();
Counter = Counter +1;
TemperatureSensorRead ();
LightSensorRead ();
PressureSensorRead ();
PrintDataSDCard ();
}
default:
break;
}// End Case
TimeAdesso = millis();
TimeDelta = TimeAdesso - TimeUltima - TimeDelay;
}
void PrintDataSDCard () {
if(OnDebug == true) {
Serial.print("PrintDataSDCard ");
Serial.print("flagSts ");
Serial.println(flagSts);
Serial.print("flagDHT22 ");
Serial.println(flagDHT22);
}
if (flagSts == 2){
if (flagDHT22) {
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
dataFile = SD.open("datalog.txt", FILE_WRITE);
// if the file is available, write to it:
if (dataFile) {
dataFile.print(Counter - 1);
dataFile.print(" ; ");
dataFile.print(tempo - TimeDelay);
dataFile.print(" ; ");
dataFile.print(Temperatura);
dataFile.print(" ; ");
dataFile.print(Umidita);
dataFile.print(" ; ");
dataFile.print(Luminosita);
dataFile.print(" ; ");
dataFile.print(Pressione);
dataFile.print(" ; ");
dataFile.println(Temperatura2);
dataFile.close();
}
// if the file isn't open, pop up an error:
else {
Serial.println("error opening datalog.txt");
}
Serial.print(Counter);
Serial.print(" ; ");
Serial.print(tempo);
Serial.print(" ; ");
Serial.print(Temperatura);
Serial.print(" ; ");
Serial.print(Umidita);
Serial.print(" ; ");
Serial.print(Luminosita);
Serial.print(" ; ");
Serial.print(Pressione);
Serial.print(" ; ");
Serial.println(Temperatura2);
}
}
}
//--------------------------------------------------------------------------------------------------------------
// Inizializzazione
//--------------------------------------------------------------------------------------------------------------
void InitializeSensor (){
Serial.println("---------------------------");
Serial.println("initializing");
Serial.println("---------------------------");
// Initialize the sensor
lightMeter.begin();
Serial.println("BH1750 init success");
// Initialize the sensor (it is important to get calibration values stored on the device).
if (pressure.begin())
Serial.println("BMP180 init success");
else
{
// Oops, something went wrong, this is usually a connection problem,
// see the comments at the top of this sketch for the proper connections.
Serial.println("BMP180 init fail\n\n");
while(1); // Pause forever.
}
// Initialize the sensor
Serial.println("Inizializzazione sensore DHT22");
TemperatureSensorRead ();
delay (2000);
Serial.println("---------------------------");
}
//--------------------------------------------------------------------------------------------------------------
// Questa funzione legge lo stato del sensore
// di luminosità BH1750
//--------------------------------------------------------------------------------------------------------------
void LightSensorRead (){
//digitalWrite (ledLightPin, HIGH);
uint16_t lux = lightMeter.readLightLevel();
if(OnDebug == true) {
Serial.println("---------------------------");
Serial.println("response from BH1750");
Serial.println("---------------------------");
Serial.print("Light: ");
Serial.print(lux);
Serial.println(" lx");
}
Luminosita = lux;
}
//--------------------------------------------------------------------------------------------------------------
// Questa funzione legge lo stato del sensore
// di temperatura/umidita DHT022
//--------------------------------------------------------------------------------------------------------------
void TemperatureSensorRead (){
DHT22_ERROR_t errorCode;
// The sensor can only be read from every 1-2s, and requires a minimum
// 2s warm-up after power-on.
// delay(2000);
if(OnDebug == true) {
Serial.println("---------------------------");
Serial.println("response from DHT022");
Serial.println("---------------------------");
Serial.print("Requesting data...");
}
flagDHT22 = 0;
errorCode = myDHT22.readData();
switch(errorCode)
{
case DHT_ERROR_NONE:
Temperatura = myDHT22.getTemperatureC();
Umidita = myDHT22.getHumidity();
flagDHT22 = 1;
if(OnDebug == true) {
Serial.print("Got Data ");
Serial.print(myDHT22.getTemperatureC());
Serial.print("C ");
Serial.print(myDHT22.getHumidity());
Serial.println("%");
// Alternately, with integer formatting which is clumsier but more compact to store and
// can be compared reliably for equality:
//
char buf[128];
sprintf(buf, "Integer-only reading: Temperature %hi.%01hi C, Humidity %i.%01i %% RH",
myDHT22.getTemperatureCInt()/10, abs(myDHT22.getTemperatureCInt()%10),
myDHT22.getHumidityInt()/10, myDHT22.getHumidityInt()%10);
Serial.println(buf);
}
break;
case DHT_ERROR_CHECKSUM:
if(OnDebug == true) {
Serial.print("DHT22 check sum error ");
Serial.print(myDHT22.getTemperatureC());
Serial.print("C ");
Serial.print(myDHT22.getHumidity());
Serial.println("%");
}
break;
case DHT_BUS_HUNG:
Serial.println("DHT22 BUS Hung ");
break;
case DHT_ERROR_NOT_PRESENT:
Serial.println("DHT22 Not Present ");
break;
case DHT_ERROR_ACK_TOO_LONG:
Serial.println("DHT22 ACK time out ");
break;
case DHT_ERROR_SYNC_TIMEOUT:
Serial.println("DHT22 Sync Timeout ");
break;
case DHT_ERROR_DATA_TIMEOUT:
Serial.println("DHT22 Data Timeout ");
break;
case DHT_ERROR_TOOQUICK:
Serial.println("DHT22 Polled to quick ");
break;
}
}
//--------------------------------------------------------------------------------------------------------------
// Questa funzione legge lo stato del sensore
// di pressione BMP180
//--------------------------------------------------------------------------------------------------------------
void PressureSensorRead (){
char status;
double T,P,p0,a;
// Loop here getting pressure readings every 10 seconds.
// If you want sea-level-compensated pressure, as used in weather reports,
// you will need to know the altitude at which your measurements are taken.
// We're using a constant called ALTITUDE in this sketch:
if(OnDebug == true) {
Serial.println("---------------------------");
Serial.println("response from BMP180");
Serial.println("---------------------------");
Serial.print("provided altitude: ");
Serial.print(ALTITUDE,0);
Serial.print(" meters, ");
Serial.print(ALTITUDE*3.28084,0);
Serial.println(" feet");
}
// If you want to measure altitude, and not pressure, you will instead need
// to provide a known baseline pressure. This is shown at the end of the sketch.
// You must first get a temperature measurement to perform a pressure reading.
// Start a temperature measurement:
// If request is successful, the number of ms to wait is returned.
// If request is unsuccessful, 0 is returned.
status = pressure.startTemperature();
if (status != 0)
{
// Wait for the measurement to complete:
delay(status);
// Retrieve the completed temperature measurement:
// Note that the measurement is stored in the variable T.
// Function returns 1 if successful, 0 if failure.
status = pressure.getTemperature(T);
if (status != 0)
{
if(OnDebug == true) {
// Print out the measurement:
Serial.print("temperature: ");
Serial.print(T,2);
Serial.print(" deg C, ");
Serial.print((9.0/5.0)*T+32.0,2);
Serial.println(" deg F");
}
Temperatura2 = T;
// Start a pressure measurement:
// The parameter is the oversampling setting, from 0 to 3 (highest res, longest wait).
// If request is successful, the number of ms to wait is returned.
// If request is unsuccessful, 0 is returned.
status = pressure.startPressure(3);
if (status != 0)
{
// Wait for the measurement to complete:
delay(status);
// Retrieve the completed pressure measurement:
// Note that the measurement is stored in the variable P.
// Note also that the function requires the previous temperature measurement (T).
// (If temperature is stable, you can do one temperature measurement for a number of pressure measurements.)
// Function returns 1 if successful, 0 if failure.
status = pressure.getPressure(P,T);
if (status != 0)
{
if(OnDebug == true) {
// Print out the measurement:
Serial.print("absolute pressure: ");
Serial.print(P,2);
Serial.print(" mb, ");
Serial.print(P*0.0295333727,2);
Serial.println(" inHg");
}
Pressione = P;
// The pressure sensor returns abolute pressure, which varies with altitude.
// To remove the effects of altitude, use the sealevel function and your current altitude.
// This number is commonly used in weather reports.
// Parameters: P = absolute pressure in mb, ALTITUDE = current altitude in m.
// Result: p0 = sea-level compensated pressure in mb
if(OnDebug == true) {
p0 = pressure.sealevel(P,ALTITUDE); // we're at 1655 meters (Boulder, CO)
Serial.print("relative (sea-level) pressure: ");
Serial.print(p0,2);
Serial.print(" mb, ");
Serial.print(p0*0.0295333727,2);
Serial.println(" inHg");
}
// On the other hand, if you want to determine your altitude from the pressure reading,
// use the altitude function along with a baseline pressure (sea-level or other).
// Parameters: P = absolute pressure in mb, p0 = baseline pressure in mb.
// Result: a = altitude in m.
if(OnDebug == true) {
a = pressure.altitude(P,p0);
Serial.print("computed altitude: ");
Serial.print(a,0);
Serial.print(" meters, ");
Serial.print(a*3.28084,0);
Serial.println(" feet");
}
}
else Serial.println("error retrieving pressure measurement\n");
}
else Serial.println("error starting pressure measurement\n");
}
else Serial.println("error retrieving temperature measurement\n");
}
else Serial.println("error starting temperature measurement\n");
//delay(5000); // Pause for 5 seconds.
}
// this function will return the number of bytes currently free in RAM
// written by David A. Mellis
// based on code by Rob Faludi http://www.faludi.com
int availableMemory() {
int size = 1024; // Use 2048 with ATmega328
byte *buf;
while ((buf = (byte *) malloc(--size)) == NULL)
;
free(buf);
return size;
}
ZappocoS - 11 aprile 2015