Home

Awesome

uPy - ADXL345 - SPI

Library for controlling through the SPI protocol an 'Analog Devices ADXL345' accelerometer from an MCU flashed with MicroPython (in particular this was tested with a ESP32-WROVER (4MB RAM)).

Methods are optimised for being as fast as possible, trying to reach max available sampling rate (3.2kHz) for this device.

Wiring

The following wirings refers to the tested setup on an ESP32-WROVER:

ADXL345 Pin nameESP32 Pin name (number)
Vs3v3
GNDGND
CSvspi cs (D5)
SCL/SCLKvspi scl (D18)
SDO/ALT ADDRESSvspi miso (D19)
SDA/SDI/SDOvspi mosi (D23)

RAM and MemoryErrors

Consider that at high sampling rates the MCU collects 3_axes x sampling_rate floats per second. This may result in ending the available RAM of MCUs very quickly: set your acquisition time accordingly and clear data arrays when you are done with them.

Examples

read one x, y, z

from ADXL345_spi import ADXL345 as Accelerometer
accelerometer = Accelerometer(cs_pin=5, scl_pin=18, sda_pin=23, sdo_pin=19, spi_freq=5000000)
accelerometer.init_spi()
accelerometer.set_sampling_rate(1.56)   # Hz
accelerometer.set_g_range(2)            # max measurable acceleration pm 2g
accelerometer.set_fifo_mode('bypass')
accelerometer.set_power_mode('measure')
buf, T = accelerometer.read_many_xyz(n=1)
accelerometer.set_power_mode('standby')
x, y, z = accelerometer.xyzbytes2g(buf)  # convert bytearray in 3 acceleration arrays (x, y, z) in g units
accelerometer.deinit_spi()  # this is necessary, otherwise if another SPI is initialized it won't work

read many x, y, z

from ADXL345_spi import ADXL345 as Accelerometer
accelerometer = Accelerometer()                     # assumes accelerometer is connected to MCU spi default Pins
accelerometer.init_spi()
accelerometer.set_sampling_rate(3200)
accelerometer.set_g_range(2)
accelerometer.set_fifo_mode('bypass')
accelerometer.set_power_mode('measure')
buf, T = accelerometer.read_many_xyz(n=10)  # reads ten samples for each axis at the requested sampling rate
accelerometer.set_power_mode('standby')
x, y, z = accelerometer.xyzbytes2g(buf)     # arrays of length 10, to be associated with the T array that holds the times of the measure of each sample
accelerometer.deinit_spi()

read continuosly when data is ready

from ADXL345_spi import ADXL345 as Accelerometer
accelerometer = Accelerometer()
accelerometer.init_spi()
accelerometer.set_sampling_rate(3200)
accelerometer.set_g_range(2)
accelerometer.set_fifo_mode('bypass')
accelerometer.set_power_mode('measure')
buf, T = accelerometer.read_continuos_xyz(acquisition_time=1.5)  # reads samples for 1.5 seconds from each axis at the requested sampling rate
accelerometer.set_power_mode('standby')
x, y, z = accelerometer.xyzbytes2g(buf)  # arrays (in principle) of length acquisition_time * sampling_rate 
accelerometer.deinit_spi()

read continuosly from fifo

The method for reading from fifo is implemented even though it doesn't read more than one row of the fifo in one transaction, making its performances equal to the method reading measures when they are ready. Trying to read more than one row of the fifo in one transaction always resulted in reading following registers instead of other rows of the fifo.

from ADXL345_spi import ADXL345 as Accelerometer
accelerometer = Accelerometer()
accelerometer.init_spi()
accelerometer.set_sampling_rate(3200)
accelerometer.set_g_range(2)
accelerometer.set_fifo_mode('stream')
accelerometer.set_power_mode('measure')
buf, T = accelerometer.read_continuos_xyz_fromfifo(acquisition_time=1.5)
accelerometer.set_power_mode('standby')
x, y, z = accelerometer.xyzbytes2g(buf)
accelerometer.deinit_spi()