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/modulesadd the following lines:
i2c-bcm2708 i2c-devRemove I2C from the blacklist:
sudo nano /etc/modprobe.d/raspi-blacklist.confcomment out:
blacklist i2c-bcm2708so its:
#blacklist i2c-bcm2708Reboot to make the changes:
sudo shutdown -r nowInstall Software
You will need to install some software:
sudo apt-get install python-smbus i2c-tools git-coreTest ADXL345
You can check that your ADXL345 is found on the I2C bus, by running:
sudo i2cdetect -y 1You should see a device at address 53
Download the ADXL345 pimoroni python library from github:
git clone https://github.com/pimoroni/adxl345-pythonRun the example code and test it is working:
cd adxl345-python sudo python example.pyYou 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 zChange 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.
Hi,
ReplyDeleteIt 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?
Hi,
DeleteDoes 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.
Connect the CS pin to HIGH (Vs / 3.3V). This fixed it for me.
DeleteThank you, Diego. Setting CS to high did it for me, too.
DeleteI would like to note that I needed to adjust the i2c to "enabled" using the pi button (top left) -> preferences -> pi config -> interfaces.
DeleteHi,
ReplyDeletethere is any error when I run sudo i2cdetect -y 1 .. I'll try with other sensor.
Regards,
When you say "SDL", I assume you mean "SCL"?
ReplyDeleteI do indeed, a slip of the keyboard. Post updated!
DeleteCould i connect multiple Accelerometers?
ReplyDeleteyes sure its how you connect SD0 you can change the i2c bus adress
Deletewith 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
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!!
ReplyDeleteThat 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.
DeleteWhy does it show ~1g on the Z axis while sitting stationary?
ReplyDeleteIn order to get an accurate reading while vibrating, should the ~1g be subtracted?
Great write up, it's super appreciated!
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!
DeleteHi,
ReplyDeleteThank 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?
python-smbus is installed (newest version).
DeleteHi
ReplyDeleteI got the wrong values. While not woving the acceleration is much greater then the acceleration of the earth. I ve got two sensors and both of them messure nearly the same wrong values. Cann you say me what to do?
Thanks for your help
What are the values?
DeleteFor instance:
Deleteroot@raspberry: /DatenManuel/ADXL345/adxl345-python# python example.py
ADXL345 on address 0x53:
x=-0.640G
y=-1.092G
z=2.044G
Do you have any idea how to fix that?
And that is when the accelerometer is flat on a surface not being moved? If so, no idea. Although if you minus out all the values you do get to about 1g. I wonder if it just needs calibrating, I never had to do mine but adafruit have a tutorial https://learn.adafruit.com/adxl345-digital-accelerometer/programming
DeleteThose are not invalid numbers. Could you describe us how is the accelerometer displayed over your test surface? May be necessary to calibrate the sensor in order to correct the baseline (removing the offset)
DeleteWhere did you buy your sensors?
Regards
News: z axis seems to be stuck on z=2.044G even if I move the sensor. x and y are changing the values.
ReplyDeleteroot@raspberrypi:/DatenManuel/ADXL345/adxl345-python# sudo python myexample.py
ReplyDeleteADXL345 on address 0x53:
x = -0.652G
y = -1.100G
z = 2.044G
x = -0.652G
y = -1.100G
z = 2.044G
x = -0.640G
y = -1.108G
z = 2.044G
x = -0.652G
y = -1.104G
z = 2.044G
x = -0.644G
y = -1.100G
z = 2.044G
x = -0.644G
y = -1.104G
z = 2.044G
x = -0.648G
y = -1.108G
z = 2.044G
x = -0.620G
y = -1.456G
z = 2.044G
x = -0.680G
y = -0.676G
z = 2.044G
x = -1.908G
y = -1.508G
z = 2.044G
Is it the ADXL345 accelerometer
Deletewell of corse... i just wrote myexample.py with a Loop to take several messurements instead of one ... i don't now what to do now....
DeletePerhaps try calibrating the accelerometer. Other than that, I would be tempted to start again. Reimage, reconnect, recode.
DeleteHow to calibrate? I don't understand how to manage to adapt the arduino tutorial to raspberry
DeleteSame issue here. Any updates?
DeleteHi, i follow the step exactly as you said.
ReplyDeleteI'm using Raspberry Pi 2, and the address I've got is !E instead...
When i run the python code, I get only one reading no matter how i move my accelerometer (ADXL345)
ADXL345 on address 0x1e:
x = 20.480G
y = 120.840G
z = 0.276G
mind helping??
Those values are definitely not right. are you sure these arent the readings from a different device? Im pretty sure this isnt from the accelerometer.
DeleteI record the time that I sample data. It appears that regardless of the value of BW_rate I enter, my rate hovers around 800 Hz. I have added a print statement, and the value that I expect gets passed into .setBandwidthRate. Any ideas as to what might be amiss? (I am actually using the SainSmart GY-85 board, a combo Accelerometer/compass/gyro, but it does use the ADXL345, and the address appears good and I am certainly getting good data from it.
ReplyDeleteSorry I dont have anything to add..
DeleteThis comment has been removed by the author.
DeleteDid your error get solved ?? @Allen Takahashi
DeleteHi it keeps showing importError: no module name adxl345 when I run it outside of the directory adxl345-Python. How do I get around this problem?
ReplyDeleteEither copy the adxl345.py into your programs folder or package up adxl345 as a python module and install it.
DeleteHi guys all is working well but would there be any way to make the ADXL345 take a consistent reading instead of having to hit enter every time?
ReplyDeleteYou should code some kind of trigger into a loop
Deleteregards
For the example you might use this too...
Deletewhile true; do clear; sudo python example.py; sleep .1; done;
I followed the instructions but when I input sudo i2cdetect -y 1 I get an error that says No such file or directory exist.
ReplyDeleteIts not an error ive seen before, it suggest i2cdetect isnt installed, are you using raspbian?
DeleteYour i2c is like still off. Use sudo raspi-config. select advanced options. and turn it on.
DeleteHi! when i run the command : sudo python example.py, i get this error
ReplyDeleteTraceback (most recent call last):
File "example.py", line 11, in
adxl345 = ADXL345()
File "/home/pi/adxl345-python/adxl345.py", line 47, in __init__
self.setBandwidthRate(BW_RATE_100HZ)
File "/home/pi/adxl345-python/adxl345.py", line 55, in setBandwidthRate
bus.write_byte_data(self.address, BW_RATE, rate_flag)
IOError: [Errno 5] Input/output error
I change the command to sudo python3.2 example.py to run it to python 3 and i get this error:
DeleteFile "example.py", line 14
print "ADXL345 on address 0x%x:" % (adxl345.address)
^
SyntaxError: invalid syntax
The code isn't python 3 compatible, hence why you get a syntax error.
DeleteThe input/output error suggests the Pi cant talk to the module.
This post is a little old, I dont know if the methods of enabling I2C have changed. I vaguely remember there is an option in raspi-config to enable I2C nowadays.
This comment has been removed by the author.
Deletei am using different adxl345 not from adafruit and when i use sudo i2cdetect -y 1 i get this result:
Delete0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- 1d -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
i believe this adxl345 is using the address 1D. Please correct me if i am wrong
Well something is using 1d for sure..
DeleteI had a quick look at pimoroni's library and you can pass in an address when you invoke the ADXL345 class, other than the default 53.
So:
accel = adxl345.ADXL345(0x1d)
Whether the library will work with your accelerometer is a different question!
ok thank you! i will try it
DeleteBig thanks! I did what you said and i think it now working. You are right that it is not compatible to python 3 because i still get errors when i run it with it.
DeleteHI! can I ask if you could explain to me the following lines of code in your program?
Deletebytes = bus.read_i2c_block_data(self.address, AXES_DATA, 6)
x = bytes[0] | (bytes[1] << 8)
if(x & (1 << 16 - 1)):
x = x - (1<<16)
y = bytes[2] | (bytes[3] << 8)
if(y & (1 << 16 - 1)):
y = y - (1<<16)
z = bytes[4] | (bytes[5] << 8)
if(z & (1 << 16 - 1)):
z = z - (1<<16)
Thanks in advance
It is just pulling the x,y,z values from the raw data stream that gets returned from the accelerometer.
Delete@Mark Aala, how did you sort out the issue of python
Deleteprint "ADXL345 on address 0x%x:" % (adxl345.address)
^
SyntaxError: invalid syntax
Following was my output
pi@raspberrypi ~/adxl345-python $ sudo i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- 04 05 06 -- 08 09 0a -- 0c 0d 0e --
10: 10 11 12 -- 14 15 16 -- 18 19 1a -- 1c 1d 1e --
20: 20 21 22 -- 24 25 26 -- 28 29 2a -- 2c 2d 2e --
30: 30 -- 32 -- 34 -- 36 -- 38 39 3a -- 3c 3d 3e --
40: 40 41 42 -- 44 45 46 -- 48 49 4a -- 4c 4d 4e --
50: 50 -- 52 -- 54 -- 56 -- 58 -- 5a -- 5c -- 5e --
60: 60 61 62 -- 64 65 66 -- 68 69 6a -- 6c 6d 6e --
70: 70 71 72 -- 74 75 76 --
I was wondering how to get M/S using this accelerometer. Any help would be appreciated!
ReplyDeleteHi, Will...what does M/S means for you? Are you thinking in velocity units? This kind of accelerometer isn't good enough for that kind of integration, unless you will measure high amplitude (in acceleration)
ReplyDeletePlease, specify your question
Mine says "ImportError: No module named adxl345", please help :/
ReplyDeleteHave you downloaded the adxl345.py code from pimoroni?
Deletez axis also stuck at 2.044 please help.
ReplyDeleteThank you for given the program.i got output. and then, how to check activity & inactivity detection? Please help me
ReplyDeleteYou need to look for changes in the x,y,z values. A big change in one of the values will tell you which way it has moved.
DeleteHi guys; on my Pi3 it's nice working, but I would need measurements over a longer time (for example for 20 seconds and one dataset every millisecond) is that possible?
ReplyDeletewhen i am using this cd adxl345-python i am getting an error like bash: cd: /home/pi/adxl345-python: Not a directory what should i supose to do pls whatsapp me .i am in my death line of my project pls help me my whats app number is +919809915235
ReplyDeleteDid You git clone https://github.com/pimoroni/adxl345-python ??
DeleteAs Surendra says, if you didnt clone or the clone failed the code wont have been downloaded into the adxl345-python library, so when you cd (change directory) to it, it wont be there.
DeleteHi. I followed all instructions but when I do the command i2cdetect -y 1 the list is empty. It's not finding any i2c connection. I'm sure I connected all jumpers correctly, +3.3V to 3V3, -3.3V to GND(tried GND to GND), SDA to SDA and SCL to SCL. I'm using a Raspberry pi 3 model B
ReplyDelete