Read the ADXL345 accelerometer with Raspberry Pi, using SPI bus

I recently had to read the Analog Devices ADXL345 accelerometer, using SPI. So I used the Raspberry Pi. I only needed to verify the functionality in Python, so the code do have some rough edges, when it comes to the calculation of the gravity, but the code that reads the device is correct.

Note: You need to have the python-dev package installed, along with the SpiDev. You can get the former, using apt-get, but you have to install SpiDev manually.

Another note, and this is important; You shouldn’t set the spi.mode = 3 field before calling the open() function. I have no idea what so ever why, but the SPI on the Raspberry Pi, will absolutely not work for me, if I do that.

The code is provided, here below:

#!/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(0,0)
spi.mode = 3

# Read the Device ID (should be xE5)
id = spi.xfer2([128,0])
print 'Device ID (Should be 0xE5):\n'+str(hex(id[1])) + '\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[1]
print yoffset[1]
print str(zoffset[1]) + "\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])

    # 
    out = [rx[1] | (rx[2] << 8),rx[3] | (rx[4] << 8),rx[5] | (rx[6] << 8)]
    # Format x-axis
    if (out[0] & (1<<16 - 1 )):
        out[0] = out[0] - (1<<16)
    out[0] = out[0] * 0.004 * 9.82
    # Format y-axis
    if (out[1] & (1<<16 - 1 )):
        out[1] = out[1] - (1<<16)
    out[1] = out[1] * 0.004 * 9.82
    # Format z-axis
    if (out[2] & (1<<16 - 1 )):
        out[2] = out[2] - (1<<16)
    out[2] = out[2] * 0.004 * 9.82

    return out

# Initialize the ADXL345 accelerometer
initadxl345()

# Read the ADXL345 every half second
timeout = 0.5
while(1):
    axia = readadxl345()
    # Print the reading
    print axia[0]
    print axia[1]
    print str(axia[2]) + '\n'

    elapsed = time.clock()
    current = 0
    while(current < timeout):
        current = time.clock() - elapsed

Eternity 2

I’ve been writing a solver for the Eternity 2 puzzle. Here’s a sample, when setting the dimensions to 4×4. The puzzle itself is 16×16.

It’s written in Python, which of course is not the optimal language, but performance wasn’t the goal anyway.

The goal, amongst others, was to explore techniques for solving the puzzle, and to get more into Python.

More to come on this…


ET2Mini16

 

ET2_Triangle

The solver now, partially at least, works in a distributed environment, using sockets for communication. Some features that might be handy, if the solver should ever find a solution are missing, but that was never the point of this project anyway. More to come on the distributed solver as well.

I’ve built a small cluster of Raspberry Pi’s for testing:

PiCluster1

Interfacing Raspberry Pi and Microchip MCP3304 SPI ADC

Alright. So a lot of people on blogs and forums have been busy interfacing the MCP 3008 DAC to the Raspberry Pi.

But when I came to need one, RS Components, where i do most almost all of my shopping for components, couldn’t supply one, I had to buy another one.

Still cheap, the MCP3304, but with some minor differences. It can be configured to take both single ended and balanced input, and it has 13 bits (12 unsigned), rather than the 10 positive signed bits the MCP3008 offers.

I used Python as language and adjusted some code i found on this blog: http://jeremyblythe.blogspot.dk/2012/09/raspberry-pi-hardware-spi-analog-inputs.html

The Python code:
SPI_MCP3308.py

#!/usr/bin/python
# -*- coding: utf-8 -*-
# mcp3008_lm35.py - read an LM35 on CH0 of an MCP3008 on a Raspberry Pi
# mostly nicked from
#  http://jeremyblythe.blogspot.ca/2012/09/raspberry-pi-hardware- spi-analog-inp$
# Changed to work w. MCP3308 by Kim H. Rasmussen, June 2013
import spidev
import time

spi = spidev.SpiDev()
spi.open(0, 0)

def readadc(adcnum):

 # read SPI data from MCP3008 chip, 8 possible adc's (0 thru 7)
 if adcnum > 7 or adcnum < 0:
    return -1

 # Frame format: 0000 1SCC | C000 000 | 000 000
 r = spi.xfer2([((adcnum & 6) >> 1)+12 , (adcnum & 1) << 7, 0])
 adcout = ((r[1] & 15) << 8) + r[2]
 return adcout

while True:

   # Read from ADC channels and convert the bits read into the voltage
   ch1 = (readadc(1) * 3.3) / 4095
   ch2 = (readadc(2) * 3.3) / 4095
   # Divisor changed from 1023 to 4095, due to 4 more bits
   # Print the stuff just read
   print ('Voltages: ', ch1, ' ', ch2)

   time.sleep(1)

Prerequisites:

Install Python development package:

sudo apt-get update && sudo apt-get install python-dev

Enable SPI to be loaded into the kernel on boot:

sudo raspi-config

And enable SPI on boot in The advanced menu <8>.

Install spi-dev via a terminal:

git clone git://github.com/doceme/py-spidev

cd py-spidev/

sudo python setup.py install