diff --git a/epicardium/epicardium.h b/epicardium/epicardium.h
index 87b24e8975dff763119aa4ffe6ce336e1cb75212..a1921400cc5962dec6674449d03ead467dac1255 100644
--- a/epicardium/epicardium.h
+++ b/epicardium/epicardium.h
@@ -106,6 +106,8 @@ typedef _Bool bool;
 #define API_PERSONAL_STATE_GET     0xc1
 #define API_PERSONAL_STATE_IS_PERSISTENT 0xc2
 
+#define API_BME_GET_DATA					 0xD0
+
 /* clang-format on */
 
 typedef uint32_t api_int_id_t;
@@ -662,6 +664,41 @@ API(API_LEDS_SET_GAMMA_TABLE, void epic_leds_set_gamma_table(
  */
 API(API_LEDS_CLEAR_ALL, void epic_leds_clear_all(uint8_t r, uint8_t g, uint8_t b));
 
+/**
+ * BME680
+ * ======
+ */
+
+/**
+ * BME680 Sensor Data
+ */
+struct bme_sensor_data {
+	/*! Temperature in degree celsius */
+	float temperature;
+	/*! Pressure in Pascal */
+	float pressure;
+	/*! Humidity in % relative humidity x1000 */
+	float humidity;
+	/*! Gas resistance in Ohms */
+	float gas_resistance;
+};
+
+/**
+ * Get the current BME680 data.
+ *
+ * :param data: Where to store the environmental data.
+ * :return: 0 on success or ``-Exxx`` on error.  The following
+ *     errors might occur:
+ *
+ *     - ``-EFAULT``:  On NULL-pointer.
+ *     - ``-EINVAL``:  Invalid configuration.
+ *     - ``-EIO``:  Communication with the device failed.
+ *     - ``-ENODEV``:  Device was not found.
+ */
+API(API_BME_GET_DATA, int epic_bme_get_data(struct bme_sensor_data *data));
+
+
+
 /**
  * Personal State
  * ==============
diff --git a/epicardium/modules/bme680.c b/epicardium/modules/bme680.c
new file mode 100644
index 0000000000000000000000000000000000000000..1d0b01d7caa60de97f119e810e8316c344dc6727
--- /dev/null
+++ b/epicardium/modules/bme680.c
@@ -0,0 +1,120 @@
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdio.h>
+
+#include "bme680.h"
+#include "bosch.h"
+#include "card10.h"
+
+#include "epicardium.h"
+
+#define HEATR_DUR	2000
+#define N_MEAS		6
+#define LOW_TEMP	150
+#define HIGH_TEMP 	350
+
+static bool initialized;
+static struct bme680_dev bme;
+
+static int convert_error(int8_t error)
+{
+	switch (error) {
+	case BME680_E_NULL_PTR:
+		return EFAULT;
+	case BME680_E_COM_FAIL:
+		return EIO;
+	case BME680_E_DEV_NOT_FOUND:
+		return ENODEV;
+	case BME680_E_INVALID_LENGTH:
+		return EINVAL;
+	default:
+		return 1;
+	}
+}
+
+int epic_bme_get_data(struct bme_sensor_data *data)
+{
+	int8_t result = BME680_OK;
+  uint16_t settings_sel;
+
+	if (__builtin_expect(!initialized, 0)) {
+    /*
+		bma.intf_ptr = NULL;
+		bma.delay_ms = card10_bosch_delay;
+		bma.dev_id   = BMA400_I2C_ADDRESS_SDO_LOW;
+		bma.read     = card10_bosch_i2c_read_ex;
+		bma.write    = card10_bosch_i2c_write_ex;
+		bma.intf     = BMA400_I2C_INTF;
+  */
+		result = bme680_init(&bme);
+		if (result != BME680_OK) {
+			printf("bme680_init error: %d\n", result);
+			return -convert_error(result);
+		}    
+
+    /* Select the power mode */
+		/* Must be set before writing the sensor configuration */
+    bme.power_mode = BME680_FORCED_MODE;
+
+		/* Set the temperature, pressure and humidity & filter settings */
+		bme.tph_sett.os_hum = BME680_OS_1X;
+		bme.tph_sett.os_pres = BME680_OS_16X;
+		bme.tph_sett.os_temp = BME680_OS_2X;
+
+    /* Set the remaining gas sensor settings and link the heating profile */
+		bme.gas_sett.run_gas = BME680_ENABLE_GAS_MEAS;
+		bme.gas_sett.heatr_dur = HEATR_DUR;
+
+    settings_sel = BME680_OST_SEL | BME680_OSP_SEL | BME680_OSH_SEL | BME680_GAS_SENSOR_SEL;
+
+		initialized = true;
+	}
+
+  struct bme680_field_data raw_data[N_MEAS];
+
+	uint16_t profile_dur = 0;
+	bme680_get_profile_dur(&profile_dur, &bme);
+
+  uint8_t i = 0;
+  while ((result == BME680_OK) && (i < N_MEAS)) {
+    if (result == BME680_OK) {
+
+      if (i % 2 == 0)
+        bme.gas_sett.heatr_temp = HIGH_TEMP; /* Higher temperature */
+      else
+        bme.gas_sett.heatr_temp = LOW_TEMP; /* Lower temperature */
+
+      result = bme680_set_sensor_settings(settings_sel, &bme);
+      if (result != BME680_OK) {
+        printf("bme680_set_sensor_settings error: %d\n", result);
+        return -convert_error(result);
+      }
+
+      if (result == BME680_OK) {
+
+        result = bme680_set_sensor_mode(&bme); /* Trigger a measurement */
+        if (result != BME680_OK) {
+          printf("bme680_set_sensor_mode error: %d\n", result);
+          return -convert_error(result);
+        }
+
+        bme.delay_ms(profile_dur); /* Wait for the measurement to complete */
+
+        result = bme680_get_sensor_data(&raw_data[i], &bme);
+        if (result != BME680_OK) {
+          printf("bme680_get_sensor_data error: %d\n", result);
+          return -convert_error(result);
+        }
+      }
+    }
+
+    i++;
+  }
+
+  data->temperature = raw_data[0].temperature;
+  data->humidity = raw_data[0].humidity;
+  data->pressure = raw_data[0].pressure;
+  data->gas_resistance = raw_data[0].gas_resistance;
+
+	return 0;
+}
diff --git a/epicardium/modules/meson.build b/epicardium/modules/meson.build
index 5b4199b1739de26ef4a633397e0aa80dabd42c5d..dc2318359ecafaae8b78566b4ec87ecf891af44b 100644
--- a/epicardium/modules/meson.build
+++ b/epicardium/modules/meson.build
@@ -1,4 +1,5 @@
 module_sources = files(
+  'bme680.c',
   'buttons.c',
   'dispatcher.c',
   'display.c',
diff --git a/pycardium/meson.build b/pycardium/meson.build
index 40fabde700ce03eff4d117b7e5e87c024b5f35f5..f0a3798a6ab5ef5538673a98f6de9748e705f3b7 100644
--- a/pycardium/meson.build
+++ b/pycardium/meson.build
@@ -13,6 +13,7 @@ modsrc = files(
   'modules/sys_display.c',
   'modules/utime.c',
   'modules/vibra.c',
+  'modules/bme680.c'
 )
 
 #################################
diff --git a/pycardium/modules/bme680.c b/pycardium/modules/bme680.c
new file mode 100644
index 0000000000000000000000000000000000000000..3c781f353c3a78577b700eccbfb32eccdba5b55f
--- /dev/null
+++ b/pycardium/modules/bme680.c
@@ -0,0 +1,37 @@
+#include "py/obj.h"
+#include "py/objlist.h"
+#include "py/runtime.h"
+
+#include "epicardium.h"
+
+static mp_obj_t mp_bme_get_data()
+{
+  struct bme_sensor_data data;
+  int ret = epic_bme_get_data(&data);
+
+	if (ret < 0) {
+		mp_raise_OSError(-ret);
+	}
+
+	mp_obj_t values_list[] = {
+		mp_obj_new_float(data.temperature),
+		mp_obj_new_float(data.humidity),
+		mp_obj_new_float(data.pressure),
+	};
+	return mp_obj_new_tuple(3, values_list);
+}
+static MP_DEFINE_CONST_FUN_OBJ_0(bme_get_bme_data_obj, mp_bme_get_data);
+
+static const mp_rom_map_elem_t bme_module_globals_table[] = {
+	{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_bme680) },
+	{ MP_ROM_QSTR(MP_QSTR_get_bme_data), MP_ROM_PTR(&bme_get_bme_data_obj) },
+};
+static MP_DEFINE_CONST_DICT(bme_module_globals, bme_module_globals_table);
+
+const mp_obj_module_t bme_module = {
+	.base    = { &mp_type_module },
+	.globals = (mp_obj_dict_t *)&bme_module_globals,
+};
+
+/* Register the module to make it available in Python */
+MP_REGISTER_MODULE(MP_QSTR_bme680, bme_module, MODULE_BME_ENABLED);
\ No newline at end of file
diff --git a/pycardium/modules/qstrdefs.h b/pycardium/modules/qstrdefs.h
index 9e3f3979af79ebbfb16f821b7127424cadb563ff..46e9cf54536737f6cfe3c07c65f6624d2f7e00dd 100644
--- a/pycardium/modules/qstrdefs.h
+++ b/pycardium/modules/qstrdefs.h
@@ -74,6 +74,10 @@ Q(start)
 Q(get_reading)
 Q(stop)
 
+/* bme680 */
+Q(bme680)
+Q(get_bme_data)
+
 /* file */
 Q(__del__)
 Q(__enter__)
diff --git a/pycardium/mpconfigport.h b/pycardium/mpconfigport.h
index a1c88a7476f0b63111a4e6049aaac33f32b7fa0c..db2000b3b9c009f0d5b12beb7deec0090bb28c8b 100644
--- a/pycardium/mpconfigport.h
+++ b/pycardium/mpconfigport.h
@@ -55,6 +55,7 @@ int mp_hal_trng_read_int(void);
 #define MODULE_PERSONAL_STATE_ENABLED       (1)
 #define MODULE_UTIME_ENABLED                (1)
 #define MODULE_VIBRA_ENABLED                (1)
+#define MODULE_BME680_ENABLED               (1)
 
 /*
  * This port is intended to be 32-bit, but unfortunately, int32_t for