Sensore Co2 MH-Z16

Ciao a tutti qualcuno sa come devo collegare questo sensore al mio arduino?
Dal sito 10,000ppm MH-Z16 NDIR CO2 Sensor with I2C/UART 5V/3.3V Interface for Arduino/Raspeberry Pi | Sandbox Electronics non capisco bene come fare…da quello che ho capito la corrente fornita dall’USB non è sufficiente per alimentare sia arduino che il sensore Co2 simultaneamente, quindi è consigliato usare un alimentatore esterno.
Ho scaricato la libreria del sensore, e ho provato ad usare una alimentazione esterna da 9v.
Apro un nuovo sketch, File, Esempi, NDIR_I2C, Read Concentration e si apre lo sketch di esempio per la misurazione del Co2.
Adesso dalla schedina del sensore ho 4 cavetti nero, rosso, giallo, verde, rispettivamente GND, VCC, Rx/SDA, Tx/SCL. Da quello che ho capito io:

GND a GND arduino, VCC a 5v arduino, RX/SDA a Rx arduino, Tx/SCL a Tx arduino Corretto?

Questo è il codice di esempio:

#include <Wire.h>
#include <NDIR_I2C.h>

NDIR_I2C mySensor(0x4D); //Adaptor's I2C address (default: 0x4D)

void setup()
{
    Serial.begin(9600);

    if (mySensor.begin()) {
        Serial.println("Wait 10 seconds for sensor initialization...");
        delay(10000);
    } else {
        Serial.println("ERROR: Failed to connect to the sensor.");
        while(1);
    }
}

void loop() {
    if (mySensor.measure()) {
        Serial.print("CO2 Concentration is ");
        Serial.print(mySensor.ppm);
        Serial.println("ppm");
    } else {
        Serial.println("Sensor communication error.");
    }

    delay(1000);
}

Quando accendo arduino e apro il monitor seriale mi restituisce il messaggio ERROR: Failed to connect to the sensor.

Qualcuno può aiutarmi? Grazie in anticipo

sotto la schedina Arduino dovresti leggere SDA e SCL

ok sotto la schedina leggo SDA e SCL ma SCL non lo vedo...

mayette89:
ok sotto la schedina leggo SDA e SCL ma SCL non lo vedo...

Io ho la revisione 3. Quei piedini sono dopo "Aref" vicino al pulsante di reset. Se guardi sotto c'e scritto SDA e SCL

si ok scusa li ho visti tutti e due, ho provato e adesso lo rileva....ho un'altra domanda...Io vorrei usare questo sensore in una serra ma non ho ben capito come fare per disattivare l'autocalibrazione del sensore. sempre dal sito MH-Z16 NDIR CO2 Sensor with I2C/UART Interface Board | Sandbox Electronics spiega qualcosa a riguardo ma visto anche il mio scarso inglese no ho ben capito..Qualcuno può illuminarmi?

Grazie ancora

Also, the manufacturer of the sensor claims a ±(50ppm +5%reading value) initial accuracy of this sensor, and it is factory calibrated. According to the datasheet of the sensor, the re-calibration of the sensor is recommended over 6 months of use. The method of the calibration is quite easy compared to the MG811, just put it in fresh air for a couple of minutes and press the “CALI” button on the adapter board or issue a “calibration” command.

Non l'ho mai usato però secondo me c'e scritto che devi premere un pulsante in aria ( fuori dalla finestra...:D)

lo zero lo fai con un gas che lui non rileva che può essere a zero o molto basso, quindi appunto zero
( ogni sei mesi dice)
Zibaldone Scientifico: luglio 2015 ( il primo link che ho trovato su google)

Poco più sotto però dicè:

The manufacturer claims that the algorithm is effective against long time drift. This feature is good for applications which the sensor will be in fresh air for at least some period of time in a cycle(24hours). For example, in your application, there is always sometime in a day that the CO2 concentration in the room is around 400ppm(theoretically, the CO2 concentration will never below 400ppm in fresh air). However, it is a disaster if the sensor is in an atmosphere where the co2 concentration is always low or above 400ppm(for example,greenhouse).

To “break” the auto-calibration cycle, or to “disable” the auto-calibration, please turn OFF the sensor at least once every 24hours. User could turn ON/OFF the sensor by changing the state SC16IS750’s PIN15 via I2C interface.

PIN16 of the SC16IS750 chip is used as a calibration signal to the sensor, and PIN15 of the chip is connected to a power MOSFET which could be used to switch the sensor ON/OFF. As both the PIN15 and PIN16 is software programmable, the calibration and ON/OFF could be controlled by software via I2C interface.

Io dovrei usarlo proprio in serra...

Attendo notizie...

il sensore si autocalibra ogni 24 ore per elininare la deriva che introduce un errore.

Ovviamente non può fare lo zero in una serra quindi lo devi spegnere tu ogni 24 ore via I2C ovvero con arduino

nel link c'e una funzione che si chiama power , basta che chiami quella funzione ogni 24

//Power control function for NDIR sensor. 1=ON, 0=OFF
void power (uint8_t state) {
    i2cuart.pinMode(0, INPUT);      //set up for the power control pin
 
    if (state) {
        i2cuart.pinMode(0, INPUT);  //turn on the power of MH-Z16
    } else {
        i2cuart.pinMode(0, OUTPUT);
        i2cuart.digitalWrite(0, 0); //turn off the power of MH-Z16
    }
}

power(0) --> spegne il sensore

per capirci meglio:

MH-Z16 ha una funzione chiamata "Auto Calibrazione", che è un algoritmo integrato nel firmware del sensore. Il principio di funzionamento semplificato di questo algoritmo è qualcosa di simile a questo:

  1. Il sensore mantiene il tracciamento della lettura più bassa del sensore poiché è acceso.
  2. Dopo le prime 24 ore da quando è acceso, registra il valore più basso (valore A).
  3. Dopo le prime 48 ore da quando è acceso, registra il valore più basso negli ultimi 24 ore (valore B).
  4. Esso confronta il valore A e il valore B, se partite in una certa misura, utilizzerà questo valore come nuovo valore di base.
  5. Il sensore ripete 2 e 3 dopo 4.

Fino qui tutto chiaro poi...

Il produttore sostiene che l'algoritmo è efficace contro lunga deriva tempo. Questa caratteristica è buona per applicazioni quali il sensore sarà in aria fresca per almeno un certo periodo di tempo in un ciclo (24 ore). Ad esempio, nella vostra applicazione, c'è sempre un momento in un giorno in cui la concentrazione di CO2 nella stanza è di circa 400 ppm (in teoria, la concentrazione di CO2 non sarà mai al di sotto di 400ppm in aria fresca). Tuttavia, è un disastro se il sensore è in un'atmosfera in cui la concentrazione di CO2 è sempre basso o superiore 400ppm (per esempio, serra).

ed è il mio caso...

Per "rompere" il ciclo di auto-calibrazione, o "disabilitare" l'auto-calibrazione, spegnere il sensore almeno una volta ogni 24 ore. L'utente potrebbe attivare / disattivare il sensore modificando il PIN15 lo stato del SC16IS750 attraverso l'interfaccia I2C.

il PIN16 del chip SC16IS750 viene utilizzato come segnale di calibrazione al sensore, e il PIN15 del chip è collegato ad un MOSFET di potenza che può essere utilizzato per commutare il sensore ON / OFF. Poiché sia il PIN15 e PIN16 sono programmabili via software, la calibrazione e ON / OFF può essere controllato da un software attraverso l'interfaccia I2C.

ma come?

ok grande sei molto gentil, avresti la pazienza di spiegarmi altre due cose...

i2cuart.begin(9600)

Questa riga cosa vuol dire?

if (i2cuart.ping()) {

e anche questo?

e poi come faccio in modo che la funzione si richiami da sola ogni 24 0re?

dovresti avere una schedina oltre al sensore.

Sembra ma non sono sicuro che faccia da tramite in una comunicazione I2C->Uart per interfacciarsi con il sensore.

prima prova il programma e vedi se risponde il sensore

ok ho provato questo codice

#include <Wire.h>
#include <SPI.h>
#include <SC16IS750.h>
#include <string.h>
#include <NDIRZ16.h>


SC16IS750 i2cuart = SC16IS750(SC16IS750_PROTOCOL_I2C,SC16IS750_ADDRESS_BB);
NDIRZ16 mySensor = NDIRZ16(&i2cuart);

void setup() 
{
    Serial.begin(115200);
    i2cuart.begin(9600);

    if (i2cuart.ping()) {
        Serial.println("SC16IS750 found.");
        Serial.println("Wait 10 seconds for sensor initialization...");
    } else {
        Serial.println("SC16IS750 not found.");
        while(1);
    }

    power(1);
    //Wait for the NDIR sensor to initialize.
    delay(10000);
};

void loop() {
    if (mySensor.measure()) {
        Serial.print("CO2 Concentration is ");
        Serial.print(mySensor.ppm);
        Serial.println("ppm");
    } else {
        Serial.println("Sensor communication error.");
    }
    delay(1000);
}

//Power control function for NDIR sensor. 1=ON, 0=OFF
void power (uint8_t state) {
    i2cuart.pinMode(0, INPUT);      //set up for the power control pin
 
    if (state) {
        i2cuart.pinMode(0, INPUT);  //turn on the power of MH-Z16
    } else {
        i2cuart.pinMode(0, OUTPUT);
        i2cuart.digitalWrite(0, 0); //turn off the power of MH-Z16
    }
}

ho provato e sembra andare tutto bene il sensore risponde…
ma non ho capito bene il codice qualcuno può spiegarmi meglio, più che altro come fà dopo 24 ore a spegnersi da solo e poi riaccendersi per evitare di autocalibrarsi?

mayette89:
ho provato e sembra andare tutto bene il sensore risponde…
ma non ho capito bene il codice qualcuno può spiegarmi meglio, più che altro come fà dopo 24 ore a spegnersi da solo e poi riaccendersi per evitare di autocalibrarsi?

Infatti non lo fa , devi scrivere tu il programma per spegnerlo utilizzando la fuzione power

Devi creare un timer e raggiunto il periodo di 24 ore chiama la funzione power(0) per spegnere il sensore
attendi qualche minuto( altro timer) quindi riaccendi con power(1)

Edit:

li c’e un esempio di timer per 24h non è preciso come un orologio ma puoi provare e migliorare dopo se server con un componente esterno.

un esempio del tuo loop. Tieni presente che lo devi eventualmente correggere , no hai la precisione di un orologio quindi prima prova con 1h vedi l'errore o anche più ore.

void loop() {
  static uint32_t prevTime;
  uint32_t curTime = millis();
  
    if (mySensor.measure()) {
        Serial.print("CO2 Concentration is ");
        Serial.print(mySensor.ppm);
        Serial.println("ppm");
    } else {
        Serial.println("Sensor communication error.");
    }
    delay(200);

if ( curTime - prevTime >= 24*60*60*1000UL )
  {
    prevTime = curTime;

    // do things every 24h here

    power(0); // spengo il sensore
    delay(60000); //aspetto un minuto 
    power(1); // riaccendo il sensore
    //Wait for the NDIR sensor to initialize.
    delay(10000);
  } // proseguo e rileggo


    
}

ok farò delle prove....sei stato davvero molto gentile fino ad ora, ma vorrei capire bene la logica dietro a questo codice non capisco alcuni passaggi, togliendo tutti i Serial.print(), mi potresti spiegare meglio come funziona anche per capire meglio cosa sto facendo...

Grazie ancora e scusa se magari faccio domande banali :wink:

il codice che stò usando è il seguente… ho aggiunto un led e un buzzer in modo che quando la concentrazione dazione di co2 sale sopra le 1200 ppm un segnale acustico e visivo avverta degli alti livelli di Co2…

#include <Wire.h>
#include <SPI.h>
#include <SC16IS750.h>
#include <string.h>
#include <NDIRZ16.h>


SC16IS750 i2cuart = SC16IS750(SC16IS750_PROTOCOL_I2C,SC16IS750_ADDRESS_BB);
NDIRZ16 mySensor = NDIRZ16(&i2cuart);

void setup() 
{
    Serial.begin(115200);
    i2cuart.begin(9600);
    pinMode(12, OUTPUT); //Led
    pinMode(11, OUTPUT); //Buzzer

    if (i2cuart.ping()) {
        Serial.println("SC16IS750 Trovato.");
        Serial.println("Attendere 10 secondi per l'inizializzazione del sensore...");
    } else {
        Serial.println("SC16IS750 non trovato.");
        while(1);
    }

    power(1);
    //Wait for the NDIR sensor to initialize.
    delay(10000);
};

void loop() {
   
   static uint32_t prevTime;
   uint32_t curTime = millis(); 
   
   if (mySensor.measure()) {
        Serial.print("La concentrazione di Co2 e ");
        Serial.print(mySensor.ppm);
        Serial.println("ppm.");
    } else {
        Serial.println("Errore comunicazione sensore.");
    }
    delay(1000);
    
    if ( curTime - prevTime >= 24*60*60*1000UL )
  {
    prevTime = curTime;
    // do things every 24h here

    power(0); // spengo il sensore
    Serial.print("Sensore OFF");
    delay(60000); //aspetto un minuto 
    power(1); // riaccendo il sensore
  }
    if (mySensor.ppm > 1200) {
      digitalWrite(12, HIGH); //Accendo il Led
      digitalWrite(11, HIGH); //Accendo il Buzzer
    }
    else {
      digitalWrite(12, LOW);  //Spengo il Led 
      digitalWrite(11, LOW);  //Spengo il Buzzer
    }
    
}

//Power control function for NDIR sensor. 1=ON, 0=OFF
void power (uint8_t state) {
    i2cuart.pinMode(0, INPUT);      //set up for the power control pin
 
    if (state) {
        i2cuart.pinMode(0, INPUT);  //turn on the power of MH-Z16
    } else {
        i2cuart.pinMode(0, OUTPUT);
        i2cuart.digitalWrite(0, 0); //turn off the power of MH-Z16
    }
}

Adesso se ho capito bene modificando questa riga :

if ( curTime - prevTime >= 24*60*60*1000UL )

dovrei poter fare delle prove per testare la precisione del timer, mi basta modificare così per far si che si spenga dopo un’ora?
if ( curTime - prevTime >=60*60*1000UL )
Cosa vuol dire poi 1000UL?

E qualcuno potrebbe spiegarmi più nello specifico come funzionano questi codici?

if (i2cuart.ping()) {}
static uint32_t prevTime;
   uint32_t curTime = millis();
 if ( curTime - prevTime >= 24*60*60*1000UL )
  {
    prevTime = curTime;
void power (uint8_t state) {
    i2cuart.pinMode(0, INPUT);      //set up for the power control pin
 
    if (state) {
        i2cuart.pinMode(0, INPUT);  //turn on the power of MH-Z16
    } else {
        i2cuart.pinMode(0, OUTPUT);
        i2cuart.digitalWrite(0, 0); //turn off the power of MH-Z16
    }
}

Grazie a tutti in anticipo…

Purtroppo molti esperti di arduino sono in ferie o in vacanza .
Se vuoi posso dirti la mia

Cosa vuol dire poi 1000UL?

leggi qui :Integer Constants - Arduino Reference

E qualcuno potrebbe spiegarmi più nello specifico come funzionano questi codici?

if (i2cuart.ping()) {}

i2uart è il nome che è stato assegnato all'oggetto di classe SC16IS750
Le librerie di arduino sono in realtà classi (c++) nate come tutte le classi per essere utilizzate in altri programmi , in questo caso il tuo ) nascondendo la complessità delle loro funzioni svolte all'interno.
In questo caso l'interfacciamento verso il sensore.
Se ti vai a leggere le librerie scoprirai cosa fanno e come, ed è quello che ho fatto io non conoscendo il sensore e tanto meno le classi associate. Solitamente ogni classe viene accompagnata da una documentazione. comunque si trova qui : UART_Bridge/SC16IS750.cpp at master · SandboxElectronics/UART_Bridge · GitHub
Scoperto cosa fanno vai sul datasheet del chip e studi quello.
Sarebbe preferibile però fare il contrario , prima studiare il chip.
Tutto questo però lo puoi fare se hai delle basi almeno di C, almeno potrai distinguere classi da istruzioni o parole chiave

uint8_t SC16IS750::ping()
{
	WriteRegister(SC16IS750_REG_SPR,0x55);
	if (ReadRegister(SC16IS750_REG_SPR) !=0x55) {
		return 0;
	}

	WriteRegister(SC16IS750_REG_SPR,0xAA);
	if (ReadRegister(SC16IS750_REG_SPR) !=0xAA) {
		return 0;
	}

	return 1;

}

dove nel file header (.h) leggi :
#define SC16IS750_REG_SPR (0X07)

credo faccia un ping ovvero invia una informazione e poi attende una risposta.
se la risposta è corretta allora il destinatorio esiste ( il sensore risponde)
In questo caso scrive su due registri all'indirizzo 0x07 chiamato SPR presente nel datasheet a pagina 21
del costruttore del chip NXP : http://www.nxp.com/documents/data_sheet/SC16IS740_750_760.pdf
mentre a pagina 28:

Scratch Pad Register (SPR)
This 8-bit register is used as a temporary
data storage register. User’s program can
write to or read from this register without
any effect on the operation of the device.

Evidentemente quando la funzione ping scrive su SPR e rilegge quanto memorizzato , ritiene che il sensore sia attivo.
La scheda che hai davanti ti permette di interfacciarti al sensore con quel chip (SC16IS750) , perchè probabilmente tu parli con il protocollo I2C da arduino e lui pero riceve con una UART (UART - Wikipedia)

static uint32_t prevTime;
   uint32_t curTime = millis();


Code: [Select]

if ( curTime - prevTime >= 24*60*60*1000UL )
  {
    prevTime = curTime;

millis() misura il tempo in millisecondi dalla prima accensione di Arduino ( dopo 50 giorni si azzera)
Trascorse le 24h , memorizza i millisecondi equivalenti (prevTime) e quel valore sarà il suo nuovo punto di partenza(il prossimo ciclo loop). Si comporta come un offset nel tempo che dura 24 ore, quindi se curTime-prevTime >=24ore vuole dire che sono trascorse 24 ore, nella forma 24h60min60sec*1000 ( 1000 per trasformare tutto in millisecondi)

void power (uint8_t state) {
    i2cuart.pinMode(0, INPUT);      //set up for the power control pin
 
    if (state) {
        i2cuart.pinMode(0, INPUT);  //turn on the power of MH-Z16
    } else {
        i2cuart.pinMode(0, OUTPUT);
        i2cuart.digitalWrite(0, 0); //turn off the power of MH-Z16
    }
}

questo codice dovrebbe configurare il pin di arduino com input( three state) per accendere il sensore
quando state = 1, mentre per spegnerlo lo configura come uscita e porta l'uscita a zero.

intanto ti ringrazio per il tempo e la pazienza che mi stai dedicando, grazie d’avvero, mi ha chiarito alcune cose ma ancora non capisco appieno…
ricapitoliamo un’attimo…

#include <Wire.h>
#include <SPI.h>
#include <SC16IS750.h>
#include <string.h>
#include <NDIRZ16.h>

Correggimi se sbaglio, con questi comandi includo le librerie Wire.h, SPI.h, ecc… e tutte le loro funzioni.

Serial.begin(115200);
    i2cuart.begin(9600);

Serial.begian(115200) imposta il canale di comunicazione con il monitor seriale a una velocità di 115200 baud.
i2cuart.begin(9600) imposta il canale di comunicazione con la schedina del sensore co2 a una velocità di 9600 baud.

if (i2cuart.ping()) {
        Serial.println("SC16IS750 Trovato.");
        Serial.println("Attendere 10 secondi per l'inizializzazione del sensore...");
    } else {
        Serial.println("SC16IS750 non trovato.");
        while(1);
    }

Qui praticamente dice, Se si riceve risposta da i2cuart Allora scrivi a monitor ecc.ecc.
altrimenti scrivi a monitor ecc… ecc…
while(1) ? non mi è chiaro…

power(1);

richiama la funzione power accendendo il sensore

static uint32_t prevTime;
   uint32_t curTime = millis();

creo una variabile di tipo static, uint32_t con lunghezza 32 bit? a cui assegno il nome prevTime.
curtTime = millis()…dà alla variabile curtTime il valore di millis() cioè del tempo trascorso sino a quel momento.

if (mySensor.measure()) {
        Serial.print("La concentrazione di Co2 e ");
        Serial.print(mySensor.ppm);
        Serial.println("ppm.");
    } else {
        Serial.println("Errore comunicazione sensore.");
    }
    delay(1000);

Se il sensore rileva una misura allora ecc.c ecc…
altrimenti ecc…ecc.

 if ( curTime - prevTime >= 24*60*60*1000UL )
  {
    prevTime = curTime;

qui dice, Se il valore di curTime - il valore di prevTime = 86.400.000 che sono i millisecondi in 24 h allora ecc… ecc…

ma non capisco…mettiamo che io accendo adesso arduino, inizia il void loop(),
e gli dico che prevTime deve avere il valore di millis(), quindi dopo un’ora prevTime= 3.600.000 millisecondi Giusto? e via dicendo…
Passano 24H e scatta il fatidico

 if ( curTime - prevTime >= 24*60*60*1000UL )
  {
    prevTime = curTime;

Quindi curTime adessò varrà 86.400.000 - prevTime (Che non ho capito quanto vale, suppongo 0?)
86.400.000 - 0 = 86.400.000 quindi si verifica la condizione, a questo punto assegna a prevTime 86.400.000, passa un’altra ora curTime = 17.280.000

17.280.000 - 86.400.000 = 86.400.000 condizione dinuovo vera…e questa la logica?

non capisco, nel sito dove ho acquistato questo sensore nei dati tecnici c’è scritto che per interrompere il ciclo di auto calibrazione, (che avviene ogni 24 ore) basta togliere alimentazione ad arduino. Ma questa operazione non andrebbe fatta prima e non dopo che siano passate 24 h? Nel senso lui ogni 24 h si autocalibra, io lo spengo PASSATE le 24 h, non mi è servito a niente praticamente :o :o o sbaglio?

mayette89:
intanto ti ringrazio per il tempo e la pazienza che mi stai dedicando, grazie d’avvero, mi ha chiarito alcune cose ma ancora non capisco appieno…
ricapitoliamo un’attimo…
Esatto. Dice al compilatore ( ovvero un “software” che traduce quello che scrivi qui in un linguaggio comprensibile per arduino) di includere nel tuo programma (appunto #include) le classi con quel nome.

#include <Wire.h>

#include <SPI.h>
#include <SC16IS750.h>
#include <string.h>
#include <NDIRZ16.h>



Correggimi se sbaglio, con questi comandi includo le librerie Wire.h, SPI.h, ecc.. e tutte le loro funzioni.


Serial.begin(115200);
    i2cuart.begin(9600);



Serial.begian(115200) imposta il canale di comunicazione con il monitor seriale a una velocità di 115200 baud.
i2cuart.begin(9600) imposta il canale di comunicazione con la schedina del sensore co2 a una velocità di 9600 baud.
*Esatto.*


if (i2cuart.ping()) {
        Serial.println(“SC16IS750 Trovato.”);
        Serial.println(“Attendere 10 secondi per l’inizializzazione del sensore…”);
    } else {
        Serial.println(“SC16IS750 non trovato.”);
        while(1);
    }



Qui praticamente dice, Se si riceve risposta da i2cuart Allora scrivi a monitor ecc.ecc.
altrimenti scrivi a monitor ecc.. ecc..
while(1) ? non mi è chiaro..
*è una scelta del autore. Quando non trova il sensore rimane li per sempre;è un ciclo while infinito*
*ma tu puoi benissimo scegliere di prendere altre strade, essendo tu ora il programmatore.*


power(1);



richiama la funzione power accendendo il sensore
*Esatto*


static uint32_t prevTime;
uint32_t curTime = millis();



creo una variabile di tipo static, uint32_t con lunghezza 32 bit?
a cui assegno il nome prevTime.
*Esatto*
curtTime = millis()...dà alla variabile curtTime il valore di millis() cioè del tempo trascorso sino a quel momento.
*Esatto*


if (mySensor.measure()) {
        Serial.print("La concentrazione di Co2 e ");
        Serial.print(mySensor.ppm);
        Serial.println(“ppm.”);
    } else {
        Serial.println(“Errore comunicazione sensore.”);
    }
    delay(1000);



Se il sensore rileva una misura allora ecc.c ecc..
altrimenti ecc..ecc.
*Esatto*


if ( curTime - prevTime >= 246060*1000UL )
  {
    prevTime = curTime;



qui dice, Se il valore di curTime - il valore di prevTime = 86.400.000 che sono i millisecondi in 24 h allora ecc.. ecc..
*Esatto*
ma non capisco...mettiamo che io accendo adesso arduino, inizia il void loop(),
e gli dico che prevTime deve avere il valore di millis(), quindi dopo un'ora prevTime= 3.600.000 millisecondi Giusto? e via dicendo...
Passano 24H e scatta il fatidico 

if ( curTime - prevTime >= 246060*1000UL )
  {
    prevTime = curTime;



Quindi curTime adessò varrà 86.400.000 - prevTime (Che non ho capito quanto vale, suppongo 0?) 
86.400.000 - 0 = 86.400.000 quindi si verifica la condizione, a questo punto assegna a prevTime 86.400.000, 
passa un'altra ora curTime = ~~17.280.000~~ *<<-- 86.400.000 + 3.600.000 vale 90000000*
*ma visto che tu hai scritto :*


if ( curTime - prevTime >= 246060*1000UL )



*tu non aspetti un'ora ma altre 24h quindi visto che ora prevTime = 86.400.000 ( dopo che sono trascorse le prime 24h)*
*passeranno altre 24h curTime = 86.400.000 + 86.400.000 <<- vale 172800000* 
*--> curTime - prevTime --> 172800000 - 86.400.000 = 86.400.000 , condizione ancora vera*
non capisco, nel sito dove ho acquistato questo sensore nei dati tecnici c'è scritto che per interrompere il ciclo di auto calibrazione, (che avviene ogni 24 ore) basta togliere alimentazione ad arduino. Ma questa operazione non andrebbe fatta prima e non dopo che siano passate 24 h? Nel senso lui ogni 24 h si autocalibra, io lo spengo PASSATE le 24 h, non mi è servito a niente praticamente :o :o o sbaglio? 
*certo però , potresti fare cosi ( la prima che mi viene in mente)*
*Sempre se lui inizia a contare dopo che è stato acceso ed è preciso*
*La prima volta che accendi tutto il sistema:*
*1) accendi arduino*
*2) power(0) al sensore*
*3) il tuo timer millis parte e inizia contare*
*4) attendi per esempio 15 minuti ?( con un altro timer)*
*5) trascorsi i 15 minuti , accendi il tuo sensore*
*6) avrai cosi due timer sfasati di 15 minuti senza incorrere in una sovraposizione come giustamente dicevi.*
*La parte critica è la precisione , non si devono sovrapporre .*
*Alternativa forse e mettere un orologio esterno ad arduino.*
*Io ti ho proposto Millis perchè e piu semplice e hai modo di capire come "gira il fumo" e piu avanti se non e sufficiente , perfezioni. Altrimenti rischi di incasinarti perchè hai troppi problemi all'inizio*

aspetta un attimino....se io implementassi una fotoresistenza al mio circuito non avrei più bisogno di ricorrere alla funzione millis()... ::slight_smile:

Avendo l'esigenza di usare il Co2 soalmente durante il giorno per circa 12 h, per le restanti 12 h potrei spegnere il sensore, ovviando così al problema dell'auto calibrazione...o no? Lui al massimo funziona per 12 ore :slight_smile: :slight_smile: :slight_smile:

Per collegare la fotoresistenza che criterio devo usare per scegliere la resistenza adeguata?
in giro ci sono mille schemi con resistenze diverse, sembra che ognuno dica la sua...

i dati che ricevo nel monitor seriale dipendono anche dalla resistenza usata?

Avrei anche un'altra domanda, ho un alimentatore da 9v 600mA posso collegarlo tranquillamente all'arduino?

devo considerare l'assorbimento totale del mio progetto?