Da un po’ di tempo cercavo un sistema per un semplice datalogger a basso consumo, funzionante a batteria per qualche mese. Dopo aver fatto alcune ricerche su deepsleep e watchdog, mi sono imbattuto in questo forum sull’ESP8266, in cui si utilizzava l’alarm di un modulo RTC per attivare/disattivare un mosfet collegato all’alimentazione di Arduino.
A questo link è pubblicato il mio progetto. Anche se qualche passaggio non mi è ancora chiaro, funziona come previsto.
Consumi:
RTC: 0.8uA. Facendo alcuni conti, una batteria a bottone da 210mAh durerebbe per 29 anni! (ipoteticamente, senza tenere conto dell’autoscarica)
Arduino: 45mA x 13sec ogni mezz’ora. Una batteria da 1800mAh durerebbe per 232giorni.
Se può essere utile a qualcuno ben venga. E se qualcuno ha qualche suggerimento per migliorare il progetto meglio ancora.
volendo ridurre ulteriormente i consumi potresti togliere le 2 resistenze di pullup su sda/scl ed utilizzare le interne di arduino.
manca un'uscita di arduino che piloti il mosfet (ad esempio se qualche operazione dura > 13 sec. serve che non si spenga fino al termine)... forse previsto via software?
di conseguenza.... è previsto l'autospegnimento tramite la riprogrammazione dell'allarme al termine delle operazioni? (così riduci i 13 secondi qualora ne bastassero 2)
Come spunto per i bassi assorbimenti, cerca "micrologio" (un progetto di Leo, uno dei nostri mod, sulla sua pagina web c'era anche lo sketch) ... credo che piu di quello, sia difficile abbassare gli assorbimenti di un 328 ...
@cam9500
Le resistenze di pull-up le avevo già tolte in realtà. Devo correggere il disegno.
Il tempo di 13 secondi di attività non è impostato a priori, ma è quello che effettivamente serve ad Arduino per la lettura e scrittura dei dati (tempo di inizializzazione della scheda SD, riscaldamento del DHT22, scrittura file sulla scheda). Probabilmente si potrebbe ridurre un delay, ma ho visto che il DHT se non è riscaldato per bene dà valori sballati. Alla fine dello sketch viene subito riprogrammato l'alarm. Non vi sono tempi "morti".
@Etemenanki
Non sapevo della possibilità di collegare un quarzo ad Arduino per ricavare un RTC. Molto interessante.
Non so però quanto sia complicato usare la tecnica del micrologio per un datalogger collegato a vari sensori. Senza usare un mosfet non so se sia possibile disattivarli portando il consumo a zero.
In ogni caso, a dire il vero il consumo in stand-by (che è quello che cercavo di tenere basso) del micrologio è superiore: 1-2uA contro 0.8uA del mio progetto (non che faccia la differenza eh).
Grazie del link. Un consumo in stand-by di 0.22mA è un ottimo risultato. Con una batteria da 1800mAh, avrei una durata di 340giorni. (Andrebbe però aggiunto il consumo in fase attiva).
cam9500:
...
manca un'uscita di arduino che piloti il mosfet (ad esempio se qualche operazione dura > 13 sec. serve che non si spenga fino al termine)... forse previsto via software?
di conseguenza.... è previsto l'autospegnimento tramite la riprogrammazione dell'allarme al termine delle operazioni? (così riduci i 13 secondi qualora ne bastassero 2)
Partendo dalla tua osservazione sul tempo in cui Arduino è acceso, ho realizzato che 13 secondi erano troppi e dovevo diminurlo; sono riuscito ad abbassarlo a circa 3secondi (in teoria per il DHT22 il tempo di riscaldamento è di 2s, ma ho notato che la prima lettura è leggermente più bassa sull'umidità, -1.5% circa, per questo avevo aggiunto un altro delay; ora ho corretto via software l'imprecisione).
Quindi ipotizzando 3secondi a 45mA e 1797 secondi (mezz'ora -3s) a 0A, la stessa batteria da 1800mAh durerebbe ben 2 anni e 269 giorni! Mi sembra un buon risultato...
/*
datalogging di un sensore DHT22
+collegamento con RTC clock
+utilizzo del p-mosfet IRF9530 per risparmio enegetico
tramite l'alarm dell'RTC
*/
#include <Wire.h>
#include <Rtc_Pcf8563.h>
//init the real time clock
Rtc_Pcf8563 rtc;
#include <SPI.h>
#include <SD.h>
const int chipSelect = 10;
//sensore DHT
#include <DHT22.h>
#define DHT22_PIN A0
// Setup a DHT22 instance
DHT22 myDHT22(DHT22_PIN);
void setup()
{
Serial.begin(9600);
//clear out the registers
/*rtc.initClock();
// set a time to start with.
// day, weekday, month, century(1=1900, 0=2000), year(0-99)
rtc.setDate(18, 1, 9, 0, 16);
// hr, min, sec
rtc.setTime(19, 17, 00);*/
//scrive una volta l'ora attuale
//both format functions call the internal getTime() so that the
//formatted strings are at the current time/date.
Serial.print(rtc.formatTime());
Serial.print("\r\n");
Serial.print(rtc.formatDate());
Serial.print("\r\n");
//inizializza SD
Serial.print("Initializing SD card...");
pinMode(10, OUTPUT);
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not present");
}
Serial.println("card initialized.");
//cancella e ricrea il file:
/*
// delete the file:
Serial.println("Removing datalog.txt...");
SD.remove("datalog.txt");
// open a new file and immediately close it:
Serial.println("Creating datalog.txt...");
File dataFile = SD.open("datalog.txt", FILE_WRITE);
dataFile.close();
*/
lettura();
/* set an alarm
* alarm pin goes low when match occurs
* this triggers the interrupt routine
* min, hr, day, weekday
* 99 = no alarm value to be set
*/
// imposta un alarm all'ora successiva
rtc.setAlarm(00, 99, 99, 99);
Serial.print("Nuovo allarme alle ore ");
Serial.print(rtc.getHour() + 1);
Serial.println(":00");
}
void lettura()
{
// scrive l'ora
Serial.print(rtc.formatTime());
Serial.print("\r\n");
//leggo i valori del DHT22
float valDHTHum = 0;//DHT22
float valDHTTemp = 0;//DHT22
Serial.println("");
Serial.println("_____________________________________");
Serial.println("");
Serial.println("Orario rilevazione:");
Serial.print(rtc.formatTime());
Serial.print("\r\n");
Serial.print(rtc.formatDate());
Serial.print("\r\n");
Serial.println("DHThum, DHTTemp");
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);
errorCode = myDHT22.readData();
switch (errorCode)
{
case DHT_ERROR_NONE:
valDHTHum = 1.5 + (myDHT22.getHumidity());//+1.5 per correzione prima lettura
valDHTTemp = (myDHT22.getTemperatureC());
Serial.print(valDHTHum);
Serial.print("%");
Serial.print("\t");
Serial.print(valDHTTemp);
Serial.println("C ");
break;
case DHT_ERROR_CHECKSUM:
Serial.print("check sum error ");
Serial.print(valDHTTemp);
Serial.print("C ");
Serial.print(valDHTHum);
Serial.println("%");
break;
case DHT_BUS_HUNG:
Serial.println("BUS Hung ");
break;
case DHT_ERROR_NOT_PRESENT:
Serial.println("Not Present ");
break;
case DHT_ERROR_ACK_TOO_LONG:
Serial.println("ACK time out ");
break;
case DHT_ERROR_SYNC_TIMEOUT:
Serial.println("Sync Timeout ");
break;
case DHT_ERROR_DATA_TIMEOUT:
Serial.println("Data Timeout ");
break;
case DHT_ERROR_TOOQUICK:
Serial.println("Polled to quick ");
break;
}
// make a string for assembling the data to log:
String dataString = "";
dataString += String(rtc.formatDate());
dataString += ",";
dataString += String(rtc.formatTime());
dataString += ",";
dataString += String(valDHTHum);
dataString += ",";
dataString += String(valDHTTemp);
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
File dataFile = SD.open("datalog.txt", FILE_WRITE);
// if the file is available, write to it:
if (dataFile) {
dataFile.println(dataString);
dataFile.close();
// print to the serial port too:
Serial.println("");
Serial.println("dati salvati su SD:");
Serial.println(dataString);
}
// if the file isn't open, pop up an error:
else {
Serial.println("error opening datalog.txt");
}
}
void loop() {}