This article was written using Linux Kernel 4.19.x
1-Wire is a device communications bus system designed by Dallas Semiconductor that provides low-speed data, signaling, and power over a single signal. 1-Wire is similar in concept to I2C, but with lower data rates and longer range.
1-Wire is typically used to communicate with small inexpensive devices such as digital thermometers and weather instruments. This article illustrates how to read a popular DS18B20 thermal sensor.
The DS18B20 digital thermometer provides 9-bit to 12-bit Celsius temperature measurements. It communicates over a 1-Wire bus that by definition requires only one data line (and ground) for communication with a central microprocessor.
It has an operating temperature range of -55°C to +125°C and is accurate to ±0.5°C over the range of °10°C to +85°C. (read more on datasheet).
DS18B20 | Berta D2 Board |
---|---|
1 - GND | GND |
2 . Data | PB5 |
3 - Vcc | 3V3 |
A 4.7kOhm is requested between the DS18B20 pins Vcc and Data
The 1-wire bus is managed in bit banging mode by the Kernel driver called w1-gpio.
To enable the Kernel drivers (master and slave) follow this tutorial: . When using this command:
make arch=ARM menuconfig
use this configuration.
Enable the Dallas's 1-wire support and the Thermal family implementation as shown below:
Device Drivers --->
<*> Dallas's 1-wire support
1-wire Bus Masters --->
<*> GPIO 1-wire busmaster
1-wire Slaves --->
<*> Thermal family implementation
Any GPIO can be used as 1-wire bus. The pin used depends by the device tree definition
Edit the device tree source of your board and add in __apb__section these lines (change PB5 with the GPIO you intend to use):
onewire@0 {
compatible = "w1-gpio";
gpios = <&pioB 5 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_w1_0>;
status = "okay";
};
then add also these lines in the section pinctrl@fffff200:
pinctrl_w1_0: w1_0 {
atmel,pins =
<AT91_PIOB 5 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>;
};
Changing the gpio parameter you can change the GPIO to use as 1-wire bus
The 1-wire driver automatically scans every 10 seconds if new sensors are plugged on the 1-wire bus.
For each 1-wire device detected a new directory is created on /sys/bus/w1/devices/w1 bus master.
Type:
ls /sys/bus/w1/devices/*/w1_slave
if everything is ok you should obtain this reply:
/sys/bus/w1/devices/28-000006c52e56/w1_slave
these lines indicates that a thermal sensors is probed on the bus (28 is the family ID) and their unique ID are 000006c52e56.
To read the temperature from each sensor type:
cat /sys/bus/w1/devices/28-000006c52e56/w1_slave
58 01 4b 46 7f ff 08 10 f9 : crc=f9 YES
58 01 4b 46 7f ff 08 10 f9 t=21500
t=21500 indicates that the temperature read is 21.5 °C
#!/usr/bin/python3
import os
import time
w1path = "/sys/bus/w1/devices/w1_bus_master1"
# Extract the sensor id
if not os.path.exists(w1path):
print ("1-wire bus not found")
print ("Check if the 1-wire bus is installed")
exit(1)
deviceList = os.listdir(w1path)
# for deviceId in deviceList:
# print(deviceId)
onewire_id=[deviceId for deviceId in deviceList if deviceId[0:2]=="28"]
# print(onewire_id[0])
# Read temp
while True:
f = open("/sys/bus/w1/devices/" + onewire_id[0] + "/w1_slave","r")
tString=f.read()
f.close()
if tString.find("NO")>=0:
print ("Wrong CRC")
exit(1)
p=tString.find("t=")
value =float(tString[p+2:-1])/1000
formatted_value = "{:.2f}".format(value)
print(formatted_value)
time.sleep(1)