1

Before I start, I have browsed the "similar questions" section before writing this and could not see one that matched a situation like mine. If one is found, please let me know and I will mark it as "answered" if it is in fact similar. I am a .net full stack developer by profession, i only recently started dabbling in Python and Electrical Engineering as a hobby.

I am creating an Automated Aquaponics Control system, a part of the project reads the temp of the grow bed media and with the input of various other sensors, recalculates the frequency at which the pump cycles to flood the bed. I am using a DS18B20 with Python3.9 and the W1ThermSensor v2.0.0a2 library. Here is the init and first of several functions for the sensor. I have the w1thermsensor as a property of the class instead of inheritance just during the initial testing, since it is easier to manipulate the code this way for me.

#!/usr/bin/env python3

from w1thermsensor import W1ThermSensor, Sensor, Unit
from datetime import datetime
import os
import numpy
import traceback


class DS18B20:

    def __init__(self, min_temp=18, max_temp=26):
        self.sensor = W1ThermSensor()
        self.temp_string = "{dt} : Sensor: {id} :: {temp_c}C - {temp_f}F"
        self.temp_c = 0.00
        self.temp_f = 0.00
        self.is_active = False
        self.is_alert = False
        self.min_temp = min_temp
        self.max_temp = max_temp
        self.values = [0.00, 0.00, 0.00, 0.00, 0.00]
        self.value = 0.00

    def start(self):
        if self.sensor is None:
            return False
        os.system('modprobe w1-gpio')
        os.system('modprobe w1-therm')
        # Set baseline for values Average
        self.is_active = True
        self.monitor()
        self.values = [self.temp_c, self.temp_c, self.temp_c, self.temp_c, self.temp_c]
        self.value = numpy.average(self.values)

This issue that I am running into is that it will have one of 3 issues:

  1. Raises w1thermsensor.errors.NoSensorFoundError
  2. Raises w1thermsensor.errors.SensorNotReadyError
  3. Returns no value in the temp_c property after calling get_temperature()

I looked into this a bit more, If i load up the IDLE in Terminal using the 'sudo python3' command I can enter the following commands and it works no problem:

sudo python3
>>> from w1thermsensor import W1ThermSensor, Sensor
>>> import time
>>> temp_sensor = W1ThermSensor(Sensor.DS18B20)
>>> while True:
...    print(str(round(temp_sensor.get_temperature()))
...    time.sleep(2)

and it works without issue. I also try the 'cat' command

cd /sys/bus/w1/devices
cd 28-3c01d607414b
cat w1_slave
94 01 55 05 7f a5 81 66 5b : crc=5b YES
94 01 55 05 7f a5 81 66 5b t=25250

The stacktrace shows that it is throwing the Errors when it is calling the W1Termsensor() function in "init()". My question is, is it my code or implementation that is causing the issue, or is it something else. My sleep is set to 2 seconds in the hope that I am just catching it in the middle of an update. Any help would be a big help.

Addtional Info:

  • the DS18B20 is wired to a separate 5v power source, the capacitor it to stableize the voltage since there is a 5v relay and a LED array on the same 5v power rail of the power supply.
    5v+ -------------+---------VCC------
                     |                  |
                   4.7 Kohm             |
                     |                  |
    GPIO4 ---------------------DQ       = 1uf polCap
                                        |
                                        |
                                        |
    GND ----------------------GND-------
  • I have double-checked that I have 1-wire enabled.

EDIT - Added code for file system read as well

def read_file(self):
    try:
        self.lines = []
        print(self.file + ' - temp Location')
        print('Opening File')
        f = open(self.file, 'r')
        print('Reading File')
        print(f.readlines())
        self.lines = f.readlines()
        print('Closing File')
        f.close()
    except Exception as e:
        print(e)
        print(traceback.print_exc())
        print('Error in read_file')

def read_temp(self):
    try:
        lines_read = 0
        self.read_file()
        lines_read = int(len(self.lines))
        print(str(lines_read) + ' lines found.')
        while lines_read < 2 or self.lines[0].strip()[-3:] != 'YES':
            time.sleep(0.2)
            self.read_file()
            lines_read = int(len(self.lines))
            print(str(lines_read) + ' lines found  Repeating.')
        print('Reading Temp Line')
        print(self.lines)
        equals_pos = self.lines[1].find('t=')
        if equals_pos != -1:
            temp_raw = self.lines[1].strip()[equals_pos + 2:]
            if self.read_as_c:
                print('Reading C Temp')
                self.temp = float(temp_raw) / 1000.0
            else:
                print('Reading F Temp')
                self.temp = (float(temp_raw) / 1000.0) * 9.0 / 5.0 + 32.0
        if len(self.values) >= 4:
            print('Removing oldest Temp')
            self.values.pop(0)
        print('Appending Newest Temp')
        self.values.append(self.temp)
    except Exception as e:
        print(e)
        print(traceback.print_exc())
        print('Error in read_temp')
6
  • DO NOT connect GPIO4 to 5V, even through a resistor, You will sooner or later destroy the GPIO and then the Pi. If you must use 5V change the GPIO4 pull-up to the 3V3 pin. Why not use dtoverlay=w1-gpio in /boot/config.txt and the file system interface to read the sensor? – joan Jan 19 at 19:08
  • @joan Thank you for the tip. All of the tutorials I read said to use 5v for this sensor, i will switch to 3.3v at your suggestion and see what happens. Also, I do use the /boot/config.txt setting, the os commands are as a precaution in case it isn't already configured since it does not do any harm. Any ideas though as to why i can read it via CLI but not when running my python code. I have tried reading it via the file system also, will update question with code, and it shows 0 lines read. – Kelby Criswell Jan 19 at 19:44
  • You can power using 5V. But you mustn't use a pull-up to 5V on any GPIO. – joan Jan 19 at 20:49
  • @joan ok, if I do use 5V+ then i do not need the Pull-up resistor and it should still work? If you know the answer, What is the benefit of using 5v vs 3v3? All of the tutorials say use 5V but the spec of the device says can use either 5v or 3v3. – Kelby Criswell Jan 20 at 16:54
  • You need a pull-up The pull-up must be to 3V3 on the Pi. The pull-up is marked as 4.7 Kohm on your diagram. Rather than going from GPIO4/DQ to the 5V rail it should go to the 3V3 rail. Vcc can still be 5V. – joan Jan 20 at 17:44
0

Try the following.

#!/usr/bin/env python

import glob
import time

# Typical reading
# 73 01 4b 46 7f ff 0d 10 41 : crc=41 YES
# 73 01 4b 46 7f ff 0d 10 41 t=23187

while True:

   for sensor in glob.glob("/sys/bus/w1/devices/28-*/w1_slave"):
      print(sensor)
      id = sensor.split("/")[5]

      try:
         f = open(sensor, "r")
         data = f.read()
         f.close()
         if "YES" in data:
            (discard, sep, reading) = data.partition(' t=')
            t = float(reading) / 1000.0
            print("{} {:.1f}".format(id, t))
         else:
            print("999.9")

      except:
         pass

   time.sleep(3.0)
2
  • Tested using SSH as a standalone file, that worked. I will attempt it integrated into the project and will let you know. This is also using it on 3v3 with a 4.7Kohm pull-up. Will update as soon as I know – Kelby Criswell Jan 20 at 17:19
  • This worked like a charm! Thank you very much @joan – Kelby Criswell Jan 20 at 19:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.