ADXL345 with Pyboard

The official pyboard running MicroPython.
This is the reference design and main target board for MicroPython.
You can buy one at the store.
Target audience: Users with a pyboard.
Abhinay_1
Posts: 6
Joined: Tue Apr 05, 2016 6:28 am

ADXL345 with Pyboard

Post by Abhinay_1 » Tue Apr 05, 2016 6:55 am

Hi all,
Last edited by Abhinay_1 on Mon Apr 18, 2016 11:05 am, edited 4 times in total.

Jim.S
Posts: 84
Joined: Fri Dec 18, 2015 7:36 pm

Re: Interfacing Sparkfun ADXL345 with Pyboard.

Post by Jim.S » Wed Apr 06, 2016 7:58 pm

if you search this forum for the ADXL345 you will find that other people have got this working with the pyboard. But other accelerometer (and IMU) boards such as the IMU9250 and LSM9DS0 have a more developed code base. I think you will have to rewrite any code that interfaces with the pyboard hardware but you might be able to reuse any other code. For instance, writing to a file in Python is the same if it is linux or the pyboard. The snippet of code below reads and writes to files on the pyboard, but probably will run on linux (with only a change in filesystem name)

Code: Select all

    with open('/sd/testx.bin', "rb") as f, open('out.csv','w') as c:
        c.write(out_file_header)
        for line in read_bin_lines(f,x_str,x_bytes):
            c.write(INT.format(*line))
I'm writing some code to log data from the IMU9250 using the i2c interface. Currently I can samples four pieces of data per second (one voltage and three accelerations) and write them to a binary file, 350 times per second. My code is over complex, and SPI might be faster

(On a philosophical note, don't wish for too much success on your project because you will learn far more from your mistakes)

Abhinay_1
Posts: 6
Joined: Tue Apr 05, 2016 6:28 am

Re: Interfacing Sparkfun ADXL345 with Pyboard.

Post by Abhinay_1 » Fri Apr 08, 2016 12:55 pm

Hello,

could someone help me in this. My idea is to interface the sparkfun ADXL345 with the pyboard through SPI communication, and log the data in to the SD card. please help me with code. Im new to programming and pyboard too.

Thing is I have done the program in python for the same application using raspberry pi. But I am very confused with this.
Any suggestion could be a great help for me.

Hope I get this porblem solved.

Thanks,

Regards,
ABHI

User avatar
platforma
Posts: 258
Joined: Thu May 28, 2015 5:08 pm
Location: Japan

Re: Interfacing Sparkfun ADXL345 with Pyboard.

Post by platforma » Fri Apr 08, 2016 1:28 pm

Please don't cross-post in multiple topics. This is a good place to keep the thread, the others are removed.

Abhinay_1
Posts: 6
Joined: Tue Apr 05, 2016 6:28 am

Re: Interfacing Sparkfun ADXL345 with Pyboard.

Post by Abhinay_1 » Mon Apr 11, 2016 12:10 pm

Hello everyone,

does anyone know how to change this code, to code that will be compatible with pyboard. Thank you.

Code: Select all

import time 
import spidev
import datetime
import RPi.GPIO as GPIO

spi = spidev.SpiDev()

spi.open(0,0)
spi.max_speed_hz = 2000000
spi.mode = 3

pinNum = 21

GPIO.setmode(GPIO.BCM)
GPIO.setup(pinNum,GPIO.IN)

id = spi.xfer2([128,0])

#print 'Device ID (Should be 0xE5):\n'+str(hex(id[1])) + '\n'

xoffset = spi.xfer2([30 | 128,0])
yoffset = spi.xfer2([31 | 128,0])
zoffset = spi.xfer2([32 | 128,0])

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

    # Set data rate to 3200 Hz
    spi.xfer2([44, 15])

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

    # Enable measurement
    spi.xfer2([45, 8])

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

axia = datetime.datetime.now().strftime("%y%m%d-%H%M%S")
f = open('/home/pi/Documents/Vibration/' + axia + '.txt', 'a')

def writetofilex(A,B,C):
               
         f.write(str(datetime.datetime.now()) + " " + " X= " + str(A) + " " + " Y= " + str(B) + " " + " Z= " + str(C)) # each data set is time stamped
         f.write("\n")
       

# Initialize the ADXL345 accelerometer
initadxl345()
 
while True:     
     
  axia = readadxl345()
        
  writetofilex(axia[0], axia[1], axia[2])
    
  if(GPIO.input(pinNum)):  
   
      
     break

User avatar
platforma
Posts: 258
Joined: Thu May 28, 2015 5:08 pm
Location: Japan

Re: Interfacing Sparkfun ADXL345 with Pyboard.

Post by platforma » Mon Apr 11, 2016 12:19 pm

Hi Abhi,

As I mentioned before, please do not cross-post in different topics or describe your problem in several different ways in multiple threads, this probably won't help you any quicker. I am going to merge all 4 of your topics into one, since they're pretty much all talking about using ADXL345 accelerometer.

As a note: It is probably not the best way to just ask people to "translate" you code from one device to another, you ought to read and understand the basics yourself, together with Micropython Docs and whatever you used to write your RPi2 code. Jim.S has pointed you in the right direction and the fact that people already have gotten ADXL345 to work with pyboard. Do use the search function and keep your thread updated with your progress and findings.

Abhinay_1
Posts: 6
Joined: Tue Apr 05, 2016 6:28 am

Re: Interfacing Sparkfun ADXL345 with Pyboard.

Post by Abhinay_1 » Tue Apr 12, 2016 9:37 am

Hello,

Can someone help me how to read the x,y,z offsets through spi in Micropython.

Here is the corresponding python code.

Code: Select all

xoffset = spi.xfer2([30 | 128,0])
yoffset = spi.xfer2([31 | 128,0])
zoffset = spi.xfer2([32 | 128,0])

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

    # Set data rate to 3200 Hz
    spi.xfer2([44, 15])

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

    # Enable measurement
    spi.xfer2([45, 8])


Turbinenreiter
Posts: 288
Joined: Sun May 04, 2014 8:54 am

Re: Interfacing Sparkfun ADXL345 with Pyboard.

Post by Turbinenreiter » Tue Apr 12, 2016 5:38 pm

Why don't you read the docs?

http://docs.micropython.org/en/latest/p ... b.SPI.html
https://github.com/doceme/py-spidev
https://www.sparkfun.com/datasheets/Sen ... DXL345.pdf

All you need to do is figure out what the spidev functions do and replace them with the pyb.SPI functions.

Maybe you should use I2C instead of SPI. I find it to be easier.
Here is a library using I2C:
https://github.com/pimoroni/adxl345-pyt ... adxl345.py

Instead of

Code: Select all

smbus
, use

Code: Select all

pyb.I2C
and create an I2C bus with that.

Code: Select all

bus.i2c = I2C(1, I2C.MASTER)
Then,

Code: Select all

bus.read_i2c_block_data(address of device, address in memory, number of bytes)
has to replaced with:

Code: Select all

i2c_bus.mem_read(number of bytes, address of device, address in memory)
This is the I2C doc:
http://docs.micropython.org/en/latest/p ... b.I2C.html

I know reading docs suck, but honestly, nobody here will do it for you.

Abhinay_1
Posts: 6
Joined: Tue Apr 05, 2016 6:28 am

Re: Interfacing Sparkfun ADXL345 with Pyboard.

Post by Abhinay_1 » Wed Apr 13, 2016 9:05 am

Hi Turbinenreiter,
Thanks for the info, but my application itself is to design a data logger for higher output sample rate. So I must go with SPI.

Regards,
Abhi
Last edited by Abhinay_1 on Wed Apr 13, 2016 10:03 am, edited 1 time in total.

Abhinay_1
Posts: 6
Joined: Tue Apr 05, 2016 6:28 am

Re: Interfacing Sparkfun ADXL345 with Pyboard.

Post by Abhinay_1 » Wed Apr 13, 2016 9:59 am

Hi all,

With some reference and modicafication, I think I got the driver for ADXL345 for the pyboard. can some one help me, how to to log the data of x,y,z axes to a text file. for this code.

Code: Select all

from pyb import Pin
from pyb import SPI

READWRITE_CMD = const(0x80)
MULTIPLEBYTE_CMD = const(0x40)
DEVID_ADDR = const(0x00)
DATAX1_ADDR = const(0x33)
DATAY1_ADDR = const(0x35)
DATAZ1_ADDR = const(0x37)

ADXL345_DEVID_VAL = const(0xE5)
ADXL345_POWER_CTL_ADDR = const(0x2D)
ADXL345_BW_RATE_ADDR = const(0x2C)
ADXL345_DATA_FORMAT_ADDR = const(0x31)
ADXL345_ENABLE_MSRM_ADDR = const(0x2D)

ADXL345_POWER_CTL_CONF = const(0x00)
ADXL345_BW_RATE_CONF = const(0x0F)
ADXL345_DATA_FORMAT_CONF = const(0x10)
ADXL345_ENABLE_MSRM_CONF = const(0x08)

class ADXL345Accel:
        def _init_(self):
                self.cs_pin = Pin('X5', Pin.OUT_PP, Pin.PULL_NONE)
                self.cs_pin.high()
                self.spi = SPI(1, SPI.MASTER, baudrate=2000000, polarity=0, phase=1, bits=8)
                
                self.devid = self.read_id()
                if self.devid == ADXL345_DEVID_VAL:
                      self.write_bytes(ADXL345_POWER_CTL_ADDR, bytearray([ADXL345_POWER_CTL_CONF]))
                      self.write_bytes(ADXL345_BW_RATE_ADDR, bytearray([ADXL345_BW_RATE_CONF]))
                      self.write_bytes(ADXL345_DATA_FORMAT_ADDR, bytearray([ADXL345_DATA_FORMAT_CONF]))
                      self.write_bytes(ADXL345_ENABLE_MSRM_ADDR, bytearray([ADXL345_ENABLE_MSRM_CONF]))
                      self.sensitivity = 32
                else:
                      raise Exception('ADXL345 accelerometer not present')
     def convert_raw_to_g(self, x):
             if x & 0x80:
                   x = x - 256
             return x * self.sensitivity / 1000
  def read_bytes(self, addr, nbytes):
          if len(buf) > 1:
         addr |= MULTIPLEBYTE_CMD
    self.cs_pin.low()
    self.spi.send(addr)
    for b in buff:
     self.spi.send(b) 
                 self.cs_pin.high()
        def read_id(self):
                return self.read_bytes(DEVID_ADDR, 1)[0]
        def x(self):
                return self.convert_raw_to_g(self.read_bytes(DATAX1_ADDR, 1)[0])
        def y(self):                                                                                                                                
                return self.convert_raw_to_g(self.read_bytes(DATAY1_ADDR, 1)[0])
        def z(self):
                return self.convert_raw_to_g(self.read_bytes(DATAZ1_ADDR, 1)[0])
        def xyz(self):
                return (self.x(), self.y(), self.z())
Thnaks,

Regards,
Abhi

Post Reply