DS18B20 With BeagleBone: Easy One-wire Interface Temperature Monitoring
Using a DS18B20 temperature sensor on a BeagleBone isn’t difficult, but requires a bit of coding. Let’s get started with an introduction on the different types of sensors.
Choose A Sensor
The actual DS18B20 sensor is around the size of a pea. You can order it pre-wired in a few different configurations, or purchase just the sensor itself. For my application, I am using the already waterproof sensor shown here. It is enclosed in a stainless thermowell and wrapped with shrinkwrap.
Wire It Up

Each manufacturer seems to use a different color for the data wire, so yours may differ. Here is how mine was setup:
- Red – 3V
- White – Data
- Black – GND
Connect Sensor to the BeagleBone
Next, you will need to choose a GPIO pin to plug your DS18B20 into. I used this image to help visualize where each pinout was located . For this example, I used the P8 header, pin number 11.
Notice that the number of the pin does not correspond to the GPIO number! Also of importance, you cannot simply choose any pin. Some of the pins are reserved- for example, most of the higher numbered pins on the P9 header are taken up by the HDMI interface unless you have disabled it.
Which pins are free are detailed in the next step.
Preparing to Build the Device Tree
If you’re familiar with raspian (the optimized debian distro running on Raspberry Pi’s), you’ll recall the setup is essentially plug and play thanks to raspian’s kernel. On the Beaglebone, it’s consistent with the newer linux kernel so you will need to compile a device tree. At it’s most basic level, a device tree simply informs the kernel about the location and type of a specific piece of hardware.
Now that we are wired up, boot your Beaglebone and login with SSH. We now need to compile a device tree for the one-wire interface. This is where noting the GPIO pin becomes important. Open the P8 or P9 PDF below and find the head pin you used. You may need to click ‘Raw’ if you are taken to Github.
Now, let’s get into some coding. Login via SSH. Using your favorite text editor, copy and paste the below code (I usually use nano
). If you are using a different GPIO pin, you will need to make some changes. See below.
1 |
nano w1.dts |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
/* * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * Modified by Russell Senior from the weather cape's DTS file. * Minor formatting by C W Rose. */ /dts-v1/; /plugin/; / { compatible = "ti,beaglebone", "ti,beaglebone-black"; part-number = "BB-W1"; version = "00A0"; exclusive-use = "P8.11"; fragment@0 { target = <&am33xx_pinmux>; __overlay__ { bb_w1_pins: pinmux_bb_w1_pins { pinctrl-single,pins = <0x34 0x37 /* gpmc_ad13.gpio1_13, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE7 - w1-gpio */ >; }; }; }; fragment@1 { target = <&ocp>; __overlay__ { onewire@0 { status = "okay"; compatible = "w1-gpio"; pinctrl-names = "default"; pinctrl-0 = <&bb_w1_pins> gpios = <&gpio2 13 0>; }; }; }; }; |
If you are using a pin other than P8_11, you will need to make a few changes. See the PDF header tables linked above for GPIO information.
- On line 19, change
exclusive-use = "P8.11";
to the corresponding header and header pin you used. - On line 25, change
0x34
to your corresponding GPIO offset. The offsets are found in the PDF’s above. For example, if I used P8_12, the code should be0x30
. Leave0x37
where it is.
Save your edit and return to the shell.
Build the Device Tree
Now we can build the file using dtc:
1 |
dtc -O dtb -o w1-00A0.dtbo -b 0 -@ w1.dts |
Missing -@ flag error:
If you come across this error, you probably have a dated version of dtc. You can download a newer version that is compatible at:
1 wget -c https://raw.githubusercontent.com/RobertCNelson/tools/master/pkgs/dtc.sh
Copy it to /lib/firmware and load:
1 2 |
cp w1-00A0.dtbo /lib/firmware echo w1 > /sys/devices/bone_capemgr.9/slots |
You should be set now. To ensure everything has loaded correctly, run the following command. If everything is correctly configured, you should see Override Board Name
in your list.
1 2 3 4 5 6 7 8 9 |
$ cat /sys/devices/bone_capemgr.9/slots 0: 54:PF--- 1: 55:PF--- 2: 56:PF--- 3: 57:PF--- 4: ff:P-O-L Bone-LT-eMMC-2G,00A0,Texas Instrument,BB-BONE-EMMC-2G 5: ff:P-O-L Bone-Black-HDMI,00A0,Texas Instrument,BB-BONELT-HDMI 7: ff:P-O-L Override Board Name,00A0,Override Manuf,w1 |
You will need to run the echo w1 > /sys/devices/bone_capemgr.9/slots
command on every boot. To do this automatically, add the line to your /etc/rc.local file somewhere after the comments section.
Taking a Temperature Reading
Your temperature sensors are located at /sys/devices/w1_bus_master1/
. They are of the format 28-00000xxxxxxx
and correspond to your sensor’s unique serial number.
To view the current value just cat
the file. You will have two lines of output. The temperature (in celsius) is at the very end.
1 2 3 |
$ cat /sys/devices/w1_bus_master1/28-0000045d9d8a/w1_slave 07 01 4b 46 7f ff 09 10 da : crc=da YES 07 01 4b 46 7f ff 09 10 da t=16437 |
The current reading is 16.4 degrees celsius.
Using Multiple DS18B20 Sensors
This is where the one wire interface really shines. You can connect up to about ten temperature probes and still use the same GPIO pin. This is incredibly useful and makes using multiple sensors clean and mess-free. You still only need to use one 4.7k resistor. The sensors are connected as shown in this diagram:
The and & are messed up in the code block.
Thanks. I believe I fixed it (again).
Hi, there is an error in the dts fiile in line 39:
should be
otherwise it does not compile.
Regards, Ben
It didn’t work with gpio1 but DID work with gpio2, as written (once I’d added the missing semicolon at end of line 37 – AND after applying the patch specified in http://www.embedded-things.com/bbb/patching-the-device-tree-compiler-for-ubuntu/)
Nice tutorial, yet a little confusing sometimes.
In the w1.dts code, when you say “Next, in line 24, change 0x34 to your corresponding GPIO offset.” didn’t you mean line 25? The 0x34 is missing in that line and I found that it should be inside greater-than/lesser-than symbols, like
Also, in line 39 “gpios = ;” should it be gpio2? Because that link to github about P8 says that P8.11 is the GPIO1_13.
When using the dtc command I had “permission denied”, so I found in another tutorial to use the command: sudo sh -c “echo w1 > /sys/devices/bone_capemgr.9/slots”. This way it worked.
Ops, symbols have been interpreted as HTML tags. I wanted to say <0x34> in line 25 and <&gpio2 13 0> in line 39.
Thanks! I’ve fixed this a dozen times now but WP keeps changing it back!
Thanks mate! Just FYI, the hex on line 24 is not being rendered in the code block. It should read: “pinctrl-single,pins = ;”
Looks like it doesn’t show up here either. Correct code is left angle bracket 0x30 0x37 right angle bracket.
I needed to add a semicolon at the end of line 37 to correct a syntax error
If using a different pin, doesn’t one need to change the “gpios=” statement too?
If so, is it “gpio1” for every P8 or P9 pin (if not, how does one work out the setting)? And it is the “$PINS” value that is used for the second parameter?
Hi –
I’m able to install compile and install the “overlay” and getting the “/sys/devices/w1_bus_master1/” directory. However I’m not seeing my temperature sensor. I did try to play with the gpios setting but without luck.
What I do see in dmesg is:
[ 1412.404837] bone-capemgr bone_capemgr.9: part_number ‘w1’, version ‘N/A’
[ 1412.405016] bone-capemgr bone_capemgr.9: slot #10: generic override
[ 1412.405062] bone-capemgr bone_capemgr.9: bone: Using override eeprom data at slot 10
[ 1412.405111] bone-capemgr bone_capemgr.9: slot #10: ‘Override Board Name,00A0,Override Manuf,w1’
[ 1412.405359] bone-capemgr bone_capemgr.9: slot #10: Requesting part number/version based ‘w1-00A0.dtbo
[ 1412.405406] bone-capemgr bone_capemgr.9: slot #10: Requesting firmware ‘w1-00A0.dtbo’ for board-name ‘Override Board Name’, version ’00A0′
[ 1412.405479] bone-capemgr bone_capemgr.9: slot #10: dtbo ‘w1-00A0.dtbo’ loaded; converting to live tree
[ 1412.408709] bone-capemgr bone_capemgr.9: slot #10: #2 overlays
[ 1412.416304] of_get_named_gpio_flags exited with status 45
[ 1412.416349] of_get_named_gpio_flags: can’t parse gpios property
[ 1412.420421] bone-capemgr bone_capemgr.9: slot #10: Applied #2 overlays.
My sensor: http://www.mouser.com/ds/2/256/DS18B20-28978.pdf
My DTS file: http://pastebin.com/ma7qd6HK
Running Debian 7.5
Any help is appreciated!
Thanks,
Michaël
Check your wiring. In my experience when everything appeared to be setup properly it was a wiring issue (wrong GPIO, bare wires touching, etc)
I get the same “can’t parse gpios property” error but my DS18B20 sensor is detected. I used the .dts file as posted above except for adding a semi-colon to the end of line 37. Wiring was done like the schematic above, but for now I’ve only hooked up one sensor. It worked fine the first time. As brew said, check your wiring. Don’t forget that the sensor could be faulty, too.
Yea. I believe I see the property parse error all the time, even when it is working. I’m not sure why that shows up.
Hi Brew and Ryan,
Do wee need to configure the sensor before starting it or it’s a just a plug and play sensor?. I attached all the wires correctly and check three sensors but all are giving the same error of not parsing and also not being detected in the devices. So i am just wondering do we need to do something at beagle board to make it detect the sensor before following this tutorial or just attach the sensor and trying compiling this code.
Thanks
Saad
Same issue, anybody solved it already?
Instead of
gpios = ;
Try
gpios = ;
Derek Molloy’s Cheat-Sheet shows mode7 for 8.11 as “gpio1(13)” and name as “GPIO1_13”
Oops – my pasted code got mangled.
The step is to change from “gpios=gpio2 13” to “gpios=gpio1 13” (with braces around, of course)
Hi John –
Did try that before but without luck, same when I just retried. What are my options to debug outside of dmesg?
Thanks,
Michaël
Hey Michael,
You got any success, I am facing the same problem as you. Everything is okay except that, there is no thermometer being detected on the beaglebone board side. Any hint will be appreciated.
Thanks
Saad
Great post… just for sake of curiosity, can you explain line 39.
gpios = ;
What does it do?
It says to the hardware which mode it needs to be set (like Mode 7), pull-up or pull-down and rxactive and which speeds and that kind of stuff. There is a database (I couldn’t find it myself yet), which explains every bit (6 bits total).
Runs flawlessly…
Could you tell me how can I interface 17 ds18b20 sensors. I have tried 10 on one pin works great…. how about using another pin??? what mods I would need to make in dts file??? any idea??
I’ve tried unsuccessfully to edit the dts file to use more than 1 line to be able to use more than 10 sensors. Has anyone suceeded at this?
Cheers
Dave
Yes, you can connect multiple 1-wire networks using multiple pins. you need to write tree files for each pin you want to control, and keep the names separate.
when you use the above guide, with the comments about the missing parsing colon, you can get it to work on pin 11. if you duplicate the file, and rename it to 2w.dts… you can edit it and remap the pin muxes using the pdf files above. after compiling and copying this new file to your /lib/firmware/, echo 2w > /sys/devices/slots and voila, you have another pin doing 1 wire comms.
great guide, most comprehensive on the web to date, but still needs some polish.
that missing colon had me and my head against a wall for a while. lol
thanks!!
Hi Brad,
At last had time enough to break out the Beaglebone Black again and try this out.
Don’t seem to be able to get this to work. Have got w1.dts & 2w.dts files working independently on 2 different channels. On a reboot I type the following:
root@ewsbeagle1:~# dtc -O dtb -o w1-00A0.dtbo -b 0 -@ w1.dts
root@ewsbeagle1:~# cp w1-00A0.dtbo /lib/firmware
root@ewsbeagle1:~# echo w1 > /sys/devices/bone_capemgr.8/slots
root@ewsbeagle1:~# dtc -O dtb -o w1-00A0.dtbo -b 0 -@ 2w.dts
root@ewsbeagle1:~# cp w1-00A0.dtbo /lib/firmware
root@ewsbeagle1:~# echo 2w > /sys/devices/bone_capemgr.8/slots
When I check in the /sys/devices/w1_bus_master1/ directory I only get one device listed. Do I need to rename the output file in the dtc command at all.
Thanks in advance for any help.
Cheers
Dave
oops that first line should have 2w.dts and not w1.dts
Disregard that comment, Monday morning and not thinking 🙂
There appears to be something missing from your post. I have created the additional dts file and compiled it. I can load it and it works but when I try to load my original file which also works by itself it will not read sensors. Either config will work alone but only the first one loaded will work if I load both.
I have followed you instructions but it is not clear what name should be used when compiling the new dts file. also are the sensors on the new pin also supposed to show up in w1_master_driver?
This is very cool! Thanks a lot.
One question:
Is it possible to have multiple one-wire-interfaces? I want to connect many sensors.
Thanks
Thank you very much, works great! There are two minor changes when doing this on a BeagleBone A4 (not black):
echo w1 > /sys/devices/bone_capemgr.8/slots
and
cat /sys/devices/w1_bus_master1/10-0008006b34e8/w1_slave
Instead of the lines above.
I love beagles
I have given this a good try but still seem unable to make it work. I’m sure I’m missing something even tho I’ve followed each step exactly given all comments. I am using a the Black version and revision A6.
I am using the waterproof version of probe/sensor and but I keep getting a syntax error:
Error: w1.dts:39.17-18 syntax error
FATAL ERROR: Unable to parse input tree
I figure this to be line 39 and column 17-18
I have played with this, with limited knowledge as to what I’m doing, but to no avail.
Any thoughts?
/T
Hi,
I did this with 3.8.13 kernel and everything went fine. I tried with the 4.1 kernel on beaglebone black without success. The kernel introduces again the cape-manager with device-tree overlays. The new path is /sys/devices/platform/bone_capemgr/slots. The w1 cape is added to the slots, but no device is found under /sys/bus/w1/devices.
when I try the echo w1 > /sys/devices/bone_cape_mgr.9/slots
I get write error: invalid argument
@Atanas
Same here. Debian Jessie. No device detected
Also I had to unload hdmi overlay.
@Tim M
Missing semicolon at the end of line 37
Can you provide more detail, or a link explaining the earlier statement “You can connect up to about ten temperature probes and still use the same GPIO pin. This is incredibly useful and makes using multiple sensors clean and mess-free. You still only need to use one 4.7k resistor. “? Thanks
Yep just need one resistor. Take a look at the last image. It shows two of them connected to one GPIO.
I am unable to get this to work on my BBB rev c. My Kernel is 3.8.13-bone80, with debian 7.11. I checked my connection with the DS18b20 with a oscope, and confirmed if I manually take control of P8.11 and force it low and release it, the signal is pulled up for 20uS then the DS18B20 pulls it low for 130uS and then releases it. Do you have any ideas where I should look next? Thanks
I’m trying to connect to P8_18, but devices just do not list.
have changed line 19 to:
exclusive-use = “P8.18”;
have changed line 25 to:
pinctrl-single,pins = ;
it does compile (have added the semicolumn on line 37 ).
after adding to cape manager, it is listed (
cat /sys/devices/bone_capemgr.*/slots
0: 54:PF—
1: 55:PF—
2: 56:PF—
3: 57:PF—
4: ff:P-O-L Bone-LT-eMMC-2G,00A0,Texas Instrument,BB-BONE-EMMC-2G
5: ff:P-O-L Bone-Black-HDMI,00A0,Texas Instrument,BB-BONELT-HDMI
7: ff:P-O-L Override Board Name,00A0,Override Manuf,BB-UART1
8: ff:P-O-L Override Board Name,00A0,Override Manuf,w1
but there are no devices in /sys/devices/w1_bus_master1/
Any suggestions?
A number of people here have had problems with trying to use multiple pins for multiple one wire busses. I sturggled with this and ended up using a script to rotate the overlays. I finally found the solution, you do not write a separate DTS file for each pin. all the pins need to be setup in ONE DTS file. I have included my DTS file using pins P* 11, 12, and 14. I do not fully understand working with the device tree and overlays, I took the file here and some information I found on device trees and put this together. Maybe someone could look this over and suggest any changes or improvements? It does work for 3 pins at the same time but I may not have done everything properly. I hope this helps someone down the road.
/dts-v1/;
/plugin/;
/ {
compatible = "ti,beaglebone", "ti,beaglebone-black";
part-number = "BB-W1";
version = "00A0";
exclusive-use = "P8.11","P8.12","P8.14";
fragment@0 {
target = ;
__overlay__ {
bb_w1_pins: pinmux_bb_w1_pins {
pinctrl-single,pins = ;
};
bb_w1_1_pins: pinmux_bb_w1_1_pins {
pinctrl-single,pins = ;
};
bb_w1_2_pins: pinmux_bb_w1_2_pins {
pinctrl-single,pins = ;
};
};
};
fragment@1 {
target = ;
__overlay__ {
w1: onewire@0 {
status = "okay";
compatible = "w1-gpio";
pinctrl-names = "default";
pinctrl-0 = ;
gpios = ;
};
w1_1: onewire@1 {
status = "okay";
compatible = "w1-gpio";
pinctrl-names = "default";
pinctrl-0 = ;
gpios = ;
};
w1_2: onewire@2 {
status = "okay";
compatible = "w1-gpio";
pinctrl-names = "default";
pinctrl-0 = ;
gpios = ;
};
};
};
};
Hi
A good tutorial and I got it to work with no problems on P8_11, however I need it on P9_14. I changed the offset and pin number in the dts file, recompiled the device tree and copied to the firmware directory. The problem I have now is it still works on P8_11 and not on P9_14, I have restarted the beaglebone and deleted the relevant files but it still works on P8_11……any ideas?
I’m new to BBB and Linux. I have a DS18B20 and I’m trying to get it working. I have the latest Debian Linux installed and it uses U-Boot for overlays. I don’t know how to use that so I’m struggling to get this to work. Any and all help, references, links, online resources to help me out would be greatly appreciated!!!
I’ve used the dts code from above, made the corrections indicated in the comments and got it to compile to a *.dtbo file. I just don’t understand what I do with it under U-Boot. I tried to cp it to /sys/firmware but that wasn’t allowed. Could be permissions but I’m not sure how to fix that. (Linux newbie.) I just want to learn and I’m willing to dig for help but so far I haven’t found any resources that have helped me enough to get this working.