jposada202020 / MicroPython_DPS310

MicroPython Driver for the DPS310 Sensor
MIT License
0 stars 1 forks source link

IndexError, fixed(?), but now temperature sensor is wrong (< 0) #1

Open flashypepo opened 1 year ago

flashypepo commented 1 year ago

Hi @jposada202020,

First, thanks for making the micropython driver for a DPS310 sensor.

I'm using your driver for a Lolin HP303B sensor (shield), which seems compatibly with the DPS310. I'm a software engineer, so apologies if that is a wrong assumption.

I'm using your simple test example, and got an IndexError in method mode() of class DPS310. After some research on github.com/wemos, I found an Arduino sample with Mode-values. It seems that two values are missing from your "mode_values"(index 3 and 4 in table must be present, although they are invalid).

My changes in module dps310.py:

line 85: added INVAL_OP_CMD_BOTH and INVAL_OP_CONT_NONE

# Source: https://github.com/wemos/LOLIN_HP303B_Library/blob/master/src/LOLIN_HP303B.h  -> enum Mode...
IDLE = const(0b000)
ONE_PRESSURE = const(0b001)
ONE_TEMPERATURE = const(0b010)
INVAL_OP_CMD_BOTH = const(0b011)  # invalid
INVAL_OP_CONT_NONE  = const(0b100) # invalid
CONT_PRESSURE = const(0b101)
CONT_TEMP = const(0b110)
CONT_PRESTEMP = const(0b111)
mode_values = (
    IDLE,             #0
    ONE_PRESSURE,     #1
    ONE_TEMPERATURE,  #2
    INVAL_OP_CMD_BOTH,  #3 - invalid
    INVAL_OP_CONT_NONE, #4 - invalid
    CONT_PRESSURE,    #5
    CONT_TEMP,        #6
    CONT_PRESTEMP,    #7
)

and in method mode() (around line 438):

#DEBUG: print(f"sensor_mode: {self._sensor_mode}")  # PP: 7 = 0b111 = CONT_PRESTEMP
        values = (
            "IDLE",
            "ONE_PRESSURE",
            "ONE_TEMPERATURE",
            "INVAL_OP_CMD_BOTH",   # invalid
            "INVAL_OP_CONT_NONE",  # invalid
            "CONT_PRESSURE",
            "CONT_TEMP",
            "CONT_PRESTEMP",
        )
        return values[self._sensor_mode]

The IndexError is gone! However, I'll get from the sensor temperature values below zero, while it definitely is above 20 degrees Celsius. The pressure value from the sensor seems correct.

Output sensor (simple test): Temperature -1.872383°C, Pressure: 990.9458HPa Room temperature: 22°C.

Could you have a look at it what is the problem and make a fix? I do not know what to do next. I'm willing to test it (with Lolin HP303B sensor).

Kind regards, Peter

jposada202020 commented 1 year ago

Hello there :) Interesting, I did not know about the "compatibility" between these two sensors. I have committed the changes for the index error, and I saw the same results as you mentioned with the temperature. Need to take a look in more deep to correct that in this library, sadly will kind of busy for a few weeks. Could you try this version in the gist. This is just an adaptation from the CircuitPython library (https://github.com/adafruit/Adafruit_CircuitPython_DPS310)

https://gist.github.com/jposada202020/3ea7bde4ec10f0bf1dec147a6bc9f845

It worked in my DPS310 sensor, but might or might not work in yours

Cheers and good luck

flashypepo commented 1 year ago

Hi Jose, gist-version: much better and it seems to work with HP303B sensor, meaning: I get reasonable values (except the first time):

Sample run:

Temperature 100.0°C, Pressure: 892.05HPa, Altitude: 948.3174m
Temperature 20.72327°C, Pressure: 997.5029HPa, Altitude: 16.02539m
Temperature 20.71877°C, Pressure: 997.5041HPa, Altitude: 16.01746m
Temperature 20.72602°C, Pressure: 997.5033HPa, Altitude: 16.02275m
Temperature 20.72927°C, Pressure: 997.5008HPa, Altitude: 16.04389m
..........

Code simple test - using Lolin HP303B sensor-shield:

import time
from machine import I2C
# GIST-version
from dps310 import DPS310

i2c = I2C(0)    # Lolin ESP32-s3mini
dps = DPS310(i2c)    #default  address=0x77)

# sea level pressure A'dam:
# https://barometricpressure.app/amsterdam#
dps.sea_level_pressure = 999.4  # 2023-0922 11:10

while True:
    print(f"Temperature {dps.temperature}°C, Pressure: {dps.pressure}HPa, Altitude: {dps.altitude}m")
    #print()
    time.sleep(1)

I'll use the gist version!

Thanks for your conversion of the CircuitPython DPS310-driver. Any plans with the gist version?

PS. It is always a "battle" between using micropython or circuitpython. Circuitpython does have more support for sensors and actuators. However, it is getting too complex (especially when looking in the displayio). Anyway, that is another subject.

Kind regards, Peter

flashypepo commented 1 year ago

Additional remark: a simple delay (about 400 ms) before getting the sensor values is enough to skip the first weird reading.

Looking into the DPS310 code: wait_temperature_ready and wait_pressure_ready might be worth to look into (or the "compatibility" ends between DPS310 and HP303B sensors).

Peter

jposada202020 commented 1 year ago

Hello, thanks for the info regarding the waiting time. :) Yes, planning to check where is the problem in the library and fix accordingly. Probably over the weekend!

radaidl commented 6 months ago

Hello, I did this quick and dirty fix to DPS310 code. I appears that the register changes are not working correctly.

Added to the end of init of class DPS310: This sets fixed values to oversampling and rate. So only 64 Hz os and 4 Hz rate are working with this fix.. but the temperature value and pressure values are now correct. I will check a bit more bit, but presently this is just a quick and dirty fix to anybody having problems with this...

    ## THIS fixes the code -- seems that assumed setting of registers fails!!
    # Oversampling Rate Setting (64time)
    self._i2c.writeto_mem(self._address, 0x06, b'\x26')
    self._i2c.writeto_mem(self._address, 0x07, b'\xA6') ##-- this line fixes the problem with pressure and temperature...
    self._i2c.writeto_mem(self._address, 0x08, b'\x07')
    # Oversampling Rate Configuration
    self._i2c.writeto_mem(self._address, 0x09, b'\x0C')

As you can see checking the original driver and the change made, the issue is about state of TMP_EXT bit in Temperature Configuration Register (0x7). If the highest bit is set to one, external temperature sensor is used. This fixes the problem with incorrect temperature values, causing also error in pressure readings. 0xA6 sets the bit 7 to one, and selects temperature measurement rate=1 Hz and Temperature oversampling is 64 times.. So basically there is need to fix the driver to set the highest bit of register 0x7 to 1. That fixes the problem.