diy/아두이노

voc 측정기(ccs811) 만들기 2

do121 2022. 9. 28. 15:22
#include <SoftwareSerial.h>


#include "SparkFunBME280.h"
BME280 bme280;
#include <Wire.h>

#include "U8glib.h"

//sda - a4
//scl - a5

#include "SparkFunCCS811.h"

//#define CCS811_ADDR 0x5B //Default I2C Address
#define CCS811_ADDR 0x5A //Alternate I2C Address
CCS811 mySensor(CCS811_ADDR);
String drivecode ="";
String sensorcode ="";


U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE);

int error;

float co2, tmp2;
int tvoc;

//temp, humid
float temp, humi, hpa, pa;

void setup() {

  Serial.begin(9600);

  Serial.println("Initialized complete");

//ccs811_spark
 Serial.println("CCS811 Basic Example");

  //It is recommended to check return status on .begin(), but it is not
  //required.
  CCS811Core::status returnCode = mySensor.begin();
  if (returnCode != CCS811Core::SENSOR_SUCCESS)
  {
    Serial.println(".begin() returned with an error.");

  printDriverError( returnCode );
  
    dis_oled2("CCS811 ERROR!","Failed to start","","","");  
    while (1); //Hang if there was a problem.
  }


 dis_oled2("init ... ","","","","");
delay(300);

//sparkfun bme280
  Wire.begin();
  bme280.setI2CAddress(0x76); //Connect to a second sensor
  if (bme280.beginI2C() == false) //Begin communication over I2C
  {
    Serial.println("The sensor did not respond. Please check wiring.");
     dis_oled2("BME280 ERROR!","Failed to start","Check the wiring","","");

    while (1); //Freeze
  }
  else
  {
    dis_oled2("BME280 OK~","","","","");

  }
delay(300);
}

void dis_oled2(String msg1, String msg2, String msg3, String msg4, String msg5) {

  int idx[] = {10, 23, 36, 49, 62};

  String str[5];

  str[0] = msg1;

  str[1] = msg2;

  str[2] = msg3;

  str[3] = msg4;

  str[4] = msg5;

  disp.firstPage();

  do {

    disp.setFont(u8g_font_unifont);

    for (int i = 0; i < 5; i++) {

      disp.setPrintPos(0, idx[i]);

      disp.print(str[i]);

    }

  } while (disp.nextPage());

}

void loop() {

  //ccs811 sparkfun
  //Check to see if data is ready with .dataAvailable()
  if (mySensor.dataAvailable())
  {
    //If so, have the sensor read and calculate the results.
    //Get them later
    mySensor.readAlgorithmResults();

    Serial.print("CO2[");
    //Returns calculated CO2 reading
    co2 = mySensor.getCO2();
    Serial.print(co2);
    Serial.print("] tVOC[");
    //Returns calculated TVOC reading
    tvoc =mySensor.getTVOC();
    Serial.print(tvoc);
    Serial.print("] millis[");
    //Simply the time since program start
    Serial.print(millis());
    Serial.print("]");
    Serial.println();
    tmp2 = mySensor.getTemperature();
  }   else if (mySensor.checkForStatusError())
  {
    //If the CCS811 found an internal error, print it.
      dis_oled2("CCS811 ERROR!","","","","");
    printSensorError();
    while(1);
  }
	//ccs811 sparkfun

    //sparkfun bme280
    Serial.print("Humidity: ");
    humi = bme280.readFloatHumidity();
    Serial.print(humi, 0);

    Serial.print(" Pressure: ");
    pa = bme280.readFloatPressure();
    hpa = pa / 100;
    Serial.print(pa, 0);

    Serial.print(" Alt: ");
    Serial.print(bme280.readFloatAltitudeMeters(), 1);

    Serial.print(" Temp: ");
    temp = bme280.readTempC() - 2; //slightly higher than dht22 about 2 degree
    Serial.print(temp, 2);


    Serial.println();
  
   dis_oled2("tvoc:" + String(tvoc) + " ppb","eco2:" + String(co2),"tmp:" + String(temp) + " *C","humi:" + String(humi),"hpa:" + String(hpa));

  delay(30000); //30s



}



//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:
      drivecode = "SUCCESS"; 
      Serial.print("SUCCESS");
      break;
    case CCS811Core::SENSOR_ID_ERROR:
      drivecode = "ID_ERROR"; 
      Serial.print("ID_ERROR");
      break;
    case CCS811Core::SENSOR_I2C_ERROR:
    drivecode = "I2C_ERROR"; 
      Serial.print("I2C_ERROR");
      break;
    case CCS811Core::SENSOR_INTERNAL_ERROR:
    drivecode = "INTERNAL_ERROR"; 
      Serial.print("INTERNAL_ERROR");
      break;
    case CCS811Core::SENSOR_GENERIC_ERROR:
    drivecode = "GENERIC_ERROR"; 
      Serial.print("GENERIC_ERROR");
      break;
    default:
    drivecode = "Unspecified error."; 
      Serial.print("Unspecified error.");
  }
}

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

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