logoi5893
Posts: 10
Joined: Thu Nov 10, 2016 3:01 pm

How to power and read multiple DS18B20 temperature sensors

Thu Feb 08, 2018 10:30 pm

I have multiple areas of our facility for which I monitor temperatures. My sensor of choice is Dallas DS18B20 digital OneWire sensors. These things are great! Very cheap, accurate, and easy to deploy. I'm using Rpi's and python scripts to:
  1. read the sensors once each minute
  2. write the results to a CSV file
  3. email the CSV file once per day so that we can graph the results and look at trends, and
  4. email if a sensor is over a set temperature threshold for a set period of time
Each sensor is run with audio wire (Belden 9451). I have one RPi that hosts five sensors, with a total run of (I'm guessing here) about 75-100 feet.
This has worked long term, and I'm fairly satisfied with the results. The one problem that I've run into is that if I were to add another sensor to this RPi it causes several of the sensors to disappear.

My question is related to this problem. I want to add an arbitrary number of additional sensors, but I'm not sure whether the problem is the overall capacitance of the run, or whether there's too much voltage drop in the Vin line to the sensors. I'm powering the entire bus off of the RPi 3V3 rail.

My solution so far was to just get another RPi in order to host the additional sensors. But because of the size of the facility, if we wanted to monitor even more locations this could get to be a silly number of Pi's. I was thinking of trying to externally power the bus instead of feeding it from the RPI, but then how do I properly do this without causing problems to the Pi?

Any ideas would be appreciated. Thanks!

User avatar
rpdom
Posts: 12757
Joined: Sun May 06, 2012 5:17 am
Location: Ankh-Morpork

Re: How to power and read multiple DS18B20 temperature sensors

Fri Feb 09, 2018 6:47 am

You can power the DS18B20s from the 5V on the Pi, as long as the 4K7 pull up resistor is only connected to the 3.3V supply. That might help on such a long run.

logoi5893
Posts: 10
Joined: Thu Nov 10, 2016 3:01 pm

Re: How to power and read multiple DS18B20 temperature sensors

Fri Feb 09, 2018 2:22 pm

You can power the DS18B20s from the 5V on the Pi, as long as the 4K7 pull up resistor is only connected to the 3.3V supply. That might help on such a long run.
I'm having a hard time visualizing that. I do have a 2K0 resistor between 3V3 and data. Are you saying that I can use 5V with a higher ohm resistor between 5V and data, or did you mean that 3V3 still needs to be hooked up in some way?

So just to be clear about how I'm set up:
  • Ground of each sensor is connected as a bus to GND on the Pi.
  • Data of each sensor is connected as a bus to GPIO4 on the Pi.
  • Vin of each sensor is connected to 3v3 on the Pi.
  • There is a 2kohm resistor between the data and 3v3 buses (I tried higher ohms as initially recommended but the number of sensors that it could sustain were even fewer).

Thanks for the input!

danjperron
Posts: 2977
Joined: Thu Dec 27, 2012 4:05 am
Location: Québec, Canada

Re: How to power and read multiple DS18B20 temperature sensors

Fri Feb 09, 2018 2:32 pm

The ds18b20 could sink down up to 4ma. If you don't go near that limit you will be ok. The typical resistor is 4700 ohms. But for long cable it will be needed to decrease the value to compensate the capacitance of the cable which is around 50pF per meter. 9us delay is the typical readout of the data.

The data output pin is an open collector. If you power 5V to the sensor the data pin won't have 5V. This is why the pullup is needed!

logoi5893
Posts: 10
Joined: Thu Nov 10, 2016 3:01 pm

Re: How to power and read multiple DS18B20 temperature sensors

Wed Feb 14, 2018 4:38 pm

Okay, I took a fresh look at the datasheet and I've got one more question. Are you recommending running Vdd (supply voltage) from the Pi's 5V, and running DQ (data bus) from the Pi's 3v3 (via a pullup resistor)? Or are you recommending running both Vdd and DQ from the Pi's 5V (with the resistor connected between 5V and DQ)?

Thanks again!

User avatar
rpdom
Posts: 12757
Joined: Sun May 06, 2012 5:17 am
Location: Ankh-Morpork

Re: How to power and read multiple DS18B20 temperature sensors

Wed Feb 14, 2018 5:03 pm

logoi5893 wrote:
Wed Feb 14, 2018 4:38 pm
Okay, I took a fresh look at the datasheet and I've got one more question. Are you recommending running Vdd (supply voltage) from the Pi's 5V, and running DQ (data bus) from the Pi's 3v3 (via a pullup resistor)? Or are you recommending running both Vdd and DQ from the Pi's 5V (with the resistor connected between 5V and DQ)?

Thanks again!
The first option. Vdd from 5V, DQ with a pull up to 3V3.

logoi5893
Posts: 10
Joined: Thu Nov 10, 2016 3:01 pm

Re: How to power and read multiple DS18B20 temperature sensors

Wed Feb 14, 2018 5:09 pm

Cool... thanks! I'll give it a go.

logoi5893
Posts: 10
Joined: Thu Nov 10, 2016 3:01 pm

Re: How to power and read multiple DS18B20 temperature sensors

Thu Feb 15, 2018 5:50 pm

I re-wired as explained above. My pullup resistor is 1500 ohms. I am currently running 5 sensors. They all showed up, but the problem is that three of them read 185 degrees, as if they couldnt tak the reading. One by one they started reading correctly over a 10 minute period. Any ideas?

Rsterw123
Posts: 1
Joined: Tue Feb 20, 2018 4:15 pm

Re: How to power and read multiple DS18B20 temperature sensors

Tue Feb 20, 2018 4:19 pm

Hi,

does anyone have a python script that reads 3(or more) DS18b20? , i am trying to cloud basically read temperature data and send to cloud.

Thanks

logoi5893
Posts: 10
Joined: Thu Nov 10, 2016 3:01 pm

Re: How to power and read multiple DS18B20 temperature sensors

Tue Feb 20, 2018 7:44 pm

Hi,

does anyone have a python script that reads 3(or more) DS18b20? , i am trying to cloud basically read temperature data and send to cloud.

Thanks
Here is the relevant portion of what I'm using. I have just cobbled this over the months, so I'm sure there's a more elegant way to do this with for loops of some sort. All I could figure out at the time is to add more functions for more sensors.

You'll need to alter the serial numbers for your particular sensors. Those are the actual folder names found in the /sys/bus/w1/devices/ folder.

This script produces CSV file with the readings; filename is stored as out_filename. The delay at the end makes it take readings approximately once per minute.

Code: Select all

import os
import glob
import time
from datetime import datetime
import csv


########################
# Set up all variables #
########################

#allows use of the sensors 
os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')
base_dir = '/sys/bus/w1/devices/'

#name the CSV file for the data log
out_filename = '/home/pi/Desktop/temp.csv'

#initialize variables for counting hot readings
i1 = 0
i2 = 0
i3 = 0

#insert device serial numbers here
sn1 = '28-000007fa7b38'
sn2 = '28-000007fa204b'
sn3 = '28-000007f94437'

#initialize all of the directories for the sensors
device_file1 = glob.glob(base_dir + sn1)[0] + '/w1_slave'
device_file2 = glob.glob(base_dir + sn2)[0] + '/w1_slave'
device_file3 = glob.glob(base_dir + sn3)[0] + '/w1_slave'

################################
# Routines to read each sensor #
################################
#Read Sensor 1
def read_temp_raw1():
	f = open(device_file1, 'r')
	lines1 = f.readlines()
	f.close()
	return lines1

def read_temp1():
	lines1 = read_temp_raw1()
	while lines1[0].strip()[-3:] != 'YES':
		time.sleep(0.2)
		lines1 = read_temp_raw1()
	equals_pos = lines1[1].find('t=')
	if equals_pos != -1:
		temp_string1 = lines1[1][equals_pos+2:]
		temp_c1 = float(temp_string1) / 1000.0
		temp_f1 = temp_c1 * 9.0 / 5.0 + 32.0
		return temp_f1

#Read Sensor 2
def read_temp_raw2():
	f = open(device_file2, 'r')
	lines2 = f.readlines()
	f.close()
	return lines2

def read_temp2():
	lines2 = read_temp_raw2()
	while lines2[0].strip()[-3:] != 'YES':
		time.sleep(0.2)
		lines2 = read_temp_raw2()
	equals_pos = lines2[1].find('t=')
	if equals_pos != -1:
		temp_string2 = lines2[1][equals_pos+2:]
		temp_c2 = float(temp_string2) / 1000.0
		temp_f2 = temp_c2 * 9.0 / 5.0 + 32.0
		return temp_f2

#Read Sensor 3
def read_temp_raw3():
        f = open(device_file3, 'r')
        lines3 = f.readlines()
        f.close()
        return lines3

def read_temp3():
        lines3 = read_temp_raw3()
        while lines3[0].strip()[-3:] != 'YES':
                time.sleep(0.2)
                lines3 = read_temp_raw3()
        equals_pos = lines3[1].find('t=')
        if equals_pos != -1:
                temp_string3 = lines3[1][equals_pos+2:]
                temp_c3 = float(temp_string3) / 1000.0
                temp_f3 = temp_c3 * 9.0 / 5.0 + 32.0
                return temp_f3


#############
# Main Loop #
#############

while True:
	
	currenttime = time.ctime()
	temp1 = read_temp1()
	temp2 = read_temp2()
	temp3 = read_temp3()

	with open(out_filename, 'a') as f:
		writer = csv.writer(f)
		writer.writerow((
			currenttime,
			temp1,
			temp2,
			temp3,
		))
	open(out_filename).close()

	time.sleep(60)

pcmanbob
Posts: 4270
Joined: Fri May 31, 2013 9:28 pm
Location: Mansfield UK

Re: How to power and read multiple DS18B20 temperature sensors

Wed Feb 21, 2018 11:52 am

Fist you should not be using

Code: Select all

os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')
To enable the 1-wire interface, you should use sudo raspi-config and under interfaces you will find 1-wire which you can then enable, you then need to reboot your pi.

With regards a more efficient way of reading multiple sensors this is how I did it.

Code: Select all

sensorids = ["28-041701672bff", "28-04170170feff", "28-0116035524ee", "28-021603a172ee"]


def read_temp_raw():
    f = open(device_file, "r")
    lines = f.readlines()
    f.close()
    return lines
 
def read_temp():
    lines = read_temp_raw()
    while lines[0].strip()[-3:] != "YES":
        time.sleep(0.2)
        lines = read_temp_raw()
    equals_pos = lines[1].find("t=")
    if equals_pos != -1:
        temp_string = lines[1][equals_pos+2:]
        temp_c = float(temp_string) / 1000.0
        
        return temp_c
	
while True:
    data =""
    for sensor in range(len(sensorids)):
        device_file = "/sys/bus/w1/devices/"+ sensorids[sensor] +"/w1_slave"
        temperature = (read_temp())
        dtemp = "%.1f" % temperature
        result = (str(dtemp)) + " C "
        
its just the relevant bit of my code and you will have to change the sensor ID's to your own.

so when the code in the loop defined by for sensor in range(len(sensorids)): runs it returns the temp reading in the variable named result, for each sensor in the list sensorids.

In my case I wanted it to be a string which included C at the end, if you just want the raw temp reading as a number you can remove the result line and use variable dtemp for the results.
Remember we want information.......................no information no help
The use of crystal balls & mind reading is not supported

User avatar
bensimmo
Posts: 3127
Joined: Sun Dec 28, 2014 3:02 pm
Location: East Yorkshire

Re: How to power and read multiple DS18B20 temperature sensors

Wed Feb 21, 2018 12:05 pm

Have you thought about running another chain off another GPIO pin. You don't have to stick to just one pin.
You can add them to config.txt or load dynamically (I've not done this part)
https://pinout.xyz/pinout/1_wire

Or use Wi-Fi/ESP8266 modules to send the data around, but that does require a local power source.

User avatar
bensimmo
Posts: 3127
Joined: Sun Dec 28, 2014 3:02 pm
Location: East Yorkshire

Re: How to power and read multiple DS18B20 temperature sensors

Wed Feb 21, 2018 12:11 pm

For quick and easy 1-Wire reading (and multple reading)
I use https://github.com/timofurrer/w1thermsensor
You can then add sensors ass needed, use that to collect the sensorID and store them to the CSV as needed.

If I can find my old code before I messed it up with threading I'll post it.
I moved to other methods for threading as he didn't wish to implent it




(threading, so I could send a read command and they would all start reading in parallel rather than in the slower series one after the other method normally used, not normally a problem for most things witha good time intrval between readings)

logoi5893
Posts: 10
Joined: Thu Nov 10, 2016 3:01 pm

Re: How to power and read multiple DS18B20 temperature sensors

Wed Feb 21, 2018 2:53 pm

bensimmo wrote:
Wed Feb 21, 2018 12:05 pm
Have you thought about running another chain off another GPIO pin. You don't have to stick to just one pin.
You can add them to config.txt or load dynamically (I've not done this part)
https://pinout.xyz/pinout/1_wire

Or use Wi-Fi/ESP8266 modules to send the data around, but that does require a local power source.
Excellent idea! I hadn't seen this before, and thought that GPIO4 was the only one that would do 1-wire.

Return to “Automation, sensing and robotics”

Who is online

Users browsing this forum: No registered users and 12 guests