ADXL 345 (from Adafruit)



  • Has anyone already written a library for this sensor? Or are in the proces of doing so?
    Am a bit lost at the moment on how to write the sensor driver.

    The sensor is this one https://www.adafruit.com/products/1231



  • @Lokefar Can you post the final working code for this sensor with lopy 4?



  • @Lokefar I'm happy to help with clean up and testing your code.



  • @livius Yup I got it working. Just looking into cleaning up the code and add a few things then I will make it available for all to use :)



  • @Lokefar any progress? :)



  • @Lokefar said in ADXL 345 (from Adafruit):

    I noticed that you changed BW_RATE to an int instead of a hex. Tried changing DATA_FORMAT to 49 but that didn't solve the issue.

    i revert this - this was only my try and forgot to revert

    this line should be:

    value = i2c.readfrom_mem(self.addr, DATA_FORMAT, range_flag)
    


  • @bucknall Will do :)



  • @livius Thanks for the fixes. However, I still get an error:

      File "main.py", line 79, in <module>
      File "main.py", line 27, in __init__
      File "main.py", line 39, in setRange
    TypeError: can't convert bytes to int
    

    The problem seems to be with this line:

    value = i2c.readfrom_mem(self.addr, DATA_FORMAT, bytes([range_flag]))
    

    I noticed that you changed BW_RATE to an int instead of a hex. Tried changing DATA_FORMAT to 49 but that didn't solve the issue.



  • Hey @Lokefar this looks really cool! I'd love to add it to our libraries repository on GitHub!

    When you finish and wish to share it, feel free to drop a pull request at https://github.com/pycom/pycom-libraries and we'll happily add it to our example library :)



  • @Lokefar

    i do not have this sensor to test but i have fixed some errors:

    import time
    from machine import I2C
    
    
    ADXL345_ADDR = 0x53
    
    i2c = I2C(0, I2C.MASTER, baudrate=100000)
    
    BW_RATE_100HZ = 0x0B
    POWER_CTL = 0x2D 
    MEASURE = 0x08
    DATA_FORMAT = 0x31
    AXES_DATA = 0x32
    BW_RATE = 0x2C
    RANGE_2G = 0x00
    SCALE_MULTIPLIER = 0.004
    EARTH_GRAVITY_MS2 = 9.80665
    
    class ADXL345(object):
    	
    
    	def __init__(self, i2c=None):
    		self.i2c = i2c
    		self.addr = ADXL345_ADDR
    		print('One')
    		self.setBandwidthRate(BW_RATE_100HZ)
    		self.setRange(RANGE_2G)
    		self.enableMeasurement()
    
    	def enableMeasurement(self):
    		i2c.writeto(self.addr, bytes([POWER_CTL]))
    		i2c.writeto(self.addr, bytes([MEASURE])) 
    
    	def setBandwidthRate(self, rate_flag):
    		print('Two')
    		i2c.writeto_mem(self.addr, BW_RATE, bytes([rate_flag]))
    
    	def setRange(self, range_flag):
    		value = i2c.readfrom_mem(self.addr, DATA_FORMAT, bytes([range_flag]))
    		print('here')
    		value &= ~0x0F;
    		value |= range_flag;
    		value |= 0x08;
    
    		i2c.writeto(self.addr, DATA_FORMAT, value)
    
    	def getAxes(self, gforce = False):
    		bytes = i2c.readfrom(self.addr, AXES_DATA, 6)
    
    		x = bytes[0] | (bytes[1] << 8)
    		if(x & (1 << 16 - 1)):
    			x = x - (1<<16)
    
    		y = bytes[2] | (bytes[3] << 8)
    		if(y & (1 << 16 - 1)):
    			y = y - (1<<16)
    
    		z = bytes[4] | (bytes[5] << 8 )
    		if(z & (1 << 16 - 1)):
    			z = z - (1<<16)
    
    		x = x * SCALE_MULTIPLIER
    		y = y * SCALE_MULTIPLIER
    		z = z * SCALE_MULTIPLIER
    
    		if gforce == False: 
    			x = x * EARTH_GRAVITY_MS2
    			y = y * EARTH_GRAVITY_MS2
    			z = z * EARTH_GRAVITY_MS2
    
    		x = round(x,4)
    		y = round(y,4)
    		z = round(z,4)
    
    		return {"x": x, "y": y, "z": z}
    print('Start')
    
    for i in range(0,10):
    	adxl345 = ADXL345()
    	axes = adxl345.getAxes(True)
    	print(axes['x'])
    	sleep_ms(25)
    


  • @Lokefar

    I Think the heartbeat is Enabled

    Please put the following code in your main.py or boot.py

    import pycom
    
    pycom.heartbeat(False)
    

    I hope this is the solution for your blue light problem



  • Have been trying to write a library for the sensor (Or at least a class that can be turned into a library), but I can't seem to get it to work. This is the code I have written and it is inspired by this https://github.com/pimoroni/adxl345-python/blob/master/adxl345.py

    Any help would be greatly appreciated!

    import time
    from machine import I2C
    
    
    ADXL345_ADDR = 0x53
    
    i2c = I2C(0, I2C.MASTER, baudrate=100000)
    
    BW_RATE_100HZ = 0x0B
    POWER_CTL = 0x2D 
    MEASURE = 0x08
    DATA_FORMAT = 0x31
    AXES_DATA = 0x32
    BW_RATE = 0x2C
    RANGE_2G = 0x00
    SCALE_MULTIPLIER = 0.004
    EARTH_GRAVITY_MS2 = 9.80665
    
    class ADXL345(object):
    	
    
    	def __init__(self, i2c=None):
    		self.i2c = i2c
    		self.addr = ADXL345_ADDR
    		print('One')
    		self.setBandwidthRate(BW_RATE_100HZ)
    		self.setRange(RANGE_2G)
    		self.enableMeasurement()
    
    	def enableMeasurement(self):
    		i2c.writeto(self.addr, bytes(POWER_CTL))
    		i2c.writeto(self.addr, bytes(MEASURE)) 
    
    	def setBandwidthRate(self, rate_flag):
    		print('Two')
    		i2c.writeto_mem(self.addr, bytes(BW_RATE)
    
    	def setRange(self, range_flag):
    		value = i2c.readfrom_mem(self.addr, bytes(DATA_FORMAT))
    		print('here')
    		value &= ~0x0F;
    		value |= range_flag;
    		value |= 0x08;
    
    		i2c.writeto(self.addr, DATA_FORMAT, value)
    
    	def getAxes(self, gforce = False):
    		bytes = i2c.readfrom(self.addr, AXES_DATA, 6)
    
    		x = bytes[0] | (bytes[1] << 8)
    		if(x & (1 << 16 - 1)):
    			x = x - (1<<16)
    
    		y = bytes[2] | (bytes[3] << 8)
    		if(y & (1 << 16 - 1)):
    			y = y - (1<<16)
    
    		z = bytes[4] | (bytes[5] << 8 )
    		if(z & (1 << 16 - 1)):
    			z = z - (1<<16)
    
    		x = x * SCALE_MULTIPLIER
    		y = y * SCALE_MULTIPLIER
    		z = z * SCALE_MULTIPLIER
    
    		if gforce == False: 
    			x = x * EARTH_GRAVITY_MS2
    			y = y * EARTH_GRAVITY_MS2
    			z = z * EARTH_GRAVITY_MS2
    
    		x = round(x,4)
    		y = round(y,4)
    		z = round(z,4)
    
    		return {"x": x, "y": y, "z": z}
    print('Start')
    
    for i in range(0,10):
    	adxl345 = ADXL345()
    	axes = adxl345.getAxes(True)
    	print(axes['x'])
    	sleep_ms(25)
    

    Also for some reason the LED light on the expansion board has started to blink blue again.



  • @livius Thanks. I will look into that one.





Pycom on Twitter