staccel.py 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. """
  2. Driver for accelerometer on STM32F4 Discover board.
  3. Sets accelerometer range at +-2g.
  4. Returns list containing X,Y,Z axis acceleration values in 'g' units (9.8m/s^2).
  5. See:
  6. STM32Cube_FW_F4_V1.1.0/Drivers/BSP/Components/lis302dl/lis302dl.h
  7. STM32Cube_FW_F4_V1.1.0/Drivers/BSP/Components/lis302dl/lis302dl.c
  8. STM32Cube_FW_F4_V1.1.0/Drivers/BSP/STM32F4-Discovery/stm32f4_discovery.c
  9. STM32Cube_FW_F4_V1.1.0/Drivers/BSP/STM32F4-Discovery/stm32f4_discovery.h
  10. STM32Cube_FW_F4_V1.1.0/Drivers/BSP/STM32F4-Discovery/stm32f4_discovery_accelerometer.c
  11. STM32Cube_FW_F4_V1.1.0/Drivers/BSP/STM32F4-Discovery/stm32f4_discovery_accelerometer.h
  12. STM32Cube_FW_F4_V1.1.0/Projects/STM32F4-Discovery/Demonstrations/Src/main.c
  13. """
  14. from micropython import const
  15. from pyb import Pin
  16. from pyb import SPI
  17. READWRITE_CMD = const(0x80)
  18. MULTIPLEBYTE_CMD = const(0x40)
  19. WHO_AM_I_ADDR = const(0x0f)
  20. OUT_X_ADDR = const(0x29)
  21. OUT_Y_ADDR = const(0x2b)
  22. OUT_Z_ADDR = const(0x2d)
  23. OUT_T_ADDR = const(0x0c)
  24. LIS302DL_WHO_AM_I_VAL = const(0x3b)
  25. LIS302DL_CTRL_REG1_ADDR = const(0x20)
  26. # Configuration for 100Hz sampling rate, +-2g range
  27. LIS302DL_CONF = const(0b01000111)
  28. LIS3DSH_WHO_AM_I_VAL = const(0x3f)
  29. LIS3DSH_CTRL_REG4_ADDR = const(0x20)
  30. LIS3DSH_CTRL_REG5_ADDR = const(0x24)
  31. # Configuration for 100Hz sampling rate, +-2g range
  32. LIS3DSH_CTRL_REG4_CONF = const(0b01100111)
  33. LIS3DSH_CTRL_REG5_CONF = const(0b00000000)
  34. class STAccel:
  35. def __init__(self):
  36. self.cs_pin = Pin('PE3', Pin.OUT_PP, Pin.PULL_NONE)
  37. self.cs_pin.high()
  38. self.spi = SPI(1, SPI.MASTER, baudrate=328125, polarity=0, phase=1, bits=8)
  39. self.who_am_i = self.read_id()
  40. if self.who_am_i == LIS302DL_WHO_AM_I_VAL:
  41. self.write_bytes(LIS302DL_CTRL_REG1_ADDR, bytearray([LIS302DL_CONF]))
  42. self.sensitivity = 18
  43. elif self.who_am_i == LIS3DSH_WHO_AM_I_VAL:
  44. self.write_bytes(LIS3DSH_CTRL_REG4_ADDR, bytearray([LIS3DSH_CTRL_REG4_CONF]))
  45. self.write_bytes(LIS3DSH_CTRL_REG5_ADDR, bytearray([LIS3DSH_CTRL_REG5_CONF]))
  46. self.sensitivity = 0.06 * 256
  47. else:
  48. raise Exception('LIS302DL or LIS3DSH accelerometer not present')
  49. def convert_raw_to_g(self, x):
  50. if x & 0x80:
  51. x = x - 256
  52. return x * self.sensitivity / 1000
  53. def read_bytes(self, addr, nbytes):
  54. if nbytes > 1:
  55. addr |= READWRITE_CMD | MULTIPLEBYTE_CMD
  56. else:
  57. addr |= READWRITE_CMD
  58. self.cs_pin.low()
  59. self.spi.send(addr)
  60. #buf = self.spi.send_recv(bytearray(nbytes * [0])) # read data, MSB first
  61. buf = self.spi.recv(nbytes)
  62. self.cs_pin.high()
  63. return buf
  64. def write_bytes(self, addr, buf):
  65. if len(buf) > 1:
  66. addr |= MULTIPLEBYTE_CMD
  67. self.cs_pin.low()
  68. self.spi.send(addr)
  69. for b in buf:
  70. self.spi.send(b)
  71. self.cs_pin.high()
  72. def read_id(self):
  73. return self.read_bytes(WHO_AM_I_ADDR, 1)[0]
  74. def x(self):
  75. return self.convert_raw_to_g(self.read_bytes(OUT_X_ADDR, 1)[0])
  76. def y(self):
  77. return self.convert_raw_to_g(self.read_bytes(OUT_Y_ADDR, 1)[0])
  78. def z(self):
  79. return self.convert_raw_to_g(self.read_bytes(OUT_Z_ADDR, 1)[0])
  80. def xyz(self):
  81. return (self.x(), self.y(), self.z())