diff --git a/Documentation/pycardium/bhi160.rst b/Documentation/pycardium/bhi160.rst
index 6905f779c29d0d92b5a73a0c0020bdeace2c1df1..3b7faa0670947d15ed8790ab2371fa92da263188 100644
--- a/Documentation/pycardium/bhi160.rst
+++ b/Documentation/pycardium/bhi160.rst
@@ -100,3 +100,29 @@ Supports the BHI160 sensor on the card10 for accelerometer, gyroscope...
 
    Close the connection to the sensor
 
+.. class:: bhi160.BHI160Magnetometer
+
+    Magnetometer of the BHI160
+
+    Parameters:
+        sample_rate: int, optional
+            Sample rate (default is 4)
+        dynamic_range: int, optional
+            Dynamic range (default is 1)
+        callback: callable, optional
+            Call this callback when enough data is collected (default is None)
+
+            .. todo:: The callback functionality is untested, so do not be confused if it does not work.
+        sample_buffer_len: int, optional
+            Length of sample buffer (default is 200)
+
+   .. py:method:: read():
+
+   Read sensor values
+
+   :returns: Collected sensor values as list
+
+   .. py:method:: close():
+
+   Close the connection to the sensor
+
diff --git a/epicardium/epicardium.h b/epicardium/epicardium.h
index 74ad1a26d93b7bb95b7f2c80a3767e5c91a75ba3..67dcf2760056e4ac2e6715b522865b403947d654 100644
--- a/epicardium/epicardium.h
+++ b/epicardium/epicardium.h
@@ -188,17 +188,19 @@ API(API_INTERRUPT_DISABLE, int epic_interrupt_disable(api_int_id_t int_id));
 #define EPIC_INT_UART_RX                2
 /** RTC Alarm interrupt.  See :c:func:`epic_isr_rtc_alarm`. */
 #define EPIC_INT_RTC_ALARM              3
-/** BHI180 Accelerometer.  See :c:func:`epic_isr_bhi160_accelerometer`. */
+/** BHI160 Accelerometer.  See :c:func:`epic_isr_bhi160_accelerometer`. */
 #define EPIC_INT_BHI160_ACCELEROMETER   4
-/** BHI180 Orientation Sensor.  See :c:func:`epic_isr_bhi160_orientation`. */
+/** BHI160 Orientation Sensor.  See :c:func:`epic_isr_bhi160_orientation`. */
 #define EPIC_INT_BHI160_ORIENTATION     5
-/** BHI180 Gyroscope.  See :c:func:`epic_isr_bhi160_gyroscope`. */
+/** BHI160 Gyroscope.  See :c:func:`epic_isr_bhi160_gyroscope`. */
 #define EPIC_INT_BHI160_GYROSCOPE       6
 /** MAX30001 ECG.  See :c:func:`epic_isr_max30001_ecg`. */
 #define EPIC_INT_MAX30001_ECG           7
+/** BHI160 Magnetometer.  See :c:func:`epic_isr_bhi160_magnetometer`. */
+#define EPIC_INT_BHI160_MAGNETOMETER    8
 
 /* Number of defined interrupts. */
-#define EPIC_INT_NUM                    8
+#define EPIC_INT_NUM                    9
 /* clang-format on */
 
 /*
@@ -1045,7 +1047,12 @@ enum bhi160_sensor_type {
 	 * - Dynamic range: g's (1x Earth Gravity, ~9.81m*s^-2)
 	 */
 	BHI160_ACCELEROMETER               = 0,
-	/** Magnetometer (**Unimplemented**) */
+	/**
+	 * Magnetometer
+	 *
+	 * - Data type: :c:type:`bhi160_data_vector`
+	 * - Dynamic range: -1000 to 1000 microtesla
+	 */
 	BHI160_MAGNETOMETER                = 1,
 	/** Orientation */
 	BHI160_ORIENTATION                 = 2,
@@ -1177,6 +1184,14 @@ API(API_BHI160_DISABLE_ALL, void epic_bhi160_disable_all_sensors());
  */
 API_ISR(EPIC_INT_BHI160_ACCELEROMETER, epic_isr_bhi160_accelerometer);
 
+/**
+ * **Interrupt Service Routine** for :c:data:`EPIC_INT_BHI160_MAGNETOMETER`
+ *
+ * :c:func:`epic_isr_bhi160_magnetometer` is called whenever the BHI160
+ * magnetometer has new data available.
+ */
+API_ISR(EPIC_INT_BHI160_MAGNETOMETER, epic_isr_bhi160_magnetometer);
+
 /**
  * **Interrupt Service Routine** for :c:data:`EPIC_INT_BHI160_ORIENTATION`
  *
diff --git a/epicardium/modules/bhi.c b/epicardium/modules/bhi.c
index 711d5fe7fcb9ed3fe64a6a848f25c66cfa3cf993..811961413cbc9a5c2edd8ee044e71e11a0d32986 100644
--- a/epicardium/modules/bhi.c
+++ b/epicardium/modules/bhi.c
@@ -91,6 +91,8 @@ static bhy_virtual_sensor_t bhi160_lookup_vs_id(enum bhi160_sensor_type type)
 	switch (type) {
 	case BHI160_ACCELEROMETER:
 		return VS_ID_ACCELEROMETER;
+	case BHI160_MAGNETOMETER:
+		return VS_ID_MAGNETOMETER;
 	case BHI160_ORIENTATION:
 		return VS_ID_ORIENTATION;
 	case BHI160_GYROSCOPE:
@@ -108,6 +110,8 @@ static int bhi160_lookup_sd(enum bhi160_sensor_type type)
 	switch (type) {
 	case BHI160_ACCELEROMETER:
 		return SD_BHI160_ACCELEROMETER;
+	case BHI160_MAGNETOMETER:
+		return SD_BHI160_MAGNETOMETER;
 	case BHI160_ORIENTATION:
 		return SD_BHI160_ORIENTATION;
 	case BHI160_GYROSCOPE:
@@ -267,11 +271,13 @@ bhi160_handle_packet(bhy_data_type_t data_type, bhy_data_generic_t *sensor_data)
 			    sensor_data->data_scalar_u16.data;
 		break;
 	case VS_ID_ACCELEROMETER_WAKEUP:
+	case VS_ID_MAGNETOMETER_WAKEUP:
 	case VS_ID_ORIENTATION_WAKEUP:
 	case VS_ID_GYROSCOPE_WAKEUP:
 		wakeup = true;
 		/* fall through */
 	case VS_ID_ACCELEROMETER:
+	case VS_ID_MAGNETOMETER:
 	case VS_ID_ORIENTATION:
 	case VS_ID_GYROSCOPE:
 		switch (sensor_id) {
@@ -280,6 +286,11 @@ bhi160_handle_packet(bhy_data_type_t data_type, bhy_data_generic_t *sensor_data)
 			sensor_type = BHI160_ACCELEROMETER;
 			epic_int    = EPIC_INT_BHI160_ACCELEROMETER;
 			break;
+		case VS_ID_MAGNETOMETER_WAKEUP:
+		case VS_ID_MAGNETOMETER:
+			sensor_type = BHI160_MAGNETOMETER;
+			epic_int    = EPIC_INT_BHI160_MAGNETOMETER;
+			break;
 		case VS_ID_ORIENTATION_WAKEUP:
 		case VS_ID_ORIENTATION:
 			sensor_type = BHI160_ORIENTATION;
diff --git a/epicardium/modules/stream.h b/epicardium/modules/stream.h
index 1b4cba074035c6b8d6e276f9b01b5c0fecbe19f3..1327fd7a0352d5f7189b0b5c5cdcb6d325bb31f9 100644
--- a/epicardium/modules/stream.h
+++ b/epicardium/modules/stream.h
@@ -27,6 +27,7 @@ typedef unsigned int size_t;
 enum stream_descriptor {
 	/** BHI160 */
 	SD_BHI160_ACCELEROMETER,
+	SD_BHI160_MAGNETOMETER,
 	SD_BHI160_ORIENTATION,
 	SD_BHI160_GYROSCOPE,
 	SD_MAX30001_ECG,
diff --git a/preload/apps/bhi160/__init__.py b/preload/apps/bhi160/__init__.py
index 3632008c0375fe10d40c24096c56600be7f6c4dc..988af93764d04ec35108da50b3dd73cb52541115 100644
--- a/preload/apps/bhi160/__init__.py
+++ b/preload/apps/bhi160/__init__.py
@@ -10,6 +10,7 @@ sensors = [
     {"sensor": bhi160.BHI160Orientation(), "name": "Orientation"},
     {"sensor": bhi160.BHI160Accelerometer(), "name": "Accelerometer"},
     {"sensor": bhi160.BHI160Gyroscope(), "name": "Gyroscope"},
+    {"sensor": bhi160.BHI160Magnetometer(), "name": "Magnetometer"},
 ]
 
 while True:
diff --git a/pycardium/modules/interrupt.c b/pycardium/modules/interrupt.c
index 838ef2b3a397887221041804a0477a5d1cfdbce5..9e2058e591c85333058976f667c88e5450635b4f 100644
--- a/pycardium/modules/interrupt.c
+++ b/pycardium/modules/interrupt.c
@@ -87,6 +87,8 @@ static const mp_rom_map_elem_t interrupt_module_globals_table[] = {
 	  MP_OBJ_NEW_SMALL_INT(EPIC_INT_RTC_ALARM) },
 	{ MP_ROM_QSTR(MP_QSTR_BHI160_ACCELEROMETER),
 	  MP_OBJ_NEW_SMALL_INT(EPIC_INT_BHI160_ACCELEROMETER) },
+	{ MP_ROM_QSTR(MP_QSTR_BHI160_MAGNETOMETER),
+	  MP_OBJ_NEW_SMALL_INT(EPIC_INT_BHI160_MAGNETOMETER) },
 	{ MP_ROM_QSTR(MP_QSTR_BHI160_ORIENTATION),
 	  MP_OBJ_NEW_SMALL_INT(EPIC_INT_BHI160_ORIENTATION) },
 	{ MP_ROM_QSTR(MP_QSTR_BHI160_GYROSCOPE),
diff --git a/pycardium/modules/py/bhi160.py b/pycardium/modules/py/bhi160.py
index 5d28e1e61dfbb913c3ee4dfdc00064fc4bb1342a..231ba75ffbeac6379d694d000c3dd30bad7a8364 100644
--- a/pycardium/modules/py/bhi160.py
+++ b/pycardium/modules/py/bhi160.py
@@ -127,3 +127,23 @@ class BHI160Orientation(BHI160):
 
     def convert(self, sample):
         return self.convert_data_vector(sample)
+
+
+class BHI160Magnetometer(BHI160):
+    def __init__(
+        self, sample_rate=4, dynamic_range=1, callback=None, sample_buffer_len=200
+    ):
+        self.sample_rate = sample_rate
+        self.dynamic_range = dynamic_range
+        self.callback = callback
+        self.sample_buffer_len = sample_buffer_len
+        self.sensor_id = 1
+        self.interrupt_id = interrupt.BHI160_MAGNETOMETER
+        self._callback = callback
+        self.enable_sensor()
+
+    def convert_single(self, value):
+        return 1000 * value / 32768.0
+
+    def convert(self, sample):
+        return self.convert_data_vector(sample)
diff --git a/pycardium/modules/qstrdefs.h b/pycardium/modules/qstrdefs.h
index 0ff0a8caac12fff03bcdb18b781a091a5784e98e..3e28a1034714a2555c6ddba7a82290506ecef437 100644
--- a/pycardium/modules/qstrdefs.h
+++ b/pycardium/modules/qstrdefs.h
@@ -61,6 +61,7 @@ Q(set_callback)
 Q(enable_callback)
 Q(disable_callback)
 Q(BHI160_ACCELEROMETER)
+Q(BHI160_MAGNETOMETER)
 Q(BHI160_ORIENTATION)
 Q(BHI160_GYROSCOPE)
 Q(RTC_ALARM)