Skip to content

correct temperature readings for defective ICs + misc. improvements #6

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from May 13, 2020
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,16 @@ Usage Example
print("")
time.sleep(1.0)

Caveat: by default the library initializes the IC with constant temperature and pressure measurements at 64Hz with 64 samples. It is not possible to change the IC's mode, temperature_oversample_count or pressure_oversample_count on-the-fly so resetting the IC and operation parameteres is required. For instance, to set the mode to continuous pressure measurement at 1Hz with 2 samples:

.. code-block:: python3

dps310.reset()
dps310.pressure_oversample_count = adafruit_dps310.SampleCount.COUNT_2
dps310.pressure_rate = adafruit_dps310.Rate.RATE_1_HZ
dps310.mode = adafruit_dps310.Mode.CONT_PRESSURE
dps310.wait_pressure_ready()


Contributing
============
Expand Down
70 changes: 58 additions & 12 deletions adafruit_dps310.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,10 @@ class DPS310:

_calib_coeff_temp_src_bit = ROBit(_DPS310_TMPCOEFSRCE, 7)

_reg0e = RWBits(8, 0x0E, 0)
_reg0f = RWBits(8, 0x0F, 0)
_reg62 = RWBits(8, 0x62, 0)

def __init__(self, i2c_bus, address=_DPS310_DEFAULT_ADDRESS):
self.i2c_device = i2c_device.I2CDevice(i2c_bus, address)

Expand Down Expand Up @@ -234,13 +238,9 @@ def __init__(self, i2c_bus, address=_DPS310_DEFAULT_ADDRESS):
self.initialize()

def initialize(self):
"""Reset the sensor to the default state"""

self._reset()
self._read_calibration()
"""Initialize the sensor to continuous measurement"""

# make sure we're using the temperature source used for calibration
self._temp_measurement_src_bit = self._calib_coeff_temp_src_bit
self.reset()

self.pressure_rate = Rate.RATE_64_HZ
self.pressure_oversample_count = SampleCount.COUNT_64
Expand All @@ -249,17 +249,35 @@ def initialize(self):
self.mode = Mode.CONT_PRESTEMP

# wait until we have at least one good measurement

while (self._temp_ready is False) or (self._pressure_ready is False):
sleep(0.001)

def _reset(self):
"""Perform a soft-reset on the sensor"""
self.wait_temperature_ready()
self.wait_pressure_ready()

# (https://github.com/Infineon/DPS310-Pressure-Sensor#temperature-measurement-issue)
# similar to DpsClass::correctTemp(void) from infineon's c++ library
def _correct_temp(self):
"""Correct temperature readings on ICs with a fuse bit problem"""
self._reg0e = 0xA5
self._reg0f = 0x96
self._reg62 = 0x02
self._reg0e = 0
self._reg0f = 0

# perform a temperature measurement
# the most recent temperature will be saved internally
# and used for compensation when calculating pressure
_unused = self._raw_temperature

def reset(self):
"""Reset the sensor"""
self._reset_register = 0x89
# wait for hardware reset to finish
sleep(0.010)
while not self._sensor_ready:
sleep(0.001)
self._correct_temp()
self._read_calibration()
# make sure we're using the temperature source used for calibration
self._temp_measurement_src_bit = self._calib_coeff_temp_src_bit

@property
def pressure(self):
Expand Down Expand Up @@ -296,11 +314,39 @@ def temperature_ready(self):
"""Returns true if there is a temperature reading ready"""
return self._temp_ready

def wait_temperature_ready(self):
"""Wait until a temperature measurement is available"""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a note to the docstrings for the wait_nnn_ready methods about which modes are supported so that hapless meteorologists aren't ambushed by wild Errors 🐅

if (
self._mode_bits == Mode.IDLE
or self._mode_bits == Mode.ONE_PRESSURE
or self._mode_bits == Mode.CONT_PRESSURE
):
raise RuntimeError(
"Sensor mode is set to idle or pressure measurement,\
can't wait for a temperature measurement"
)
while self._temp_ready is False:
sleep(0.001)

@property
def pressure_ready(self):
"""Returns true if pressure readings are ready"""
return self._pressure_ready

def wait_pressure_ready(self):
"""Wait until a pressure measurement is available"""
if (
self._mode_bits == Mode.IDLE
or self._mode_bits == Mode.ONE_TEMPERATURE
or self._mode_bits == Mode.CONT_TEMP
):
raise RuntimeError(
"Sensor mode is set to idle or temperature measurement,\
can't wait for a pressure measurement"
)
while self._pressure_ready is False:
sleep(0.001)

@property
def mode(self):
"""The measurement mode. Must be a `Mode`. See the `Mode` documentation for details"""
Expand Down
31 changes: 31 additions & 0 deletions examples/dps310_low_power_weather_station.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# configure the sensor for continuous measurement for a
# low power weather station as recommended in the datasheet:
# https://www.infineon.com/dgdl/Infineon-DPS310-DS-v01_00-EN.pdf)

# (disable pylint warnings for adafruit_dps310.{SampleCount,Rate,Mode}.*
# as they are generated dynamically)
# pylint: disable=no-member

import time
import board
import busio
import adafruit_dps310

i2c = busio.I2C(board.SCL, board.SDA)

dps310 = adafruit_dps310.DPS310(i2c)

dps310.reset()
dps310.pressure_oversample_count = adafruit_dps310.SampleCount.COUNT_2
dps310.pressure_rate = adafruit_dps310.Rate.RATE_1_HZ
dps310.temperature_oversample_count = adafruit_dps310.SampleCount.COUNT_16
dps310.temperature_rate = adafruit_dps310.Rate.RATE_1_HZ
dps310.mode = adafruit_dps310.Mode.CONT_PRESTEMP
dps310.wait_temperature_ready()
dps310.wait_pressure_ready()

while True:
print("Temperature = %.2f *C" % dps310.temperature)
print("Pressure = %.2f hPa" % dps310.pressure)
print("")
time.sleep(10.0)