DS18B20 With BeagleBone: Easy One-wire Interface Temperature Monitoring

 Jan, 26 - 2014   42 comments   BeagleBoneLinuxTutorial

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

Wires

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

 

DS18B20_main_mode
You will need to connect a 4.7k resistor between the data wire and 3V wire. This diagram shows 5V, but we can still have it work using 3V. You only need one if you are using multiple sensors. More on this below.

 

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.

P8Header

P8 Header

P9Header

P9 Header

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.

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 be 0x30. Leave 0x37 where it is.

Save your edit and return to the shell.

Build the Device Tree

Now we can build the file using dtc:

Missing [email protected] 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:

Copy it to /lib/firmware and load:

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.

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.

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:
download


Related articles

 Comments 42 comments

  • Steve says:

    The and & are messed up in the code block.

  • Ben says:

    Hi, there is an error in the dts fiile in line 39:

    should be

    otherwise it does not compile.
    Regards, Ben

  • Leonardo says:

    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.

  • Alan says:

    Thanks mate! Just FYI, the hex on line 24 is not being rendered in the code block. It should read: “pinctrl-single,pins = ;”

    • Alan says:

      Looks like it doesn’t show up here either. Correct code is left angle bracket 0x30 0x37 right angle bracket.

  • John Geddes says:

    I needed to add a semicolon at the end of line 37 to correct a syntax error

  • John Geddes says:

    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?

  • Michaël Vaes says:

    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

    • brew says:

      Check your wiring. In my experience when everything appeared to be setup properly it was a wiring issue (wrong GPIO, bare wires touching, etc)

    • Ryan Wilkins says:

      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.

      • brew says:

        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.

        • Saad says:

          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

    • Melroy van den Berg says:

      Same issue, anybody solved it already?

  • John Geddes says:

    Instead of
    gpios = ;
    Try
    gpios = ;

    Derek Molloy’s Cheat-Sheet shows mode7 for 8.11 as “gpio1(13)” and name as “GPIO1_13”

    • John Geddes says:

      Oops – my pasted code got mangled.

      The step is to change from “gpios=gpio2 13” to “gpios=gpio1 13” (with braces around, of course)

      • Michaël Vaes says:

        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

        • Saad says:

          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

  • Azar says:

    Great post… just for sake of curiosity, can you explain line 39.
    gpios = ;

    What does it do?

    • Melroy van den Berg says:

      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).

  • Azar says:

    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??

  • Dave Blomfield says:

    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

    • Brad M says:

      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!!

      • Dave Blomfield says:

        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:

        [email protected]:~# dtc -O dtb -o w1-00A0.dtbo -b 0 [email protected] w1.dts
        [email protected]:~# cp w1-00A0.dtbo /lib/firmware
        [email protected]:~# echo w1 > /sys/devices/bone_capemgr.8/slots
        [email protected]:~# dtc -O dtb -o w1-00A0.dtbo -b 0 [email protected] 2w.dts
        [email protected]:~# cp w1-00A0.dtbo /lib/firmware
        [email protected]:~# 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

      • Paul says:

        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?

  • Robert says:

    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

  • Kevin says:

    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.

  • TonyBalony says:

    I love beagles

  • Tim M. says:

    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

  • Atanas says:

    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.

  • pedro says:

    when I try the echo w1 > /sys/devices/bone_cape_mgr.9/slots

    I get write error: invalid argument

  • AriZone says:

    @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

  • john says:

    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

  • john says:

    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

  • Carl says:

    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?

  • Paul says:

    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";

    [email protected] {
    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 = ;
    };

    };
    };

    [email protected] {
    target = ;
    __overlay__ {

    w1: [email protected] {
    status = "okay";
    compatible = "w1-gpio";
    pinctrl-names = "default";
    pinctrl-0 = ;

    gpios = ;
    };

    w1_1: [email protected] {
    status = "okay";
    compatible = "w1-gpio";
    pinctrl-names = "default";
    pinctrl-0 = ;

    gpios = ;
    };

    w1_2: [email protected] {
    status = "okay";
    compatible = "w1-gpio";
    pinctrl-names = "default";
    pinctrl-0 = ;

    gpios = ;
    };

    };
    };
    };


  • Leave a Reply

    Your email address will not be published. Fields with * are mandatory.