diff --git a/examples/knx-esp-bme680/bme680.knxprod b/examples/knx-esp-bme680/bme680.knxprod
new file mode 100644
index 0000000..05f7fbe
Binary files /dev/null and b/examples/knx-esp-bme680/bme680.knxprod differ
diff --git a/examples/knx-esp-bme680/bme680.xml b/examples/knx-esp-bme680/bme680.xml
new file mode 100644
index 0000000..5239f18
--- /dev/null
+++ b/examples/knx-esp-bme680/bme680.xml
@@ -0,0 +1,98 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/knx-esp-bme680/knx-bme680.ino b/examples/knx-esp-bme680/knx-bme680.ino
new file mode 100644
index 0000000..1eee699
--- /dev/null
+++ b/examples/knx-esp-bme680/knx-bme680.ino
@@ -0,0 +1,257 @@
+#include
+#include
+
+// declare array of all groupobjects with their sizes in byte
+GroupObject groupObjects[]
+{
+ GroupObject(2),
+ GroupObject(2),
+ GroupObject(2),
+ GroupObject(2),
+ GroupObject(2),
+ GroupObject(1),
+ GroupObject(2),
+ GroupObject(2),
+ GroupObject(1),
+ GroupObject(2)
+}
+;
+
+// create named references for easy access to group objects
+GroupObject& goRawTemperature = groupObjects[0];
+GroupObject& goPressure = groupObjects[1];
+GroupObject& goRawHumidity = groupObjects[2];
+GroupObject& goGasResistance = groupObjects[3];
+GroupObject& goIaqEstimate = groupObjects[4];
+GroupObject& goIaqAccurace = groupObjects[5];
+GroupObject& goTemperature = groupObjects[6];
+GroupObject& goHumidity = groupObjects[7];
+GroupObject& goTriggerSample = groupObjects[8];
+GroupObject& goCo2Ppm = groupObjects[9];
+
+#define STATE_SAVE_PERIOD UINT32_C(360 * 60 * 1000) // 360 minutes - 4 times a day
+
+// Helper functions declarations
+void checkIaqSensorStatus(void);
+void errLeds(void);
+uint8_t* saveBme680State(uint8_t* buffer);
+uint8_t* loadBme680State(uint8_t* buffer);
+void triggerCallback(GroupObject& go);
+void updateState();
+
+///const uint8_t bsec_config_iaq[304] =
+// { 0, 6, 4, 1, 61, 0, 0, 0, 0, 0, 0, 0, 24, 1, 0, 0, 40, 0, 1, 0, 137, 65, 0, 63, 0, 0, 64, 63, 205, 204, 76, 62, 0, 0, 225, 68, 0, 192, 168, 71, 0, 0, 0, 0, 0, 80, 10, 90, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 2, 0, 0, 244, 1, 225, 0, 25, 10, 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, 51, 0, 9, 0, 10, 215, 163, 59, 205, 204, 204, 61, 225, 122, 148, 62, 41, 92, 15, 61, 0, 0, 0, 63, 0, 0, 0, 63, 154, 153, 89, 63, 154, 153, 25, 62, 1, 1, 0, 0, 128, 63, 6, 236, 81, 184, 61, 51, 51, 131, 64, 12, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 0, 254, 0, 2, 1, 5, 48, 117, 100, 0, 44, 1, 151, 7, 132, 3, 197, 0, 144, 1, 64, 1, 64, 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, 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, 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, 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, 98, 149, 0, 0 };
+const uint8_t bsec_config_iaq[304] =
+ { 0, 6, 4, 1, 61, 0, 0, 0, 0, 0, 0, 0, 24, 1, 0, 0, 40, 0, 1, 0, 137, 65, 0, 63, 0, 0, 64, 63, 205, 204, 76, 62, 0, 0, 225, 68, 0, 168, 19, 73, 0, 0, 0, 0, 0, 80, 10, 90, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 2, 0, 0, 244, 1, 225, 0, 25, 10, 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, 51, 0, 9, 0, 10, 215, 163, 59, 205, 204, 204, 61, 225, 122, 148, 62, 41, 92, 15, 61, 0, 0, 0, 63, 0, 0, 0, 63, 154, 153, 89, 63, 154, 153, 25, 62, 1, 1, 0, 0, 128, 63, 6, 236, 81, 184, 61, 51, 51, 131, 64, 12, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 0, 254, 0, 2, 1, 5, 48, 117, 100, 0, 44, 1, 151, 7, 132, 3, 197, 0, 144, 1, 64, 1, 64, 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, 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, 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, 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, 253, 222, 0, 0 };
+
+
+// Create an object of the class Bsec
+Bsec iaqSensor;
+uint16_t stateUpdateCounter = 0;
+uint8_t sendCounter = 0;
+uint32_t cyclSend = 0;
+bool trigger = false;
+
+// Entry point for the example
+void setup(void)
+{
+ Serial.begin(115200);
+ delay(5000);
+ Serial.println("start");
+ // register group objects
+ knx.registerGroupObjects(groupObjects, 10);
+
+ // read adress table, association table, groupobject table and parameters from eeprom
+ knx.readMemory();
+
+ // register callback for reset GO
+ goTriggerSample.updateHandler = triggerCallback;
+
+
+ iaqSensor.begin(BME680_I2C_ADDR_SECONDARY, Wire);
+ checkIaqSensorStatus();
+
+ iaqSensor.setConfig(bsec_config_iaq);
+ checkIaqSensorStatus();
+
+ bsec_virtual_sensor_t sensorList[7] = {
+ BSEC_OUTPUT_RAW_TEMPERATURE,
+ BSEC_OUTPUT_RAW_PRESSURE,
+ BSEC_OUTPUT_RAW_HUMIDITY,
+ BSEC_OUTPUT_RAW_GAS,
+ BSEC_OUTPUT_IAQ_ESTIMATE,
+ BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE,
+ BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY,
+ };
+
+ knx.setSaveCallback(saveBme680State);
+ knx.setRestoreCallback(loadBme680State);
+
+ if (knx.configured())
+ {
+ cyclSend = knx.paramInt(0);
+ Serial.printf("Zykl. send: %d\n", cyclSend);
+ }
+
+ // 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 [%]";
+ Serial.println(output);
+}
+
+// Function that is looped forever
+void loop(void)
+{
+ // don't delay here to much. Otherwise you might lose packages or mess up the timing with ETS
+ knx.loop();
+
+ // only run the application code if the device was configured with ETS
+ if(!knx.configured())
+ return;
+
+ if (iaqSensor.run())
+ {
+ String output = String(millis());
+ output += ", " + String(iaqSensor.rawTemperature);
+ output += ", " + String(iaqSensor.pressure);
+ output += ", " + String(iaqSensor.rawHumidity);
+ output += ", " + String(iaqSensor.gasResistance);
+ output += ", " + String(iaqSensor.iaqEstimate);
+ output += ", " + String(iaqSensor.iaqAccuracy);
+ output += ", " + String(iaqSensor.temperature);
+ output += ", " + String(iaqSensor.humidity);
+ Serial.println(output);
+ updateState();
+
+ if (sendCounter++ == cyclSend || trigger)
+ {
+ sendCounter = 0;
+ trigger = false;
+
+ goRawTemperature.objectWrite(iaqSensor.rawTemperature);
+ goPressure.objectWrite(iaqSensor.pressure);
+ goRawHumidity.objectWrite(iaqSensor.rawHumidity);
+ goGasResistance.objectWrite(iaqSensor.gasResistance);
+ goIaqEstimate.objectWrite(iaqSensor.iaqEstimate);
+ goIaqAccurace.objectWrite(iaqSensor.iaqAccuracy);
+ goTemperature.objectWrite(iaqSensor.temperature);
+ goHumidity.objectWrite(iaqSensor.humidity);
+ }
+ }
+ else {
+ checkIaqSensorStatus();
+ }
+}
+
+// Helper function definitions
+void checkIaqSensorStatus(void)
+{
+ if (iaqSensor.status != BSEC_OK) {
+ if (iaqSensor.status < BSEC_OK) {
+ String output = "BSEC error code : " + String(iaqSensor.status);
+ Serial.println(output);
+ for (;;)
+ errLeds(); /* Halt in case of failure */
+ }
+ else {
+ String output = "BSEC warning code : " + String(iaqSensor.status);
+ Serial.println(output);
+ }
+ }
+
+ if (iaqSensor.bme680Status != BME680_OK) {
+ if (iaqSensor.bme680Status < BME680_OK) {
+ String output = "BME680 error code : " + String(iaqSensor.bme680Status);
+ Serial.println(output);
+ for (;;)
+ errLeds(); /* Halt in case of failure */
+ }
+ else {
+ String output = "BME680 warning code : " + String(iaqSensor.bme680Status);
+ Serial.println(output);
+ }
+ }
+}
+
+void errLeds(void)
+{
+ pinMode(LED_BUILTIN, OUTPUT);
+ digitalWrite(LED_BUILTIN, HIGH);
+ delay(100);
+ digitalWrite(LED_BUILTIN, LOW);
+ delay(100);
+}
+
+uint8_t* loadBme680State(uint8_t* buffer)
+{
+ // Existing state in EEPROM
+ Serial.println("Reading state from EEPROM");
+
+ for (uint8_t i = 0; i < BSEC_MAX_STATE_BLOB_SIZE; i++) {
+ Serial.println(buffer[i], HEX);
+ }
+
+ iaqSensor.setState(buffer);
+ checkIaqSensorStatus();
+ return buffer + BSEC_MAX_STATE_BLOB_SIZE;
+}
+
+uint8_t* saveBme680State(uint8_t* buffer)
+{
+ iaqSensor.getState(buffer);
+ checkIaqSensorStatus();
+
+ Serial.println("Writing state to EEPROM");
+
+ for (uint8_t i = 0; i < BSEC_MAX_STATE_BLOB_SIZE; i++) {
+ Serial.println(buffer[i], HEX);
+ }
+ return buffer + BSEC_MAX_STATE_BLOB_SIZE;
+}
+
+void updateState(void)
+{
+ bool update = false;
+ if (stateUpdateCounter == 0) {
+ /* First state update when IAQ accuracy is >= 1 */
+ if (iaqSensor.iaqAccuracy >= 3) {
+ update = true;
+ stateUpdateCounter++;
+ }
+ }
+ else {
+ /* Update every STATE_SAVE_PERIOD minutes */
+ if ((stateUpdateCounter * STATE_SAVE_PERIOD) < millis()) {
+ update = true;
+ stateUpdateCounter++;
+ }
+ }
+
+ if (update) {
+ knx.writeMemory();
+ }
+}
+
+// callback from trigger-GO
+void triggerCallback(GroupObject& go)
+{
+ Serial.println("trigger");
+ Serial.println(go.objectReadBool());
+ if (!go.objectReadBool())
+ return;
+
+ trigger = true;
+ /* We call bsec_update_subscription() in order to instruct BSEC to perform an extra measurement at the next
+ possible time slot
+ */
+ Serial.println("Triggering ULP plus.");
+ bsec_virtual_sensor_t sensorList[1] = {
+ BSEC_OUTPUT_IAQ_ESTIMATE,
+ };
+
+ iaqSensor.updateSubscription(sensorList, 1, BSEC_SAMPLE_RATE_ULP_MEASUREMENT_ON_DEMAND);
+ checkIaqSensorStatus();
+}
\ No newline at end of file
diff --git a/visualstudio/knx-bme680.vgdbproj b/visualstudio/knx-bme680.vgdbproj
new file mode 100644
index 0000000..86b5086
--- /dev/null
+++ b/visualstudio/knx-bme680.vgdbproj
@@ -0,0 +1,283 @@
+
+
+ Release
+
+
+
+ Unknown
+
+
+ 58afeecd-06e2-4bb7-a13f-e1d5dbaed13f
+ true
+ true
+ ..\examples\knx-esp-bme680
+ basic_config_state_ulp_plus.ino
+
+
+
+ knx-bme680.ino
+
+
+
+
+
+
+
+ ..
+ ..\..
+
+ Output\$(PlatformName.defuse)\$(ConfigurationName.defuse)
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+ Default
+
+
+
+ COM5
+
+ 115200
+ 8
+ None
+ One
+ None
+
+
+ 0
+ false
+ false
+ true
+ ASCII
+
+
+ 255
+ 0
+ 0
+ 0
+
+
+ 255
+ 169
+ 169
+ 169
+
+
+ 255
+ 211
+ 211
+ 211
+
+
+ 255
+ 144
+ 238
+ 144
+
+
+ 255
+ 169
+ 169
+ 169
+
+
+
+ 16
+ true
+ true
+ true
+ true
+ 0
+
+ LF
+ true
+ true
+ true
+
+
+
+ true
+
+
+
+
+ True
+
+ true
+ true
+
+ Enabled
+ true
+ true
+ true
+
+ true
+
+
+
+ false
+
+ apiModeling.google.GTest
+ core.builtin.BuiltinFunctions
+ core.builtin.NoReturnFunctions
+ core.CallAndMessage
+ core.DivideZero
+ core.DynamicTypePropagation
+ core.NonnilStringConstants
+ core.NonNullParamChecker
+ core.NullDereference
+ core.StackAddressEscape
+ core.UndefinedBinaryOperatorResult
+ core.uninitialized.ArraySubscript
+ core.uninitialized.Assign
+ core.uninitialized.Branch
+ core.uninitialized.CapturedBlockVariable
+ core.uninitialized.UndefReturn
+ core.VLASize
+ cplusplus.NewDelete
+ cplusplus.NewDeleteLeaks
+ cplusplus.SelfAssignment
+ deadcode.DeadStores
+ nullability.NullPassedToNonnull
+ nullability.NullReturnedFromNonnull
+ security.insecureAPI.getpw
+ security.insecureAPI.gets
+ security.insecureAPI.mkstemp
+ security.insecureAPI.mktemp
+ security.insecureAPI.UncheckedReturn
+ security.insecureAPI.vfork
+ unix.API
+ unix.cstring.BadSizeArg
+ unix.cstring.NullArg
+ unix.Malloc
+ unix.MallocSizeof
+ unix.MismatchedDeallocator
+ unix.StdCLibraryFunctions
+ unix.Vfork
+
+
+ -analyzer-store=region
+ -analyzer-opt-analyze-nested-blocks
+ -analyzer-eagerly-assume
+
+
+
+
+
+ NodeMCU 1 0 (ESP-12E Module)
+
+
+
+
+ false
+ false
+ false
+ false
+ false
+ false
+ false
+ false
+ false
+
+ false
+ false
+ false
+ false
+ false
+ false
+ true
+ false
+ None
+ false
+ false
+ main
+ true
+ false
+ false
+ false
+ 0
+
+
+ gdbstub
+
+ 74880
+ 115200
+ 50
+ !DTR;RTS;SLEEP;DTR;!RTS;SLEEP;!DTR;SLEEP
+ Enabled
+ false
+
+ size4M
+ freq40M
+ QIO
+
+
+
+ true
+ Disabled
+ 0
+ false
+ false
+ true
+ false
+ false
+
+ _estack
+ 0
+ false
+ true
+
+
+ esp8266:esp8266:nodemcuv2
+ COM5
+
+
+
+ CpuFrequency
+ 80
+
+
+ VTable
+ flash
+
+
+ FlashSize
+ 4M1M
+
+
+ LwIPVariant
+ v2mss536
+
+
+ Debug
+ Serial
+
+
+ DebugLevel
+ None____
+
+
+ FlashErase
+ none
+
+
+ UploadSpeed
+ 115200
+
+
+
+ Sketch
+
+
+
+
+
\ No newline at end of file