58
58
_ADXL345_MG2G_MULTIPLIER = 0.004 # 4mg per lsb
59
59
_STANDARD_GRAVITY = 9.80665 # earth standard gravity
60
60
61
- _ADXL345_REG_DEVID = const (0x00 ) # Device ID
62
- _ADXL345_REG_THRESH_TAP = const (0x1D ) # Tap threshold
63
- _ADXL345_REG_OFSX = const (0x1E ) # X-axis offset
64
- _ADXL345_REG_OFSY = const (0x1F ) # Y-axis offset
65
- _ADXL345_REG_OFSZ = const (0x20 ) # Z-axis offset
66
- _ADXL345_REG_DUR = const (0x21 ) # Tap duration
67
- _ADXL345_REG_LATENT = const (0x22 ) # Tap latency
68
- _ADXL345_REG_WINDOW = const (0x23 ) # Tap window
69
- _ADXL345_REG_THRESH_ACT = const (0x24 ) # Activity threshold
70
- _ADXL345_REG_THRESH_INACT = const (0x25 ) # Inactivity threshold
71
- _ADXL345_REG_TIME_INACT = const (0x26 ) # Inactivity time
72
- _ADXL345_REG_ACT_INACT_CTL = const (0x27 ) # Axis enable control for [in]activity detection
73
- _ADXL345_REG_THRESH_FF = const (0x28 ) # Free-fall threshold
74
- _ADXL345_REG_TIME_FF = const (0x29 ) # Free-fall time
75
- _ADXL345_REG_TAP_AXES = const (0x2A ) # Axis control for single/double tap
76
- _ADXL345_REG_ACT_TAP_STATUS = const (0x2B ) # Source for single/double tap
77
- _ADXL345_REG_BW_RATE = const (0x2C ) # Data rate and power mode control
78
- _ADXL345_REG_POWER_CTL = const (0x2D ) # Power-saving features control
79
- _ADXL345_REG_INT_ENABLE = const (0x2E ) # Interrupt enable control
80
- _ADXL345_REG_INT_MAP = const (0x2F ) # Interrupt mapping control
81
- _ADXL345_REG_INT_SOURCE = const (0x30 ) # Source of interrupts
82
- _ADXL345_REG_DATA_FORMAT = const (0x31 ) # Data format control
83
- _ADXL345_REG_DATAX0 = const (0x32 ) # X-axis data 0
84
- _ADXL345_REG_DATAX1 = const (0x33 ) # X-axis data 1
85
- _ADXL345_REG_DATAY0 = const (0x34 ) # Y-axis data 0
86
- _ADXL345_REG_DATAY1 = const (0x35 ) # Y-axis data 1
87
- _ADXL345_REG_DATAZ0 = const (0x36 ) # Z-axis data 0
88
- _ADXL345_REG_DATAZ1 = const (0x37 ) # Z-axis data 1
89
- _ADXL345_REG_FIFO_CTL = const (0x38 ) # FIFO control
90
- _ADXL345_REG_FIFO_STATUS = const (0x39 ) # FIFO status
61
+ _REG_DEVID = const (0x00 ) # Device ID
62
+ _REG_THRESH_TAP = const (0x1D ) # Tap threshold
63
+ _REG_OFSX = const (0x1E ) # X-axis offset
64
+ _REG_OFSY = const (0x1F ) # Y-axis offset
65
+ _REG_OFSZ = const (0x20 ) # Z-axis offset
66
+ _REG_DUR = const (0x21 ) # Tap duration
67
+ _REG_LATENT = const (0x22 ) # Tap latency
68
+ _REG_WINDOW = const (0x23 ) # Tap window
69
+ _REG_THRESH_ACT = const (0x24 ) # Activity threshold
70
+ _REG_THRESH_INACT = const (0x25 ) # Inactivity threshold
71
+ _REG_TIME_INACT = const (0x26 ) # Inactivity time
72
+ _REG_ACT_INACT_CTL = const (0x27 ) # Axis enable control for [in]activity detection
73
+ _REG_THRESH_FF = const (0x28 ) # Free-fall threshold
74
+ _REG_TIME_FF = const (0x29 ) # Free-fall time
75
+ _REG_TAP_AXES = const (0x2A ) # Axis control for single/double tap
76
+ _REG_ACT_TAP_STATUS = const (0x2B ) # Source for single/double tap
77
+ _REG_BW_RATE = const (0x2C ) # Data rate and power mode control
78
+ _REG_POWER_CTL = const (0x2D ) # Power-saving features control
79
+ _REG_INT_ENABLE = const (0x2E ) # Interrupt enable control
80
+ _REG_INT_MAP = const (0x2F ) # Interrupt mapping control
81
+ _REG_INT_SOURCE = const (0x30 ) # Source of interrupts
82
+ _REG_DATA_FORMAT = const (0x31 ) # Data format control
83
+ _REG_DATAX0 = const (0x32 ) # X-axis data 0
84
+ _REG_DATAX1 = const (0x33 ) # X-axis data 1
85
+ _REG_DATAY0 = const (0x34 ) # Y-axis data 0
86
+ _REG_DATAY1 = const (0x35 ) # Y-axis data 1
87
+ _REG_DATAZ0 = const (0x36 ) # Z-axis data 0
88
+ _REG_DATAZ1 = const (0x37 ) # Z-axis data 1
89
+ _REG_FIFO_CTL = const (0x38 ) # FIFO control
90
+ _REG_FIFO_STATUS = const (0x39 ) # FIFO status
91
+ _INT_SINGLE_TAP = const (0b01000000 ) # SINGLE_TAP bit
92
+ _INT_DOUBLE_TAP = const (0b00100000 ) # DOUBLE_TAP bit
93
+ _INT_ACT = const (0b00010000 ) # ACT bit
94
+ _INT_INACT = const (0b00001000 ) # INACT bit
95
+ _INT_FREE_FALL = const (0b00000100 ) # FREE_FALL bit
91
96
92
97
class DataRate : #pylint: disable=too-few-public-methods
93
98
"""An enum-like class representing the possible data rates.
@@ -153,42 +158,148 @@ class ADXL345:
153
158
:param address: The I2C device address for the sensor. Default is ``0x53``.
154
159
155
160
"""
156
- def __init__ (self , i2c , address = _ADXL345_DEFAULT_ADDRESS ):
161
+ def __init__ (self , i2c , address = _ADXL345_DEFAULT_ADDRESS , int1 = None , int2 = None ):
157
162
158
163
self ._i2c = i2c_device .I2CDevice (i2c , address )
159
164
self ._buffer = bytearray (6 )
160
165
# set the 'measure' bit in to enable measurement
161
- self ._write_register_byte (_ADXL345_REG_POWER_CTL , 0x08 )
166
+ self ._write_register_byte (_REG_POWER_CTL , 0x08 )
167
+ self ._int1 = int1
168
+ self ._int2 = int2
169
+ self ._tap = None
162
170
163
171
@property
164
172
def acceleration (self ):
165
173
"""The x, y, z acceleration values returned in a 3-tuple in m / s ^ 2."""
166
- x , y , z = unpack ('<hhh' , self ._read_register (_ADXL345_REG_DATAX0 , 6 ))
174
+ x , y , z = unpack ('<hhh' , self ._read_register (_REG_DATAX0 , 6 ))
167
175
x = x * _ADXL345_MG2G_MULTIPLIER * _STANDARD_GRAVITY
168
176
y = y * _ADXL345_MG2G_MULTIPLIER * _STANDARD_GRAVITY
169
177
z = z * _ADXL345_MG2G_MULTIPLIER * _STANDARD_GRAVITY
170
178
return (x , y , z )
171
179
180
+ @property
181
+ def tapped (self ):
182
+ """
183
+ True if a tap was detected recently. Whether it's looking for a single or double tap is
184
+ determined by the tap param on ``tap_parameters``.
185
+
186
+ """
187
+ if self ._int2 and not self ._int2 .value :
188
+ return False
189
+
190
+ interrupt_source_register = self ._read_clear_interrupt_source ()
191
+ if self ._tap == 1 :
192
+ return interrupt_source_register & _INT_SINGLE_TAP > 0
193
+ if self ._tap == 2 :
194
+ return interrupt_source_register & _INT_DOUBLE_TAP > 0
195
+
196
+ return False
197
+
198
+ @property
199
+ def dropped (self ):
200
+ """True if the sensor was in freefall"""
201
+
202
+ return self ._read_clear_interrupt_source () & _INT_FREE_FALL > 0
203
+
204
+ @property
205
+ def active (self ):
206
+ """True if the sensor has seen acceleration above the threshold set with
207
+ ``active_parameters``."""
208
+ return self ._read_clear_interrupt_source () & _INT_ACT > 0
209
+
210
+ def active_parameters (self , threshold = 0x5 ):
211
+ """
212
+ The activity detection parameters.
213
+
214
+ :param int threshold: The value that acceleration on any axis must exceed to\
215
+ register as active. The scale factor is 62.5 mg/LSB.
216
+
217
+ """
218
+ self ._write_register_byte (_REG_INT_ENABLE , 0x0 ) # disable interrupts for setup
219
+ self ._write_register_byte (_REG_ACT_INACT_CTL , 0b01110000 ) # enable activity on X,Y,Z
220
+ self ._write_register_byte (_REG_THRESH_ACT , threshold )
221
+ self ._write_register_byte (_REG_INT_ENABLE , _INT_ACT ) # Inactive interrupt only
222
+
223
+ def dropped_parameters (self , threshold = 0x5 , time = 0x14 ):
224
+ """
225
+ Freefall detection parameters:
226
+
227
+ :param int threshold: The value that acceleration on all axes must be under to\
228
+ register as dropped. The scale factor is 62.5 mg/LSB.
229
+
230
+ :param int time: The amount of time that acceleration on all axes must be less than\
231
+ ``threshhold`` to register as dropped. The scale factor is 5 ms/LSB. Values between 100 ms\
232
+ and 350 ms (0x14 to 0x46) are recommended.
233
+ """
234
+ self ._write_register_byte (_REG_INT_ENABLE , 0x0 ) # disable interrupts for setup
235
+ self ._write_register_byte (_REG_THRESH_FF , threshold )
236
+ self ._write_register_byte (_REG_TIME_FF , time )
237
+ self ._write_register_byte (_REG_INT_ENABLE , 0b00000100 ) # FREE_FALL interrupt only
238
+
239
+ def tap_parameters (self , tap , threshold , * , time_duration = 10 , time_latency = 20 , time_window = 255 ):
240
+ """
241
+ The tap detection parameters.
242
+
243
+ :param int tap: 0 to disable tap detection, 1 to detect only single taps, and 2 to detect\
244
+ only double taps.
245
+
246
+ :param int threshold: A threshold for the tap detection. The scale factor is 62.5 mg/LSB\
247
+ The higher the value the less sensitive the detection. This changes based on the\
248
+ accelerometer range.
249
+
250
+ :param int time_duration: This caps the duration of the impulse above ``threshhold``.\
251
+ Anything above ``time_duration`` won't register as a tap. The scale factor is 625 µs/LSB
252
+
253
+ :param int time_latency(double tap only): The length of time after the initial impulse falls below\
254
+ ``threshold`` to start the window looking for a second impulse.\
255
+ The scale factor is 1.25 ms/LSB.
256
+
257
+ :param int time_window(double tap only): The length of the window in which to look for a\
258
+ second tap. The scale factor is 1.25 ms/LSB
259
+ """
260
+ if tap == 0 :
261
+ self ._write_register_byte (_REG_INT_ENABLE , 0x0 ) # disable all interrupts
262
+ self ._write_register_byte (_REG_TAP_AXES , 0x0 ) # disable all axes for tap
263
+ return
264
+ self ._write_register_byte (_REG_INT_ENABLE , 0x0 ) # disable interrupts for setup
265
+ self ._write_register_byte (_REG_TAP_AXES , 0b00000111 ) # enable X, Y, Z axes for tap
266
+ self ._write_register_byte (_REG_THRESH_TAP , threshold )
267
+ self ._write_register_byte (_REG_DUR , time_duration )
268
+
269
+ self ._tap = tap # save to determine which register to check later
270
+ if tap == 1 :
271
+ if self ._int2 :
272
+ self ._write_register_byte (_REG_INT_MAP , _INT_SINGLE_TAP ) # send SINGLE_TAP to INT2
273
+ self ._write_register_byte (_REG_INT_ENABLE , _INT_SINGLE_TAP ) # DOUBLE_TAP interrupt only
274
+ elif tap == 2 :
275
+ self ._write_register_byte (_REG_LATENT , time_latency )
276
+ self ._write_register_byte (_REG_WINDOW , time_window )
277
+ if self ._int2 :
278
+ self ._write_register_byte (_REG_INT_MAP , _INT_DOUBLE_TAP ) # send DOUBLE_TAP to INT2
279
+ self ._write_register_byte (_REG_INT_ENABLE , _INT_DOUBLE_TAP ) # DOUBLE_TAP interrupt only
280
+ else :
281
+ raise ValueError ("tap must be 0 to disable, 1 for single tap, or 2 for double tap" )
282
+
172
283
@property
173
284
def data_rate (self ):
174
285
"""The data rate of the sensor."""
175
- rate_register = unpack ("<b" , self ._read_register (_ADXL345_REG_BW_RATE , 1 ))[0 ]
286
+ rate_register = unpack ("<b" , self ._read_register (_REG_BW_RATE , 1 ))[0 ]
176
287
return rate_register & 0x0F
177
288
178
289
@data_rate .setter
179
290
def data_rate (self , val ):
180
- self ._write_register_byte (_ADXL345_REG_BW_RATE , val )
291
+ self ._write_register_byte (_REG_BW_RATE , val )
181
292
182
293
@property
183
294
def range (self ):
184
295
"""The measurement range of the sensor."""
185
- range_register = unpack ("<b" , self ._read_register (_ADXL345_REG_DATA_FORMAT , 1 ))[0 ]
296
+ range_register = unpack ("<b" , self ._read_register (_REG_DATA_FORMAT , 1 ))[0 ]
186
297
return range_register & 0x03
187
298
188
299
@range .setter
189
300
def range (self , val ):
190
301
# read the current value of the data format register
191
- format_register = unpack ("<b" , self ._read_register (_ADXL345_REG_DATA_FORMAT , 1 ))[0 ]
302
+ format_register = unpack ("<b" , self ._read_register (_REG_DATA_FORMAT , 1 ))[0 ]
192
303
193
304
# clear the bottom 4 bits and update the data rate
194
305
format_register &= ~ 0x0F
@@ -198,7 +309,10 @@ def range(self, val):
198
309
format_register |= 0x08
199
310
200
311
# write the updated values
201
- self ._write_register_byte (_ADXL345_REG_DATA_FORMAT , format_register )
312
+ self ._write_register_byte (_REG_DATA_FORMAT , format_register )
313
+
314
+ def _read_clear_interrupt_source (self ):
315
+ return unpack ("<b" , self ._read_register (_REG_INT_SOURCE , 1 ))[0 ]
202
316
203
317
def _read_register (self , register , length ):
204
318
self ._buffer [0 ] = register & 0xFF
0 commit comments