{"id":16620,"date":"2021-02-15T08:56:32","date_gmt":"2021-02-15T13:56:32","guid":{"rendered":"https:\/\/scruss.com\/blog\/?p=16620"},"modified":"2022-09-24T10:58:22","modified_gmt":"2022-09-24T14:58:22","slug":"raspberry-pi-pico-ds18x20-in-micropython","status":"publish","type":"post","link":"https:\/\/scruss.com\/blog\/2021\/02\/15\/raspberry-pi-pico-ds18x20-in-micropython\/","title":{"rendered":"Raspberry Pi Pico: DS18x20 in MicroPython"},"content":{"rendered":"\n<p><strong>Updated<\/strong>: Thanks to Ben, who noticed the Fritzing diagrams had the sensors the wrong way round. Fixed now&#8230;<\/p>\n\n\n\n<p>Hidden away in the <a href=\"https:\/\/datasheets.raspberrypi.com\/pico\/raspberry-pi-pico-python-sdk.pdf\">Pico MicroPython guide<\/a> is a hint that there may be more modules installed in the system than they let on. In the section about picotool, the guide has a seemingly innocuous couple of lines:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">frozen modules: _boot, rp2, ds18x20, onewire, uasyncio, uasyncio\/core, uasyncio\/event, uasyncio\/funcs, uasyncio\/lock, uasyncio\/stream<\/pre>\n\n\n\n<p>The third and fourth &#8216;frozen modules&#8217; are a giveaway: it shows that support for the  popular Dallas\/Maxim DS18x20 1-Wire temperature sensors is built in. Nowhere else in the guide are they mentioned. I guess someone needs to write them up.<\/p>\n\n\n\n<p>DS18x20 digital temperature sensors &#8211; usually sold as DS18B20 by Maxim and the many clone\/knock-off suppliers &#8211; are handy. They can report temperatures from -55 to 125 \u00b0C, although not every sensor will withstand that range. They come in a variety of packages, including immersible sealed units. They give a reliable result, free from ADC noise. They&#8217;re fairly cheap, the wiring&#8217;s absurdly simple, and you can chain long strings of them together from the same input pin and they&#8217;ll all work. What they aren&#8217;t, though, is fast: 1-Wire is a slow serial protocol that takes a while to query all of its attached devices and ferry the results back to the controller. But when we&#8217;re talking about environmental temperature, querying more often than a few times a minute is unnecessary.<\/p>\n\n\n\n<p>So this is the most complex way you can wire up a DS18x20 sensor:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"948\" height=\"945\" src=\"https:\/\/scruss.com\/wordpress\/wp-content\/uploads\/2021\/11\/Pico-ds18x20_bb-mk2.png\" alt=\"breadboard with raspberry Pi Pico, DS18x20 sensor with 47 k? pull-up resistor between 3V3 power and sensor data line\" class=\"wp-image-16919\" srcset=\"https:\/\/scruss.com\/wordpress\/wp-content\/uploads\/2021\/11\/Pico-ds18x20_bb-mk2.png 948w, https:\/\/scruss.com\/wordpress\/wp-content\/uploads\/2021\/11\/Pico-ds18x20_bb-mk2-320x320.png 320w, https:\/\/scruss.com\/wordpress\/wp-content\/uploads\/2021\/11\/Pico-ds18x20_bb-mk2-160x160.png 160w, https:\/\/scruss.com\/wordpress\/wp-content\/uploads\/2021\/11\/Pico-ds18x20_bb-mk2-768x766.png 768w\" sizes=\"auto, (max-width: 948px) 100vw, 948px\" \/><figcaption>Raspberry Pi Pico connected to a single DS18x20 sensor<\/figcaption><\/figure>\n\n\n\n<p>and this is how it&#8217;s wired:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">   DS18X20    Pico\n   =========  =========\n   VDD      ? 3V3\n              \/\n     --47 k?--\n    \/\n   DQ       ? GP22\n   GND      ? GND\n\n (47 k? resistor between DQ and 3V3 as pull-up)<\/pre>\n\n\n\n<p>Adding another sensor is no more complicated: connect it exactly as the first, chaining the sensors together &#8211;<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"948\" height=\"945\" src=\"https:\/\/scruss.com\/wordpress\/wp-content\/uploads\/2021\/11\/Pico-ds18x20-2_bb-mk2.png\" alt=\"breadboard with raspberry Pi Pico, two DS18x20 sensors with 47 k? pull-up resistor between 3V3 power and sensor data line\" class=\"wp-image-16921\" srcset=\"https:\/\/scruss.com\/wordpress\/wp-content\/uploads\/2021\/11\/Pico-ds18x20-2_bb-mk2.png 948w, https:\/\/scruss.com\/wordpress\/wp-content\/uploads\/2021\/11\/Pico-ds18x20-2_bb-mk2-320x320.png 320w, https:\/\/scruss.com\/wordpress\/wp-content\/uploads\/2021\/11\/Pico-ds18x20-2_bb-mk2-160x160.png 160w, https:\/\/scruss.com\/wordpress\/wp-content\/uploads\/2021\/11\/Pico-ds18x20-2_bb-mk2-768x766.png 768w\" sizes=\"auto, (max-width: 948px) 100vw, 948px\" \/><figcaption>Two DS18x20 sensors, though quite why you&#8217;d want two temperature sensors less than 8 mm apart, I&#8217;ll never know. Imagine one is a fancy immersible one on a long cable<\/figcaption><\/figure>\n\n\n\n<p>The code is not complex, either:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n# Raspberry Pi Pico - MicroPython DS18X20 Sensor demo\n# scruss - 2021-02\n# -*- coding: utf-8 -*-\n\nfrom machine import Pin\nfrom onewire import OneWire\nfrom ds18x20 import DS18X20\nfrom time import sleep_ms\nfrom ubinascii import hexlify    # for sensor ID nice display\n\nds = DS18X20(OneWire(Pin(22)))\nsensors = ds.scan()\n\nwhile True:\n    ds.convert_temp()\n    sleep_ms(750)     # mandatory pause to collect results\n    for s in sensors:\n        print(hexlify(s).decode(), &quot;:&quot;, &quot;%6.1f&quot; % (ds.read_temp(s)))\n        print()\n    sleep_ms(2000)\n<\/pre><\/div>\n\n\n<p>This generic code will read any number of attached sensors and return their readings along with the sensor ID. The sensor ID is a big ugly hex string (the one I&#8217;m using right now has an ID of <em>284c907997070344<\/em>, but its friends call it ThreeFourFour) that&#8217;s unique across all of the sensors that are out there.<\/p>\n\n\n\n<p>If you&#8217;re reading a single sensor, the code can be much simpler:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n# Raspberry Pi Pico - MicroPython 1x DS18X20 Sensor demo\n# scruss - 2021-02\n# -*- coding: utf-8 -*-\n\nfrom machine import Pin\nfrom onewire import OneWire\nfrom ds18x20 import DS18X20\nfrom time import sleep_ms\n\nds = DS18X20(OneWire(Pin(22)))\nsensor_id = ds.scan()&#x5B;0]  # the one and only sensor\n\nwhile True:\n    ds.convert_temp()\n    sleep_ms(750)         # wait for results\n    print(ds.read_temp(sensor_id), &quot; \u00c2\u00b0C&quot;)\n    sleep_ms(2000)\n<\/pre><\/div>\n\n\n<p>The important bits of the program:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Tell your Pico you have a DS18x20 on pin GP22: <br><em>ds = DS18X20(OneWire(Pin(22)))<\/em><\/li><li>Get the first (and only) sensor ID: <br><em>sensor_id = ds.scan()[0]<\/em><\/li><li>Every time you need a reading:<ol><li>Request a temperature reading: <br><em>ds.convert_temp()<\/em><\/li><li>Wait for results to come back: <br><em>sleep_ms(750)<\/em><\/li><li>Get the reading back as a floating-point value in \u00b0C: <br><em>ds.read_temp(sensor_id)<\/em><\/li><\/ol><\/li><\/ol>\n\n\n\n<p>That&#8217;s it. No faffing about with analogue conversion factors and mystery multipliers. No &#8220;<em>will it feel like returning a result this time?<\/em>&#8221; like the DHT sensors. While the 1-Wire protocol is immensely complicated (Trevor Woerner has a really clear summary: <a href=\"https:\/\/twoerner.blogspot.com\/2021\/01\/device-enumeration-on-1-wire-bus.html\">Device Enumeration on a 1-Wire Bus<\/a>) it&#8217;s not something you need to understand to make them work.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Updated: Thanks to Ben, who noticed the Fritzing diagrams had the sensors the wrong way round. Fixed now&#8230; Hidden away in the Pico MicroPython guide is a hint that there may be more modules installed in the system than they let on. In the section about picotool, the guide has a seemingly innocuous couple of [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"Raspberry Pi Pico: DS18x20 temperature sensing in MicroPython #RaspberryPiPico","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[7,2],"tags":[3261,3094,3262,3258,3260],"class_list":["post-16620","post","type-post","status-publish","format-standard","hentry","category-computers-suck","category-goatee-stroking-musing-or-something","tag-ds18x20","tag-micropython","tag-onewire","tag-pico","tag-temperature"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/pQNZZ-4k4","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/scruss.com\/blog\/wp-json\/wp\/v2\/posts\/16620","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/scruss.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/scruss.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/scruss.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/scruss.com\/blog\/wp-json\/wp\/v2\/comments?post=16620"}],"version-history":[{"count":6,"href":"https:\/\/scruss.com\/blog\/wp-json\/wp\/v2\/posts\/16620\/revisions"}],"predecessor-version":[{"id":17099,"href":"https:\/\/scruss.com\/blog\/wp-json\/wp\/v2\/posts\/16620\/revisions\/17099"}],"wp:attachment":[{"href":"https:\/\/scruss.com\/blog\/wp-json\/wp\/v2\/media?parent=16620"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/scruss.com\/blog\/wp-json\/wp\/v2\/categories?post=16620"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/scruss.com\/blog\/wp-json\/wp\/v2\/tags?post=16620"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}