From 9adeea17bbdd4820363b225b8528acd9fd34a5c1 Mon Sep 17 00:00:00 2001 From: Francesco Gazzetta Date: Fri, 27 May 2022 23:45:23 +0200 Subject: [PATCH] Allow to set accel sensor orientation Signed-off-by: Francesco Gazzetta --- apps/Level.py | 16 +++++++++------- wasp/drivers/bma421.py | 24 ++++++++++++++++++++++-- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/apps/Level.py b/apps/Level.py index 11723a5..302d21d 100644 --- a/apps/Level.py +++ b/apps/Level.py @@ -77,17 +77,19 @@ class LevelApp(): def _update(self): if not self.prompt: draw = wasp.watch.drawable + # Clear the old bubble draw.fill(None, self.old_xy[0] - 3 + _X_CENTER, self.old_xy[1] - 3 + _Y_CENTER, 6, 6) # draw guide lines draw.line(0, _Y_CENTER, _X_MAX, _Y_CENTER, color = wasp.system.theme('mid')) draw.line(_X_CENTER, 0, _X_CENTER, _Y_MAX, color = wasp.system.theme('mid')) - # We save x as y and -y as x because we use the screen's coordinate - # system. - # We also clamp and scale the values down a bit to make them fit better, - # and apply the calibration - (new_y, new_x, _) = watch.accel.accel_xyz() + (new_x, new_y, _) = watch.accel.accel_xyz() + # We clamp and scale the values down a bit to make them fit better, + # and apply the calibration. + # The scaling factor is negative because when gravity pulls in one + # direction we want the bubble to go the other direction. new_x = min(_X_CENTER, max(-_X_CENTER, (new_x-self.calibration[0])//-3)) - new_y = min(_Y_CENTER, max(-_Y_CENTER, (new_y-self.calibration[1])//3)) + new_y = min(_Y_CENTER, max(-_Y_CENTER, (new_y-self.calibration[1])//-3)) + # Draw the new bubble draw.fill(wasp.system.theme('bright'), new_x - 3 + _X_CENTER, new_y - 3 + _Y_CENTER, 6, 6) self.old_xy = (new_x, new_y) @@ -99,7 +101,7 @@ class LevelApp(): if self.prompt: # Handle buttons if self.calibrate.touch(event): - (y, x, _) = watch.accel.accel_xyz() + (x, y, _) = watch.accel.accel_xyz() self.calibration = (x, y) if self.reset.touch(event): self.calibration = (0,0) diff --git a/wasp/drivers/bma421.py b/wasp/drivers/bma421.py index 271b4af..14562d4 100644 --- a/wasp/drivers/bma421.py +++ b/wasp/drivers/bma421.py @@ -8,17 +8,33 @@ import bma42x import time +# Sensor orientation definition. +# The 6 most significant bits define the indexes of the x, y, and z values +# in the acceleration tuple returned by the sensor, while the 3 least +# significant bits define their sign (1 = keep original sign, 0 = negate). +# +# Z index ─────────────────┐ +# Y index ───────────────┐ │ +# X index ─────────────┐ │ │ +# ├┐├┐├┐ +_DEFAULT_ORIENTATION = const(0b010010101) +# 1 = keep, 0 = negate │││ +# X sign ───────────────────┘││ +# Y sign ────────────────────┘│ +# Z sign ─────────────────────┘ + class BMA421: """BMA421 driver .. automethod:: __init__ """ - def __init__(self, i2c): + def __init__(self, i2c, orientation=_DEFAULT_ORIENTATION): """Configure the driver. :param machine.I2C i2c: I2C bus used to access the sensor. """ self._dev = bma42x.BMA42X(i2c) + self._orientation = orientation def reset(self): """Reset and reinitialize the sensor.""" @@ -52,4 +68,8 @@ class BMA421: def accel_xyz(self): """Return a triple with acceleration values""" - return self._dev.read_accel_xyz() + raw = self._dev.read_accel_xyz() + x = raw[self._orientation >> 7 & 0b11] * ((self._orientation >> 1 & 0b10) - 1) + y = raw[self._orientation >> 5 & 0b11] * ((self._orientation & 0b10) - 1) + z = raw[self._orientation >> 3 & 0b11] * ((self._orientation << 1 & 0b10) - 1) + return (x, y, z)