come già anticipato nella presentazione, il mio primo progetto con Arduino ha visto nascere un barometro; le componenti utilizzate sono state le seguenti:
Arduino uno rev3
Arduino Ethernet Shield
TMP36 <-- termometro analogico
DHT22 <-- termometro digitale + igrometro
MPL3115A2 <-- barometro + altimetro
Display LCD contenuto nello starter kit
la realizzazione in breadboard è stata la seguente:
Ora, torniamo al topic, la mia voglia è quella di realizzare una sonda esterna, comunicante tramite RF a 433mhz con la stazione presente in casa (Arduino + Ethernet) e magari con alimentazione a pile.
Visto il previsto uso in pile ho letto nel forum che si può abbassare la velocità di clock a 1 Mhz per limitare i consumi; ho provato a replicare tutto con una standalone (ATmega328) programmata tramite Arduino con il connettore ISP; riscritto il bootloader per funzionare a 1 Mhz.
Ho dei problemi, sembra che il sensore di pressione non sia funzionante, e l'igrometro registra valori fuori dal regolare.
Non escludo di aver effettuato errori logici e fisici; vi espongo il mio schema che momentaneamente ho disegnato:

Stavo valutando anche di spostare l'MPL3115A2 nella stazione in casa.
Secondo voi esperti, i sensori DHT22, MPL3115A2 e i futuri RF (come li ho sotto mano aggiungo dettagli) possono essere comandati dall'ATmega328 a 1Mhz?
è differente rispetto alla megaguida di Menniti, ho provato con quella riportata sulla guida ma ho avuto problemi.
Ho rivisto "l'architettura" della sonda esterna, adesso è semplicemente un ATmega standalone, un sensore DHT22 e un trasmettitore RF a 433Mhz; tutto alimentato da una batteria per cellulari.
Attualmente la sonda esterna comunica via RF con la postazione arduino uno + ethernet presente in casa equipaggiata con un altro sensore DHT22. Ho implementato l'invio dei dati rilevati sul servizio Xively (ex Cosm).
Lo scambio prevede la seguente sintassi "/T00.00/U00.00#"
il codice sulla sonda:
#include <avr/wdt.h>
#include <avr/sleep.h>
#include <avr/power.h>
#include <VirtualWire.h>
#include <DHT22.h>
const int DHT22_PIN = 7;
const int DHT22_power = 6;
//const int LedRF_trans = 11;
const int RF_power = 9;
const int RF_transmit_pin = 10;
byte masterLoop=7;
byte correct = 1;
byte checker = 0;
volatile int counter = 0;
DHT22 myDHT22(DHT22_PIN);
void setup() {
Serial.begin(9600);
Serial.println("supertest");
// Initialise the IO and ISR
vw_set_tx_pin(RF_transmit_pin);
//vw_set_rx_pin(receive_pin);
//vw_set_ptt_pin(transmit_en_pin);
vw_set_ptt_inverted(true); // Required for DR3100
vw_setup(1200); // Bits per sec
MCUSR = 0;
wdt_disable();
pinMode(DHT22_power,OUTPUT);
digitalWrite(DHT22_power,LOW);
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // setta registri per il modo sleep
sleep_enable(); // abilita la sleep all'uso
}
// watchdog interrupt
ISR (WDT_vect) {
wdt_disable(); // disable watchdog
} // end of WDT_vect
void loop() {
if (counter==masterLoop) {
digitalWrite(DHT22_power,HIGH);
delay(2000);
// Read values from the sensor
DHT22 loclDHT22 = getDHT22value();
Serial.println("spegno il pin");
digitalWrite(DHT22_power,LOW);
if(correct==1){
float temp_c = loclDHT22.getTemperatureC();
float humidity = loclDHT22.getHumidity();
Serial.print(temp_c); Serial.print("C "); Serial.println(humidity);
digitalWrite(RF_power, HIGH);
delay(1500);
char dataToSend[24];
char _buffer[10];
dtostrf(temp_c, 2, 2, _buffer);
////////////////////////////////////////////////////////////////////////////////////////
char dataToSend2[24];
char _buffer2[10];
dtostrf(humidity, 2, 2, _buffer2);
sprintf(dataToSend2, "/T%s/U%s#", (char*)_buffer, (char*)_buffer2);
Serial.println(dataToSend2);
vw_send((uint8_t *)dataToSend2, strlen(dataToSend2));
vw_wait_tx(); // Wait until the whole message is gone
digitalWrite(RF_power, LOW);
}
counter=1;
} else {
counter=counter+1;
}
Serial.print ("Numero cicli: "); Serial.println (counter);
delay (500);
// disable ADC
ADCSRA = 0;
// clear various "reset" flags
MCUSR = 0;
// allow changes, disable reset
WDTCSR = _BV (WDCE) | _BV (WDE);
// set interrupt mode and an interval
WDTCSR = _BV (WDIE) | _BV (WDP3) | _BV (WDP0); // set WDIE, and 8 seconds delay
wdt_reset(); // pat the dog
set_sleep_mode (SLEEP_MODE_PWR_DOWN);
sleep_enable();
// turn off brown-out enable in software
MCUCR = _BV (BODS) | _BV (BODSE);
MCUCR = _BV (BODS);
sleep_cpu ();
// cancel sleep as a precaution
sleep_disable();
} // end of loop
DHT22 getDHT22value(){
correct = 1;
if(checker<10){
checker++;
DHT22_ERROR_t errorCode;
delay(2200);
Serial.print("Requesting DHT22: ");
errorCode = myDHT22.readData();
switch(errorCode) {
case DHT_ERROR_NONE:
Serial.print(myDHT22.getTemperatureC()); Serial.print("C "); Serial.print(myDHT22.getHumidity()); Serial.println("%");
checker= 0;
return myDHT22;
break;
case DHT_ERROR_CHECKSUM:
Serial.print("check sum error "); Serial.print(myDHT22.getTemperatureC()); Serial.print("C "); Serial.print(myDHT22.getHumidity()); Serial.println("%");
// return myDHT22;
getDHT22value();
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 ");
getDHT22value();
break;
case DHT_ERROR_TOOQUICK:
Serial.println("Polled to quick ");
break;
}
} else {
checker = 0;
Serial.println("impossibile rilevare valori");
correct = 0;
}
}
attento a NON confondere il atmega328 con il atmega328P, l'ardiono di defult usa la versione P, che sta per low power, e quindi vari settaggi sono mlto differenti.
non so che sleep riesci ad ottenere, ma lì si raggiunge il limite minimo (da datasheet) dell'atmega328p: 1 uA, circa 22 anni con una batteria a bottone da orologio.
esdit:q quello è per il 328, il 328p arriva a 0.1uA
non vorrei dire fesserie ma dal multimetro mi sembra di stare sul limite minimo quando è in sleep; in funzionamento non mi ricordo proprio.
Stasera riprovo a monitorarlo
Il limite di 0,1 uA mi pare difficile che lo possa raggiungere se spenge solo l'ADC e lascia alimentato tutto il resto, a cominciare dal watchdog per poi passare ai vari timer, al circuito di brown-out, all'AC.
Disattivare non vuol dire spengere, volevo far capire questo concetto.
Quando entra in modalità Power-Down il micro toglie il clock a diverse periferiche ma queste continuano a ricevere comunque l'alimentazione. Consumano poco perché "non girano" ma un minimo di corrente continuano a prendersela. Il core PicoPower permette una gestione capillare di tutte le periferiche integrate, dove si può andare letteralmente a staccare la spina ad ogni cosa che non serve.
Riesco a vederlo ma non tornano i valori .
Il datasheet dice che con WDT attivo in Power Down il consumo è di minimo 4.2 uA.
Come fa a te a registrare 0.0?
In quel caso dovrebbe avere qualche mal funzionamento, eppure lavora senza problemi...
Comunque ho controllato più volte le saldature e non sono presenti falsi contatti, la struttura è così semplice
intendevo più dal punto di vista sonde delmultimetro, o magari il multimetro semplicemente è falsato per quelle misure. non ne hai altri da mettere a confronto?