Files
lighthub/lighthub/modules/in_ccs811_hdc1080.cpp

233 lines
5.7 KiB
C++

#include "modules/in_ccs811_hdc1080.h"
#include "Arduino.h"
#include "options.h"
#include "Streaming.h"
#if defined(M5STACK)
#include <M5Stack.h>
#endif
#ifndef CSSHDC_DISABLE
static ClosedCube_HDC1080 hdc1080;
static CCS811 ccs811(CCS811_ADDR);
long ccs811Baseline;
static bool HDC1080ready = false;
static bool CCS811ready = false;
int in_ccs811::Setup()
{
if (CCS811ready) {debugSerial<<F("ccs811 is already initialized")<<endl; return 0;}
#ifdef WAK_PIN
pinMode(WAK_PIN,OUTPUT);
digitalWrite(WAK_PIN,LOW);
#endif
Serial.println("CCS811 Init");
Wire.begin(); //Inialize I2C Harware
//It is recommended to check return status on .begin(), but it is not
//required.
CCS811Core::status returnCode = ccs811.begin();
if (returnCode != CCS811Core::SENSOR_SUCCESS)
{
Serial.println("CCS811 Init error");
printDriverError(returnCode);
return 0;
}
//ccs811.setBaseline(62000);
CCS811ready = true;
//returnCode = ccs811.setDriveMode(1);
//printDriverError(returnCode);
/*
delay(2000);Poll();
delay(2000);Poll();
delay(2000);Poll();
delay(2000); */
return 1;
}
int in_hdc1080::Setup()
{
if (HDC1080ready) {debugSerial<<F("hdc1080 is already initialized")<<endl; return 0;}
Serial.println("HDC1080 Init ");
Wire.begin(); //Inialize I2C Harware
// Default settings:
// - Heater off
// - 14 bit Temperature and Humidity Measurement Resolutions
hdc1080.begin(0x40);
Serial.print("Manufacturer ID=0x");
Serial.println(hdc1080.readManufacturerId(), HEX); // 0x5449 ID of Texas Instruments
Serial.print("Device ID=0x");
Serial.println(hdc1080.readDeviceId(), HEX); // 0x1050 ID of the device
printSerialNumber();
HDC1080ready = true;
return 1;
}
void i2cReset(){
Wire.endTransmission(true);
#if defined (ARDUINO_ARCH_ESP8266)
SCL_LOW();
delay(300);
SCL_HIGH();
#endif
}
int in_hdc1080::Poll()
{
float h,t;
int reg;
if (!HDC1080ready) {debugSerial<<F("HDC1080 not initialized")<<endl; return 0;}
Serial.print("HDC Status=");
Serial.println(reg=hdc1080.readRegister().rawData,HEX);
if (reg!=0xff)
{
Serial.print(" T=");
Serial.print(t=hdc1080.readTemperature());
Serial.print("C, RH=");
Serial.print(h=hdc1080.readHumidity());
Serial.println("%");
#ifdef M5STACK
M5.Lcd.print(" T=");
//Returns calculated CO2 reading
M5.Lcd.print(t=hdc1080.readTemperature());
M5.Lcd.print("C, RH=");
//Returns calculated TVOC reading
M5.Lcd.print(h=hdc1080.readHumidity());
M5.Lcd.print("%\n");
#endif
publish(t,"/T");
publish(h,"/H");
if (CCS811ready) ccs811.setEnvironmentalData(h,t);
}
else //ESP I2C glitch
{
Serial.println("I2C Reset");
i2cReset();
}
return 1;
}
int in_ccs811::Poll()
{
if (!CCS811ready) {debugSerial<<F("ccs811 not initialized")<<endl; return 0;}
#ifdef WAK_PIN
digitalWrite(WAK_PIN,LOW);
#endif
delay(1);
//Check to see if data is ready with .dataAvailable()
if (ccs811.dataAvailable())
//if (1)
{
//If so, have the sensor read and calculate the results.
//Get them later
CCS811Core::status returnCode = ccs811.readAlgorithmResults();
printDriverError(returnCode);
float co2,tvoc;
Serial.print(" CO2[");
//Returns calculated CO2 reading
Serial.print(co2 = ccs811.getCO2());
Serial.print("] tVOC[");
//Returns calculated TVOC reading
Serial.print(tvoc = ccs811.getTVOC());
Serial.print("] baseline[");
Serial.print(ccs811Baseline = ccs811.getBaseline());
#ifdef M5STACK
M5.Lcd.print(" CO2[");
//Returns calculated CO2 reading
M5.Lcd.print(co2 = ccs811.getCO2());
M5.Lcd.print("] tVOC[");
//Returns calculated TVOC reading
M5.Lcd.print(tvoc = ccs811.getTVOC());
M5.Lcd.print("]\n");
#endif
publish(co2,"/CO2");
publish(tvoc,"/TVOC");
publish(ccs811Baseline,"/base");
Serial.println("]");
printSensorError();
#ifdef WAK_PIN
digitalWrite(WAK_PIN,HIGH); //Relax some time
#endif
} else {debugSerial<<F("ccs811: data not available")<<endl; return 0;}
return 1;
}
void in_hdc1080::printSerialNumber() {
Serial.print("Device Serial Number=");
HDC1080_SerialNumber sernum = hdc1080.readSerialNumber();
char format[16];
sprintf(format, "%02X-%04X-%04X", sernum.serialFirst, sernum.serialMid, sernum.serialLast);
Serial.println(format);
}
//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 in_ccs811::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 in_ccs811::printSensorError()
{
uint8_t error = ccs811.getErrorRegister();
if ( error == 0xFF ) //comm error
{
Serial.println("Failed to get ERROR_ID register.");
}
else
{
//Serial.print("");
if (error & 1 << 5) Serial.print("Error: HeaterSupply");
if (error & 1 << 4) Serial.print("Error: HeaterFault");
if (error & 1 << 3) Serial.print("Error: MaxResistance");
if (error & 1 << 2) Serial.print("Error: MeasModeInvalid");
if (error & 1 << 1) Serial.print("Error: ReadRegInvalid");
if (error & 1 << 0) Serial.print("Error: MsgInvalid");
Serial.println();
}
}
#endif