Pages: [1] 2   Go Down
Author Topic: Barometro DIY; consigli e aiuti per la sonda esterna  (Read 1766 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Buonasera,

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:


.. e in funzione:



il codice per gestire tutto, con sincronizzazione sul sito Cosm

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?
« Last Edit: May 12, 2013, 02:23:21 am by djscudo » Logged

0
Online Online
Shannon Member
****
Karma: 130
Posts: 10453
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ciao,
ottimo lavoro!
Quote
riscritto il bootloader per funzionare a 1 Mhz
uhmmm, cosa moolto error prone, perchè no hai usato quelli già fatti? hai settato in modo corretto i FUSE? vedi la gioda di menniti in megatopic
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ciao lesto, grazie  smiley

ho scoperto il problema alcuni giorni fa, credo sia dovuto proprio a qualche Fuse errato. Ho cambiato il clock a 8 Mhz configurando così:

Code:
atmega328bb.name=ATmega328 (8 MHz internal clock)
 
atmega328bb.upload.protocol=stk500
atmega328bb.upload.maximum_size=32768
atmega328bb.upload.speed=57600
atmega328bb.upload.using=arduino:arduinoisp
atmega328bb.bootloader.low_fuses=0xE2
atmega328bb.bootloader.high_fuses=0xDA
atmega328bb.bootloader.extended_fuses=0x05
atmega328bb.bootloader.path=arduino:atmega
atmega328bb.bootloader.file=ATmegaBOOT_168_atmega328_pro_8MHz.hex
atmega328bb.bootloader.unlock_bits=0x3F
atmega328bb.bootloader.lock_bits=0x0F
atmega328bb.build.mcu=atmega328p
atmega328bb.build.f_cpu=8000000L
atmega328bb.build.core=arduino:arduino
atmega328bb.build.variant=standard

è 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:
Code:
#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;
  }
}
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

e il codice sulla postazione in casa:
Code:
#include <SPI.h>
#include <Ethernet.h>
#include <HttpClient.h>
#include <Xively.h>
#include <DHT22.h>
#include <VirtualWire.h>


//Definizione PIN
DHT22 myDHT22(7);


IPAddress dns_local (192, 168, 1, 1);
IPAddress ip_dis ( 192, 168, 1, 3 );
// MAC address for your Ethernet shield
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

float extTemp = 0;
float extUmid = 0;


unsigned long lastCheck = 0;
const unsigned long tempoMaster = 60000;
// Initialize the Xively library
char xivelyKey[] = "xxxxxxxxxxxxxxxxxxxxxxxxxxx";


char bufferValue[140]; // enough space to store the string we're going to send
XivelyDatastream datastreams[] = {
  XivelyDatastream("temp_int", strlen("temp_int"), DATASTREAM_FLOAT),
  XivelyDatastream("temp_ext", strlen("temp_ext"), DATASTREAM_FLOAT),
  XivelyDatastream("umid_int", strlen("umid_int"), DATASTREAM_FLOAT),
  XivelyDatastream("umid_ext", strlen("umid_ext"), DATASTREAM_FLOAT),
};
// Finally, wrap the datastreams into a feed
XivelyFeed feed(129843, datastreams, 4 /* number of datastreams */);

EthernetClient client;
XivelyClient xivelyclient(client);


void setup() {
 
  //inizialize Serial comunication
  Serial.begin(9600);
  delay(2000);

  Serial.println("Inizializzazione board...");
  Serial.print("Tempo di loop (ms): "); Serial.println(tempoMaster);

  Serial.print("IP dispositivo: "); Serial.println(ip_dis);

  Serial.println("Done.");
  Ethernet.begin(mac, ip_dis, dns_local);
  delay(1000);
  
  vw_set_tx_pin(8);
  vw_set_rx_pin(9);
  vw_set_ptt_pin(3);
  vw_set_ptt_inverted(true); // Required for DR3100
  vw_setup(1200); // Bits per sec
  vw_rx_start();
  Serial.println("started RF receiver");  
    

}




void loop(){
  
  uint8_t buf[VW_MAX_MESSAGE_LEN];
  uint8_t buflen = VW_MAX_MESSAGE_LEN;
  
  if (vw_get_message(buf, &buflen)) // Non-blocking
    {
int i;

  //      digitalWrite(led_pin, HIGH); // Flash a light to show received good message
// Message with a good checksum received, print it.
        Serial.println("################");
Serial.print("Got: ");
char str[5];
        char umid[5];
    //    char type = buf[1];
        
        str[0] = buf[2];
        str[1] = buf[3];
        str[2] = buf[4];
        str[3] = buf[5];
        str[4] = buf[6];
    
        umid[0] = buf[9];
        umid[1] = buf[10];
        umid[2] = buf[11];
        umid[3] = buf[12];
        umid[4] = buf[13];


  //      digitalWrite(led_pin, LOW);

        Serial.print("Temperatura: "); Serial.println(str);
          extTemp= atof(str);
          
        Serial.print("Umidita: "); Serial.println(umid);    
          extUmid= atof(umid);
    }  
    
    
   if (millis() - lastCheck > tempoMaster) {
  
      delay(2000);
      DHT22 loclDHT22 = getDHT22value();

      float fTemp = loclDHT22.getTemperatureC();
      float fUmid = loclDHT22.getHumidity();

      Serial.print("temperatura interna: "); Serial.println(fTemp);
      Serial.print("temperatura esterna: "); Serial.println(extTemp);
      Serial.print("umidita interna: "); Serial.println(fUmid);
      Serial.print("umidita esterna: "); Serial.println(extUmid);

        
          datastreams[0].setFloat(fTemp);
          datastreams[1].setFloat(extTemp);
          datastreams[2].setFloat(fUmid);
          datastreams[3].setFloat(extUmid);
      

          
          Serial.println("Uploading it to Xively");
          int ret = xivelyclient.put(feed, xivelyKey);
          Serial.print("xivelyclient.put returned ");
          Serial.println(ret);

    lastCheck = millis();
    }
  
}

DHT22 getDHT22value(){

 DHT22_ERROR_t errorCode;
 delay(500);
  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("%");
      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;
      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;
  }

}



prossimo step:
- aggiungere il sensore di pressione nella stazione in casa e trasformarla in una standalone con ethernet e display  smiley-cool
Logged

0
Online Online
Shannon Member
****
Karma: 130
Posts: 10453
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

quello che utilizzo è l'ATmega328P
Logged

0
Online Online
Shannon Member
****
Karma: 130
Posts: 10453
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

non ho mai lavorato cn gli spleep, ma questa mi pare una buona guida:

https://www.sparkfun.com/tutorials/309
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Grazie per la guida, questo fine settimana me la studio un po' smiley

comunque il codice presente sulla sonda mette il processore in sleep
Logged

0
Online Online
Shannon Member
****
Karma: 130
Posts: 10453
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
« Last Edit: May 30, 2013, 07:44:13 am by lesto » Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 325
Posts: 22498
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.  smiley-wink
Disattivare non vuol dire spengere, volevo far capire questo concetto.  smiley-sweat

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.
Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Questo è quanto mi consuma
https://www.youtube.com/watch?v=07_ycb9mFlA&feature=youtube_gdata_player
Logged

0
Online Online
Shannon Member
****
Karma: 130
Posts: 10453
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

non ved il video, si blocca dopo uno o due secondi
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 325
Posts: 22498
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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?  smiley-sweat
Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Proprio per questo motivo ho voluto fare un video!
Non riesco a spiegarmelo nemmeno io..

Il Multimetro sembra essere ok, ho provato a utilizzarlo per altre cose; ora sto provando a tenerlo alimentato dalla batteria fino ad esaurimento
Logged

Pages: [1] 2   Go Up
Jump to: