Giter VIP home page Giter VIP logo

adxl345spi's Introduction

ADXL345 accelerometer reader for Raspberry Pi

This simple command line tool provides an easy to use and reliable non-realtime access to ADXL345 three-axis digital accelerometer (datasheet) over SPI interface of Raspberry Pi at sampling rates up to 3200 Hz. The output can be redirected to a standard output or CSV file.

Usage

Note: root privileges are required to run adxl345spi (i.e. sudo adxl345spi [OPTIONS]).

Usage: adxl345spi [OPTION]...

Mandatory arguments to long options are mandatory for short options too.
  -s, --save FILE     save data to specified FILE (data printed to command-line
                      output, if not specified)
  -t, --time TIME     set the duration of data stream to TIME seconds
                      (default: 5 seconds) [integer]
  -f, --freq FREQ     set the sampling rate of data stream to FREQ samples per
                      second, 1 <= FREQ <= 3200 (default: 5 Hz) [integer]

Data is streamed in comma separated format, e. g.:
  time,     x,     y,     z
   0.0,  10.0,   0.0, -10.0
   1.0,   5.0,  -5.0,  10.0
   ...,   ...,   ...,   ...
  time shows seconds elapsed since the first reading;
  x, y and z show acceleration along x, y and z axis in fractions of <g>.

Exit status:
  0  if OK
  1  if error occurred during data reading or wrong cmdline arguments.

Installation

sudo apt-get update
git clone https://github.com/nagimov/adxl345spi
cd adxl345spi
sudo make
sudo make install

Notes:

  • root privileges are required by make in order to install dependencies (pigpio)
  • root privileges are required by make install in order to install compiled binary to /usr/local/bin
  • build is only tested on Raspbian / Raspbian Pi OS

Wiring

Fritzing diagrams for two popular breadboards:

adxl345spi_bb

adxl345spi_schem

CS  : SPI_CE0_N (pin 24)
SDO : SPI_MISO (pin 21)
SDA : SPI_MOSI (pin 19)
SCL : SPI_CLK (pin 23)

Some ADXL345 breadboards have VCC pin marked as 3V3.

Testing

Accelerometer can be tested by running adxl345spi without arguments and verifying its output. Values of x, y and z acceleration should appear to be non-zero. Rotate the accelerometer around its x, y and z axis and observe acceleration values change accordingly from approximately -1.0 to +1.0.

Measuring vibration spectrums using FFT

This simple setup demonstrates how to use ADXL345 accelerometer in order to measure vibration spectrums.

adxl345_hdd_setup

2.5" 5400 RPM laptop hard drive is used as source of vibrations. USB enclosure (a.k.a. "SATA to USB adapter") is used to power the hard drive from a USB port of Raspberry Pi. ADXL345 accelerometer board is mounted to the body of the hard drive using a C-clamp. Care must be taken to prevent shorting or contacting exposed components on the accelerometer board or the hard drive. Accelerometer is wired according to a wiring diagram.

Peak acceleration is expected to be measured at 90 Hz:

(5400 revolutions/min) / (60 sec/min) = 90 revolutions/sec = 90 Hz

A simple python script can be used to measure and display vibration spectrums:

import os
import numpy as np
from matplotlib import mlab
import matplotlib.pyplot as plt
sample_rate_Hz = 3200
length_s = 2
os.system(f'sudo adxl345spi -t {length_s} -f {sample_rate_Hz} -s out.csv')
acc_data = np.genfromtxt('out.csv', delimiter=',', names=True)
acc_x, freq_x, _ = mlab.specgram(acc_data['x'], Fs=sample_rate_Hz, NFFT=sample_rate_Hz * length_s)
acc_y, freq_y, _ = mlab.specgram(acc_data['y'], Fs=sample_rate_Hz, NFFT=sample_rate_Hz * length_s)
acc_z, freq_z, _ = mlab.specgram(acc_data['z'], Fs=sample_rate_Hz, NFFT=sample_rate_Hz * length_s)
plt.plot(freq_x[10:], acc_x[10:], label='x', linewidth=0.5)
plt.plot(freq_y[10:], acc_y[10:], label='y', linewidth=0.5)
plt.plot(freq_z[10:], acc_z[10:], label='z', linewidth=0.5)
plt.yscale('log')
plt.xlim((0, 160))
plt.legend(loc='upper right')
plt.savefig('spectrum.png')

As expected, peak accelerations on all three axis are observed at 90 Hz:

adxl345_hdd_fft

SPI bus and sampling rates

Due to limitations of I2C bus, it is impossible to achieve high sampling rates using I2C interface. SPI interface is used to achieve sampling rates up to 3200 samples per second (upper limit of ADXL345 chip itself). SPI baud rate is set to 2 Mbps, to ensure that no readings are lost during transmission.

For a standard output, downsampling is achieved by calling sleep() between transmissions, providing somewhat unstable sampling rate. If a reliable sampling rate is required, output to a file should be used.

For a file output, data is always read at a higher than required sampling rate (~30000 Hz for 2 Mbps SPI baud rate) and accurately downsampled to a specified value. Applications that require stable sampling rates and reliable time steps (e.g. spectrum analysis via FFT) should use a file output option.

adxl345spi's People

Contributors

bluet avatar folkhack avatar nagimov avatar

Stargazers

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

Watchers

 avatar  avatar  avatar

adxl345spi's Issues

help

anil@pi:~ $ sudo i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
anil@pi:~ $ adxl345spi
2024-06-09 20:46:29 gpioHardwareRevision: unknown rev code (d04170)
2024-06-09 20:46:29 initCheckPermitted:
+---------------------------------------------------------+
|Sorry, this system does not appear to be a raspberry pi. |
|aborting. |
+---------------------------------------------------------+

Multiple Sensor operability

Is there a way to add multiple sensor support into the program and make it print in the format of
time, x1, y1, z1, x2, y2, z2? I think it might have something to do with the chip select

sometimes the values are all zeroes when running adxl345spi

when running sudo adxl345spi command occasionally I run into issues whereby all my values are 0.

example :

pi@raspberrypi:~/adxl345spi $ sudo adxl345spi
time = 0.000, x = 0.000, y = 0.000, z = 0.000
time = 0.200, x = 0.000, y = 0.000, z = 0.000
time = 0.400, x = 0.000, y = 0.000, z = 0.000
time = 0.600, x = 0.000, y = 0.000, z = 0.000
time = 0.801, x = 0.000, y = 0.000, z = 0.000
time = 1.001, x = 0.000, y = 0.000, z = 0.000
time = 1.201, x = 0.000, y = 0.000, z = 0.000
time = 1.401, x = 0.000, y = 0.000, z = 0.000
time = 1.601, x = 0.000, y =``` 0.000, z = 0.000
time = 1.801, x = 0.000, y = 0.000, z = 0.000
time = 2.001, x = 0.000, y = 0.000, z = 0.000
time = 2.202, x = 0.000, y = 0.000, z = 0.000
time = 2.402, x = 0.000, y = 0.000, z = 0.000
time = 2.602, x = 0.000, y = 0.000, z = 0.000
time = 2.802, x = 0.000, y = 0.000, z = 0.000
time = 3.002, x = 0.000, y = 0.000, z = 0.000
time = 3.202, x = 0.000, y = 0.000, z = 0.000
time = 3.402, x = 0.000, y = 0.000, z = 0.000
time = 3.603, x = 0.000, y = 0.000, z = 0.000
time = 3.803, x = 0.000, y = 0.000, z = 0.000
time = 4.003, x = 0.000, y = 0.000, z = 0.000
time = 4.203, x = 0.000, y = 0.000, z = 0.000
time = 4.403, x = 0.000, y = 0.000, z = 0.000
time = 4.603, x = 0.000, y = 0.000, z = 0.000
time = 4.803, x = 0.000, y = 0.000, z = 0.000
25 samples read in 5.03 seconds with sampling rate 5.0 Hz
Done

sometimes this happens halfway through the command. For example when running sudo adxl345spi -f 3200

code snippet cut
time = 0.814, x = -0.047, y = -0.125, z = 1.016
time = 0.814, x = -0.031, y = -0.516, z = 1.242
time = 0.815, x = -0.031, y = -0.133, z = 1.016
time = 0.815, x = -0.016, y = -0.133, z = 1.008
time = 0.815, x = 0.000, y = -0.164, z = 0.969
time = 0.816, x = -0.016, y = -0.117, z = 1.000
time = 0.816, x = -0.102, y = -0.109, z = 1.047
time = 0.817, x = 0.117, y = -0.172, z = 1.047
time = 0.817, x = 0.000, y = -0.148, z = 1.023
time = 0.818, x = -0.031, y = -0.141, z = 1.000
time = 0.818, x = -0.023, y = -0.141, z = 1.000
time = 0.818, x = -0.031, y = 0.156, z = 0.992
time = 0.819, x = 0.000, y = -0.148, z = 1.023
time = 0.819, x = -0.039, y = -0.148, z = 1.031
time = 0.820, x = -116.270, y = -116.457, z = -0.457
time = 0.820, x = 0.000, y = 0.000, z = 0.000
time = 0.820, x = 0.000, y = 0.000, z = 0.000
time = 0.821, x = 0.000, y = 0.000, z = 0.000
time = 0.821, x = 0.000, y = 0.000, z = 0.000
time = 0.822, x = 0.000, y = 0.000, z = 0.000
time = 0.822, x = 0.000, y = 0.000, z = 0.000
time = 0.822, x = 0.000, y = 0.000, z = 0.000
time = 0.823, x = 0.000, y = 0.000, z = 0.000
time = 0.823, x = 0.000, y = 0.000, z = 0.000
time = 0.824, x = 0.000, y = 0.000, z = 0.000
time = 0.824, x = 0.000, y = 0.000, z = 0.000
time = 0.824, x = 0.000, y = 0.000, z = 0.000
time = 0.825, x = 0.000, y = 0.000, z = 0.000
time = 0.825, x = 0.000, y = 0.000, z = 0.000
time = 0.826, x = 0.000, y = 0.000, z = 0.000
time = 0.826, x = 0.000, y = 0.000, z = 0.000
... zeros continue

typically once im in an ALL ZEROES phase the only way to get out of this is to reboot the pi.

any ideas as to why? Suggestions? It is very hard for me to determine exactly when/why/what behavior causes these errors. Trying to keep finding a repeatable occurrence but cannot.

Optimize dummy lookup of downsampling (slow on large samples)

This dummy lookup loops through the entire array (~30,000 samples per second of execution) once per value of downsampled array: https://github.com/nagimov/adxl345spi/blob/master/adxl345spi.c#L263

pi@raspberrypi:~/adxl345spi $ time sudo ./adxl345spi -f 3200 -t 5 -s out.csv
Reading 16000 samples in 5.0 seconds with sampling rate 3200.0 Hz...
4.00 seconds left...
3.00 seconds left...
2.00 seconds left...
1.00 seconds left...
0.00 seconds left...
Writing to the output file...
Done

real    2m23.326s
user    2m23.150s
sys     0m0.630s

0g in csv

For some reason the data appears in the console, but when exporting it only measures up to 0.25 [sec], the others give me a value of 0 g.

Independent if I extract in txt, json or csv.
If you could help me. I use a rasp 3B, in Raspbian 11 (Bullseye)

Not installing on latest Raspian image

Hello, I have used your very useful tool previously on various Buster builds and never had any issues. However on a fresh Bullseye release on rp4 I'm not able to install, see attached error.

pi@raspberrypi:~/adxl345spi $ sudo make if ! dpkg-query -W -f='${Status}' pigpio | grep "ok installed"; then apt-get -y install pigpio; fi install ok installed gcc -Wall -pthread -lpigpio -lrt adxl345spi.c -o adxl345spi adxl345spi.c: In function ‘printUsage’: adxl345spi.c:28:34: warning: ‘%s’ directive argument is not a nul-terminated string [-Wformat-overflow=] 28 | printf( "adxl345spi (version %s) \n" | ^~ ...... 54 | "", codeVersion, timeDefault, freqMax, freqDefault); | ~~~~~~~~~~~ adxl345spi.c:16:12: note: referenced argument declared here 16 | const char codeVersion[3] = "0.3"; // code version number | ^~~~~~~~~~~ /usr/bin/ld: /tmp/ccwOsOAb.o: in function readBytes':
adxl345spi.c:(.text+0xa8): undefined reference to spiXfer' /usr/bin/ld: /tmp/ccwOsOAb.o: in function writeBytes':
adxl345spi.c:(.text+0x108): undefined reference to spiWrite' /usr/bin/ld: /tmp/ccwOsOAb.o: in function main':
adxl345spi.c:(.text+0x42c): undefined reference to gpioInitialise' /usr/bin/ld: adxl345spi.c:(.text+0x45c): undefined reference to spiOpen'
/usr/bin/ld: adxl345spi.c:(.text+0x570): undefined reference to time_sleep' /usr/bin/ld: adxl345spi.c:(.text+0x590): undefined reference to time_time'
/usr/bin/ld: adxl345spi.c:(.text+0x624): undefined reference to time_time' /usr/bin/ld: adxl345spi.c:(.text+0x69c): undefined reference to time_sleep'
/usr/bin/ld: adxl345spi.c:(.text+0x6bc): undefined reference to gpioTerminate' /usr/bin/ld: adxl345spi.c:(.text+0x6c0): undefined reference to time_time'
/usr/bin/ld: adxl345spi.c:(.text+0x7f8): undefined reference to time_time' /usr/bin/ld: adxl345spi.c:(.text+0x8b0): undefined reference to time_time'
/usr/bin/ld: adxl345spi.c:(.text+0x994): undefined reference to gpioTerminate' /usr/bin/ld: adxl345spi.c:(.text+0xa28): undefined reference to gpioTerminate'
collect2: error: ld returned 1 exit status
make: *** [Makefile:17: adxl345spi] Error 1
`

Appreciate supporting of non standard installations is outwith skills but any support to get it working again on the default pi configuration would be great. Happy to assist in testing if this is feasible.

Changing accelerometer sensing range

Hi, I am looking for help to change the sensing range of the sensor. I would like to know what I should change for it to work correctly, since from what I understand, not only do you have to change the scaling factor but also the DATA_FORMAT. Thanks!

ADXL345SPI always return 0,0,0

sudo adxl345spi
[sudo] password for pi:
time = 0.000, x = 0.000, y = 0.000, z = 0.000
time = 0.201, x = 0.000, y = 0.000, z = 0.000
time = 0.401, x = 0.000, y = 0.000, z = 0.000
time = 0.602, x = 0.000, y = 0.000, z = 0.000
time = 0.803, x = 0.000, y = 0.000, z = 0.000
time = 1.004, x = 0.000, y = 0.000, z = 0.000
time = 1.205, x = 0.000, y = 0.000, z = 0.000
time = 1.405, x = 0.000, y = 0.000, z = 0.000
time = 1.606, x = 0.000, y = 0.000, z = 0.000
time = 1.807, x = 0.000, y = 0.000, z = 0.000
time = 2.008, x = 0.000, y = 0.000, z = 0.000
time = 2.209, x = 0.000, y = 0.000, z = 0.000
time = 2.410, x = 0.000, y = 0.000, z = 0.000
time = 2.611, x = 0.000, y = 0.000, z = 0.000
time = 2.812, x = 0.000, y = 0.000, z = 0.000
time = 3.013, x = 0.000, y = 0.000, z = 0.000
time = 3.214, x = 0.000, y = 0.000, z = 0.000
time = 3.415, x = 0.000, y = 0.000, z = 0.000
time = 3.616, x = 0.000, y = 0.000, z = 0.000
time = 3.817, x = 0.000, y = 0.000, z = 0.000
time = 4.017, x = 0.000, y = 0.000, z = 0.000
time = 4.218, x = 0.000, y = 0.000, z = 0.000
time = 4.419, x = 0.000, y = 0.000, z = 0.000
time = 4.620, x = 0.000, y = 0.000, z = 0.000
time = 4.821, x = 0.000, y = 0.000, z = 0.000

My system data:

RPI3B+
5.10.17-v7+ #1403 SMP Mon Feb 22 11:29:51 GMT 2021 armv7l GNU/Linux
Debian Buster

I have checked the continuity of the cables with a multimeter and it is correct. Any idea about this problem? Many thanks for your time

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.