Sunday, 29 June 2014

Raspberry Pi - ADXL345 Accelerometer & Python


A little while ago I got my hands on a Adafuit ADXL345 (a triple axis accelerometer) from pimoroni, you can also get them from Amazon (US, UK) if that's easier, and I finally got around to setting it up.

Pimoroni also provide a really useful python module to interacting with the ADXL345 which you can get from github - https://github.com/pimoroni/adxl345-python.

Connecting it up
Wiring up the accelerometer is pretty easy, there are only 4 connections:

Raspberry Pi -> ADXL345:
  • GND - GND 
  • 3V - 3V3
  • SDA - SDA
  • SCL - SCL

Configure your Pi
The ADXL345 supports both I2C and SPI connections, I used I2C, which requires some configuration on the Pi:

Add the I2C modules to the Pi's configuration:
sudo nano /etc/modules
add the following lines:
i2c-bcm2708
i2c-dev
Remove I2C from the blacklist:
sudo nano /etc/modprobe.d/raspi-blacklist.conf
comment out:
blacklist i2c-bcm2708
so its:
#blacklist i2c-bcm2708
Reboot to make the changes:
sudo shutdown -r now
Install Software
You will need to install some software:
sudo apt-get install python-smbus i2c-tools git-core
Test ADXL345
You can check that your ADXL345 is found on the I2C bus, by running:
sudo i2cdetect -y 1
You should see a device at address 53


Download the ADXL345 pimoroni python library from github:
git clone https://github.com/pimoroni/adxl345-python
Run the example code and test it is working:
cd adxl345-python
sudo python example.py
You should see the G readings from the ADXL345.


If you get 0.000G for all axis then something probably isn't set-up correctly.

Writing your own python program
The adxl345-python project from pimoroni contains a python module for reading data from the ADXL345 perhaps not unsurprisingly called "adxl345.py", inside there is a class called "ADXL345" which is how you to interact with the accelerometer

The program below imports the module, instantiates an ADXL345 object and reads values from the accelerometer as g-forces.
#import the adxl345 module
import adxl345

#create ADXL345 object
accel = adxl345.ADXL345()

#get axes as g
axes = accel.getAxes(True)
# to get axes as ms^2 use
#axes = accel.getAxes(False)

#put the axes into variables
x = axes['x']
y = axes['y']
z = axes['z']

#print axes
print x
print y
print z
Change sensitivity
You can change the sensitivity of the ADXL345 by using the .setRange() method of the class.

The default range is 2g which means that the maximum G the ADXL345 can measure is 2.048, but at a high degree of sensitivity, you can change it so the maximum is 2g, 4g, 8g or 16g but with a lower level of sensitivity using:
accel.setRange(adxl345.RANGE_2G)
accel.setRange(adxl345.RANGE_4G)
accel.setRange(adxl345.RANGE_8G)
accel.setRange(adxl345.RANGE_16G)
Its a great accelerometer and really easy to use in your python projects.

13 comments:

  1. Hi,

    It doesn't work with my RPi Model B Rev 2. I tried all that you said in your post. I don't know why I can't read any address. I connected all wires in the correct gpio pin, so I don't understand (I have two Rpi, same model...same results)

    Can you help me?

    ReplyDelete
    Replies
    1. Hi,

      Does the module show up when you run sudo i2cdetect -y 1 ? Or are any errors shown?

      If there are no errors and it doesn't show up I suspect its either not wired up properly or doesn't work.

      Mart

      p.s. I wrote this setup based on a model b rev 2.

      Delete
  2. Hi,

    there is any error when I run sudo i2cdetect -y 1 .. I'll try with other sensor.

    Regards,

    ReplyDelete
  3. When you say "SDL", I assume you mean "SCL"?

    ReplyDelete
    Replies
    1. I do indeed, a slip of the keyboard. Post updated!

      Delete
  4. Could i connect multiple Accelerometers?

    ReplyDelete
    Replies
    1. yes sure its how you connect SD0 you can change the i2c bus adress
      with a other adress you can read a other device

      http://wiki.analog.com/resources/tools-software/linux-drivers/input-misc/adxl345

      Configuration

      Selectable ADXL34X I2C Device Address:
      SDO I2C Address
      0 0x53
      1 0x1D

      Delete
  5. I would like to use the accelerometer data to set off a buzzer if a car is tilted 15 degrees to horizontal. Any ideas how to do this in Python. I'm very new to this , but I'm trying hard to introduce the raspberry Pi into our high school curriculum. Any help much appreciated!!

    ReplyDelete
    Replies
    1. That doesnt sound too complicated. You will need to work out the maths to convert g to 3d angles (http://lmgtfy.com/?q=accelerometer+calculate+angle). Then an if statement and turn on a GPIO pin which is connected to a buzzer.

      Delete
  6. Why does it show ~1g on the Z axis while sitting stationary?

    In order to get an accurate reading while vibrating, should the ~1g be subtracted?

    Great write up, it's super appreciated!

    ReplyDelete
    Replies
    1. Right if I understand you correctly... It measures 1g on the Z axis (which is presumably down for you), because the earth is pulling it down to the tune of 1g!

      Delete
  7. Hi,
    Thank you for your tutorial, it is really helpful. It works perfectly on Python 2 (Idle) but I have problems on Python 3 (Idle3). Error message: "ImportError: No module named smbus". Any idea what to do?

    ReplyDelete
    Replies
    1. python-smbus is installed (newest version).

      Delete