From 6fd06fb97ee705d0d1ac98a00d5c707d27a94249 Mon Sep 17 00:00:00 2001 From: Xiretza <xiretza@xiretza.xyz> Date: Wed, 4 Sep 2019 16:19:34 +0200 Subject: [PATCH] feat(bhi160): Provide magnetometer data --- Documentation/pycardium/bhi160.rst | 26 ++++++++++++++++++++++++++ epicardium/epicardium.h | 25 ++++++++++++++++++++----- epicardium/modules/bhi.c | 11 +++++++++++ epicardium/modules/stream.h | 1 + preload/apps/bhi160/__init__.py | 1 + pycardium/modules/interrupt.c | 2 ++ pycardium/modules/py/bhi160.py | 20 ++++++++++++++++++++ pycardium/modules/qstrdefs.h | 1 + 8 files changed, 82 insertions(+), 5 deletions(-) diff --git a/Documentation/pycardium/bhi160.rst b/Documentation/pycardium/bhi160.rst index 6905f779..3b7faa06 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 74ad1a26..67dcf276 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 711d5fe7..81196141 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 1b4cba07..1327fd7a 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 3632008c..988af937 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 838ef2b3..9e2058e5 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 5d28e1e6..231ba75f 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 0ff0a8ca..3e28a103 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) -- GitLab