My accelerometer is connected to spidev2.0 (pins 1, 3, 28, 29, 30, 31). Overlays are loaded correctly, HDMI is turned off, ports are tested using Molloy’s spidev_test.c and to this point things are good.I have a problem with reading the data from accelerometer ADXL345 via SPI port using Python code I found on http://www.havnemark.dk/?p=148 (‘Read the ADXL345 accelerometer with Raspberry Pi, using SPI bus’). Main problem is that I don’t know how to use spidev Python library and I am not sure how SPI communication goes, although I am aware of the SPI principle thats says “if you want to send the data to read the data”. It would be much easier for me if you can explain me what and how to send and how to read data.
I successfully connected sensor via I2C port and was able to read the accelerations. Everything worked perfectly and I get the idea behind I2C, which goes like this (please correct me if I am wrong): Device has its address (ADXL345 has 0x53 or 0x1d, it was 0x1d in my case). First, by going to address you go to a register which has 64 bytes. In register every byte is used for controlling sensor or for storing data that sensor acquires. Every one of these bytes has its position from 0x00 to 0x3f, and some values are stored in these bytes. For example, device ID is stored in byte at position 0x00, and value of device ID is always 0xe5. On the other hand at position 0x2d we can turn on or turn off accelerometar by writing a desired value to this byte, value of 0x08 will set the accelerometar in measurement mode. And then we need to read bytes from position 0x32 to position 0x37 to read the accelerations. For every axis (X, Y, Z) value of acceleration is stored in 2 bytes (because we have resoultions of 10 or 13 bits. After reading these bytes we combine values to get voltage and after that by using some math we can get accelerations in m/s^2 or g’s or whatever we like.
And I know that I must to do similar things when communicating via SPI but I don’t know how to read or write the register values. So my questions are:
How to read the register data using spidev package. How would line of code that says “Go to address XxXX and read the value at the position YxYY” look like?
By using code from question 1 how would line that returns device ID look like.
How to write the data to the register? How would line of code that says “Go to address XxXX and write the value ZxZZ at the position YxYY” look like?
By using code from question 3 how to set the accelerometer in the measurement mode
How to combine bytes where the values of accelerations are stored? For example if I have 10 bit resolution I would have to combine first byte with last two bits of second byte. Then by multiplying the value of combination of bytes with 3.3 and then dividing with 1024 I would get a voltage. And then by knowing the range of measurement I can translate that in acceleration. How to do whole proccess?
Here is the code I used:
#!/usr/bin/python # -*- coding: utf-8 -*- # Example on how to read the ADXL345 accelerometer. # Kim H. Rasmussen, 2014 import time import spidev # Setup SPI spi = spidev.SpiDev() #spi.mode = 3 <-- Important: Do not do this! Or SPI won't work as intended, or even at all. spi.open(2,0) spi.mode = 3
spi.max_speed_hz = 3500000 # Read the Device ID (should be xE5) id = spi.xfer2([128,0]) print 'Device ID (Should be 0xE5):\n'+str(hex(id)) + '\n' # Read the offsets xoffset = spi.xfer2([30 | 128,0]) yoffset = spi.xfer2([31 | 128,0]) zoffset = spi.xfer2([32 | 128,0]) print 'Offsets: ' print xoffset print yoffset print str(zoffset) + "\n\nRead the ADXL345 every half second:" # Initialize the ADXL345 def initadxl345(): # Enter power saving state spi.xfer2([45, 0]) # Set data rate to 100 Hz spi.xfer2([44, 10]) # Enable full range (10 bits resolution) and +/- 16g 4 LSB spi.xfer2([49, 16]) # Enable measurement spi.xfer2([45, 8]) # Read the ADXL x-y-z axia def readadxl345(): rx = spi.xfer2([242,0,0,0,0,0,0])