Update knx-bme680.ino

Made Pins and i2cAdress configurable
This commit is contained in:
henfri 2018-11-21 20:46:36 +01:00 committed by GitHub
parent 4f9e518ead
commit ee32cefb42
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,120 +1,125 @@
#include <bsec.h> #include <bsec.h>
#include <knx.h> #include <knx.h>
#define LED_PROG 15 //GPIO15 D8
// declare array of all groupobjects with their sizes in byte #define BUTTONPIN 4 //GPIO 4 D2
GroupObject groupObjects[] #define sda D0 //16 //GPIO16 D0
{ #define scl D5 //14 //GPIO14 D5
GroupObject(2), #define i2cAdress 0x77
GroupObject(2),
GroupObject(2), // declare array of all groupobjects with their sizes in byte
GroupObject(2), GroupObject groupObjects[]
GroupObject(2), {
GroupObject(1), GroupObject(2),
GroupObject(2), GroupObject(2),
GroupObject(2), GroupObject(2),
GroupObject(1), GroupObject(2),
GroupObject(2) GroupObject(2),
} GroupObject(1),
; GroupObject(2),
GroupObject(2),
// create named references for easy access to group objects GroupObject(1),
GroupObject& goRawTemperature = groupObjects[0]; GroupObject(2)
GroupObject& goPressure = groupObjects[1]; }
GroupObject& goRawHumidity = groupObjects[2]; ;
GroupObject& goGasResistance = groupObjects[3];
GroupObject& goIaqEstimate = groupObjects[4]; // create named references for easy access to group objects
GroupObject& goIaqAccurace = groupObjects[5]; GroupObject& goRawTemperature = groupObjects[0];
GroupObject& goTemperature = groupObjects[6]; GroupObject& goPressure = groupObjects[1];
GroupObject& goHumidity = groupObjects[7]; GroupObject& goRawHumidity = groupObjects[2];
GroupObject& goTriggerSample = groupObjects[8]; GroupObject& goGasResistance = groupObjects[3];
GroupObject& goCo2Ppm = groupObjects[9]; GroupObject& goIaqEstimate = groupObjects[4];
GroupObject& goIaqAccurace = groupObjects[5];
#define STATE_SAVE_PERIOD UINT32_C(360 * 60 * 1000) // 360 minutes - 4 times a day GroupObject& goTemperature = groupObjects[6];
GroupObject& goHumidity = groupObjects[7];
// Helper functions declarations GroupObject& goTriggerSample = groupObjects[8];
void checkIaqSensorStatus(void); GroupObject& goCo2Ppm = groupObjects[9];
void errLeds(void);
uint8_t* saveBme680State(uint8_t* buffer); #define STATE_SAVE_PERIOD UINT32_C(360 * 60 * 1000) // 360 minutes - 4 times a day
uint8_t* loadBme680State(uint8_t* buffer);
void triggerCallback(GroupObject& go); // Helper functions declarations
void updateState(); void checkIaqSensorStatus(void);
void errLeds(void);
// from generic_33v_3s_28d uint8_t* saveBme680State(uint8_t* buffer);
const uint8_t bsec_config_iaq[454] = uint8_t* loadBme680State(uint8_t* buffer);
{1,7,4,1,61,0,0,0,0,0,0,0,174,1,0,0,48,0,1,0,137,65,0,63,205,204,204,62,0,0,64,63,205,204,204,62,0,0,225,68,0,168,19,73,64,49,119,76,0,0,0,0,0,80,5,95,0,0,0,0,0,0,0,0,28,0,2,0,0,244,1,225,0,25,0,0,128,64,0,0,32,65,144,1,0,0,112,65,0,0,0,63,16,0,3,0,10,215,163,60,10,215,35,59,10,215,35,59,9,0,5,0,0,0,0,0,1,88,0,9,0,229,208,34,62,0,0,0,0,0,0,0,0,218,27,156,62,225,11,67,64,0,0,160,64,0,0,0,0,0,0,0,0,94,75,72,189,93,254,159,64,66,62,160,191,0,0,0,0,0,0,0,0,33,31,180,190,138,176,97,64,65,241,99,190,0,0,0,0,0,0,0,0,167,121,71,61,165,189,41,192,184,30,189,64,12,0,10,0,0,0,0,0,0,0,0,0,229,0,254,0,2,1,5,48,117,100,0,44,1,112,23,151,7,132,3,197,0,92,4,144,1,64,1,64,1,144,1,48,117,48,117,48,117,48,117,100,0,100,0,100,0,48,117,48,117,48,117,100,0,100,0,48,117,48,117,100,0,100,0,100,0,100,0,48,117,48,117,48,117,100,0,100,0,100,0,48,117,48,117,100,0,100,0,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,112,23,112,23,112,23,112,23,112,23,112,23,112,23,112,23,112,23,112,23,112,23,112,23,112,23,112,23,255,255,255,255,255,255,255,255,220,5,220,5,220,5,255,255,255,255,255,255,220,5,220,5,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,44,1,0,0,0,0,50,91,0,0}; void triggerCallback(GroupObject& go);
void updateState();
// from generic_33v_3s_28d
// Create an object of the class Bsec const uint8_t bsec_config_iaq[454] = {1,7,4,1,61,0,0,0,0,0,0,0,174,1,0,0,48,0,1,0,137,65,0,63,205,204,204,62,0,0,64,63,205,204,204,62,0,0,225,68,0,168,19,73,64,49,119,76,0,0,0,0,0,80,5,95,0,0,0,0,0,0,0,0,28,0,2,0,0,244,1,225,0,25,0,0,128,64,0,0,32,65,144,1,0,0,112,65,0,0,0,63,16,0,3,0,10,215,163,60,10,215,35,59,10,215,35,59,9,0,5,0,0,0,0,0,1,88,0,9,0,229,208,34,62,0,0,0,0,0,0,0,0,218,27,156,62,225,11,67,64,0,0,160,64,0,0,0,0,0,0,0,0,94,75,72,189,93,254,159,64,66,62,160,191,0,0,0,0,0,0,0,0,33,31,180,190,138,176,97,64,65,241,99,190,0,0,0,0,0,0,0,0,167,121,71,61,165,189,41,192,184,30,189,64,12,0,10,0,0,0,0,0,0,0,0,0,229,0,254,0,2,1,5,48,117,100,0,44,1,112,23,151,7,132,3,197,0,92,4,144,1,64,1,64,1,144,1,48,117,48,117,48,117,48,117,100,0,100,0,100,0,48,117,48,117,48,117,100,0,100,0,48,117,48,117,100,0,100,0,100,0,100,0,48,117,48,117,48,117,100,0,100,0,100,0,48,117,48,117,100,0,100,0,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,112,23,112,23,112,23,112,23,112,23,112,23,112,23,112,23,112,23,112,23,112,23,112,23,112,23,112,23,255,255,255,255,255,255,255,255,220,5,220,5,220,5,255,255,255,255,255,255,220,5,220,5,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,44,1,0,0,0,0,50,91,0,0};
Bsec iaqSensor;
uint16_t stateUpdateCounter = 0; // Create an object of the class Bsec
uint8_t sendCounter = 0; Bsec iaqSensor;
uint32_t cyclSend = 0; uint16_t stateUpdateCounter = 0;
bool trigger = false; uint8_t sendCounter = 0;
uint32_t cyclSend = 0;
// Entry point for the example bool trigger = false;
void setup(void)
{ // Entry point for the example
Serial.begin(115200); void setup(void)
delay(5000); {
Serial.println("start"); Serial.begin(115200);
// register group objects delay(5000);
knx.registerGroupObjects(groupObjects, 10); Serial.println("start");
// register group objects
// read adress table, association table, groupobject table and parameters from eeprom knx.registerGroupObjects(groupObjects, 10);
knx.readMemory(); knx.ledPin(LED_PROG);
knx.buttonPin(BUTTONPIN);
// register callback for reset GO
goTriggerSample.updateHandler = triggerCallback; // read adress table, association table, groupobject table and parameters from eeprom
knx.readMemory();
iaqSensor.begin(BME680_I2C_ADDR_SECONDARY, Wire); // register callback for reset GO
checkIaqSensorStatus(); goTriggerSample.updateHandler = triggerCallback;
iaqSensor.setConfig(bsec_config_iaq); Wire.begin(sda, scl); //GPIO SDA und SCL D3,D1 0,2 /D3,D4 funktioniert auch
checkIaqSensorStatus(); iaqSensor.begin(i2cAdress, Wire);
//iaqSensor.begin(BME680_I2C_ADDR_SECONDARY, Wire);
bsec_virtual_sensor_t sensorList[] = { checkIaqSensorStatus();
BSEC_OUTPUT_RAW_TEMPERATURE,
BSEC_OUTPUT_RAW_PRESSURE, iaqSensor.setConfig(bsec_config_iaq);
BSEC_OUTPUT_RAW_HUMIDITY, checkIaqSensorStatus();
BSEC_OUTPUT_RAW_GAS,
BSEC_OUTPUT_IAQ, bsec_virtual_sensor_t sensorList[] = {
BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE, BSEC_OUTPUT_RAW_TEMPERATURE,
BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY, BSEC_OUTPUT_RAW_PRESSURE,
BSEC_OUTPUT_CO2_EQUIVALENT BSEC_OUTPUT_RAW_HUMIDITY,
}; BSEC_OUTPUT_RAW_GAS,
BSEC_OUTPUT_IAQ,
knx.setSaveCallback(saveBme680State); BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE,
knx.setRestoreCallback(loadBme680State); BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY,
BSEC_OUTPUT_CO2_EQUIVALENT
if (knx.configured()) };
{
cyclSend = knx.paramInt(0); knx.setSaveCallback(saveBme680State);
Serial.print("Zykl. send:"); knx.setRestoreCallback(loadBme680State);
Serial.println(cyclSend);
} if (knx.configured())
{
// start the framework. Will get wifi first. cyclSend = knx.paramInt(0);
knx.start(); Serial.print("Zykl. send:");
Serial.println(cyclSend);
iaqSensor.updateSubscription(sensorList, 7, BSEC_SAMPLE_RATE_LP); }
checkIaqSensorStatus();
// start the framework. Will get wifi first.
knx.start();
iaqSensor.updateSubscription(sensorList, 7, BSEC_SAMPLE_RATE_LP);
checkIaqSensorStatus();
String output = "Timestamp [ms], raw temperature [°C], pressure [hPa], raw relative humidity [%], gas [Ohm], IAQ, IAQ accuracy, temperature [°C], relative humidity [%], CO2"; String output = "Timestamp [ms], raw temperature [°C], pressure [hPa], raw relative humidity [%], gas [Ohm], IAQ, IAQ accuracy, temperature [°C], relative humidity [%], CO2";
Serial.println(output); Serial.println(output);
} }
// Function that is looped forever // Function that is looped forever
void loop(void) void loop(void)
{ {
// don't delay here to much. Otherwise you might lose packages or mess up the timing with ETS // don't delay here to much. Otherwise you might lose packages or mess up the timing with ETS
knx.loop(); knx.loop();
// only run the application code if the device was configured with ETS // only run the application code if the device was configured with ETS
if(!knx.configured()) if(!knx.configured())
return; return;
if (iaqSensor.run()) if (iaqSensor.run())
{ {
String output = String(millis()); String output = String(millis());
output += ", " + String(iaqSensor.rawTemperature); output += ", " + String(iaqSensor.rawTemperature);
output += ", " + String(iaqSensor.pressure); output += ", " + String(iaqSensor.pressure);
@ -126,136 +131,136 @@ void loop(void)
output += ", " + String(iaqSensor.humidity); output += ", " + String(iaqSensor.humidity);
output += ", " + String(iaqSensor.co2Equivalent); output += ", " + String(iaqSensor.co2Equivalent);
output += ", " + String(iaqSensor.co2Accuracy); output += ", " + String(iaqSensor.co2Accuracy);
Serial.println(output); Serial.println(output);
updateState(); updateState();
if (sendCounter++ == cyclSend || trigger) if (sendCounter++ == cyclSend || trigger)
{ {
sendCounter = 0; sendCounter = 0;
trigger = false; trigger = false;
goRawTemperature.objectWrite(iaqSensor.rawTemperature); goRawTemperature.objectWrite(iaqSensor.rawTemperature);
goPressure.objectWrite(iaqSensor.pressure); goPressure.objectWrite(iaqSensor.pressure);
goRawHumidity.objectWrite(iaqSensor.rawHumidity); goRawHumidity.objectWrite(iaqSensor.rawHumidity);
goGasResistance.objectWrite(iaqSensor.gasResistance); goGasResistance.objectWrite(iaqSensor.gasResistance);
goIaqEstimate.objectWrite(iaqSensor.iaqEstimate); goIaqEstimate.objectWrite(iaqSensor.iaqEstimate);
goIaqAccurace.objectWrite(iaqSensor.iaqAccuracy); goIaqAccurace.objectWrite(iaqSensor.iaqAccuracy);
goTemperature.objectWrite(iaqSensor.temperature); goTemperature.objectWrite(iaqSensor.temperature);
goHumidity.objectWrite(iaqSensor.humidity); goHumidity.objectWrite(iaqSensor.humidity);
goCo2Ppm.objectWrite(iaqSensor.co2Equivalent); goCo2Ppm.objectWrite(iaqSensor.co2Equivalent);
} }
} }
else { else {
checkIaqSensorStatus(); checkIaqSensorStatus();
} }
} }
// Helper function definitions // Helper function definitions
void checkIaqSensorStatus(void) void checkIaqSensorStatus(void)
{ {
if (iaqSensor.status != BSEC_OK) { if (iaqSensor.status != BSEC_OK) {
if (iaqSensor.status < BSEC_OK) { if (iaqSensor.status < BSEC_OK) {
String output = "BSEC error code : " + String(iaqSensor.status); String output = "BSEC error code : " + String(iaqSensor.status);
Serial.println(output); Serial.println(output);
for (;;) for (;;)
errLeds(); /* Halt in case of failure */ errLeds(); /* Halt in case of failure */
} }
else { else {
String output = "BSEC warning code : " + String(iaqSensor.status); String output = "BSEC warning code : " + String(iaqSensor.status);
Serial.println(output); Serial.println(output);
} }
} }
if (iaqSensor.bme680Status != BME680_OK) { if (iaqSensor.bme680Status != BME680_OK) {
if (iaqSensor.bme680Status < BME680_OK) { if (iaqSensor.bme680Status < BME680_OK) {
String output = "BME680 error code : " + String(iaqSensor.bme680Status); String output = "BME680 error code : " + String(iaqSensor.bme680Status);
Serial.println(output); Serial.println(output);
for (;;) for (;;)
errLeds(); /* Halt in case of failure */ errLeds(); /* Halt in case of failure */
} }
else { else {
String output = "BME680 warning code : " + String(iaqSensor.bme680Status); String output = "BME680 warning code : " + String(iaqSensor.bme680Status);
Serial.println(output); Serial.println(output);
} }
} }
} }
void errLeds(void) void errLeds(void)
{ {
pinMode(LED_BUILTIN, OUTPUT); pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH); digitalWrite(LED_BUILTIN, HIGH);
delay(100); delay(100);
digitalWrite(LED_BUILTIN, LOW); digitalWrite(LED_BUILTIN, LOW);
delay(100); delay(100);
} }
uint8_t* loadBme680State(uint8_t* buffer) uint8_t* loadBme680State(uint8_t* buffer)
{ {
// Existing state in EEPROM // Existing state in EEPROM
Serial.println("Reading state from EEPROM"); Serial.println("Reading state from EEPROM");
for (uint8_t i = 0; i < BSEC_MAX_STATE_BLOB_SIZE; i++) { for (uint8_t i = 0; i < BSEC_MAX_STATE_BLOB_SIZE; i++) {
Serial.println(buffer[i], HEX); Serial.println(buffer[i], HEX);
} }
iaqSensor.setState(buffer); iaqSensor.setState(buffer);
checkIaqSensorStatus(); checkIaqSensorStatus();
return buffer + BSEC_MAX_STATE_BLOB_SIZE; return buffer + BSEC_MAX_STATE_BLOB_SIZE;
} }
uint8_t* saveBme680State(uint8_t* buffer) uint8_t* saveBme680State(uint8_t* buffer)
{ {
iaqSensor.getState(buffer); iaqSensor.getState(buffer);
checkIaqSensorStatus(); checkIaqSensorStatus();
Serial.println("Writing state to EEPROM"); Serial.println("Writing state to EEPROM");
for (uint8_t i = 0; i < BSEC_MAX_STATE_BLOB_SIZE; i++) { for (uint8_t i = 0; i < BSEC_MAX_STATE_BLOB_SIZE; i++) {
Serial.println(buffer[i], HEX); Serial.println(buffer[i], HEX);
} }
return buffer + BSEC_MAX_STATE_BLOB_SIZE; return buffer + BSEC_MAX_STATE_BLOB_SIZE;
} }
void updateState(void) void updateState(void)
{ {
bool update = false; bool update = false;
if (stateUpdateCounter == 0) { if (stateUpdateCounter == 0) {
/* First state update when IAQ accuracy is >= 1 */ /* First state update when IAQ accuracy is >= 1 */
if (iaqSensor.iaqAccuracy >= 3) { if (iaqSensor.iaqAccuracy >= 3) {
update = true; update = true;
stateUpdateCounter++; stateUpdateCounter++;
} }
} }
else { else {
/* Update every STATE_SAVE_PERIOD minutes */ /* Update every STATE_SAVE_PERIOD minutes */
if ((stateUpdateCounter * STATE_SAVE_PERIOD) < millis()) { if ((stateUpdateCounter * STATE_SAVE_PERIOD) < millis()) {
update = true; update = true;
stateUpdateCounter++; stateUpdateCounter++;
} }
} }
if (update) { if (update) {
knx.writeMemory(); knx.writeMemory();
} }
} }
// callback from trigger-GO // callback from trigger-GO
void triggerCallback(GroupObject& go) void triggerCallback(GroupObject& go)
{ {
Serial.println("trigger"); Serial.println("trigger");
Serial.println(go.objectReadBool()); Serial.println(go.objectReadBool());
if (!go.objectReadBool()) if (!go.objectReadBool())
return; return;
trigger = true; trigger = true;
/* We call bsec_update_subscription() in order to instruct BSEC to perform an extra measurement at the next /* We call bsec_update_subscription() in order to instruct BSEC to perform an extra measurement at the next
possible time slot possible time slot
*/ */
Serial.println("Triggering ULP plus."); Serial.println("Triggering ULP plus.");
bsec_virtual_sensor_t sensorList[] = { bsec_virtual_sensor_t sensorList[] = {
BSEC_OUTPUT_IAQ, BSEC_OUTPUT_CO2_EQUIVALENT BSEC_OUTPUT_IAQ, BSEC_OUTPUT_CO2_EQUIVALENT
}; };
iaqSensor.updateSubscription(sensorList, 1, BSEC_SAMPLE_RATE_ULP_MEASUREMENT_ON_DEMAND); iaqSensor.updateSubscription(sensorList, 1, BSEC_SAMPLE_RATE_ULP_MEASUREMENT_ON_DEMAND);
checkIaqSensorStatus(); checkIaqSensorStatus();
} }