Initial implementation of interrupt-based wrist tilt detection on BMA425

This commit is contained in:
Peter Cai 2022-06-18 10:40:42 -04:00
parent c08eb7c350
commit 6332f11502
6 changed files with 50 additions and 8 deletions

View file

@ -22,6 +22,7 @@ freeze('../..', manifest_240x240.manifest +
'gadgetbridge.py', 'gadgetbridge.py',
'ppg.py', 'ppg.py',
'shell.py', 'shell.py',
'motion.py',
'wasp.py', 'wasp.py',
), ),
opt=3 opt=3

View file

@ -90,7 +90,7 @@ try:
Signal(Pin('CHARGING', Pin.IN), invert=True), Signal(Pin('CHARGING', Pin.IN), invert=True),
Signal(Pin('USB_PWR', Pin.IN), invert=True)) Signal(Pin('USB_PWR', Pin.IN), invert=True))
i2c = I2C(1, scl='I2C_SCL', sda='I2C_SDA') i2c = I2C(1, scl='I2C_SCL', sda='I2C_SDA')
accel = BMA421(i2c) accel = BMA421(i2c, Pin('ACCEL_INT', Pin.IN))
hrs = HRS3300(i2c) hrs = HRS3300(i2c)
touch = CST816S(i2c, touch = CST816S(i2c,
Pin('TP_INT', Pin.IN), Pin('TP_RST', Pin.OUT, value=0), Pin('TP_INT', Pin.IN), Pin('TP_RST', Pin.OUT, value=0),

View file

@ -7,6 +7,8 @@
import bma42x import bma42x
import time import time
import motion
from machine import Pin
# Sensor orientation definition. # Sensor orientation definition.
# The 6 most significant bits define the indexes of the x, y, and z values # The 6 most significant bits define the indexes of the x, y, and z values
@ -28,13 +30,18 @@ class BMA421:
.. automethod:: __init__ .. automethod:: __init__
""" """
def __init__(self, i2c, orientation=_DEFAULT_ORIENTATION): def __init__(self, i2c, intr=None, orientation=_DEFAULT_ORIENTATION):
"""Configure the driver. """Configure the driver.
:param machine.I2C i2c: I2C bus used to access the sensor. :param machine.I2C i2c: I2C bus used to access the sensor.
""" """
self._dev = bma42x.BMA42X(i2c) self._dev = bma42x.BMA42X(i2c)
self._orientation = orientation self._orientation = orientation
self._gesture_int = intr
self._gesture_event = motion.AccelGestureEvent.NONE
if self._gesture_int != None:
self._gesture_int.irq(trigger=Pin.IRQ_FALLING, handler=self.handle_interrupt)
def reset(self): def reset(self):
"""Reset and reinitialize the sensor.""" """Reset and reinitialize the sensor."""
@ -60,6 +67,29 @@ class BMA421:
# Software readout is remapped manually in accel_xyz(). # Software readout is remapped manually in accel_xyz().
dev.set_remap_axes(self._orientation) dev.set_remap_axes(self._orientation)
# Enable gesture interrupts
dev.set_int_pin_config(int_line=bma42x.INTR1_MAP,
edge_ctrl=bma42x.LEVEL_TRIGGER,
lvl=bma42x.ACTIVE_LOW,
od=bma42x.PUSH_PULL,
output_en=True, input_en=False)
dev.feature_enable(bma42x.WRIST_WEAR, True)
#dev.feature_enable(bma42x.DOUBLE_TAP, True)
dev.map_interrupt(bma42x.INTR1_MAP, bma42x.WRIST_WEAR_INT, True)
def handle_interrupt(self, pin_obj):
"""Interrupt handler for gesture events originating from the sensor"""
self._dev.read_int_status() # TODO: Actually read status from the register
self._gesture_event = motion.AccelGestureEvent.WRIST_TILT
def get_gesture_event(self):
"""Receive the latest gesture event if any"""
return self._gesture_event
def reset_gesture_event(self):
"""Call after processing the gesture event"""
self._gesture_event = motion.AccelGestureEvent.NONE
@property @property
def steps(self): def steps(self):
"""Report the number of steps counted.""" """Report the number of steps counted."""

@ -1 +1 @@
Subproject commit 85622fc37610ebb3821f0b315c37c69a4bffa72d Subproject commit 905652f9fd6541283591cf6e085c31f9aa63bf40

7
wasp/motion.py Normal file
View file

@ -0,0 +1,7 @@
from micropython import const
class AccelGestureEvent():
"""Enumerated ids for accelerometer-based gesture events
"""
NONE = const(0)
WRIST_TILT = const(1)

View file

@ -20,6 +20,7 @@ import micropython
import sys import sys
import watch import watch
import widgets import widgets
import motion
from apps.launcher import LauncherApp from apps.launcher import LauncherApp
from apps.pager import PagerApp, CrashApp, NotificationApp from apps.pager import PagerApp, CrashApp, NotificationApp
@ -498,11 +499,14 @@ class Manager():
self.wake() self.wake()
if self.raise_wake: if self.raise_wake:
now = rtc.get_uptime_ms() if watch.accel.get_gesture_event() == motion.AccelGestureEvent.WRIST_TILT:
if now >= self.accel_poll_expiry: watch.accel.reset_gesture_event()
self.accel_poll_expiry = (now + self.accel_poll_ms) self.wake()
if self._do_raise_wake(): #now = rtc.get_uptime_ms()
self.wake() #if now >= self.accel_poll_expiry:
# self.accel_poll_expiry = (now + self.accel_poll_ms)
# if self._do_raise_wake():
# self.wake()
def _do_raise_wake(self): def _do_raise_wake(self):