adxl345_upy.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. # ADXL345 Python library for Raspberry Pi
  2. #
  3. # author: Jonathan Williamson
  4. # license: BSD, see LICENSE.txt included in this package
  5. #
  6. # This is a Raspberry Pi Python implementation to help you get started with
  7. # the Adafruit Triple Axis ADXL345 breakout board:
  8. # http://shop.pimoroni.com/products/adafruit-triple-axis-accelerometer
  9. #
  10. # Minor edit to print statement for Python 3 and AntEvents API changes (need sensor_id)
  11. # Edits for MicroPython (no smbus module)
  12. from machine import I2C, Pin
  13. from time import sleep
  14. # select the correct i2c bus for this revision of Raspberry Pi
  15. #revision = ([l[12:-1] for l in open('/proc/cpuinfo','r').readlines() if l[:8]=="Revision"]+['0000'])[0]
  16. #bus = smbus.SMBus(1 if int(revision, 16) >= 4 else 0)
  17. bus = I2C(scl = Pin(5), sda = Pin(4), freq = 100000)
  18. # ADXL345 constants
  19. EARTH_GRAVITY_MS2 = 9.80665
  20. SCALE_MULTIPLIER = 0.004
  21. DATA_FORMAT = 0x31
  22. BW_RATE = 0x2C
  23. POWER_CTL = 0x2D
  24. BW_RATE_1600HZ = [0x0F]
  25. BW_RATE_800HZ = [0x0E]
  26. BW_RATE_400HZ = [0x0D]
  27. BW_RATE_200HZ = [0x0C]
  28. BW_RATE_100HZ = [0x0B]
  29. BW_RATE_50HZ = [0x0A]
  30. BW_RATE_25HZ = [0x09]
  31. RANGE_2G = 0x00
  32. RANGE_4G = 0x01
  33. RANGE_8G = 0x02
  34. RANGE_16G = 0x03
  35. MEASURE = [0x08]
  36. AXES_DATA = 0x32
  37. class ADXL345_upy:
  38. address = None
  39. def __init__(self, sensor_id, address = 0x53):
  40. self.sensor_id = sensor_id
  41. self.address = address
  42. self.setBandwidthRate(BW_RATE_100HZ)
  43. self.setRange(RANGE_2G)
  44. self.enableMeasurement()
  45. def enableMeasurement(self):
  46. bus.writeto_mem(self.address, POWER_CTL, bytearray(MEASURE))
  47. def setBandwidthRate(self, rate_flag):
  48. bus.writeto_mem(self.address, BW_RATE, bytearray(rate_flag))
  49. # set the measurement range for 10-bit readings
  50. def setRange(self, range_flag):
  51. value = bus.readfrom_mem(self.address, DATA_FORMAT,1)
  52. val2 = value[0]
  53. val2 &= ~0x0F;
  54. val2 |= range_flag;
  55. val2 |= 0x08;
  56. buf = [val2]
  57. bus.writeto_mem(self.address, DATA_FORMAT, bytearray(buf))
  58. # returns the current reading from the sensor for each axis
  59. #
  60. # parameter gforce:
  61. # False (default): result is returned in m/s^2
  62. # True : result is returned in gs
  63. def sample(self, gforce = False):
  64. #bytes = bus.read_i2c_block_data(self.address, AXES_DATA, 6)
  65. bytes = bus.readfrom_mem(self.address, AXES_DATA, 6)
  66. x = bytes[0] | (bytes[1] << 8)
  67. if(x & (1 << 16 - 1)):
  68. x = x - (1<<16)
  69. y = bytes[2] | (bytes[3] << 8)
  70. if(y & (1 << 16 - 1)):
  71. y = y - (1<<16)
  72. z = bytes[4] | (bytes[5] << 8)
  73. if(z & (1 << 16 - 1)):
  74. z = z - (1<<16)
  75. x = x * SCALE_MULTIPLIER
  76. y = y * SCALE_MULTIPLIER
  77. z = z * SCALE_MULTIPLIER
  78. if gforce == False:
  79. x = x * EARTH_GRAVITY_MS2
  80. y = y * EARTH_GRAVITY_MS2
  81. z = z * EARTH_GRAVITY_MS2
  82. x = round(x, 4)
  83. y = round(y, 4)
  84. z = round(z, 4)
  85. return {"x": x, "y": y, "z": z}
  86. if __name__ == "__main__":
  87. # if run directly we'll just create an instance of the class and output
  88. # the current readings
  89. adxl345 = ADXL345()
  90. axes = adxl345.sample(True)
  91. print("ADXL345 on address 0x%x:" % (adxl345.address))
  92. print(" x = %.3fG" % ( axes['x'] ))
  93. print(" y = %.3fG" % ( axes['y'] ))
  94. print(" z = %.3fG" % ( axes['z'] ))