GithubHelp home page GithubHelp logo

adafruit / adafruit_circuitpython_lis3dh Goto Github PK

View Code? Open in Web Editor NEW
17.0 17.0 20.0 184 KB

Adafruit CircuitPython module for the LIS3DH accelerometer.

License: MIT License

Python 100.00%
hacktoberfest

adafruit_circuitpython_lis3dh's People

Contributors

brennen avatar caternuson avatar crotwell avatar dhalbert avatar evaherrada avatar foamyguy avatar jepler avatar jerryneedell avatar jposada202020 avatar kattni avatar keiththeee avatar ladyada avatar makermelissa avatar mrmcwethy avatar perja12 avatar siddacious avatar sigafoos avatar sommersoft avatar tannewt avatar tcfranks avatar tdicola avatar tekktrik avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

adafruit_circuitpython_lis3dh's Issues

lis3dh_ad example broken

There are a few problem with the lis3dh_adc example.
I get the same results on a CPX and CPB

The I2C initialization needs to be updated:
I changed it to use the same init as in the other examples:



# Hardware I2C setup. Use the CircuitPlayground built-in accelerometer if available;
# otherwise check I2C pins.
if hasattr(board, 'ACCELEROMETER_SCL'):
    i2c = busio.I2C(board.ACCELEROMETER_SCL, board.ACCELEROMETER_SDA)
    int1 = digitalio.DigitalInOut(board.ACCELEROMETER_INTERRUPT)
    lis3dh = adafruit_lis3dh.LIS3DH_I2C(i2c, address=0x19, int1=int1)
else:
    i2c = busio.I2C(board.SCL, board.SDA)
    int1 = digitalio.DigitalInOut(board.D6)  # Set to correct pin for interrupt!
    lis3dh = adafruit_lis3dh.LIS3DH_I2C(i2c, int1=int1)


and it seems happy, but then I get


Press any key to enter the REPL. Use CTRL-D to reload.
Adafruit CircuitPython 5.0.0-alpha.0-287-g7cbae3d20 on 2019-08-28; Adafruit CircuitPlayground Express with samd21g18
>>> 
>>> import lis3dh_adc
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "lis3dh_adc.py", line 39, in <module>
  File "adafruit_lis3dh.py", line 206, in read_adc_raw
RuntimeError: buffer size must match format
>>> 

the error appears to be here
https://github.com/adafruit/Adafruit_CircuitPython_LIS3DH/blob/master/adafruit_lis3dh.py#L206

Access to single axis value

This mainly comes up in conditionals, and can currently be done like this:

if lis3dh.acceleration[2] > SOME_VALUE:
    print("Z axis exceeds the value!")

but requires knowing the index of the axis. Is there anyway this could be done where it's more obvious what's being accessed?
Like this:

if lis3dh.acceleration['Z'] > SOME_VALUE:
    print("Z axis exceeds the value!")

or this:

if lis3dh.acceleration.Z > SOME_VALUE:
    print("Z axis exceeds the value!")

No Adafruit-Blinka compatible version

When installing through pip install adafruit-circuitpython-lis3dh on a Raspberry Pi for use in the Adafruit-Blinka (MicroPython) environment, no compatible version is listed.

It would be excellent to have a version of this library for use in Adafruit-Blinka environments.

$ pip install adafruit-circuitpython-lis3dh
Collecting adafruit-circuitpython-lis3dh
  Downloading https://files.pythonhosted.org/packages/9b/92/2a88b33e1ddd0ed912d6c27f113437765929ba05dd3a0f7410785bc28d34/adafruit-circuitpython-lis3dh-4.3.2.tar.gz
Collecting Adafruit-Blinka (from adafruit-circuitpython-lis3dh)
  Could not find a version that satisfies the requirement Adafruit-Blinka (from adafruit-circuitpython-lis3dh) (from versions: )
No matching distribution found for Adafruit-Blinka (from adafruit-circuitpython-lis3dh)

Missing Type Annotations

There are missing type annotations for some functions in this library.

The typing module does not exist on CircuitPython devices so the import needs to be wrapped in try/except to catch the error for missing import. There is an example of how that is done here:

try:
    from typing import List, Tuple
except ImportError:
    pass

Once imported the typing annotations for the argument type(s), and return type(s) can be added to the function signature. Here is an example of a function that has had this done already:

def wrap_text_to_pixels(
    string: str, max_width: int, font=None, indent0: str = "", indent1: str = ""
) -> List[str]:

If you are new to Git or Github we have a guide about contributing to our projects here: https://learn.adafruit.com/contribute-to-circuitpython-with-git-and-github

There is also a guide that covers our CI utilities and how to run them locally to ensure they will pass in Github Actions here: https://learn.adafruit.com/creating-and-sharing-a-circuitpython-library/check-your-code In particular the pages: Sharing docs on ReadTheDocs and Check your code with pre-commit contain the tools to install and commands to run locally to run the checks.

If you are attempting to resolve this issue and need help, you can post a comment on this issue and tag both @FoamyGuy and @kattni or reach out to us on Discord: https://adafru.it/discord in the #circuitpython-dev channel.

The following locations are reported by mypy to be missing type annotations:

  • adafruit_lis3dh.py:97
  • adafruit_lis3dh.py:145
  • adafruit_lis3dh.py:167
  • adafruit_lis3dh.py:197
  • adafruit_lis3dh.py:230
  • adafruit_lis3dh.py:241
  • adafruit_lis3dh.py:286
  • adafruit_lis3dh.py:342
  • adafruit_lis3dh.py:346
  • adafruit_lis3dh.py:352
  • adafruit_lis3dh.py:391
  • adafruit_lis3dh.py:398
  • adafruit_lis3dh.py:405
  • adafruit_lis3dh.py:444
  • adafruit_lis3dh.py:451
  • adafruit_lis3dh.py:461

Small INT overflow on Halowing_m0

With current tip of main CP installed on a Hallowing_m0 init fails:

Press any key to enter the REPL. Use CTRL-D to reload.

Adafruit CircuitPython 6.2.0-beta.1-23-g0c0b51711 on 2021-02-01; HalloWing M0 Express with samd21g18
>>> import lis3dh_simpletest
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "lis3dh_simpletest.py", line 16, in <module>
  File "adafruit_lis3dh.py", line 332, in __init__
OverflowError: small int overflow
>>> 

Missing abs() in spinner examples to determine maximum value

Both examples/spinner.py and examples/spinner_advanced.py feature the same code which reads 32 values in total and looks for maximum absolute value from the x-axis accelerometer value. There's a missing abs() on the first read before the loop which looks like a bug?

        maxval = lis3dh.acceleration[0]  # Grab just the X acceleration value.
        for i in range(31):
            x = abs(lis3dh.acceleration[0])
            if x > maxval:
                maxval = x

Optimize struct unpacking

x = struct.unpack('<h', data[0:2])[0]
y = struct.unpack('<h', data[2:4])[0]
z = struct.unpack('<h', data[4:6])[0]

Slicing data causes an extra allocation. Struct should be able to take the whole buffer and split out the values at once.

Incorrect calculation in shake() method

The code for adafruit.lis3dh.shake() appears that it is sampling (x,y,z) acceleration values, and keeping a separate running total of x-acceleration, y-acceleration, and z-acceleration. It then divides the totals by the number of samples to get an average for each. It then computes sqrt(x * x + y * y + z * z) on the averages to give a magnitude, and compares it with a threshold.

I'm pretty sure this isn't correct. Imagine if you are shaking the accelerometer backwards and forwards parallel to the x-axis. That will give both positive and negative x-acceleration values: if you total them up, the positive and negative values will cancel out and you'll end up with approximately zero. That means when you compute the average and magnitude, you'll likely end up with a value below the threshold, no matter how vigorously you shake the accelerometer. Indeed when I shake the accelerometer and look at the values, sometimes total_accel is a lower value than when standing still.

The issue is the squaring is being delayed until after the summing. The tally should be the sum of the squares, not the square of the sums.

Can be demonstrated with this example code:

import math

# synthesize acceleration data for shaking that perfectly
# bounces between + and - 1G on all 3 axis
accel_data = (
    (-9.8, -9.8, -9.8),
    (9.8, 9.8, 9.8),
    (-9.8, -9.8, -9.8),
    (9.8, 9.8, 9.8),  
)

avg_count = len(accel_data)

shake_accel = (0, 0, 0)
for i in range(avg_count):
    shake_accel = tuple(map(sum, zip(shake_accel, accel_data[i])))
    print("shake_accel = ", shake_accel)

avg = tuple(value / avg_count for value in shake_accel)
print("avg = ", avg)
total_accel = math.sqrt(sum(map(lambda x: x * x, avg)))
print("total_accel = ", total_accel)

Which outputs:


$ python3 accel_test.py 
shake_accel =  (-9.8, -9.8, -9.8)
shake_accel =  (0.0, 0.0, 0.0)
shake_accel =  (-9.8, -9.8, -9.8)
shake_accel =  (0.0, 0.0, 0.0)
avg =  (0.0, 0.0, 0.0)
total_accel =  0.0


Probable Cause/Suggested Fix:

The code should calculate the magnitude of each acceleration (x,y,z) sample before averaging, not afterwards.

This can be done by evaluating magnitude = sqrt( x * x + y * y + z * z) for each sample, and then accumulating the total of the (scalar) magnitude values.

However, on platforms with limited CPU power and no FPU, this may be quite computationally expensive. One alternative is to evaluate (abs(x) + abs(y) + abs (z)) - this is guaranteed to be greater than the magnitude and less than sqrt(5)*magnitude, so (IMHO) it can be used as convenient proxy for the magnitude for shake detection (which doesn't need exact values).

Here is a code fragment that I have used and successfully tested as a substitute for the code in shake():


def ShakeCheck(shake_threshold, avg_count, total_delay):
    global lis3dh
    total_accel = 0
    sample_delay = total_delay / avg_count
    for _ in range(avg_count):
        # Sample the accelerometer, get the magnitude of acceleration,
        # and accumulate the total in total_accel
        # Magnitude should be calculated as sqrt(sum([x**2 for x in accel]))
        # but we can use sum of abs(x) as an approximation
        # to save CPU if needed
        accel = lis3dh.acceleration
        #print("Acceleration tuple= ", accel)
        magnitude = sum( [abs(x) for x in accel] )
        #print("Magnitude= ", magnitude)
        total_accel = total_accel + magnitude
        time.sleep(sample_delay)
    #print("Total shake_accel= ", total_accel)
    avg = total_accel/avg_count
    #print("Average accel= ", avg )
    return avg > shake_threshold

See https://forums.adafruit.com/viewtopic.php?t=198206

Automatically detect CPX in examples

The examples here currently default to hardware I2C with commented-out code for CPX, software I2C and hardware SPI.

It would be relatively simple enough to default to "CPX or hardware I2C":


if hasattr(board, 'ACCELEROMETER_SCL'):
    i2c = busio.I2C(board.ACCELEROMETER_SCL, board.ACCELEROMETER_SDA)
else:
    i2c = busio.I2C(board.SCL, board.SDA)
lis3dh = adafruit_lis3dh.LIS3DH_I2C(i2c, address=0x19)

This way the two most likely scenarios will Just Work™

(it would obviously need better documentation too)

DATA_RATE vs DATARATE

Docs say on lines 128-137 of adafruit_lis3dh.py:

        Could have the following values:
        * DATA_RATE_400_HZ
        * DATA_RATE_200_HZ

but actual constants are:

DATARATE_400_HZ = const(0b0111)  # 400Hz
DATARATE_200_HZ = const(0b0110)  # 200Hz

The extra underscore should be removed.

add orientation property

The LIS3DH supports returning orientation data but the CP library does not expose this (nor, it seems, does the Arduino library)

This seems like something useful to include.

Edit: it's also entirely possible that I have a fundamental misunderstanding of what an accelerometer is and does. There's a position (how it's oriented, though I'm not looking for a value in degrees, necessarily), and there's how quickly it's moving. Something held perfectly level and dropped in a vacuum won't have any changes in its orientation but will be falling. My expectation is that these are different values, and I'd like access to both.

lis3dh_simpletest does not work for pygamer

The current lis3dh_simpletest example uses the existence of ACCELEROMETER_SCL to determine the pin configuration and I2C address
https://github.com/adafruit/Adafruit_CircuitPython_LIS3DH/blob/master/examples/lis3dh_simpletest.py#L9

if hasattr(board, 'ACCELEROMETER_SCL'):
    i2c = busio.I2C(board.ACCELEROMETER_SCL, board.ACCELEROMETER_SDA)
    int1 = digitalio.DigitalInOut(board.ACCELEROMETER_INTERRUPT)
    lis3dh = adafruit_lis3dh.LIS3DH_I2C(i2c, address=0x19, int1=int1)
else:
    i2c = busio.I2C(board.SCL, board.SDA)
    int1 = digitalio.DigitalInOut(board.D6)  # Set to correct pin for interrupt!
    lis3dh = adafruit_lis3dh.LIS3DH_I2C(i2c, int1=int1)

But this does not work for the pygamer. It has ACCELEROMETER_INTERRUPT but uses the default board SCL/SDA.

I'll be happy to put in a PR but wanted to see how you wanted to implement it or should there just be a separate lis3dh_pygamer_simpletest?

Add proper API for enabling FIFO stream

The CircuitPlayground driver uses direct write to the device with _write_register_byte which should be replaced by a self-documenting method call.

From the CircuitPlayground driver:

self._lis3dh._write_register_byte(adafruit_lis3dh.REG_CTRL5, 0b01001000)
self._lis3dh._write_register_byte(0x2E, 0b10000000)

Shake Function

When calling the shake function: lis3dh.shake() the result always returns False. This happens even when vigorously shaking the lis3dh accelerometer device. The return of the shake function is total_accel > shake_threshold, so I'm assuming the values for total_accel are always GREATER THAN the shake_threshold. It would seem that I need to modify the parameter values of the shake function to increase the sensitivity of detecting a shake event. These parameters include shake_threshold, avg_count, and total_delay. However, I'm not sure how to write the appropriate code needed to change these parameters. Also, since the function is being called from a module in .MPY format, I am unable to edit the raw .MPY file to change the default parameters for this function. When using a .PY formatted module file instead of the .MPY module file, I receive a memory error message in the REPL (so I'm forced to work off of the .MPY file). Any help with figuring this out would be much appreciated!

Source code for the shake function within the lis3dh.mpy module file: https://github.com/adafruit/Adafruit_CircuitPython_LIS3DH/releases/tag/v1.0.0

Screenshot of shake function code within the module file:
shake code screenshot

Issue with neopixel.py

Hi,

I am currently able to use the neopixel library and the LIS3DH libraries independently. But I try to import both libraries into a single file, the program breaks and will not run. Leaving all the referenced code and removing the import adafruit_lis3dh, will allow to program to run without input from the lis3dh. Any thoughts on why this might be?

tap.py example not working

I tried the tap.py example on CP2.2.4 and CP3.0-alpha on a CPX with the latest and previous version of this driver and I cannot get it report any taps.
Not much info to privide - the script executes but never responds to taps (even no gentle ones).

Does it work for anyone else?

lis3dh.tapped returning multiple True on I2C, not responding at all on SPI

The tap.py example doesn't work as it was. I've updated it to remove the SPI hardware setup, and added a time.sleep(). It works for now, but the odd behavior needs to be addressed directly.

Without the time.sleep(), it returned True twice for every tap or double-tap detected. Tap works successfully in the cpx Express lib, but there's so much going on there, it may be acting like a debounce behind the scenes. There are three other parameters that can be set for set_tap which are set in the cpx lib, and may be able to resolve the multiple tap-return issue.

I haven't looked at the datasheet but I'm wondering if it's possible that tap isn't implemented for SPI. If I set the threshold really low, it returns True then False once on reload, but never in response to tapping.

Missing adafruit-circuitpython-busdevice dependency

This package requires the package adafruit-circuitpython-busdevice but the package is not configured to requires this package. It result on this error when we try to run the package on a clean raspbian install.

pi@raspberrypi:~ $ sudo python3 ./accel.py
Traceback (most recent call last):
File "./accel.py", line 9, in
lis3dh = adafruit_lis3dh.LIS3DH_SPI(spi, cs)
File "/usr/local/lib/python3.5/dist-packages/adafruit_lis3dh.py", line 347, in init
import adafruit_bus_device.spi_device as spi_device
ImportError: No module named 'adafruit_bus_device'


pi@raspberrypi:~ $ pip3 show adafruit-circuitpython-lis3dh
Name: adafruit-circuitpython-lis3dh
Version: 4.3.1
Summary: CircuitPython library for LIS3DH accelerometer.
Home-page: https://github.com/adafruit/Adafruit_CircuitPython_LIS3DH
Author: Adafruit Industries
Author-email: [email protected]
License: MIT
Location: /usr/local/lib/python3.5/dist-packages
Requires: Adafruit-Blinka

this last line should show
Requires: Adafruit-Blinka, adafruit-circuitpython-busdevice

Thank you!

Reading acceleration data

Using this as a reference, I am trying to print accelerometer data from a Circuit Playground Express in a CircuitPython REPL.

This script is printing values, but the values are not changing despite moving
the Circuit Playground. Any feedback would be appreciated.

import time

import board
import busio
import adafruit_lis3dh

i2c = busio.I2C(board.ACCELEROMETER_SCL, board.ACCELEROMETER_SDA)
lis3dh = adafruit_lis3dh.LIS3DH_I2C(i2c, address=25)
lis3dh.range = adafruit_lis3dh.RANGE_2_G

i = 0
while True:
    x, y, z = lis3dh.acceleration
    print('{} x = {}G, y = {}G, z = {}G'.format(i, x / 9.806, y / 9.806, z / 9.806))
    i = i + 1
    time.sleep(0.25)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.