adxl345_py3.py 3.5 KB

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