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)