diff --git a/epicardium/epicardium.h b/epicardium/epicardium.h
index 0687f9d22a3a3640cfeabd1dabcb11f224d01cb6..d2565cd75621932a5cb27befd2c3e1e1f423acb1 100644
--- a/epicardium/epicardium.h
+++ b/epicardium/epicardium.h
@@ -157,11 +157,13 @@ API(API_INTERRUPT_DISABLE, int epic_interrupt_disable(api_int_id_t int_id));
 /** BHI */
 #define EPIC_INT_BHI160_ACCELEROMETER   4
 API_ISR(EPIC_INT_BHI160_ACCELEROMETER, epic_isr_bhi160_accelerometer);
-#define EPIC_INT_BHI160_GYROSCOPE       5
+#define EPIC_INT_BHI160_ORIENTATION     5
+API_ISR(EPIC_INT_BHI160_ORIENTATION, epic_isr_bhi160_orientation);
+#define EPIC_INT_BHI160_GYROSCOPE       6
 API_ISR(EPIC_INT_BHI160_GYROSCOPE, epic_isr_bhi160_gyroscope);
 
 /* Number of defined interrupts. */
-#define EPIC_INT_NUM                    6
+#define EPIC_INT_NUM                    7
 /* clang-format on */
 
 /*
@@ -923,7 +925,7 @@ enum bhi160_sensor_type {
 	BHI160_ACCELEROMETER               = 0,
 	/** Magnetometer (**Unimplemented**) */
 	BHI160_MAGNETOMETER                = 1,
-	/** Orientation (**Unimplemented**) */
+	/** Orientation */
 	BHI160_ORIENTATION                 = 2,
 	/** Gyroscope */
 	BHI160_GYROSCOPE                   = 3,
diff --git a/epicardium/modules/bhi.c b/epicardium/modules/bhi.c
index 461039e352621f31a525db65bcd28a353f86dacb..bacb88ae0fb55f889f2f4cc168fd8d71a886f2bc 100644
--- a/epicardium/modules/bhi.c
+++ b/epicardium/modules/bhi.c
@@ -88,6 +88,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_ORIENTATION:
+		return VS_ID_ORIENTATION;
 	case BHI160_GYROSCOPE:
 		return VS_ID_GYROSCOPE;
 	default:
@@ -103,6 +105,8 @@ static int bhi160_lookup_sd(enum bhi160_sensor_type type)
 	switch (type) {
 	case BHI160_ACCELEROMETER:
 		return SD_BHI160_ACCELEROMETER;
+	case BHI160_ORIENTATION:
+		return SD_BHI160_ORIENTATION;
 	case BHI160_GYROSCOPE:
 		return SD_BHI160_GYROSCOPE;
 	default:
@@ -237,10 +241,12 @@ 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_ORIENTATION_WAKEUP:
 	case VS_ID_GYROSCOPE_WAKEUP:
 		wakeup = true;
 		/* fall through */
 	case VS_ID_ACCELEROMETER:
+	case VS_ID_ORIENTATION:
 	case VS_ID_GYROSCOPE:
 		switch (sensor_id) {
 		case VS_ID_ACCELEROMETER_WAKEUP:
@@ -248,6 +254,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_ORIENTATION_WAKEUP:
+		case VS_ID_ORIENTATION:
+			sensor_type = BHI160_ORIENTATION;
+			epic_int    = EPIC_INT_BHI160_ORIENTATION;
+			break;
 		case VS_ID_GYROSCOPE_WAKEUP:
 		case VS_ID_GYROSCOPE:
 			sensor_type = BHI160_GYROSCOPE;
diff --git a/epicardium/modules/stream.h b/epicardium/modules/stream.h
index 668f786230f8353e47ad9ea55393e98c1cd3e0b9..41064bd5d716bc340721bd7b36267d7a648ec45f 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_ORIENTATION,
 	SD_BHI160_GYROSCOPE,
 	/** Highest descriptor must always be ``SD_MAX``. */
 	SD_MAX,
diff --git a/pycardium/modules/interrupt.c b/pycardium/modules/interrupt.c
index 087facf7b9eea7976965ff419a19b812317b7231..927b936b906a8a7a8a952d12bf9940ab76ce8eff 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_ORIENTATION),
+	  MP_OBJ_NEW_SMALL_INT(EPIC_INT_BHI160_ORIENTATION) },
 	{ MP_ROM_QSTR(MP_QSTR_BHI160_GYROSCOPE),
 	  MP_OBJ_NEW_SMALL_INT(EPIC_INT_BHI160_GYROSCOPE) },
 };
diff --git a/pycardium/modules/py/bhi160.py b/pycardium/modules/py/bhi160.py
index 7d318581e34f35f43839b885cef7f5d5ca72f4a3..afd0fdba5f81457a89cae71d14e13e74cf8c2e9a 100644
--- a/pycardium/modules/py/bhi160.py
+++ b/pycardium/modules/py/bhi160.py
@@ -96,3 +96,29 @@ class BHI160Gyroscope(BHI160):
                 "z": self.convert_single(sample[2]),
             }
         )
+
+
+class BHI160Orientation(BHI160):
+    def __init__(
+        self, sample_rate=4, dynamic_range=2, 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 = 2
+        self.interrupt_id = interrupt.BHI160_ORIENTATION
+        self._callback = callback
+        self.enable_sensor()
+
+    def convert_single(self, value):
+        return 360 * value / 32768.0
+
+    def convert(self, sample):
+        return dict(
+            {
+                "x": self.convert_single(sample[0]),
+                "y": self.convert_single(sample[1]),
+                "z": self.convert_single(sample[2]),
+            }
+        )
diff --git a/pycardium/modules/qstrdefs.h b/pycardium/modules/qstrdefs.h
index 779785425e51b089cfd1d84aa5cc4371b72cfc65..d6e4efa12172392d188b3a9e3c44cbb57b1a336b 100644
--- a/pycardium/modules/qstrdefs.h
+++ b/pycardium/modules/qstrdefs.h
@@ -58,6 +58,7 @@ Q(set_callback)
 Q(enable_callback)
 Q(disable_callback)
 Q(BHI160_ACCELEROMETER)
+Q(BHI160_ORIENTATION)
 Q(BHI160_GYROSCOPE)
 Q(RTC_ALARM)