ADXL345 range setting on micropython

All ESP32 boards running MicroPython.
Target audience: MicroPython users with an ESP32 board.
Post Reply
davidbogatec
Posts: 9
Joined: Tue Feb 04, 2020 3:23 pm

ADXL345 range setting on micropython

Post by davidbogatec » Tue Feb 04, 2020 3:33 pm

I want to set the 16g range of the accelerometer. The default range is 2G. Where I need to specify this in the below code?

Code: Select all

from machine import Pin,I2C
import math
import time

device = const(0x53)
regAddress = const(0x32)
TO_READ = 6
buff = bytearray(6)
class ADXL345:
    def __init__(self,i2c,addr=device):
        self.addr = addr
        self.i2c = i2c
        b = bytearray(1)
        b[0] = 0
        self.i2c.writeto_mem(self.addr,0x2d,b)
        b[0] = 16
        self.i2c.writeto_mem(self.addr,0x2d,b)
        b[0] = 8
        self.i2c.writeto_mem(self.addr,0x2d,b)

    @property
    def xValue(self):
        buff = self.i2c.readfrom_mem(self.addr,regAddress,TO_READ)
        x = (int(buff[1]) << 8) | buff[0]
        if x > 32767:
            x -= 65536
        return x
   
    @property
    def yValue(self):
        buff = self.i2c.readfrom_mem(self.addr,regAddress,TO_READ)
        y = (int(buff[3]) << 8) | buff[2]
        if y > 32767:
            y -= 65536
        return y
     
    @property   
    def zValue(self): 
        buff = self.i2c.readfrom_mem(self.addr,regAddress,TO_READ)
        z = (int(buff[5]) << 8) | buff[4]
        if z > 32767:
            z -= 65536
        return z
           
    def RP_calculate(self,x,y,z):
        roll = math.atan2(y , z) * 57.3
        pitch = math.atan2((- x) , math.sqrt(y * y + z * z)) * 57.3
        return roll,pitch
    

cgglzpy
Posts: 33
Joined: Thu Jul 18, 2019 4:20 pm

Re: ADXL345 range setting on micropython

Post by cgglzpy » Tue Feb 04, 2020 6:38 pm

Hi,

You can see this in the data sheet: ADXL345
[Page 26-27] Register 0x31—DATA_FORMAT (Read/Write) --> Range Bits D1-D0

So you need to write to register 0x31 the byte 0x03 which is 0b00000011 (see Table 21) setting bits D1-D0 to 1.

In code should be something like:

Code: Select all

reg_DATA_FORMAT = const(0x31)
and inside 'def __init__' method add:

Code: Select all

b[0] = 3
self.i2c.writeto_mem(self.addr,reg_DATA_FORMAT,b)
I can't test this but I think this is the way.

davidbogatec
Posts: 9
Joined: Tue Feb 04, 2020 3:23 pm

Re: ADXL345 range setting on micropython

Post by davidbogatec » Wed Feb 05, 2020 8:46 am

Hi cgglpzy and thanks for your prompt reply.
i've insert the suggested lines in the code but nothing happens.
Where is the error?

from machine import Pin,I2C
import math
import time

device = const(0x53)
regAddress = const(0x32)
TO_READ = 6
buff = bytearray(6)
reg_DATA_FORMAT = const(0x31)

class ADXL345:
def __init__(self,i2c,addr=device):
self.addr = addr
self.i2c = i2c
b = bytearray(1)
b[0] = 0
self.i2c.writeto_mem(self.addr,0x2d,b)
b[0] = 16
self.i2c.writeto_mem(self.addr,0x2d,b)
b[0] = 8
self.i2c.writeto_mem(self.addr,0x2d,b)
b[0] = 3
self.i2c.writeto_mem(self.addr,reg_DATA_FORMAT,
b)

@property
def xValue(self):
buff = self.i2c.readfrom_mem(self.addr,regAddress,TO_READ)
x = (int(buff[1]) << 8) | buff[0]
if x > 32767:
x -= 65536
return x

@property
def yValue(self):
buff = self.i2c.readfrom_mem(self.addr,regAddress,TO_READ)
y = (int(buff[3]) << 8) | buff[2]
if y > 32767:
y -= 65536
return y

@property
def zValue(self):
buff = self.i2c.readfrom_mem(self.addr,regAddress,TO_READ)
z = (int(buff[5]) << 8) | buff[4]
if z > 32767:
z -= 65536
return z

def RP_calculate(self,x,y,z):
roll = math.atan2(y , z) * 57.3
pitch = math.atan2((- x) , math.sqrt(y * y + z * z)) * 57.3
return roll,pitch

cgglzpy
Posts: 33
Joined: Thu Jul 18, 2019 4:20 pm

Re: ADXL345 range setting on micropython

Post by cgglzpy » Thu Feb 06, 2020 3:58 pm

i've insert the suggested lines in the code but nothing happens.
Hmm, maybe because of this
From the data sheet Page 26:
All data, except that for the ±16 g range, must be clipped to avoid rollover
So I think you have to comment or erase the "if x > 32767" lines.
Something like this:

Code: Select all

def xValue(self):
    buff = self.i2c.readfrom_mem(self.addr,regAddress,TO_READ)
    x = (int(buff[1]) << 8) | buff[0]
    # if x > 32767: # These two lines is to "clip" the data to avoid rollover
    #     x -= 65536 # They are necessary for ranges 2g-8g but not for 16g range
    return x
Also do the same with yValue and zValue methods.
If this does not solve it then I don't know what can it be :?

Post Reply