SPX-14241 BME280 CCS811

La scheda SPX-14241 BME280 CCS811 unisce due sensori molto utili per l’analisi dei dati ambientali in ottica IoT e non solo.

SPX-14241 BME280 CCS811 Combo Board

Fonte: sparkfun.com

Nel precedente articolo dedicato alla scheda hai letto solo del primo sensore il BME280 con la finalità di rilevare la temperatura, l’umidità e la pressione barometrica.

La versione della SPX-14241 BME280 CCS811 che possiedo è l’originale prodotta dalla Spark-X, in figura, sopra, vedi la nuova versione prodotta ed inserita nel catalogo sparkfun.

Valori rilevati dalla SPX-14241 BME280 CCS811

Unendo le caratteristiche di entrambi i sensori: BME280 + CCS811, la SPX-14241 è in grado di rilevare i seguenti dati ambientali:

  • Total Volatile Organic Compound (TVOC) Range: 0 to 1187 parts-per-billion ( CCS811 )
  • eCO2 Range: 400 to 8192 parts-per-million ( CCS811 )
  • Temp Range: -40C to 85C ( BME280 )
  • Humidity Range: 0 – 100% RH, +/-3% from 20-80% ( BME280 )
  • Pressure Range: 30,000Pa to 110,000Pa, relative accuracy of 12Pa, absolute accuracy of 100Pa ( BME280 )
  • Altitude Range: 0 to 30,000ft (9.2km), relative accuracy of 3.3ft (1m) at sea level, 6.6ft (2m) at 30,000 ft. ( BME280 )

in VERDE i primi due valori, sono rilevati dal CCS811; in ROSSO i secondi 4 dal BME280 a cui ho dedicato un articolo specifico.

In questo articolo leggi come funziona il CCS811 direttamente unito al BME280 con un unico sketch.

Il collegamento della board  SPX-14241

I collegamenti non sono complessi, e sopratutto, sono identici a quelli già visti per il precedente articolo:

SPX-14241 BME280 CCS811Arduino connection spx

sul sensore puoi utilizzare i 4 pin I2C con alimentazione 3,3v ( vedi sinistra in alto nella foto ) e lato arduino:

SPX-14241 Arduino connection leonardo

I pin IIC ( SDA ed SCL ) sono collegati ai pin corrispondenti e l’alimentazione dal lato opposto. ( ATTENZIONE il pin positivo, rosso, è connesso alla 3,3v di arduino leonardo anche se nella foto potrebbe sembrati che sia collegato al RESET ).

Inoltre la scheda, come tutte quelle nate dalla Spark-X, dispone di un connettore detto Qwiic relativamente piccolo e con la volontà di creare uno standard semplificato di connessioni di questo tipo comune ad una linea di prodotto, facilitando la connessione dei sensori con una apposita scheda di interfaccia per Arduino e non solo:

Qwiic connector female SMD

Fonte: sparkfun.com

Puoi leggere i vantaggi di questo connettore in questa pagina dedicata del sito sparkfun.com ( Datasheet ).

Lo sketch del SPX-14241

Lo sketch che leggi, anche in questo caso come per il precedente articolo, si tratta du uno deli esempi forniti con la libreria del produttore della scheda stessa. 

#include <SparkFunBME280.h>
#include <SparkFunCCS811.h>

#define CCS811_ADDR 0x5B //Default I2C Address
//#define CCS811_ADDR 0x5A //Alternate I2C Address

#define PIN_NOT_WAKE 5

//Global sensor objects
CCS811 myCCS811(CCS811_ADDR);
BME280 myBME280;

void setup()
{
  Serial.begin(9600);
  Serial.println();
  Serial.println("Apply BME280 data to CCS811 for compensation.");

  //This begins the CCS811 sensor and prints error status of .begin()
  CCS811Core::status returnCode = myCCS811.begin();
  Serial.print("CCS811 begin exited with: ");
  //Pass the error code to a function to print the results
  printDriverError( returnCode );
  Serial.println();

  //For I2C, enable the following and disable the SPI section
  myBME280.settings.commInterface = I2C_MODE;
  myBME280.settings.I2CAddress = 0x77;

  //Initialize BME280
  //For I2C, enable the following and disable the SPI section
  myBME280.settings.commInterface = I2C_MODE;
  myBME280.settings.I2CAddress = 0x77;
  myBME280.settings.runMode = 3; //Normal mode
  myBME280.settings.tStandby = 0;
  myBME280.settings.filter = 4;
  myBME280.settings.tempOverSample = 5;
  myBME280.settings.pressOverSample = 5;
  myBME280.settings.humidOverSample = 5;

  //Calling .begin() causes the settings to be loaded
  delay(10);  //Make sure sensor had enough time to turn on. 
              //BME280 requires 2ms to start up.
  myBME280.begin();


}
//---------------------------------------------------------------
void loop()
{
  //Check to see if data is available
  if (myCCS811.dataAvailable())
  {
    //Calling this function updates the global tVOC and eCO2 variables
    myCCS811.readAlgorithmResults();
    //printInfoSerial fetches the values of tVOC and eCO2
    printInfoSerial();

    float BMEtempC = myBME280.readTempC();
    float BMEhumid = myBME280.readFloatHumidity();

    Serial.print("Applying new values (deg C, %): ");
    Serial.print(BMEtempC);
    Serial.print(",");
    Serial.println(BMEhumid);
    Serial.println();

    //This sends the temperature data to the CCS811
    myCCS811.setEnvironmentalData(BMEhumid, BMEtempC);
  }
  else if (myCCS811.checkForStatusError())
  {
    //If the CCS811 found an internal error, print it.
    printSensorError();
  }

  delay(2000); //Wait for next reading
}

//---------------------------------------------------------------
void printInfoSerial()
{
  //getCO2() gets the previously read data from the library
  Serial.println("CCS811 data:");
  Serial.print(" CO2 concentration : ");
  Serial.print(myCCS811.getCO2());
  Serial.println(" ppm");

  //getTVOC() gets the previously read data from the library
  Serial.print(" TVOC concentration : ");
  Serial.print(myCCS811.getTVOC());
  Serial.println(" ppb");

  Serial.println("BME280 data:");
  Serial.print(" Temperature: ");
  Serial.print(myBME280.readTempC(), 2);
  Serial.println(" degrees C");

  Serial.print(" Temperature: ");
  Serial.print(myBME280.readTempF(), 2);
  Serial.println(" degrees F");

  Serial.print(" Pressure: ");
  Serial.print(myBME280.readFloatPressure(), 2);
  Serial.println(" Pa");

  Serial.print(" Pressure: ");
  Serial.print((myBME280.readFloatPressure() * 0.0002953), 2);
  Serial.println(" InHg");

  Serial.print(" Altitude: ");
  Serial.print(myBME280.readFloatAltitudeMeters(), 2);
  Serial.println("m");

  Serial.print(" Altitude: ");
  Serial.print(myBME280.readFloatAltitudeFeet(), 2);
  Serial.println("ft");

  Serial.print(" %RH: ");
  Serial.print(myBME280.readFloatHumidity(), 2);
  Serial.println(" %");

  Serial.println();


}

//printDriverError decodes the CCS811Core::status type and prints the
//type of error to the serial terminal.
//
//Save the return value of any function of type CCS811Core::status, 
//then pass to this function to see what the output was.
void printDriverError( CCS811Core::status errorCode )
{
  switch ( errorCode )
  {
    case CCS811Core::SENSOR_SUCCESS:
      Serial.print("SUCCESS");
      break;
    case CCS811Core::SENSOR_ID_ERROR:
      Serial.print("ID_ERROR");
      break;
    case CCS811Core::SENSOR_I2C_ERROR:
      Serial.print("I2C_ERROR");
      break;
    case CCS811Core::SENSOR_INTERNAL_ERROR:
      Serial.print("INTERNAL_ERROR");
      break;
    case CCS811Core::SENSOR_GENERIC_ERROR:
      Serial.print("GENERIC_ERROR");
      break;
    default:
      Serial.print("Unspecified error.");
  }
}

//printSensorError gets, clears, then prints the errors
//saved within the error register.
void printSensorError()
{
  uint8_t error = myCCS811.getErrorRegister();

  if ( error == 0xFF ) //comm error
  {
    Serial.println("Failed to get ERROR_ID register.");
  }
  else
  {
    Serial.print("Error: ");
    if (error & 1 << 5) Serial.print("HeaterSupply");
    if (error & 1 << 4) Serial.print("HeaterFault");
    if (error & 1 << 3) Serial.print("MaxResistance");
    if (error & 1 << 2) Serial.print("MeasModeInvalid");
    if (error & 1 << 1) Serial.print("ReadRegInvalid");
    if (error & 1 << 0) Serial.print("MsgInvalid");
    Serial.println();
  }
}

Eviterò di annoiarti raccontando le parti del codice già descritte nel precedente articolo dedicato alla SPX-14241 BME280 CCS811 per cui passa alle differenti livrerie incluse, la linea 002: include la libreria specifica per il CCS811 in I2C;

linee 004-005: ti servono a definire l’indirizzo i2c su cui è connesso il sensore CCS811 e che come sai, dalla documentazione del produttore, è di default 0x5B;

linea 10: crea l’istanza dell’oggetto CCS811, chiamata myCCS811, che userai per comunicare con il sensore;

linee 19-24: inizializza la comunicazione con il sensore mediante il metodo begin() e salva il valore restituito in returnCode, che passi alla funzione printDriverError() per decodificarlo e scriverlo sul monitor seriale;

linee 026-044: riguardano il sensore BME280 e le puoi leggere nell’articolo ad esso dedicato;

linea 052: controlla che ci siano dati in arrivo dal sensore CCS811;

linea 055: usa il metodo readAlgorithmResults() della libreria del sensore per eseguire un update dei valori relatici a CO2 e tVOC in modo da poter accedere ad un dato aggiornato;

linea 057: richiama la funzione printInfoSerial() che si premurerà di leggere, e scrivere sul monitor seriale, i valori appena aggiornati dal sensore;

linee59-66: leggono dal sensore BME280 la temperatura e l’umidità che userai per compensare i valori del CCS811, motivo per cui la sparkfun ha deciso di mettere entrambi i sensori su una sola board;

linea 069: usa il metodo setEnvironmentalData(BMEhumid, BMEtempC) passando i valori di umidità e temperatura rilavati alle linee precedenti;

linea 071: ogni volta che i dati del sensore CCS811 non sono disponibili richiami il metodo checkForStatusError() per verificare se vi siano errori;

linea 074: richiama la funzione printSensorError() per visualizzare eventuali errori provenienti dal sensore;

linee 081:126: la funzione printInfoSerial() si occupa di scrivere sul monitor seriale tutti i valori letti dai sensori presenti sulla scheda SPX-14241 BME280 CCS81, accedendo ai differenti metodi di lettura delle rispettive librerie;

linee 133-155: la funzione  printDriverError( CCS811Core::status errorCode ) accetta in input il valore errorCode e lo confronta con gli stati: 

  • CCS811Core::SENSOR_SUCCESS
  • CCS811Core::SENSOR_ID_ERROR
  • CCS811Core::SENSOR_I2C_ERROR
  • CCS811Core::SENSOR_INTERNAL_ERROR
  • CCS811Core::SENSOR_GENERIC_ERROR

e scrivendo sul monitor seriale lo stato in cui si trova il driver;

linea 159: definisci la funzione printSensorError() con il chiaro scopo di scrivere sul monitor seriale eventuali errori presenti sulla scheda;

linea 161: legge dal resgistro del CCS811 eventuali errori con il metodo myCCS811.getErrorRegister();

linee 163-177: decodifica il codice di errore in esadecimale ricevuto dal sensore e scrivi il corrispettivo valore a video.

Carica lo sketch sul’Arduino

Dopo aver caricato lo sketch sull’arduino, aprendo il monitor seriale dovresti vedere qualcosa di simile:

SPX-14241 Arduino serial output BMP280 CCS811

Ora sei pronto per realizzare delle stazioni di dati ambientali molto precise.

  • Questo sito ed i suoi contenuti è fornito "così com'è" e Mauro Alfieri non rilascia alcuna dichiarazione o garanzia di alcun tipo, esplicita o implicita, riguardo alla completezza, accuratezza, affidabilità, idoneità o disponibilità del sito o delle informazioni, prodotti, servizi o grafiche correlate contenute sul sito per qualsiasi scopo.
  • Ti chiedo di leggere e rispettare il regolamento del sito prima di utilizzarlo
  • Ti chiedo di leggere i Termini e Condizioni d'uso del sito prima di utilizzarlo
  • In qualità di Affiliato Amazon io ricevo un guadagno dagli acquisti idonei qualora siano presenti link al suddetto sito.

Permalink link a questo articolo: https://www.mauroalfieri.it/elettronica/spx-14241-bme280-ccs811.html

2 commenti

    • Emanuele il 28 Ottobre 2019 alle 16:56
    • Rispondi

    Salve Mauro,
    Ho seguito il tuo tutorial per la lettura dei dati dal sensore ccs811 & BME280, ho notato confrontando i dati con un altro sensore di temperatura che il bme280, rileva i dati di temperatura differenti da quelli reali (circa tre gradi superiore), hai notato anche te questo sbalzo di temperatura?
    Se si come hai risolto?

    1. Ciao Emanuele,
      si ho notato qualche differenza di 1/2 gradi rispetto ad altri sistemi di rilevazione della temperatura e di solito correggo con un offset di taratura.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.