timofurrer / w1thermsensor

A Python package and CLI tool to work with w1 temperature sensors like DS1822, DS18S20 & DS18B20 on the Raspberry Pi, Beagle Bone and other devices.
MIT License
493 stars 113 forks source link

Conversion time delay #53

Closed Gbassous closed 5 years ago

Gbassous commented 5 years ago

I reduced the resolution to 9 bits in order to be able to acquire all my data (temperature, photovoltaic power and an image) at 1Hz, but I'm still getting what seems to be a 750 ms conversion time., 900+ ms total reading time.

Below is my test code and result:

from w1thermsensor import W1ThermSensor
import time

sensor = W1ThermSensor(W1ThermSensor.THERM_SENSOR_DS18B20, "04168613d9ff")

t1 = time.perf_counter()
temp = sensor.get_temperature()
t2 = time.perf_counter()

print(t2-t1)
print(temp)
(py3cv4gpio_mestrado) pi@GBSky:~/mestrado $ python w1thermtest.py
0.920645008000065
72.5
timofurrer commented 5 years ago

How did you set the precision / resolution?

Gbassous commented 5 years ago

I set it in the terminal: sensor.set_precision(9, persist=True) Output was True

timofurrer commented 5 years ago

Can you try to time to reads from the w1 file directly?

They are located under /sys/bus/w1/devices

timofurrer commented 5 years ago

@Gbassous any feedback?

southseaboy commented 5 years ago

Hi, I was investigating the same issue and came across this thread.

I've run a quick & dirty test using a direct file read as well as using the library. I'm getting pretty much the same read times from both methods (mainly varies between 850mSec and 920mSec with a few outliers - 1.78 secs), and these seem independent of the precision set. I'm happy that the precision setting is working as I get the expected results.

The code I used for the file reads (just in case I've made a honking mistake here):

os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')

temp_sensor = '/sys/bus/w1/devices/28-0118677f06ff/w1_slave'

def temp_raw():
    f = open(temp_sensor, 'r')
    lines = f.readlines()
    f.close()
    return lines

def read_temp():
    start = time.time()
    lines = temp_raw()
    while lines[0].strip()[-3:] != "YES":
        time.sleep(0.05)    # this value - within reason - has little effect on repeat timings
        lines = temp_raw()

    temp_output = lines[1].find('t=')

    if temp_output != -1:
        temp_string = lines[1].strip()[temp_output+2:]
        temp_c = float(temp_string)/1000.0
        duration = time.time() - start
        return temp_c, duration

while True:
    result = read_temp()
    print(result[0]," : ",result[1])
    time.sleep(1.5)

HTH

timofurrer commented 5 years ago

So to conclude it's not a problem of this library, but rather the Linux kernel modules in use, right?

southseaboy commented 5 years ago

I'm a rank beginner in python, but I don't know of anything that would contradict your conclusion.

Does your library offer a function that allows async reads similar to the arduino DallasTemperature?

timofurrer commented 5 years ago

What do you mean by async reads? I'm not familiar with the DallasTemperature library. Like asyncio ? Or just periodic reads?

southseaboy commented 5 years ago

The Maxim chip allows a conversion to the be triggered without waiting for the result. When the result is ready it can be read from a register. The sensor chip has a way of signalling that the read is complete, but I think this is dependent upon not using parasitic power so not always possible. I use the async read function as a periodic process - I trigger a conversion, then go do other stuff, when that's done I read the result and trigger another read, and so on. This does mean that the temps are one loop sample behind real time, but it's of little consequence in the applications I have.

timofurrer commented 5 years ago

I'm going to close this issue, because it doesn't seem that those issues are coming from the w1thermsensor package - it rather seems to be an hardware or linux kernel module issue.

If someone has a way to reproduce this issue with w1thermsensor and an example with reading from the sensor files (provided by the kernel module) directly - I'm happy to investigate.