I have an ADXL345 Accelerometer attached via SPI pins to my Raspberry Pi. I use the following Python script to collect data:

# -*- coding: utf-8 -*-
import sys, math, os, spidev, datetime, ftplib

# Setup SPI
spi = spidev.SpiDev()
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])
accres = 2
accrate = 15

print 'Offsets: '
print xoffset[1]
print yoffset[1]

# Initialize the ADXL345
def initadxl345():
   # Enter power saving state
   spi.xfer2([45, 0])

   # Set data rate (accrate = 15 -> 3200 Hz, 14=1600 Hz, 13=800 Hz, 12=400 Hz etc.)
   spi.xfer2([44, accrate])

   # Enable full range (10 bits resolution) and +/- 16g 4 LSB
   spi.xfer2([49, accres])

   # 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)
   # Format y-axis
   if (out[1] & (1<<16 - 1 )):
      out[1] = out[1] - (1<<16)
   # Format z-axis
   if (out[2] & (1<<16 - 1 )):
      out[2] = out[2] - (1<<16)

   return out

# Initialize the ADXL345 accelerometer

# Read the ADXL345 every half second
timetosend = 60
   with open('/proc/uptime', 'r') as f: # get uptime
     uptime_start = float(f.readline().split()[0])
   uptime_last = uptime_start
   active_file_first = "S1-" + str(pow(2,accrate)*25/256) + "hz10bit" + $
   active_file = active_file_first.replace(":", ".")
   wStream = open('/var/log/sensor/' + active_file,'wb')
   finalcount = 0
   print "Creating " + active_file
   while uptime_last < uptime_start + timetosend:
      finalcount += 1
      time1 = str(datetime.datetime.now().strftime('%S.%f'))
      time2 = str(datetime.datetime.now().strftime('%M'))
      #time3 = str(datetime.datetime.now().strftime('%H'))
      #time4 = str(datetime.datetime.now().strftime('%d'))
      #time6 = str(datetime.datetime.now().strftime('%Y'))
      axia = readadxl345()
      with open('/proc/uptime', 'r') as f:
           uptime_last = float(f.readline().split()[0])

def doftp(the_active_file):
   session = ftplib.FTP('','sensor1','L!ghtSp33d')
   file = open('/var/log/sensor/' + active_file, 'rb')    # file to send
   session.storbinary('STOR ' + active_file, file)        # send the file
   file.close()                                           # close file and FTP

As you can tell from the script I can give my ADXL345 Accelerometer a Sample Rate (e.g. 3200 Hz). However when I go through the logged data (no matter what Sample Rate I chose) there always seems to be a problem.

It feels like the Raspberry Pi or SPi pins have a Sample Rate of their own (?) around (2000-2400 Hz) which ruins the data collected. That Sample Rate even varies throughout the tests which results in different amount of data points over e.g. 10 seconds. Sometimes I get more data points than the previous test and sometimes fewer.

Is it something in my script causing this issue? Does the SPI pins have a Sample Rate of their own or what's going on here?

OBS! I'm new to Python and the abovementioned script is one I found online. I have only done edits.


Setting a sample rate of 3200 samples per second is a setting for the ADXL345. Transferring 3200 samples per second, which is presumably what you want to do, is not quite so simple.

There will be the time to transfer each reading over the physical link. This depends on what SPI clock rate in bits per second you are using. From memory the X, Y, and Z data is each two bytes long, so 16 bits each for a total of 48 bits. Divide the SPI clock rate by 48 to get the maximum number of samples you can transfer per second.

Then there will be the overhead of each SPI transfer (the spi.xfer2 call). This will be partly the Linux SPI driver overhead and partly the Python overhead. You are doing three calls per sample. That is wasteful, you could do one read of 6 bytes.

Then you have the general Python interpreter overhead to do all the looping and calculations. A compiled language such as C would be much more efficient.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.