|
53 | 53 | from micropython import const
|
54 | 54 | from adafruit_bus_device.i2c_device import I2CDevice
|
55 | 55 | from adafruit_register.i2c_struct import UnaryStruct
|
56 |
| -from adafruit_register.i2c_bit import RWBit |
| 56 | +from adafruit_register.i2c_bit import RWBit, ROBit |
57 | 57 | from adafruit_register.i2c_bits import RWBits
|
58 | 58 | from adafruit_register.i2c_struct_array import StructArray
|
59 | 59 |
|
60 |
| - |
61 | 60 | __version__ = "0.0.0-auto.0"
|
62 | 61 | __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_LSM303_Accel.git"
|
63 | 62 |
|
|
67 | 66 | _ID = const(0xD4) # (0b11010100)
|
68 | 67 |
|
69 | 68 | # Accelerometer registers
|
| 69 | + |
| 70 | +_REG_ACCEL_WHO_AM_I = const(0x0F) |
70 | 71 | _REG_ACCEL_CTRL_REG1_A = const(0x20)
|
71 | 72 | _REG_ACCEL_CTRL_REG2_A = const(0x21)
|
72 | 73 | _REG_ACCEL_CTRL_REG3_A = const(0x22)
|
|
99 | 100 | _REG_ACCEL_TIME_WINDOW_A = const(0x3D)
|
100 | 101 | _REG_ACCEL_ACT_THS_A = const(0x3E)
|
101 | 102 | _REG_ACCEL_ACT_DUR_A = const(0x3F)
|
102 |
| -_REG_ACCEL_WHO_AM_I = const(0x0F) |
103 | 103 |
|
104 | 104 | # Conversion constants
|
105 | 105 | _LSM303ACCEL_MG_LSB = 16704.0 # magic!
|
@@ -140,36 +140,124 @@ class LSM303_Accel:
|
140 | 140 | # This reduces memory allocations but means the code is not re-entrant or
|
141 | 141 | # thread safe!
|
142 | 142 | _chip_id = UnaryStruct(_REG_ACCEL_WHO_AM_I, "B")
|
143 |
| - _int2_int1_enable = RWBit(_REG_ACCEL_CTRL_REG6_A, 6, 1) |
144 |
| - _int2_int2_enable = RWBit(_REG_ACCEL_CTRL_REG6_A, 5, 1) |
| 143 | + _int2_int1_enable = RWBit(_REG_ACCEL_CTRL_REG6_A, 6) |
| 144 | + _int2_int2_enable = RWBit(_REG_ACCEL_CTRL_REG6_A, 5) |
| 145 | + _int1_latching = RWBit(_REG_ACCEL_CTRL_REG5_A, 3) |
| 146 | + _int2_latching = RWBit(_REG_ACCEL_CTRL_REG5_A, 1) |
| 147 | + _bdu = RWBit(_REG_ACCEL_CTRL_REG4_A, 7) |
145 | 148 |
|
146 |
| - _int2_activity_enable = RWBit(_REG_ACCEL_CTRL_REG6_A, 3, 1) |
147 |
| - _int_pin_active_low = RWBit(_REG_ACCEL_CTRL_REG6_A, 1, 1) |
| 149 | + _int2_activity_enable = RWBit(_REG_ACCEL_CTRL_REG6_A, 3) |
| 150 | + _int_pin_active_low = RWBit(_REG_ACCEL_CTRL_REG6_A, 1) |
148 | 151 |
|
149 | 152 | _act_threshold = UnaryStruct(_REG_ACCEL_ACT_THS_A, "B")
|
150 | 153 | _act_duration = UnaryStruct(_REG_ACCEL_ACT_DUR_A, "B")
|
151 | 154 |
|
152 |
| - _data_rate = RWBits(4, _REG_ACCEL_CTRL_REG1_A, 4, 1) |
153 |
| - _enable_xyz = RWBits(3, _REG_ACCEL_CTRL_REG1_A, 0, 1) |
| 155 | + _data_rate = RWBits(4, _REG_ACCEL_CTRL_REG1_A, 4) |
| 156 | + _enable_xyz = RWBits(3, _REG_ACCEL_CTRL_REG1_A, 0) |
154 | 157 | _raw_accel_data = StructArray(_REG_ACCEL_OUT_X_L_A, "<h", 3)
|
155 | 158 |
|
156 |
| - _low_power = RWBit(_REG_ACCEL_CTRL_REG1_A, 3, 1) |
157 |
| - _high_resolution = RWBit(_REG_ACCEL_CTRL_REG4_A, 3, 1) |
| 159 | + _low_power = RWBit(_REG_ACCEL_CTRL_REG1_A, 3) |
| 160 | + _high_resolution = RWBit(_REG_ACCEL_CTRL_REG4_A, 3) |
158 | 161 |
|
| 162 | + _range = RWBits(2, _REG_ACCEL_CTRL_REG4_A, 4) |
159 | 163 |
|
160 |
| - _range = RWBits(2, _REG_ACCEL_CTRL_REG4_A, 4, 1) |
| 164 | + # filter _REG_ACCEL_CTRL_REG2_A |
| 165 | + # CTRL_REG5_A boot (7) |
| 166 | + _int1_src = UnaryStruct(_REG_ACCEL_INT1_SOURCE_A, "B") |
| 167 | + _tap_src = UnaryStruct(_REG_ACCEL_CLICK_SRC_A, "B") |
| 168 | + |
| 169 | + _tap_interrupt_enable = RWBit(_REG_ACCEL_CTRL_REG3_A, 7, 1) |
| 170 | + _tap_config = UnaryStruct(_REG_ACCEL_CLICK_CFG_A, "B") |
| 171 | + _tap_interrupt_active = ROBit(_REG_ACCEL_CLICK_SRC_A, 6, 1) |
| 172 | + _tap_threshold = UnaryStruct(_REG_ACCEL_CLICK_THS_A, "B") |
| 173 | + _tap_time_limit = UnaryStruct(_REG_ACCEL_TIME_LIMIT_A, "B") |
| 174 | + _tap_time_latency = UnaryStruct(_REG_ACCEL_TIME_LATENCY_A, "B") |
| 175 | + _tap_time_window = UnaryStruct(_REG_ACCEL_TIME_WINDOW_A, "B") |
161 | 176 |
|
162 |
| - _BUFFER = bytearray(6) |
163 | 177 |
|
| 178 | + |
| 179 | + _BUFFER = bytearray(6) |
164 | 180 | def __init__(self, i2c):
|
165 | 181 | self._accel_device = I2CDevice(i2c, _ADDRESS_ACCEL)
|
166 | 182 | self.i2c_device = self._accel_device
|
167 | 183 | #self._write_u8(self._accel_device, _REG_ACCEL_CTRL_REG1_A, 0x27) # Enable the accelerometer
|
168 | 184 | self._data_rate = 2
|
169 | 185 | self._enable_xyz = 0b111
|
| 186 | + self._int1_latching = True |
| 187 | + self._int2_latching = True |
| 188 | + self._bdu = True |
| 189 | + |
| 190 | + # self._write_register_byte(_REG_CTRL5, 0x80) |
| 191 | + # time.sleep(0.01) # takes 5ms |
170 | 192 | self._cached_mode = 0
|
171 | 193 | self._cached_range = 0
|
172 | 194 |
|
| 195 | + def set_tap(self, tap, threshold, *, |
| 196 | + time_limit=10, time_latency=20, time_window=255, tap_cfg=None): |
| 197 | + """ |
| 198 | + The tap detection parameters. |
| 199 | + .. note:: Tap related registers are called ``CLICK_`` in the datasheet. |
| 200 | + :param int tap: 0 to disable tap detection, 1 to detect only single |
| 201 | + taps, and 2 to detect only double taps. |
| 202 | + :param int threshold: A threshold for the tap detection. The higher the value |
| 203 | + the less sensitive the detection. This changes based on |
| 204 | + the accelerometer range. Good values are 5-10 for 16G, |
| 205 | + 10-20 for 8G, 20-40 for 4G, and 40-80 for 2G. |
| 206 | + :param int time_limit: TIME_LIMIT register value (default 10). |
| 207 | + :param int time_latency: TIME_LATENCY register value (default 20). |
| 208 | + :param int time_window: TIME_WINDOW register value (default 255). |
| 209 | + :param int click_cfg: CLICK_CFG register value. |
| 210 | + """ |
| 211 | + if (tap < 0 or tap > 2) and tap_cfg is None: |
| 212 | + raise ValueError('Tap must be 0 (disabled), 1 (single tap), or 2 (double tap)!') |
| 213 | + if threshold > 127 or threshold < 0: |
| 214 | + raise ValueError('Threshold out of range (0-127)') |
| 215 | + |
| 216 | + |
| 217 | + if tap == 0 and tap_cfg is None: |
| 218 | + # Disable click interrupt. |
| 219 | + self._tap_interrupt_enable = False |
| 220 | + self._tap_config = 0 |
| 221 | + return |
| 222 | + |
| 223 | + self._tap_interrupt_enable = True |
| 224 | + |
| 225 | + if tap_cfg is None: |
| 226 | + if tap == 1: |
| 227 | + tap_cfg = 0x15 # Turn on all axes & singletap. |
| 228 | + if tap == 2: |
| 229 | + tap_cfg = 0x2A # Turn on all axes & doubletap. |
| 230 | + # Or, if a custom tap configuration register value specified, use it. |
| 231 | + self._tap_config = tap_cfg |
| 232 | + |
| 233 | + self._tap_threshold = threshold # why and? |
| 234 | + self._tap_time_limit = time_limit |
| 235 | + self._tap_time_latency = time_latency |
| 236 | + self._tap_time_window = time_window |
| 237 | + |
| 238 | + @property |
| 239 | + def tapped(self): |
| 240 | + """ |
| 241 | + True if a tap was detected recently. Whether its a single tap or double tap is |
| 242 | + determined by the tap param on ``set_tap``. ``tapped`` may be True over |
| 243 | + multiple reads even if only a single tap or single double tap occurred if the |
| 244 | + interrupt (int) pin is not specified. |
| 245 | + The following example uses ``i2c`` and specifies the interrupt pin: |
| 246 | + .. code-block:: python |
| 247 | + import adafruit_lis3dh |
| 248 | + import digitalio |
| 249 | + i2c = busio.I2C(board.SCL, board.SDA) |
| 250 | + int1 = digitalio.DigitalInOut(board.D11) # pin connected to interrupt |
| 251 | + lis3dh = adafruit_lis3dh.LIS3DH_I2C(i2c, int1=int1) |
| 252 | + lis3dh.range = adafruit_lis3dh.RANGE_8_G |
| 253 | + """ |
| 254 | + tap_src = self._tap_src |
| 255 | + # print("tap_src: %s"%bin(tap_src)) |
| 256 | + # print("int1_src: %s"%bin(self._int1_src)) |
| 257 | + # if tap_src & 0b1000000 > 0: |
| 258 | + # print("TAPPED!") |
| 259 | + return tap_src & 0b1000000 > 0 |
| 260 | + |
173 | 261 | @property
|
174 | 262 | def raw_acceleration(self):
|
175 | 263 | """The raw accelerometer sensor values.
|
|
0 commit comments