iam currently experimenting with an Adafruit LIS3DH Triple-Axis Accelerometer breakout board and CP.
i currently use a Adafruit ESP32-S3 Reverse TFT Feather as controller board.
my original need is to detect the start & end point of each shake-move and the duration. so i know some sort of speed and the start point for the next shake move...
(i know there is an internal shake detection - but that gives me just a Yes / No)
my first idea was to just print the current values as fast as possible and plot them on my computer.
for the plotting i am using SerialPlot
so i can analyze how this all happens... and then try to implement an simple *algorithm* to detect & measure start stop and duration..
(some if else statements in the simplest case)
during these experiments i found that the value updates were relative slow and i did not see every direction change of my movements.
so i dig deeper and came up with this speed test:
Code: Select all
# based on example
# https://github.com/adafruit/Adafruit_CircuitPython_LIS3DH/blob/main/examples/lis3dh_simpletest.py
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
# SPDX-License-Identifier: MIT
import time
import board
import busio
import adafruit_lis3dh
# uses board.SCL and board.SDA
i2c = board.I2C()
lis3dh = adafruit_lis3dh.LIS3DH_I2C(i2c)
# RANGE_2_G
# RANGE_4_G
# RANGE_8_G
# RANGE_16_G
lis3dh.range = adafruit_lis3dh.RANGE_16_G
def speed_test(fn, msg, count=1000):
print("{} speed test running..".format(msg))
start = time.monotonic()
for i in range(count):
fn()
end = time.monotonic()
duration = (end - start) / count
duration_ms = duration * 1000
result = {
"msg": msg,
"duration_ms": duration_ms,
}
print(
"'{}' needs {:10.3f}ms/call".format(
result["msg"],
result["duration_ms"],
)
)
return result
def print_results(speed_tests):
msg_max_length = max(len(x["msg"]) for x in speed_tests)
# print(msg_max_length)
for test in speed_tests:
msg_template = (
"'{:<" + "{}".format(msg_max_length + 5) + "}' needs {:10.3f}ms/call"
)
print(
msg_template.format(
test["msg"],
test["duration_ms"],
)
)
print("\n" * 20)
speed_tests = []
lis3dh.data_rate = adafruit_lis3dh.DATARATE_1_HZ # default → 1000ms
speed_tests.append(
speed_test(
lambda: lis3dh.acceleration[1],
msg="lis3dh.acceleration[1] → 1Hz (1000ms)",
)
)
lis3dh.data_rate = adafruit_lis3dh.DATARATE_400_HZ # default → 2,5ms
speed_tests.append(
speed_test(
lambda: lis3dh.acceleration[1],
msg="lis3dh.acceleration[1] → 400Hz (2.5ms)",
)
)
lis3dh.data_rate = adafruit_lis3dh.DATARATE_LOWPOWER_5KHZ # → 0,2ms
speed_tests.append(
speed_test(
lambda: lis3dh.acceleration[1],
msg="lis3dh.acceleration[1] → 5kHz (0,2ms)",
)
)
speed_tests.append(
speed_test(
lambda: print(3.14159),
msg="print(i * 3.14159)",
)
)
speed_tests.append(
speed_test(
lambda: print(lis3dh.acceleration[1]),
msg="print(lis3dh.acceleration[1])",
count=50,
)
)
print("\n" * 20)
time.sleep(1)
print_results(speed_tests)
time.sleep(1)
print("done...")
Code: Select all
# a bunch of output......
'lis3dh.acceleration[1] → 1Hz (1000ms) ' needs 2.882ms/call
'lis3dh.acceleration[1] → 400Hz (2.5ms) ' needs 2.886ms/call
'lis3dh.acceleration[1] → 5kHz (0,2ms) ' needs 2.861ms/call
'print(i * 3.14159) ' needs 2.284ms/call
'print(lis3dh.acceleration[1]) ' needs 20.283ms/call
done...
but so or so - the limiting factor is the combination of the read and the print...
and i have no idea why..
anyone any ideas / insights tips?!
also for my orig. goal to detect & measure shake or other movements?