-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathspl06_007.py
741 lines (660 loc) · 29 KB
/
spl06_007.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
import time
import warnings
import math
from i2c_interface import I2CInterface
class PressureSensor():
"""An interface for initializing and getting calibrated data from a
SPL06-007 pressure sensor. The data sheet for the sensor can be
found at
https://datasheet.lcsc.com/szlcsc/1912111437_Goertek-SPL06-007_C233787.pdf
"""
def __init__(self, dump_communication=False):
self._communicator = Communicator(
dump_communication=dump_communication)
self._sampling_set = False
self._first_measurement_has_happened = False
def __enter__(self):
return self._communicator.__enter__()
def __exit__(self, type, value, traceback):
self._communicator.__exit__(type, value, traceback)
def close(self):
"""Deinitializes and unlocks the I2C bus."""
self._communicator.close()
def is_present(self):
return self._communicator.is_present()
def set_sampling(self,
pressure_oversample=1,
pressure_sampling_rate=16,
temperature_oversample=1,
temperature_sampling_rate=16):
"""Set the amount of oversampling and the sampling rate
Parameters
----------
pressure_oversample=16 : {1, 2, 4, 8, 16, 32, 64, 128}
The SPL06-007 reads the sensor multiple times and combines
them into one result to achieve a higher precision. This
increases the current consumption and the measurement time,
which again reduces the maximum measurement rate.
The measurement times and precision for each oversample are
these values.
| Oversampling | Measurement time [ms] | Precision [PaRMS] |
|--------------|-----------------------|-------------------|
| 1 | 3.6 | 5 |
| 2 | 5.2 | |
| 4 | 8.4 | 2.5 |
| 8 | 14.8 | |
| 16 | 27.6 | 1.2 |
| 32 | 53.2 | 0.9 |
| 64 | 104.4 | 0.5 |
| 128 | 206.8 | |
pressure_sampling_rate=1 : {1, 2, 4, 8, 16, 32, 64, 128}
The sampling rate of for pressure in hertz. The sampling
rate is only relevant in Background Mode.
temperature_oversample=1 : {1, 2, 4, 8, 16, 32, 64, 128}
The SPL06-007 reads the sensor multiple times and combines
them into one result to achieve a higher precision. This
increases the current consumption and the measurement time,
which again reduces the maximum measurement rate.
Setting the oversample for temperature is optional and may
not be relevant.
The measurement time for oversample=1 is 3.6 ms.
temperature_sampling_rate=1 : {1, 2, 4, 8, 16, 32, 64, 128}
The sampling rate for temperature in hertz. The sampling
rate is only relevant in Background Mode.
"""
self._communicator.set_pressure_sampling(
oversample=pressure_oversample,
rate=pressure_sampling_rate
)
self._communicator.set_temperature_sampling(
oversample=temperature_oversample,
rate=temperature_sampling_rate
)
self._calibrator = Calibrator(
self._communicator.calibration_coefficients,
self._communicator.pressure_scale_factor,
self._communicator.temperature_scale_factor
)
self._sampling_set = True
return self._sampling_set
def set_op_mode(self, op_mode):
"""Sets the mode in which the sensor samples data
Parameters
----------
op_mode: {self.OpMode.standby,
self.OpMode.background,
self.OpMode.command}
self.OpMode.standby is the default mode after power on or
reset. No measurements are performed. All registers and
compensation coefficients are accessible.
In self.OpMode.background, pressure and/or temperature
measurements are performed continuously according to the
selected measurement precision and rate. The temperature
measurement is performed immediately after the pressure
measurement. The FIFO can be used to store 32 measurement
results and minimize the number of times the sensor must be
accessed to read out the results.
In self.OpMode.command, one temperature or pressure
measurement is performed according to the selected
precision. The sensor will return to Standby Mode when the
measurement is finished, and the measurement result will be
available in the data registers.
"""
return self._communicator.set_op_mode(op_mode)
def pressure(self):
"""Returns the currect pressure in Pa. If set_sampling() has
not been called, then it will return NaN.
"""
if self._sampling_set:
self._first_measurement_delay()
return self._calibrator.pressure(
self._communicator.raw_pressure(),
self._communicator.raw_temperature()
)
else:
return float("nan")
def temperature(self):
"""Returns the currect temperature in degC. If set_sampling()
has not been called, then it will return NaN.
"""
if self._sampling_set:
self._first_measurement_delay()
return self._calibrator.temperature(
self._communicator.raw_temperature()
)
else:
return float("nan")
class OpMode():
standby = "Standby"
background = "Background"
command = "Command"
def _first_measurement_delay(self):
first_measurement_delay = 0.151
if self._first_measurement_has_happened:
self._first_measurement_has_happened = True
time.sleep(first_measurement_delay)
class Calibrator():
"""Takes raw data from a SPL06-007 pressure sensor and converts it
to pressure data in Pa and temperature data in degC.
"""
def __init__(self,
calibration_coefficients,
pressure_scaling_factor,
temperature_scaling_factor):
"""Initializes self.
Parameters
----------
calibration_coefficients : iterable
An iterable with the coefficients
(c0, c1, c00, c10, c01, c11, c20, c21, c30) as defined in the
data sheet.
pressure_scaling_factor : int
A scaling factor corresponding with the selected pressure
oversampling.
temperature_scaling_factor : int
A scaling factor corresponding with the selected temperature
oversampling
"""
self._c0 = calibration_coefficients[0]
self._c1 = calibration_coefficients[1]
self._c00 = calibration_coefficients[2]
self._c10 = calibration_coefficients[3]
self._c01 = calibration_coefficients[4]
self._c11 = calibration_coefficients[5]
self._c20 = calibration_coefficients[6]
self._c21 = calibration_coefficients[7]
self._c30 = calibration_coefficients[8]
if (math.isclose(pressure_scaling_factor, 0.0)
or math.isclose(temperature_scaling_factor, 0.0)):
raise ZeroDivisionError("Cannot have pressure or temperature "
"scaling factor equal to 0.")
self._pressure_scaling_factor = pressure_scaling_factor
self._temperature_scaling_factor = temperature_scaling_factor
def pressure(self, raw_pressure, raw_temperature):
"""Pressure in Pa.
Parameters
----------
raw_pressure : int
Raw pressure from the sensor.
raw_temperature : int
Raw temperature from the sensor.
"""
scaled_pressure = float(raw_pressure / self._pressure_scaling_factor)
scaled_temperature = float(raw_temperature
/ self._temperature_scaling_factor)
qua2 = (self._c10 +
(scaled_pressure *
(self._c20 + scaled_pressure * self._c30)))
qua3 = (scaled_temperature * scaled_pressure
* (self._c11 + scaled_pressure * self._c21))
compensated_pressure = (
self._c00 + scaled_pressure * qua2
+ scaled_temperature * self._c01 + qua3)
return compensated_pressure
def temperature(self, raw_temperature):
"""Temperature in degC
Parameters
----------
raw_temperature : int
Raw temperature from the sensor.
"""
scaled_temperature = float(raw_temperature
/ self._temperature_scaling_factor)
compensated_temperature = (
self._c0 * 0.5 + self._c1 * scaled_temperature)
return compensated_temperature
class Communicator():
"""Performs I2C communication between a Raspberry Pi and a
SPL06-007 pressure sensor.
Parameters
----------
SDO_high = True: bool
Set to false if the SDO pin on the SPL06-007 is pulled to ground
dump_communication=False: bool
For every read or write to the I2C device, the transmitted and
recieved communication will be printed alongside the time in
millis since epoch. A write will look like this,
1594169517918.1819 TX -> 0x0C09
and a read will look like this.
1594169517938.8496 TX -> 0x08
1594169517939.2563 RX <- 0x40
"""
_READY_WAIT_TIME = 0.0036
def __init__(self, SDO_high=True, dump_communication=False):
"""The sensor takes(107 ± 8) ms to initialize."""
if SDO_high:
self._i2c_address = SensorConstants.DEVICE_ADDRESS_SDO_HIGH
else:
self._i2c_address = SensorConstants.DEVICE_ADDRESS_SDO_LOW
self._i2c = I2CInterface(self._i2c_address,
dump_communication=dump_communication)
self._i2c.find_device()
self._reset_sensor()
self.set_op_mode(PressureSensor.OpMode.standby)
self._calculate_calibration_coefficients()
def __enter__(self):
return self
def __exit__(self, type, value, traceback):
self.close()
def close(self):
"""Deinitializes and unlocks the I2C bus."""
self._i2c.close()
def is_present(self):
if self._i2c_address in self._i2c.scan():
return True
else:
return False
def set_op_mode(self, mode):
"""Sets the pressure sensor into a mode for data collection
Parameters
----------
mode : {PressureSensor.OpMode.standby,
PressureSensor.OpMode.command,
PressureSensor.OpMode.background}
The data output modes of the sensor
use_pressure=True : bool
Set to False if you don't want pressure data; it's
otherwise True
use_temperature=True : bool
Set to False if you don't want temperature data;
it's otherwise True
"""
set_standby = False
if mode == PressureSensor.OpMode.command:
self._op_mode = PressureSensor.OpMode.command
return PressureSensor.OpMode.command
elif mode == PressureSensor.OpMode.background:
self._i2c.write_register(
SensorConstants.MEAS_CFG,
SensorConstants.BACKGROUND_PRESSURE_TEMPERATURE
)
self._op_mode = PressureSensor.OpMode.background
return PressureSensor.OpMode.background
else:
if mode != PressureSensor.OpMode.standby:
warnings.warn("Undefined mode. Defaulting to"
"Standby Mode",
RuntimeWarning)
set_standby = True
if set_standby:
self._i2c.write_register(SensorConstants.MEAS_CFG,
SensorConstants.STANDBY)
self._op_mode = PressureSensor.OpMode.standby
return PressureSensor.OpMode.standby
@property
def calibration_coefficients(self):
"""The calibration coefficients
(c0, c1, c00, c10, c01, c11, c20, c21, c30)
"""
return self._calibration_coefficients
def set_pressure_sampling(self, oversample=1, rate=16):
"""Set the amount of oversampling and the sampling rate
Parameters
----------
oversample=16 : {1, 2, 4, 8, 16, 32, 64, 128}
The SPL06-007 reads the sensor multiple times and combines
them into one result to achieve a higher precision. This
increases the current consumption and the measurement time,
which again reduces the maximum measurement rate.
The measurement times and precision for each oversample are
these values.
| Oversampling | Measurement time [ms] | Precision [Pa RMS] |
|--------------|-----------------------|--------------------|
| 1 | 3.6 | 5 |
| 2 | 5.2 | |
| 4 | 8.4 | 2.5 |
| 8 | 14.8 | |
| 16 | 27.6 | 1.2 |
| 32 | 53.2 | 0.9 |
| 64 | 104.4 | 0.5 |
| 128 | 206.8 | |
rate=1 : {1, 2, 4, 8, 16, 32, 64, 128}
The sampling rate of the sensor in hertz. The sampling rate
is only relevant in Background Mode.
"""
try:
rate_mode = SensorConstants.PRESSURE_RATE_OPTIONS[rate]
except KeyError:
raise ValueError("Pressure sampling rate can only be "
"1, 2, 4, 8, 16, 32, 64, or 128 Hz")
try:
oversample_mode = (
SensorConstants.PRESSURE_OVERSAMPLE_OPTIONS[oversample]
)
self._pressure_scale_factor = (
SensorConstants.COMPENSATION_SCALE_FACTORS[oversample]
)
except KeyError:
raise ValueError("Pressure oversampling can only be "
"1, 2, 4, 8, 16, 32, 64, or 128X")
self._i2c.write_register(SensorConstants.PRS_CFG,
rate_mode | oversample_mode)
# The datasheet says only to do this if oversample > 8, but it
# weirdly makes data correct for all values of oversample
self._i2c.write_register(
SensorConstants.CFG_REG,
SensorConstants.P_SHIFT)
def raw_pressure(self):
"""The raw pressuring reading from the sensor. This needs to
be scaled and compensated per the data sheet to be useful.
"""
if self._op_mode == PressureSensor.OpMode.command:
self._i2c.write_register(
SensorConstants.MEAS_CFG,
SensorConstants.COMMAND_PRESSURE)
def pressure_ready():
return (self._i2c.read_register(SensorConstants.MEAS_CFG)
& SensorConstants.PRS_RDY != 0)
self._wait_for_condition_else_timeout(
pressure_ready, 4, expected_delay=0.020)
pressure_data = self._i2c.read_register(SensorConstants.PRS_B2,
number_of_bytes=3)
uint_pressure = ((pressure_data[0] << 16)
| (pressure_data[1] << 8)
| pressure_data[2])
return self._twos_complement(uint_pressure,
SensorConstants.PRESSURE_BIT_WIDTH)
@property
def pressure_scale_factor(self):
"""A constant used for calibrating the sensor."""
return self._pressure_scale_factor
def set_temperature_sampling(self, oversample=1, rate=16):
"""Set the amount of oversampling and the sampling rate.
Parameters
----------
oversample=1 : {1, 2, 4, 8, 16, 32, 64, 128}
The SPL06-007 reads the sensor multiple times and combines
them into one result to achieve a higher precision. This
increases the current consumption and the measurement time,
which again reduces the maximum measurement rate.
Setting the oversample for temperature is optional and may
not be relevant.
The measurement time for oversample=1 is 3.6 ms.
rate=1 : {1, 2, 4, 8, 16, 32, 64, 128}
The sampling rate of the sensor in hertz. The sampling rate
is only relevant in background mode.
"""
try:
rate_mode = SensorConstants.TEMPERATURE_RATE_OPTIONS[rate]
except KeyError:
raise ValueError("Temperature sampling rate can only be "
"1, 2, 4, 8, 16, 32, 64, or 128 Hz")
try:
oversample_mode = (
SensorConstants.TEMPERATURE_OVERSAMPLE_OPTIONS[oversample]
)
self._temperature_scale_factor = \
SensorConstants.COMPENSATION_SCALE_FACTORS[oversample]
except KeyError:
raise ValueError("Temperature oversampling can only be "
"1, 2, 4, 8, 16, 32, 64, or 128X")
self._i2c.write_register(
SensorConstants.TMP_CFG,
(SensorConstants.TEMPERATURE_SENSOR_EXTERNAL | rate_mode
| oversample_mode))
if oversample > 8:
self._i2c.write_register(
SensorConstants.CFG_REG,
SensorConstants.T_SHIFT
)
else:
prs_cfg_state = self._i2c.read_register(SensorConstants.CFG_REG)
if prs_cfg_state & SensorConstants.T_SHIFT != 0:
self._i2c.write_register(
SensorConstants.CFG_REG,
prs_cfg_state & (0xff - SensorConstants.T_SHIFT))
def raw_temperature(self):
"""The raw temperature reading from the sensor. This need to
be scaled and compensated per the data sheet to be useful.
"""
if self._op_mode == PressureSensor.OpMode.command:
self._i2c.write_register(SensorConstants.MEAS_CFG,
SensorConstants.COMMAND_TEMPERATURE)
def temperature_ready():
return (self._i2c.read_register(SensorConstants.MEAS_CFG)
& SensorConstants.TMP_RDY != 0)
self._wait_for_condition_else_timeout(
temperature_ready, 4, expected_delay=0.035)
temperature_data = self._i2c.read_register(SensorConstants.TMP_B2,
number_of_bytes=3)
uint_temperature = ((temperature_data[0] << 16)
| (temperature_data[1] << 8)
| temperature_data[2])
return self._twos_complement(uint_temperature,
SensorConstants.TEMPERATURE_BIT_WIDTH)
@property
def temperature_scale_factor(self):
"""A constant used for calibrating the sensor."""
return self._temperature_scale_factor
def _calculate_calibration_coefficients(self):
"""The SPL06-007 is a calibrated sensor and contains
calibration coefficients. These are used in the
application (for instance by the host processor) to
compensate the measurement results for sensor nonlinearity’s.
Note: The coefficients read from the coefficient register
{c00, c10, c01, c11, c20, c21, c30} are 16 bit 2´s complement
numbers.
Note: The coefficients read from the coefficient register
{c0, c1} are 12 bit 2´s complement numbers.
"""
def coefficients_ready():
return (self._i2c.read_register(SensorConstants.MEAS_CFG)
& SensorConstants.COEF_RDY != 0)
self._wait_for_condition_else_timeout(coefficients_ready,
4)
coefficient_data = self._i2c.read_register(SensorConstants.C0_11_4,
number_of_bytes=18)
# The data sheet says all of these should be 2's complement, but
# some of them are wrong when they're that way. Bad data sheet.
c0 = self._twos_complement(
coefficient_data[0] << 4 | coefficient_data[1] >> 4, 12)
c1 = self._twos_complement(
(coefficient_data[1] & 0x0F) << 8 | coefficient_data[2], 12)
c00 = (coefficient_data[3] << 12
| coefficient_data[4] << 4 | coefficient_data[5] >> 4)
c10 = self._twos_complement(
((coefficient_data[5] & 0x0F) << 16)
| (coefficient_data[6] << 8) | coefficient_data[7], 16)
c01 = coefficient_data[8] << 8 | coefficient_data[9]
c11 = self._twos_complement(
coefficient_data[10] << 8 | coefficient_data[11], 16)
c20 = self._twos_complement(
coefficient_data[12] << 8 | coefficient_data[13], 16)
c21 = self._twos_complement(
coefficient_data[14] << 8 | coefficient_data[15], 16)
c30 = self._twos_complement(
coefficient_data[16] << 8 | coefficient_data[17], 16)
self._calibration_coefficients = (c0, c1,
c00, c10, c01, c11, c20, c21, c30)
def _reset_sensor(self):
reset_time = 0.02
self._i2c.write_register(SensorConstants.RESET,
SensorConstants.SOFT_RESET)
time.sleep(reset_time)
def sensor_ready():
return (self._i2c.read_register(SensorConstants.MEAS_CFG)
& SensorConstants.SENSOR_RDY != 0)
self._wait_for_condition_else_timeout(sensor_ready,
4,
expected_delay=0.030)
def _wait_for_condition_else_timeout(self,
condition_function,
timeout,
expected_delay=0):
start_time = time.time()
time.sleep(expected_delay)
while not condition_function():
if time.time() - start_time > timeout:
return False
time.sleep(self._READY_WAIT_TIME)
return True
def _twos_complement(self, value, bits):
if (value & (1 << (bits - 1))) != 0:
complement = (value & (2**bits - 1)) - (1 << bits)
else:
complement = value & (2**bits - 1)
return complement
class SensorConstants():
"""The names and addresses of every register on the chip and codes
to write to them
"""
DEVICE_ADDRESS_SDO_HIGH = 0x77
DEVICE_ADDRESS_SDO_LOW = 0x76
# Register addresses
PRS_B2 = 0x00
PRS_B1 = 0x01
PRS_B0 = 0x02
TMP_B2 = 0x03
TMP_B1 = 0x04
TMP_B0 = 0x05
PRS_CFG = 0x06
TMP_CFG = 0x07
MEAS_CFG = 0x08
CFG_REG = 0x09
INT_STS = 0x0A
FIFO_STS = 0x0B
RESET = 0x0C
ID = 0x0D
# Calibration Coefficient register addresses
C0_11_4 = 0x10
C0_3_0_C1_11_8 = 0x11
C1_7_0 = 0x12
C00_19_12 = 0x13
C00_11_4 = 0x14
C00_3_0_C10_19_16 = 0x15
C10_15_8 = 0x16
C10_7_0 = 0x17
C01_15_8 = 0x18
C01_7_0 = 0x19
C11_15_8 = 0x1A
C11_7_0 = 0x1B
C20_15_8 = 0x1C
C20_7_0 = 0x1D
C21_15_8 = 0x1E
C21_7_0 = 0x1F
C30_15_8 = 0x20
C30_7_0 = 0x21
# Bitmasks to read from registers
# Read these from MEAS_CGF
COEF_RDY = 0b10000000
SENSOR_RDY = 0b01000000
TMP_RDY = 0b00100000
PRS_RDY = 0b00010000
# Read these from INT_STS
INT_FIFO_FULL = 0b00000100
INT_STS_TMP = 0b00000010
INT_STS_PRS = 0b00000001
# Read these from FIFO_STS
FIFO_FULL = 0b00000010
FIFO_EMPTY = 0b00000001
# Read these from ID
PROD_ID = 0b11110000
REV_ID = 0b00001111
# Codes to write to registers
# Write these to PRS_CFG
# The rate and oversample can bitwise-or'ed together
PRESSURE_RATE_1HZ = 0b00000000
PRESSURE_RATE_2HZ = 0b00010000
PRESSURE_RATE_4HZ = 0b00100000
PRESSURE_RATE_8HZ = 0b00110000
PRESSURE_RATE_16HZ = 0b01000000
PRESSURE_RATE_32HZ = 0b01010000
PRESSURE_RATE_64HZ = 0b01100000
PRESSURE_RATE_128HZ = 0b01110000
PRESSURE_OVERSAMPLE_1X = 0b00000000
PRESSURE_OVERSAMPLE_2X = 0b00000001
PRESSURE_OVERSAMPLE_4X = 0b00000010
PRESSURE_OVERSAMPLE_8X = 0b00000011
PRESSURE_OVERSAMPLE_16X = 0b00000100
PRESSURE_OVERSAMPLE_32X = 0b00000101
PRESSURE_OVERSAMPLE_64X = 0b00000110
PRESSURE_OVERSAMPLE_128X = 0b00000111
# Write these to TMP_CFG
# The sensor, rate, and can be bitwise-or'ed together
TEMPERATURE_SENSOR_EXTERNAL = 0b10000000
TEMPERATURE_SENSOR_INTERNAL = 0b00000000
TEMPERATURE_RATE_1HZ = 0b00000000
TEMPERATURE_RATE_2HZ = 0b00010000
TEMPERATURE_RATE_4HZ = 0b00100000
TEMPERATURE_RATE_8HZ = 0b00110000
TEMPERATURE_RATE_16HZ = 0b01000000
TEMPERATURE_RATE_32HZ = 0b01010000
TEMPERATURE_RATE_64HZ = 0b01100000
TEMPERATURE_RATE_128HZ = 0b01110000
TEMPERATURE_OVERSAMPLE_1X = 0b00000000
TEMPERATURE_OVERSAMPLE_2X = 0b00000001
TEMPERATURE_OVERSAMPLE_4X = 0b00000010
TEMPERATURE_OVERSAMPLE_8X = 0b00000011
TEMPERATURE_OVERSAMPLE_16X = 0b00000100
TEMPERATURE_OVERSAMPLE_32X = 0b00000101
TEMPERATURE_OVERSAMPLE_64X = 0b00000110
TEMPERATURE_OVERSAMPLE_128X = 0b00000111
# Write these to SensorsConstants.MEAS_CFG
STANDBY = 0b00000000
COMMAND_PRESSURE = 0b00000001
COMMAND_TEMPERATURE = 0b00000010
BACKGROUND_PRESSURE = 0b00000101
BACKGROUND_TEMPERATURE = 0b00000110
BACKGROUND_PRESSURE_TEMPERATURE = 0b00000111
# Read or write these to CFG_REG
# Note: temperature or pressure bit shift must be set when
# their respective oversample rates are set to > 8
INT_HL = 0b10000000
INT_FIFO = 0b01000000
INT_PRS = 0b00100000
INT_TMP = 0b00010000
T_SHIFT = 0b00001000
P_SHIFT = 0b00000100
FIFO_EN = 0b00000010
SPI_MODE = 0b00000001
FOUR_WIRE_SPI = 0b00000000
THREE_WIRE_SPI = 0b00000001
# Write these to RESET
# They can be bitwise-or'ed together
FLUSH_FIFO = 0b10000000
SOFT_RESET = 0b00001001
# For use in calibrating the sensor, taken from Table 4 of
# the data sheet
COMPENSATION_SCALE_FACTORS = {1: 524288,
2: 1572864,
4: 3670016,
8: 7864320,
16: 253952,
32: 516096,
64: 1040384,
128: 2088960}
# Some helper constants
PRESSURE_BIT_WIDTH = 24
TEMPERATURE_BIT_WIDTH = 24
PRESSURE_RATE_OPTIONS = {1: PRESSURE_RATE_1HZ,
2: PRESSURE_RATE_2HZ,
4: PRESSURE_RATE_4HZ,
8: PRESSURE_RATE_8HZ,
16: PRESSURE_RATE_16HZ,
32: PRESSURE_RATE_32HZ,
64: PRESSURE_RATE_64HZ,
128: PRESSURE_RATE_128HZ}
PRESSURE_OVERSAMPLE_OPTIONS = {1: PRESSURE_OVERSAMPLE_1X,
2: PRESSURE_OVERSAMPLE_2X,
4: PRESSURE_OVERSAMPLE_4X,
8: PRESSURE_OVERSAMPLE_8X,
16: PRESSURE_OVERSAMPLE_16X,
32: PRESSURE_OVERSAMPLE_32X,
64: PRESSURE_OVERSAMPLE_64X,
128: PRESSURE_OVERSAMPLE_128X}
TEMPERATURE_RATE_OPTIONS = {1: TEMPERATURE_RATE_1HZ,
2: TEMPERATURE_RATE_2HZ,
4: TEMPERATURE_RATE_4HZ,
8: TEMPERATURE_RATE_8HZ,
16: TEMPERATURE_RATE_16HZ,
32: TEMPERATURE_RATE_32HZ,
64: TEMPERATURE_RATE_64HZ,
128: TEMPERATURE_RATE_128HZ}
TEMPERATURE_OVERSAMPLE_OPTIONS = {1: TEMPERATURE_OVERSAMPLE_1X,
2: TEMPERATURE_OVERSAMPLE_2X,
4: TEMPERATURE_OVERSAMPLE_4X,
8: TEMPERATURE_OVERSAMPLE_8X,
16: TEMPERATURE_OVERSAMPLE_16X,
32: TEMPERATURE_OVERSAMPLE_32X,
64: TEMPERATURE_OVERSAMPLE_64X,
128: TEMPERATURE_OVERSAMPLE_128X}