Dallas one-wire temperature reading on BeagleBone Black with dto

w1

OK, this was very straight forward with the help of Koen’s blog and the BeagleBoard google group.

The Dallas one-wire protocol is pretty straight forward, at least when there is already a Linux driver for it.  A 18B20 was mounted with the data pin in P9.22, the same as on the new revision of Replicape but can be any GPIO pin. The reason for having an extra temperature sensor is so that the cold end can be monitored. On all metal hot-ends, the temperature needs to stay below the glass transition temperature, so it’s a good idea to keep an eye on it. The 18B20 goes up to 125 degrees celsius and should be perfect for this.

On your BeagleBone (Black), try this:

nano BB-W1-00A0.dts

Copy-paste this:

/dts-v1/;
/plugin/;

/ {
	compatible = "ti,beaglebone", "ti,beaglebone-black";

	part-number = "BB-W1";
	version = "00A0";

	/* state the resources this cape uses */
	exclusive-use =
		/* the pin header uses */
		"P9.22",
		/* the hardware IP uses */
		"gpio0_2";

	fragment@0 {
               target = <&am33xx_pinmux>;
               __overlay__ {
					dallas_w1_pins: pinmux_dallas_w1_pins {
						pinctrl-single,pins = < 							0x150 0x37 						>;
					};
               };
	};

	fragment@1 {
               target = <&ocp>;
               __overlay__ {
		       onewire@0 {
			       compatible      = "w1-gpio";
			       pinctrl-names   = "default";
			       pinctrl-0       = <&dallas_w1_pins>;
			       status          = "okay";

			       gpios = <&gpio1 2 0>;
		       };
         };
	};
};

Compile it:

dtc -O dtb -o BB-W1-00A0.dtbo -b 0 -@ BB-W1-00A0.dts

Copy it:

cp BB-W1-00A0.dtbo /lib/firmware/

Enable it:

echo BB-W1:00A0 > /sys/devices/bone_capemgr.9/slots

Test it:

python

Copy-paste this on the command-line:

import time

w1="/sys/bus/w1/devices/28-000002e34b73/w1_slave"

while True:
    raw = open(w1, "r").read()
    print "Temperature is "+str(float(raw.split("t=")[-1])/1000)+" degrees"
    time.sleep(1)

You should see something like this:

Temperature is 32.375 degrees
Temperature is 32.437 degrees
Temperature is 32.437 degrees
Temperature is 32.5 degrees
Temperature is 32.562 degrees

And that is how hot it is on a Saturday night on Oslo when the CTO of the company we share office space with insists on having the severs in-house :)

To avoid any confusion, you should probably point out that the 000002e34b73 part of/sys/bus/w1/devices/28-000002e34b73/ depends on the unique ID of the temperature sensor, so everyone will have to adjust it before running your example script.

-n.st

 

Update January 21. 2013: Also, please note that there are two different versions of the Dallas W1 temperature device. One works fine (Marking: 18B20) with the latest Linux W1-gpio driver. The other (Marking: 18B20P) only spits out 85 deg.

65 thoughts on “Dallas one-wire temperature reading on BeagleBone Black with dto

  1. Pingback: การใช้ GPIO ใน Linux ของ BeagleBone Black | BeagleBone Lover in Thailand

  2. Hi Elias,

    How do you plan on interfacing the BBB with Replicape to existing 3D printing software suites such as Pronterface and Repetier?

    Will the slicer run directly on the BBB/Replicape or does it handle Gcode printing only?

    Cheers

    • GP, nice to hear form you again! Interesting question, right now there is just one queue that takes commands from USB, Ethernet and a local FIFO file and executes them as they come in. That way to send commands in the normal way via a host software or to the printer locally, say from a GUI. The gui would then just pipe the commands to the file. The queue remembers where the command came from and answers appropriately. Obviously there should be a lock when printing so no-one can accidentally send commands..

      Eventually the printer will handle slicing as well, yes.

      • Hmm. So how would you interface that setup with Proterface or Repetier? I would like to build and help test a Replicape with a new Mendel build I am doing, is that possible at this juncture?

      • Hi Elias, glad to hear your project is moving along nicely.

        So with those APIs and when you say “command”, is that a method of interpreting g-code natively? I am trying to figure out how this will work with existing 3D printing suites. Have you considered making those APIs compatible with existing 3D controllers such as the Merlin firmware, so that the BBB/Replicape simply appears as a RAMPS-type controller to facilitate printing from suites such as Pronterface and Repetier?

        • Yes, replicape will be compatible with repetier, but it will not “be” marlin or teacup. The g-codes it accepts will be the same, in addition to a few new ones such as a command for microstepping, and one for setting the stepper current etc. There might be a compatibility mode though in case there are host softwares that act quirky for some g-codes. I’m about to order a few boards with assembly to cover early adopter demands, so I can get one extra for you if you want!

          • Yeah pick me up an extra board and let me know what it costs. Ideally the API connection between the Hipsterbot and the BBB/Replicape would be bidirectional as well, so that common configuration settings made with the touchscreen (infill type, stepping rates etc, Slic3r settings etc) could propagate automagically from the Replicape without any need for changing the application itself.

  3. When I run “dtc -O dtb -o BB-W1-00A0.dtbo -b 0 -@ BB-W1-00A0.dts” I receive “dtc: invalid option — ‘@’” any ideas as to fix this.

  4. Had to adjust this based on what was on my system.

    “echo BB-W1:00A0 > /sys/devices/bone_capemgr.9/slots”

    didn’t work because

    “bone_capemgr.9″

    is

    “bone_capemgr.8″

    on my system.

    And

    “28-000002e34b73″

    is

    “28-000004df3c7f”

    on my system.

    Once I’d made those changes, it was off to the races.

    Thanx for this.

    Question:

    “print “Temperature is “+str(float(raw.split(“t=”)[-1])/1000)+” degrees”

    reports out Celsius.

    Can that be modifed to report out Farenheit? If so, how?

  5. When I try to load the overlay, the beaglebone can’t parse the line:

    gpios = ;

    Can you explain (or point me to a reference) the meaning of this line?

    Thank you VERY much for set of guides. It’s the most useful I have found after hours of googling.

  6. If you are considering something beyond just a breadboard, like putting temperature monitors all over your house, you will have consider a host a consideration that are introduced when you have long lines and more than one sensor on the wire. A must read: http://www.1wire.org/Files/Articles/1-Wire-Design%20Guide%20v1.0.pdf

    In theory 1-wire lets you have several sensors on a bus line, but after you read or skim the Wire Design Guide you’ll see there are several restrictions on possible network topologies. The complexity about 1-wire design for anything beyond 10 feet quickly makes it a very expensive deployment — probably have to have intermediary multiplexers, a single line for each sensor, and patch connectors at the multiplexer station.

    It almost makes wireless nodes such as Zigbee back in the running simply based on expense. I wish I had studied carefully the network topology gotchas before even thinking about 1-wire of dreaming of a project that would monitors many stations to create a thermal mapping.

  7. According to your script you are using “P9.22″ and “gpio0_2″ and on the picture you are using P8.22.
    Can you tell me if this is correct ?

  8. This is awsome, thank you Elias, your guide worked well :)

    Btw, is it possible to change the data-pin? For me, the best would be to use an only-gpio pin, like P9.15 (gpio1_16), so i can use uarts for other purposes. At first attempt, I tried to move it to UART4_RXD with following changes in the dts, but had no success, it doesn’t recognises the probes : /

    $ diff BB-W1-00A0.dts BB-W1-00A0.dts.orig
    “P9.22″,

    “gpio0_2″;

    < pinctrl-single,pins = ;
    > pinctrl-single,pins = ;

    I can’t guess what’s missing, and would appreciate for any help…

    Best,
    Aron

  9. Oh the diff got formated by the website :) Here are the changes again:


    “P9.11″ -> “P9.22″
    “gpio0_30″ -> “gpio0_2″
    “0×070 0×37″ -> “0×150 0×37″

  10. Is it possible to use such a device with owfs? I tried to start owserver with the following argument:
    /usr/bin/owserver -d /dev/i2c-1 –foreground

    But I only get the error:
    DEFAULT: owlib.c:(57) No valid 1-wire buses found

    Is this even possible without buying a 1-wire cape?

  11. Thanks so much for this post!

    Similarly to Gerd, I get a constant 85°C reading (although, unlike Gerd, that’s all I’ve been able to get). According to the Maxim DS18B20 spec I found, 85°C is the power-on reset value of the temperature register for the device. From the same source — “To initiate a temperature measurement and A-to-D conversion, the master must issue a Convert T [44h] command. Following the conversion, the resulting thermal data is stored in the 2-byte temperature register in the scratchpad memory and the DS18B20 returns to its idle state.”

    I haven’t been able to figure how to send that request to the device. Any ideas?

    Again, thanks!

      • Thanks, Elias, for the source code. I think it may be helpful “down the road” but it’s not clear to me how I can use it yet. I’ll keep looking around and trying whatever seems to make any sense.

      • My problem is fixed and had nothing to do with software. I’m powering the BBB from the USB port of a Motorala lap dock. There is a voltage drop on the 3.3V power pins that brings the supplied voltage below the 3V the DS18B20 requires. However, connecting the positive voltage pins of the DS18B20 to a 5V pin (e.g., P9_5) works. My machine has now been reliably performing temperature conversions for many hours now. Perhaps this solution might work for Gerd and others who have been having similar similar issues?

        Again, thanks so much for this post!

        • Important update! Don’t do what I suggested above! I fried my BBB and I think that what I did above is responsible.
          Story: I had to re-flash my BBB and did two things: first, I disconnected the 1-wire circuit, because I couldn’t re-flash with it connected. Second, I used a better power supply (also needed to
          re-f lash). Then, when I reconnected the 1-wire circuit,I immediately fried the BBB. I’m not positive that my wiring is the fault, but I don’t have any other likely explanation. For now, anyway, the moral is to *not* use 5V to power the DS18B20′s, but to just make sure that one has a good source of voltage.

          (Elias, I’m not sure how to advise you. I don’t want anyone else to wreck their BBB, so perhaps you should just delete all my posts. On the other hand, perhaps my mistakes might be helpful to someone else.)

  12. Pingback: My first time soldering | fortune datko

  13. It is just awesome… I just want to know that how did you created the driver for the sensor.. It was really awesome.. Could you tell me some in-depth tutorials on how to create drivers..

    Thanks for the help in advance..

    • The internal pull-up of the GPIOs of the SoC is around 20K if I remember correctly. You can probably get away with just using that. I guess a lower resistance value is needed for noisy conditions, so try with the internal pull-up first and then add the external pull-up if you see any instability.

  14. Pingback: TiggyCam » Finally got the Dallas 1 Wire working on the BeagleBone Black

  15. Hello Elias,

    Thanks for this article. I managed to got mine working.
    I was wondering about 2 things and may be you could help me understand.

    First, in the DTS file, on the line
    pinctrl-single,pins = ;
    what is the meaning of 0×37 ? I thought it could only be from 0×00 to 0×07 as it is the pin mode…

    Second, I tried to use another pin (P9.20) and change the DTS file accordingly but could not get it to work.
    I changed the following :

    ...
    exclusive-use =
    "P9.20",
    "gpio0_12";
    ...
    dallas_w1_pins: pinmux_dallas_w1_pins {
    pinctrl-single,pins = ;
    };
    ...

    Would there be anything else to change ?

    Thanks !
    JS

    • Ooops… some of my post was removed due to > and <
      The way I modified the pinctrl was the following :

      pinctrl-single,pins = < 0x178 0x37 >

      Sorry…
      JS

  16. First of all, thanks for all good info.
    I am trying to use different pin for W1.
    My dts file had following changes:
    “……………..
    /* state the resources this cape uses */
    exclusive-use =
    /* the pin header uses */
    “P8.11″,
    /* the hardware IP uses */
    “gpio1_13″;
    …………….
    pinctrl-single,pins = ;

    ……………….
    gpios = ;
    “.
    After compiling, cp to /lib/firmware, echo to ……../slots , still I can not make this work. I tried different pins, 9_14, 9_23, and still it does not work. When I apply changes as mentined above for pin 9_22, 9_11 it works like the charm. The problem is I need these pins for UARTS.
    Here is my dmesg when I try to use this mine overlay ( the one that does not work):

    ” 121.929717] bone-capemgr bone_capemgr.9: slot #13: ‘Override Board Name,00A0,Override Manuf,BB-W1′
    [ 121.932347] bone-capemgr bone_capemgr.9: slot #13: Requesting part number/version based ‘BB-W1-00A0.dtbo
    [ 121.932413] bone-capemgr bone_capemgr.9: slot #13: Requesting firmware ‘BB-W1-00A0.dtbo’ for board-name ‘Override Board Name’, version ’00A0′
    [ 121.932494] bone-capemgr bone_capemgr.9: slot #13: dtbo ‘BB-W1-00A0.dtbo’ loaded; converting to live tree
    [ 121.933090] bone-capemgr bone_capemgr.9: slot #13: #2 overlays
    [ 121.940719] of_get_named_gpio_flags exited with status -517
    [ 121.940770] of_get_named_gpio_flags: can’t parse gpios property
    [ 121.940805] gpio_request: gpio–517 (w1) status -22
    [ 121.940847] w1-gpio onewire@0.13: gpio_request (pin) failed
    [ 121.957204] w1-gpio: probe of onewire@0.13 failed with error -22
    [ 121.958723] bone-capemgr bone_capemgr.9: slot #13: Applied #2 overlays.

    Any idea what could be a problem???
    Thanks in advance
    Robert

  17. Oh, yes, I see the problem with square brackets.
    Here is mine dts. I put (and) in place of brackets:
    ……………..
    /* state the resources this cape uses */
    exclusive-use =
    /* the pin header uses */
    “P8.11″,
    /* the hardware IP uses */
    “gpio1_13″;
    ……………………………………
    pinctrl-single,pins = (and) 0×034 0×37 (and) ;
    ……………………………………………
    gpios = (and)&gpio1 45 0(and);

    Sorry about that

    Robert

    • Robert, assuming you have found the right address for the pin, gpio1 should probably be gpio2 in the section for the ocp. Also, the exclusive-use of the the hardware IP should match the gpios=…

  18. Thanks Elias, I see what the problem was. I was able to get pin 8.13 to work.
    Here is the setting:(and) indicates bracket

    exlusive-use=
    “p8.13″,
    gpio0_23″;
    …………………………….
    pinctrl-single,pins = (and) 0×024 0×37 (and) ;
    ……………………………..
    gpios (and)&1 23 0(and)

    One thing I still can not understand, please explain.
    gpios &1 23 0
    Where this came from??
    23 I understand, but 1 and 0 ?
    How should it be for gpio1_18?
    I tried multiple pins where gpios were 1_* and was not able to make it work.
    Thanks in advance
    Robert

    PS I used Derek Molloy’s tabels for pins assignment: http://derekmolloy.ie/beaglebone/beaglebone-gpio-programming-on-arm-embedded-linux/

  19. Hi Elias,

    I’ve tried modifying this to use a different pin — under Ubuntu. The blob overlay loads into a slot, but no slave is created in the directory ( /sys/devices/w1_bus_master1/28-000001284447/w1_slave, as indicated by another commenter).

    Any suggestions on my code or approach..or using Ubuntu for the job…

    /dts-v1/;
    /plugin/;

    / {
    compatible = “ti,beaglebone”, “ti,beaglebone-black”;
    part-number = “BB-W1″;
    version = “00A0″;

    exclusive-use = “P9.15″;

    fragment@0 {
    target = ;
    __overlay__ {
    bb_w1_pins: pinmux_bb_w1_pins {
    pinctrl-single,pins = ;
    };
    };
    };

    fragment@1 {
    target = ;
    __overlay__ {
    onewire@0 {
    status = “okay”;
    compatible = “w1-gpio”;
    pinctrl-names = “default”;
    pinctrl-0 = ;

    gpios = ; /*grrr I think this means gpio1_16 (using 1 to 4 instread of 0-3)*/
    };
    };
    };
    };

    Thanks heaps

    Matt

  20. Sorry, not used to blogs…
    the code is:

    /dts-v1/;
    /plugin/;

    / {
    compatible = “ti,beaglebone”, “ti,beaglebone-black”;
    part-number = “BB-W1″;
    version = “00A0″;

    exclusive-use = “P9.15″;

    fragment@0 {
    target = ;
    __overlay__ {
    bb_w1_pins: pinmux_bb_w1_pins {
    pinctrl-single,pins = ;
    };
    };
    };

    fragment@1 {
    target = ;
    __overlay__ {
    onewire@0 {
    status = “okay”;
    compatible = “w1-gpio”;
    pinctrl-names = “default”;
    pinctrl-0 = ;

    gpios = ; /*grrr I think this means gpio1_16 (using 1 to 4 instread of 0-3)*/
    };
    };
    };
    };

  21. To avoid any confusion, you should probably point out that the 000002e34b73 part of /sys/bus/w1/devices/28-000002e34b73/ depends on the unique ID of the temperature sensor, so everyone will have to adjust it before running your example script.

  22. Pingback: BeagleBone Black - obsługa termometrów analogowych LM35DZ - Raspberry pi, XBMC, ODROID-X :: Portal PicoBoard.pl

  23. Pingback: DS18B20 temperature sensor on a Beaglebone Black running ubuntu | Interacting Objects

  24. Hey, question about that Python script. I’m not really familiar with Python (aside from knowing it’s a scripting language), and I don’t understand exactly what the “raw = open(w1, “r”).read()” command is doing (the rest seems pretty self explanatory). Is this some kind of integrated library specifically for w1 devices? Because I need to figure out how to set thresholds and send other commands to the DS18B20, and the datasheet is not very helpful. I’m wondering if there are some other Python commands to do those functions. Thanks!

    • Hi Sara, as you know devices are manifested as files in Unix, so the Python script opens a file in read mode (“r”) and reads the contents of the file. The path is defined on the line above. No magic other than what Python provides :)

  25. Wow, great article! Worked almost perfectly except for changing “echo BB-W1:00A0 > /sys/devices/bone_capemgr.9/slots” to echo BB-W1:00A0 > /sys/devices/bone_capemgr.8/slots.

    It might be worthwhile to add an addendum to this post to show how to run this line at startup; it took me quite awhile to get it working. It might also be worth noting that many 18B20′s can be added to the same bus and the service automatically creates virtual folders for each of them (very cool!).

    I’m building a quick-and-dirty project for plotting several real-time temperature graphs using php and javascript, and this article really helped get me started.

    • Yes, the capemgr id changes depending on what other stuff is loaded first (i think).

      Are you talking about entries in sysfs? If you are, then all (or at least most) device drivers get that.

  26. Hi Elias,

    Does this driver support other 1-wire devices? I’d like to use the DS2406 and other Dallas 1-wire devices. Can you tell me where to get documentation on the 1-wire driver?

  27. All went well until the /sys/bus/w1/devices/28-000002e34b73/ part for me. How do I tell the unique ID of my sensor? If I look under devices all I have is w1_bus_master1? Newbie on BBB, thanks for any help.

    • If
      ls -la /sys/bus/w1
      Dose not reveval any long names, the sensor is probably not connected right. Or it’s the wrong kind..

      • I have the sensor from adafruit http://www.adafruit.com/products/381 . I connected to an arduino and know that is works. I have the blue wire connected to P9_1 ground, the red wire connected to P9_4 3.3v, and the yellow (data) wire connected to P9_22. There are no long names under the sys/bus/wi or sys/bus/wi/devices directories. Was I suppost to install any software for the sensor ID to appear? Thank you very much for your help.

        • There is no other software required. It’s w1 (one), not wi (eye). This is what it looks like on my BBB:

          root@thing:~# ls -la /sys/bus/w1/devices/
          drwxr-xr-x 2 root root 0 Jan 1 2000 .
          drwxr-xr-x 4 root root 0 Jan 1 2000 ..
          lrwxrwxrwx 1 root root 0 Jan 1 2000 28-000002e34b73 -> ../../../devices/w1_bus_master1/28-000002e34b73
          lrwxrwxrwx 1 root root 0 Mar 5 14:25 w1_bus_master1 -> ../../../devices/w1_bus_master1

          Also, check dmesg after you have loaded the overlay to make sure there is not a conflict.

  28. Hi!
    I got it working.

    As already mentioned, there are 2 versions of the DS18B20. The -PAR version uses power from the data line (parasitic) and the standard version is capable of both being powered independently or by parasitic power. I have the standard version (from Adafruit). All that is necessary is to connect the VDD pin (pin 3) to the 3.3V source on the BBB. I also tied the DQ pin to VDD through an ~5K resistor as recommended. I have not tried just using parasitic power. I will try this later.

    Question I have is once the driver is loaded and pin enabled, how can I later disable the pin and return everything to its normal mode (SPI0_SCLK)?

    Will reboot do it? Is there a programmatic/terminal method to do this?

    Thanks.

    BTW, great instructions.

    Stephen

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>