From 60053a20d10ba75c9797da5ac75d64c83ac5373e Mon Sep 17 00:00:00 2001 From: Graham Jones <grahamjones139@gmail.com> Date: Fri, 5 Jan 2024 19:49:40 +0000 Subject: [PATCH 1/7] Update Bma421 acelerometer driver to return values in milli-g rather than raw counts. --- src/drivers/Bma421.cpp | 19 +++++++++++++++++-- src/drivers/Bma421.h | 5 +++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/drivers/Bma421.cpp b/src/drivers/Bma421.cpp index 84d76ab3c0..3656dc50cf 100644 --- a/src/drivers/Bma421.cpp +++ b/src/drivers/Bma421.cpp @@ -24,6 +24,17 @@ namespace { } } +// Scale factors to convert accelerometer counts to milli-g +// from datasheet: https://files.pine64.org/doc/datasheet/pinetime/BST-BMA421-FL000.pdf +// The array index to use is stored in accel_conf.range +const short Bma421::accelScaleFactors[] = { + 1024, // LSB/g +/- 2g range + 512, // LSB/g +/- 4g range + 256, // LSB/g +/- 8g range + 128 // LSB/g +/- 16g range +}; + + Bma421::Bma421(TwiMaster& twiMaster, uint8_t twiAddress) : twiMaster {twiMaster}, deviceAddress {twiAddress} { bma.intf = BMA4_I2C_INTF; bma.bus_read = user_i2c_read; @@ -74,7 +85,6 @@ void Bma421::Init() { if (ret != BMA4_OK) return; - struct bma4_accel_config accel_conf; accel_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ; accel_conf.range = BMA4_ACCEL_RANGE_2G; accel_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4; @@ -102,8 +112,13 @@ void Bma421::Write(uint8_t registerAddress, const uint8_t* data, size_t size) { Bma421::Values Bma421::Process() { if (not isOk) return {}; + struct bma4_accel rawData; struct bma4_accel data; - bma4_read_accel_xyz(&data, &bma); + bma4_read_accel_xyz(&rawData, &bma); + + data.x = 1000 * rawData.x / accelScaleFactors[accel_conf.range]; + data.y = 1000 * rawData.y / accelScaleFactors[accel_conf.range]; + data.z = 1000 * rawData.z / accelScaleFactors[accel_conf.range]; uint32_t steps = 0; bma423_step_counter_output(&steps, &bma); diff --git a/src/drivers/Bma421.h b/src/drivers/Bma421.h index fb83251449..339a557634 100644 --- a/src/drivers/Bma421.h +++ b/src/drivers/Bma421.h @@ -9,6 +9,10 @@ namespace Pinetime { public: enum class DeviceTypes : uint8_t { Unknown, BMA421, BMA425 }; + // Scale factors to convert accelerometer counts to milli-g + // The array values are initialised in Bma421.cpp + static const short accelScaleFactors[]; + struct Values { uint32_t steps; int16_t x; @@ -41,6 +45,7 @@ namespace Pinetime { TwiMaster& twiMaster; uint8_t deviceAddress = 0x18; struct bma4_dev bma; + struct bma4_accel_config accel_conf; // Store the device configuration for later reference. bool isOk = false; bool isResetOk = false; DeviceTypes deviceType = DeviceTypes::Unknown; From 2eee78264e43f15e63a056ba06fc11d0725acd4f Mon Sep 17 00:00:00 2001 From: Graham Jones <grahamjones139@gmail.com> Date: Fri, 5 Jan 2024 19:50:46 +0000 Subject: [PATCH 2/7] Update Motion screen to display values in milli-g rather than scaled. --- src/displayapp/apps/CMakeLists.txt | 2 +- src/displayapp/screens/Motion.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/displayapp/apps/CMakeLists.txt b/src/displayapp/apps/CMakeLists.txt index ddf95171fb..6778001f5f 100644 --- a/src/displayapp/apps/CMakeLists.txt +++ b/src/displayapp/apps/CMakeLists.txt @@ -1,7 +1,7 @@ if(DEFINED ENABLE_USERAPPS) set(USERAPP_TYPES ${ENABLE_USERAPPS} CACHE STRING "List of user apps to build into the firmware") else () - set(USERAPP_TYPES "Apps::Navigation, Apps::StopWatch, Apps::Alarm, Apps::Timer, Apps::Steps, Apps::HeartRate, Apps::Music, Apps::Paint, Apps::Paddle, Apps::Twos, Apps::Metronome" CACHE STRING "List of user apps to build into the firmware") + set(USERAPP_TYPES "Apps::Navigation, Apps::StopWatch, Apps::Alarm, Apps::Timer, Apps::Steps, Apps::Motion, Apps::HeartRate, Apps::Music, Apps::Paint, Apps::Paddle, Apps::Twos, Apps::Metronome" CACHE STRING "List of user apps to build into the firmware") endif () add_library(infinitime_apps INTERFACE) diff --git a/src/displayapp/screens/Motion.cpp b/src/displayapp/screens/Motion.cpp index 87c55eea9d..ecbed317c7 100644 --- a/src/displayapp/screens/Motion.cpp +++ b/src/displayapp/screens/Motion.cpp @@ -53,9 +53,9 @@ void Motion::Refresh() { lv_label_set_text_fmt(labelStep, "Steps %lu", motionController.NbSteps()); lv_label_set_text_fmt(label, - "X #FF0000 %d# Y #00B000 %d# Z #FFFF00 %d#", - motionController.X() / 0x10, - motionController.Y() / 0x10, - motionController.Z() / 0x10); + "X #FF0000 %d# Y #00B000 %d# Z #FFFF00 %d# mg", + motionController.X(), + motionController.Y(), + motionController.Z()); lv_obj_align(label, nullptr, LV_ALIGN_IN_TOP_MID, 0, 10); } From c261579e954a6647daa89b079b350de3548b39ae Mon Sep 17 00:00:00 2001 From: Graham Jones <grahamjones139@gmail.com> Date: Sun, 7 Jan 2024 16:13:37 +0000 Subject: [PATCH 3/7] Changed output from to 'binary milli-g' (scaled to 1024 rather than 1000) - this means that the values for the default range of +/-2 g are unchanged, and all ranges give something very close to milli-g - see discussion fof pull request #1950 for information. https://github.com/InfiniTimeOrg/InfiniTime/pull/1950 --- src/drivers/Bma421.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/drivers/Bma421.cpp b/src/drivers/Bma421.cpp index 3656dc50cf..89a8bac0c7 100644 --- a/src/drivers/Bma421.cpp +++ b/src/drivers/Bma421.cpp @@ -116,9 +116,13 @@ Bma421::Values Bma421::Process() { struct bma4_accel data; bma4_read_accel_xyz(&rawData, &bma); - data.x = 1000 * rawData.x / accelScaleFactors[accel_conf.range]; - data.y = 1000 * rawData.y / accelScaleFactors[accel_conf.range]; - data.z = 1000 * rawData.z / accelScaleFactors[accel_conf.range]; + // Scale the measured ADC counts to units of 'binary milli-g' + // where 1g = 1024 'binary milli-g' units. + // See https://github.com/InfiniTimeOrg/InfiniTime/pull/1950 for + // discussion of why we opted for scaling to 1024 rather than 1000. + data.x = 1024 * rawData.x / accelScaleFactors[accel_conf.range]; + data.y = 1024 * rawData.y / accelScaleFactors[accel_conf.range]; + data.z = 1024 * rawData.z / accelScaleFactors[accel_conf.range]; uint32_t steps = 0; bma423_step_counter_output(&steps, &bma); From 99cdb8eced124775a12ebe75dcf15748be35c14c Mon Sep 17 00:00:00 2001 From: Graham Jones <grahamjones139@gmail.com> Date: Sun, 7 Jan 2024 22:06:06 +0000 Subject: [PATCH 4/7] Update src/drivers/Bma421.cpp Changes to array declaration as suggested during pull request review. Co-authored-by: FintasticMan <finlay.neon.kid@gmail.com> --- src/drivers/Bma421.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/drivers/Bma421.cpp b/src/drivers/Bma421.cpp index 89a8bac0c7..d640df74a0 100644 --- a/src/drivers/Bma421.cpp +++ b/src/drivers/Bma421.cpp @@ -27,11 +27,11 @@ namespace { // Scale factors to convert accelerometer counts to milli-g // from datasheet: https://files.pine64.org/doc/datasheet/pinetime/BST-BMA421-FL000.pdf // The array index to use is stored in accel_conf.range -const short Bma421::accelScaleFactors[] = { - 1024, // LSB/g +/- 2g range - 512, // LSB/g +/- 4g range - 256, // LSB/g +/- 8g range - 128 // LSB/g +/- 16g range +constexpr int16_t accelScaleFactors[] = { + [BMA4_ACCEL_RANGE_2G] = 1024, // LSB/g +/- 2g range + [BMA4_ACCEL_RANGE_4G] = 512, // LSB/g +/- 4g range + [BMA4_ACCEL_RANGE_8G] = 256, // LSB/g +/- 8g range + [BMA4_ACCEL_RANGE_16G] = 128 // LSB/g +/- 16g range }; From 7f6ea30556da8ecdf5d50ef8eae3865bd8e087df Mon Sep 17 00:00:00 2001 From: Graham Jones <grahamjones139@gmail.com> Date: Mon, 8 Jan 2024 21:22:26 +0000 Subject: [PATCH 5/7] Moved scale factors out of class and into anonymous namespace --- src/drivers/Bma421.cpp | 21 ++++++++++----------- src/drivers/Bma421.h | 4 ---- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/src/drivers/Bma421.cpp b/src/drivers/Bma421.cpp index d640df74a0..eb8831e0b1 100644 --- a/src/drivers/Bma421.cpp +++ b/src/drivers/Bma421.cpp @@ -22,18 +22,17 @@ namespace { void user_delay(uint32_t period_us, void* /*intf_ptr*/) { nrf_delay_us(period_us); } -} - -// Scale factors to convert accelerometer counts to milli-g -// from datasheet: https://files.pine64.org/doc/datasheet/pinetime/BST-BMA421-FL000.pdf -// The array index to use is stored in accel_conf.range -constexpr int16_t accelScaleFactors[] = { - [BMA4_ACCEL_RANGE_2G] = 1024, // LSB/g +/- 2g range - [BMA4_ACCEL_RANGE_4G] = 512, // LSB/g +/- 4g range - [BMA4_ACCEL_RANGE_8G] = 256, // LSB/g +/- 8g range - [BMA4_ACCEL_RANGE_16G] = 128 // LSB/g +/- 16g range -}; + // Scale factors to convert accelerometer counts to milli-g + // from datasheet: https://files.pine64.org/doc/datasheet/pinetime/BST-BMA421-FL000.pdf + // The array index to use is stored in accel_conf.range + constexpr int16_t accelScaleFactors[] = { + [BMA4_ACCEL_RANGE_2G] = 1024, // LSB/g +/- 2g range + [BMA4_ACCEL_RANGE_4G] = 512, // LSB/g +/- 4g range + [BMA4_ACCEL_RANGE_8G] = 256, // LSB/g +/- 8g range + [BMA4_ACCEL_RANGE_16G] = 128 // LSB/g +/- 16g range + }; +} Bma421::Bma421(TwiMaster& twiMaster, uint8_t twiAddress) : twiMaster {twiMaster}, deviceAddress {twiAddress} { bma.intf = BMA4_I2C_INTF; diff --git a/src/drivers/Bma421.h b/src/drivers/Bma421.h index 339a557634..c36350b2af 100644 --- a/src/drivers/Bma421.h +++ b/src/drivers/Bma421.h @@ -9,10 +9,6 @@ namespace Pinetime { public: enum class DeviceTypes : uint8_t { Unknown, BMA421, BMA425 }; - // Scale factors to convert accelerometer counts to milli-g - // The array values are initialised in Bma421.cpp - static const short accelScaleFactors[]; - struct Values { uint32_t steps; int16_t x; From d3f667b1d2650522b74151c3dc91e7dc02cdf0bb Mon Sep 17 00:00:00 2001 From: Graham Jones <grahamjones139@gmail.com> Date: Wed, 10 Jan 2024 11:06:55 +0000 Subject: [PATCH 6/7] Adjusted number of spaces between the end of the code and start of in-line comments to keep the formatter happy --- src/drivers/Bma421.cpp | 8 ++++---- src/drivers/Bma421.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/drivers/Bma421.cpp b/src/drivers/Bma421.cpp index eb8831e0b1..aff62b8df0 100644 --- a/src/drivers/Bma421.cpp +++ b/src/drivers/Bma421.cpp @@ -27,10 +27,10 @@ namespace { // from datasheet: https://files.pine64.org/doc/datasheet/pinetime/BST-BMA421-FL000.pdf // The array index to use is stored in accel_conf.range constexpr int16_t accelScaleFactors[] = { - [BMA4_ACCEL_RANGE_2G] = 1024, // LSB/g +/- 2g range - [BMA4_ACCEL_RANGE_4G] = 512, // LSB/g +/- 4g range - [BMA4_ACCEL_RANGE_8G] = 256, // LSB/g +/- 8g range - [BMA4_ACCEL_RANGE_16G] = 128 // LSB/g +/- 16g range + [BMA4_ACCEL_RANGE_2G] = 1024, // LSB/g +/- 2g range + [BMA4_ACCEL_RANGE_4G] = 512, // LSB/g +/- 4g range + [BMA4_ACCEL_RANGE_8G] = 256, // LSB/g +/- 8g range + [BMA4_ACCEL_RANGE_16G] = 128 // LSB/g +/- 16g range }; } diff --git a/src/drivers/Bma421.h b/src/drivers/Bma421.h index c36350b2af..5269f62b79 100644 --- a/src/drivers/Bma421.h +++ b/src/drivers/Bma421.h @@ -41,7 +41,7 @@ namespace Pinetime { TwiMaster& twiMaster; uint8_t deviceAddress = 0x18; struct bma4_dev bma; - struct bma4_accel_config accel_conf; // Store the device configuration for later reference. + struct bma4_accel_config accel_conf; // Store the device configuration for later reference. bool isOk = false; bool isResetOk = false; DeviceTypes deviceType = DeviceTypes::Unknown; From f5af62f263c7346985ac7d37b55627a8fd3be6cc Mon Sep 17 00:00:00 2001 From: Graham Jones <grahamjones139@gmail.com> Date: Sun, 11 Feb 2024 19:42:31 +0000 Subject: [PATCH 7/7] Updated MotionService documentation to specify the units of the returned values. --- doc/MotionService.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/MotionService.md b/doc/MotionService.md index 429794acb3..58c7e83600 100644 --- a/doc/MotionService.md +++ b/doc/MotionService.md @@ -21,3 +21,5 @@ The current raw motion values. This is a 3 `int16_t` array: - [0] : X - [1] : Y - [2] : Z + +The three motion values are in units of "binary milli-g", where 1g is represented by a value of 1024.