{"id":8244,"date":"2013-02-02T16:58:51","date_gmt":"2013-02-02T21:58:51","guid":{"rendered":"http:\/\/scruss.com\/blog\/?p=8244"},"modified":"2016-05-24T15:20:49","modified_gmt":"2016-05-24T19:20:49","slug":"simple-adc-with-the-raspberry-pi","status":"publish","type":"post","link":"https:\/\/scruss.com\/blog\/2013\/02\/02\/simple-adc-with-the-raspberry-pi\/","title":{"rendered":"Simple ADC with the Raspberry Pi"},"content":{"rendered":"<p><a href=\"http:\/\/scruss.com\/wordpress\/wp-content\/uploads\/2013\/01\/IMG_0443.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-8247\" src=\"http:\/\/scruss.com\/wordpress\/wp-content\/uploads\/2013\/01\/IMG_0443-1024x768.jpg\" alt=\"Raspberry Pi wearing an MCP3008\" width=\"584\" height=\"438\" srcset=\"https:\/\/scruss.com\/wordpress\/wp-content\/uploads\/2013\/01\/IMG_0443-1024x768.jpg 1024w, https:\/\/scruss.com\/wordpress\/wp-content\/uploads\/2013\/01\/IMG_0443-160x120.jpg 160w, https:\/\/scruss.com\/wordpress\/wp-content\/uploads\/2013\/01\/IMG_0443-320x240.jpg 320w, https:\/\/scruss.com\/wordpress\/wp-content\/uploads\/2013\/01\/IMG_0443-400x300.jpg 400w, https:\/\/scruss.com\/wordpress\/wp-content\/uploads\/2013\/01\/IMG_0443.jpg 1280w\" sizes=\"auto, (max-width: 584px) 100vw, 584px\" \/><\/a><\/p>\n<p><span style=\"color: #ff0000;\"><strong>Hey! This is a <em>really<\/em> old article. You should really be using <a style=\"color: #ff0000;\" href=\"https:\/\/gpiozero.readthedocs.io\/\">gpiozero<\/a> these days.<\/strong><\/span><\/p>\n<p>I hadn&#8217;t realised it, but the <a href=\"http:\/\/scruss.com\/blog\/2013\/01\/19\/the-quite-rubbish-clock\/\">The Quite Rubbish Clock<\/a> did something that a lot of people seem to have trouble with on the Raspberry Pi: communicating using hardware SPI. Perhaps it&#8217;s because everything is moving so fast with Raspberry Pi development, tutorials go out of date really quickly. Thankfully, hardware SPI is much easier to understand than the older way of <a href=\"http:\/\/learn.adafruit.com\/reading-a-analog-in-and-controlling-audio-volume-with-the-raspberry-pi\/overview\">emulation through bit-banging<\/a>.<\/p>\n<p>SPI is a synchronous serial protocol, so it needs a clock line as well as a data in and data out line. In addition, it has a Chip Enable (CE, or Chip Select, CS) line that is used to choose which SPI device to talk to. The Raspberry Pi has two CE lines (pins 24 and 26) so can talk to two SPI devices at once. It supports a maximum clock rate of 32 MHz, though in practice you&#8217;ll be limited to the rate your device supports.<\/p>\n<p>The device I&#8217;m testing here is an <a href=\"http:\/\/www.microchip.com\/wwwproducts\/Devices.aspx?dDocName=en010530\">MCP3008<\/a> 10-bit Analogue-to-Digital Converter (ADC). These are simple to use, cheap and quite fast converters with 8 input channels. If you hook them up to a 3.3 V supply they will convert a DC voltage varying from 0-3.3 V to a digital reading of 0-1023 (= 2<sup>10<\/sup> &#8211; 1). Not quite up there in quality for hi-fi audio or precision sensing, but good enough to read from most simple analogue sensors.<\/p>\n<p>The sensor I&#8217;m reading is the astonishingly dull <a href=\"http:\/\/www.ti.com\/product\/lm35\">LM35DZ<\/a> temperature sensor. All the cool kids seem to be using <a href=\"http:\/\/www.analog.com\/en\/mems-sensors\/digital-temperature-sensors\/tmp36\/products\/product.html\">TMP36<\/a>s (as they can read temperatures below freezing without a negative supply voltage). One day I&#8217;ll show them all and use a <a href=\"http:\/\/www.ti.com\/product\/lm335\">LM135<\/a> direct Kelvin sensor, but not yet.<\/p>\n<p>To run this code, <a href=\"http:\/\/scruss.com\/blog\/2013\/01\/19\/the-quite-rubbish-clock\/#spi\">install the SPI libraries as before<\/a>. Now wire up the MCP3008 to the Raspberry Pi like so:<\/p>\n<pre> MCP 3008 Pin          Pi GPIO Pin #    Pi Pin Name\r\n==============        ===============  =============\r\n 16  VDD                 1              3.3 V\r\n 15  VREF                1              3.3 V\r\n 14  AGND                6              GND\r\n 13  CLK                23              GPIO11 SPI0_SCLK\r\n 12  DOUT               21              GPIO09 SPI0_MISO\r\n 11  DIN                19              GPIO10 SPI0_MOSI\r\n 10  CS                 24              GPIO08 CE0\r\n  9  DGND                6              GND<\/pre>\n<p>The wiring for the LM35 is very simple:<\/p>\n<pre> LM35 Pin        MCP3008 Pin\r\n==========      =============\r\n Vs              16 VDD\r\n Vout             1 CH0\r\n GND              9 DGND<\/pre>\n<p>The code I&#8217;m using is a straight lift of Jeremy Blythe&#8217;s <a href=\"http:\/\/jeremyblythe.blogspot.ca\/2012\/09\/raspberry-pi-hardware-spi-analog-inputs.html\">Raspberry Pi hardware SPI analog inputs using the MCP3008<\/a>. The clever bit in Jeremy&#8217;s code is the <code>readadc()<\/code> function which reads the relevant length of bits (by writing the same number of bits; <a href=\"https:\/\/projects.drogon.net\/understanding-spi-on-the-raspberry-pi\/\">SPI&#8217;s weird that way<\/a>) from the SPI bus and converting it to a single 10-bit value.<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\n#!\/usr\/bin\/python\r\n# -*- coding: utf-8 -*-\r\n# mcp3008_lm35.py - read an LM35 on CH0 of an MCP3008 on a Raspberry Pi\r\n# mostly nicked from\r\n#  http:\/\/jeremyblythe.blogspot.ca\/2012\/09\/raspberry-pi-hardware-spi-analog-inputs.html\r\n\r\nimport spidev\r\nimport time\r\n\r\nspi = spidev.SpiDev()\r\nspi.open(0, 0)\r\n\r\ndef readadc(adcnum):\r\n# read SPI data from MCP3008 chip, 8 possible adc's (0 thru 7)\r\n    if adcnum &gt; 7 or adcnum &lt; 0:\r\n        return -1\r\n    r = spi.xfer2(&#x5B;1, 8 + adcnum &lt;&lt; 4, 0])\r\n    adcout = ((r&#x5B;1] &amp; 3) &lt;&lt; 8) + r&#x5B;2]\r\n    return adcout\r\n\r\nwhile True:\r\n    value = readadc(0)\r\n    volts = (value * 3.3) \/ 1024\r\n    temperature = volts \/ (10.0 \/ 1000)\r\n    print (&quot;%4d\/1023 =&gt; %5.3f V =&gt; %4.1f \u00c2\u00b0C&quot; % (value, volts,\r\n            temperature))\r\n    time.sleep(0.5)\r\n<\/pre>\n<p>The slightly awkward code <code>temperature = volts \/ (10.0 \/ 1000)<\/code> is just a simpler way of acknowledging that the LM35DZ puts out 10 mV (= 10\/1000, or 0.01) per \u00c2\u00b0C. Well-behaved sensors generally have a linear relationship between what they indicate and what they measure.<\/p>\n<p>If you run the code:<\/p>\n<pre>sudo .\/mcp3008_lm35.py<\/pre>\n<p>you should get something like:<\/p>\n<pre>  91\/1023 =&gt; 0.293 V =&gt; 29.3 \u00c2\u00b0C\r\n  93\/1023 =&gt; 0.300 V =&gt; 30.0 \u00c2\u00b0C\r\n  94\/1023 =&gt; 0.303 V =&gt; 30.3 \u00c2\u00b0C\r\n  95\/1023 =&gt; 0.306 V =&gt; 30.6 \u00c2\u00b0C\r\n  96\/1023 =&gt; 0.309 V =&gt; 30.9 \u00c2\u00b0C\r\n  97\/1023 =&gt; 0.313 V =&gt; 31.3 \u00c2\u00b0C\r\n  97\/1023 =&gt; 0.313 V =&gt; 31.3 \u00c2\u00b0C\r\n  98\/1023 =&gt; 0.316 V =&gt; 31.6 \u00c2\u00b0C\r\n  99\/1023 =&gt; 0.319 V =&gt; 31.9 \u00c2\u00b0C\r\n  99\/1023 =&gt; 0.319 V =&gt; 31.9 \u00c2\u00b0C\r\n 100\/1023 =&gt; 0.322 V =&gt; 32.2 \u00c2\u00b0C\r\n 100\/1023 =&gt; 0.322 V =&gt; 32.2 \u00c2\u00b0C\r\n 100\/1023 =&gt; 0.322 V =&gt; 32.2 \u00c2\u00b0C\r\n 101\/1023 =&gt; 0.325 V =&gt; 32.5 \u00c2\u00b0C\r\n 101\/1023 =&gt; 0.325 V =&gt; 32.5 \u00c2\u00b0C\r\n 102\/1023 =&gt; 0.329 V =&gt; 32.9 \u00c2\u00b0C\r\n 102\/1023 =&gt; 0.329 V =&gt; 32.9 \u00c2\u00b0C\r\n 103\/1023 =&gt; 0.332 V =&gt; 33.2 \u00c2\u00b0C<\/pre>\n<p>Note that the sensor had been sitting over the Raspberry Pi&#8217;s CPU for a while; I don&#8217;t keep my house at 29 \u00c2\u00b0C. I made the temperature go up by holding the LM35.<\/p>\n<p>So, you&#8217;ve just (fairly cheaply) given your Raspberry Pi 8 analogue input channels, so it can behave much more like a real microcontroller now. I remember from my datalogging days that analogue inputs can be pretty finicky and almost always return a value even if it&#8217;s an incorrect one. Check the chip&#8217;s datasheet to see if you&#8217;re doing it right, and if in doubt, meter it!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey! This is a really old article. You should really be using gpiozero these days. I hadn&#8217;t realised it, but the The Quite Rubbish Clock did something that a lot of people seem to have trouble with on the Raspberry Pi: communicating using hardware SPI. Perhaps it&#8217;s because everything is moving so fast with Raspberry [&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":"","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":[2615,2614,2265,2616,2540,2510,2617],"class_list":["post-8244","post","type-post","status-publish","format-standard","hentry","category-computers-suck","category-goatee-stroking-musing-or-something","tag-a2d","tag-adc","tag-lm35","tag-mcp3008","tag-python","tag-raspberrypi","tag-spi"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/pQNZZ-28Y","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/scruss.com\/blog\/wp-json\/wp\/v2\/posts\/8244","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=8244"}],"version-history":[{"count":25,"href":"https:\/\/scruss.com\/blog\/wp-json\/wp\/v2\/posts\/8244\/revisions"}],"predecessor-version":[{"id":12957,"href":"https:\/\/scruss.com\/blog\/wp-json\/wp\/v2\/posts\/8244\/revisions\/12957"}],"wp:attachment":[{"href":"https:\/\/scruss.com\/blog\/wp-json\/wp\/v2\/media?parent=8244"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/scruss.com\/blog\/wp-json\/wp\/v2\/categories?post=8244"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/scruss.com\/blog\/wp-json\/wp\/v2\/tags?post=8244"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}