Interfacing DS18B20 Temperature sensor with Raspberry Pi


#1

DS18B20 is a commonly used temperature sensor providing 9 bit to 12 bit digital Celsius temperature measurements. The sensor communicates over one wire bus. Each sensor has a 64 bit serial code enabling multiple sensors to be connected to the same one wire bus.

The Raspberry Pi has drivers for one wired devices to be connected to GPIO pin-4 by default. 1-wire is a device communication data bus system developed by Dallas semiconductor providing low speed data, signalling and power over a single signal wire. One wire is similar to I2C with longer range and low data rates. It can be used to communicate with inexpensive devices like thermometers, humidity sensors and other one wire sensors over a long range. The main advantage is since each device has a unique address, any number of devices can be connected on a single wire limited by the drive capacity of Raspberry Pi’s GPIO and the total capacitance seen on the line.

Circuit Diagram

The one wire bus requires a weak pull up resistor as all devices linked to this bus via a tri-state or open drain output. Here a 4.7KΩ resistor is used as pull up.


Sensor not detecting after OS update

Users having Rasbian with updated Linux kernel 3.18 need to edit boot config file to work with one wire sensors.
In terminal edit config file,
sudo nano /boot/config.txt
And add,
dtoverlay=w1-gpio,gpiopin=4
And save (Ctrl+X)
Reading temperature using Terminal

The one wire communication device kernel modules can be loaded by typing,
sudo modprobe w1-gpio
sudo modprobe w1-therm
Point to the address of the temperature sensor,

cd /sys/bus/w1/devices/28*
Note: If more than one device is connected use cd /sys/bus/w1/devices/ and ls to list all the devices and cd address where address is the unique address of the device required. For eg.cd 28-00042d8165ff
Display temperature,

cat w1_slave
Terminal Output

The displayed data consist of two lines – first line representing the value read and CRC check and second line temperature in Celsius x 1000.

This can also be done in Python with python handling CRC errors and the temperature displayed both in Celsius and Fahrenheit.

Python code
import os # import os module
import glob # import glob module
import time # import time module
os.system(‘modprobe w1-gpio’) # load one wire communication device kernel modules
os.system(‘modprobe w1-therm’)
base_dir = ‘/sys/bus/w1/devices/’ # point to the address
device_folder = glob.glob(base_dir + ‘28*’)[0] # find device with address starting from 28*
device_file = device_folder + ‘/w1_slave’ # store the details
def read_temp_raw():
f = open(device_file, ‘r’)
lines = f.readlines() # read the device details
f.close()
return lines

def read_temp():
lines = read_temp_raw()
while lines[0].strip()[-3:] != ‘YES’: # ignore first line
time.sleep(0.2)
lines = read_temp_raw()
equals_pos = lines[1].find(‘t=’) # find temperature in the details
if equals_pos != -1:
temp_string = lines[1][equals_pos+2:]
temp_c = float(temp_string) / 1000.0 # convert to Celsius
temp_f = temp_c * 9.0 / 5.0 + 32.0 # convert to Fahrenheit
return temp_c, temp_f

while True:
print(read_temp()) # Print temperature
time.sleep(1)

The python output consists of temperature in both Celsius and Fahrenheit scale displayed at an interval of one second.

Any doubts or suggestions? Comment below.


#2

wayne pierce is a programmer in C++ / arduino who has developed remote temp sensing using xbee transmitters and using the temp / fan / water controls and reporting it in on the usb / serial port to the arduino.ide monitor. Not understanding your code or his to the level of your report, I would suggest contacting him. He has this up on a github. which I am trying to find. We also submitted the code to Rory and he has it under farmware somewhere. Please let us know if what we are conversing about is of any value or you think we can help.

best

al

Below is not the current, but shows where we are at.
/*
Sketch_chicken_Coop_Nov4

YourDuinoStarter Example: Temperature Sensor

  • Communicates with a DS18B20 temperature sensor, shows value read.
  • SEE the comments after “//” on each line below
  • CONNECTIONS: (Holding chip with pins down, label towards you)
  • Black pin: Ground// from the shield
  • Red pin: +5V // from the shield
  • White pin: Arduino Pin 10 and ALSO “Pullup Resistor”:
  • Center pin: to 4700 (4.7K) or 5K resistor * (other end goes to +5V)
  • NOTE: Two 10K resistors connected in parallel can be used.

/-----( Import needed libraries )-----/
#include <OneWire.h> // frm the libraries For many “1-wire” devices
#include <DallasTemperature.h> // Specific for temperature sensors
#include <SoftwareSerial.h>
const int switchPin = 3; // could be LED push button on end device.
const int ledPin = 13; //on shield as light. NOt what we are using.
const int K1Pin = 5;// 5 & 6 output to 110 volt relay, m1 and m2
const int K2Pin = 6;
const int SetPoint = 78; //Desired Temperature
SoftwareSerial mySerial(8,9); // RX, TX input / output to XBee.
/-----( Declare Constants and Pin Numbers )-----/
// Data wire is plugged into port 9 on the Arduino (can be changed)
#define ONE_WIRE_BUS 10 // temp from middle pin on sensor to shield.

/-----( Declare objects )-----/
// Setup a oneWire instance to communicate with any OneWire devices
// (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass address of our oneWire instance to Dallas Temperature.
DallasTemperature sensors(&oneWire); //returned var having run dallas temp with input OneWire it Passes address of our oneWire instance to Dallas Temperature.

/-----( Declare Variables )-----/
float TempInF ; //Floating Point variable for F Temperature
int switchState; //Switch was HIGH=1 or LOW=0
void setup() // SETUP: RUNS Once. void cmd. means no value returned
{
Serial.begin(9600); // start serial port… USB
// while (!Serial) {
// ;
pinMode(ledPin, OUTPUT); // This pin 13 will be an output
pinMode(switchPin, INPUT); // Not really needed: default
// Serial.begin(9600); // Start up the Serial Monitor
mySerial.println(“YourDuinoStarterSet ITS ON OFF Test”);

// wait for serial port to connect. Needed for Leonardo only
// } remed out !!!
Serial.println(“Local Output”); //printing to usb port on the arduini board. Only used when serial output is needed. Only used on the coordinator.
mySerial.begin(9600); //is out to the xbee. MySerial is another program. Output on port 8 / 9
mySerial.println(“YourDuinoStarter Example: DS18B20 Temperature Sensor Reading”);

sensors.begin(); // Start up the temperature measurement library
}//–(end setup )—

void loop() /****** LOOP: RUNS CONSTANTLY ******/
{
delay(20000);
// mySerial.print(“Grn House …”);
sensors.requestTemperatures(); // Send the command to get temperatures
// mySerial.println(“DONE”);

/----( Here we will save values to use for other things)------/
TempInF = sensors.getTempFByIndex(0); // Get and save sensor value
// mySerial.println(“Here are our saved values”);
//mySerial.print("Temperature in F = ");
mySerial.println(TempInF, 2); // “2” sets the number of decimal places
// mySerial.println();

switchState = digitalRead(switchPin);
/–(NOTE!!! “==” means “compare equal” )–/
if (switchState == HIGH) // Switch was pushed
{
// mySerial.println(“ITS -ON - !”);
digitalWrite(ledPin, HIGH);
}
else
{
// mySerial.println(“ITS -OFF- !”);
digitalWrite(ledPin, LOW);
}

/–(Compare TempInF to SetPoint and make decisions )–/
if (TempInF >= (SetPoint + 5))
{
// mySerial.println(“It’s too warm. Fan on.”);
digitalWrite(K1Pin, LOW);
}
else
{
digitalWrite(K1Pin, HIGH);// turn on fan
}
if (TempInF <= (SetPoint - 5))
{
// mySerial.println(“It’s too cold. Heat on.”);
digitalWrite(K2Pin, LOW); // active low, turn on heater
}
else
{
digitalWrite(K2Pin, HIGH); //heater off
}

}//–(end main loop )—

/-----( Declare User-written Functions )-----/
//none
//( THE END )**


#3

Hi guys, I´d like to bring this one up again.

What is currently possible with the farmbot web app (5.0.1) regarding this specific question?