{"id":146,"date":"2013-07-12T16:00:01","date_gmt":"2013-07-12T06:00:01","guid":{"rendered":"http:\/\/bandetech.com\/blog\/?p=146"},"modified":"2013-07-13T15:14:56","modified_gmt":"2013-07-13T05:14:56","slug":"taking-the-houses-temperature-engineering-edition","status":"publish","type":"post","link":"https:\/\/bandetech.com\/blog\/2013\/07\/taking-the-houses-temperature-engineering-edition\/","title":{"rendered":"Taking the house&#8217;s temperature &#8212; engineering edition"},"content":{"rendered":"<p><a href=\"http:\/\/bandetech.com\/blog\/wp-content\/uploads\/tmp102_0.jpg\" rel=\"lightbox[146]\"><img loading=\"lazy\" decoding=\"async\" class=\"alignright size-thumbnail wp-image-162\" alt=\"TMP102 sensor\" src=\"http:\/\/bandetech.com\/blog\/wp-content\/uploads\/tmp102_0-150x150.jpg\" width=\"150\" height=\"150\" srcset=\"https:\/\/bandetech.com\/blog\/wp-content\/uploads\/tmp102_0-150x150.jpg 150w, https:\/\/bandetech.com\/blog\/wp-content\/uploads\/tmp102_0-300x300.jpg 300w, https:\/\/bandetech.com\/blog\/wp-content\/uploads\/tmp102_0.jpg 900w\" sizes=\"auto, (max-width: 150px) 100vw, 150px\" \/><\/a>This is a more technical post relating to my earlier one about <a title=\"Taking the house\u2019s temperature\" href=\"http:\/\/bandetech.com\/blog\/2013\/05\/roof-temperature\/\">monitoring roof-space temperatures<\/a> &#8212; where I considered whether I might be able to move my computer gear into the roof space.<br \/>\n<!--more--><br \/>\nBelow, you&#8217;ll find a simple list of items I used in this project and the code I wrote for the Arduino and for the web page that the Arduino uploaded data to.<\/p>\n<h2>Parts and power source<\/h2>\n<p>These are the parts I used:<\/p>\n<ul>\n<li>An Arduino <a title=\"Duemilenove\" href=\"http:\/\/arduino.cc\/en\/Main\/ArduinoBoardDuemilanove\" target=\"_blank\">Duemilanove<\/a><\/li>\n<li>An <a title=\"Ethernet shield\" href=\"http:\/\/arduino.cc\/en\/Main\/ArduinoEthernetShield\" target=\"_blank\">Ethernet Shield<\/a><\/li>\n<li>2 x <a title=\"Sparkfun TMP102\" href=\"https:\/\/www.sparkfun.com\/products\/9418\" target=\"_blank\">Sparkfun TMP102<\/a> I2C temperature breakouts sourced from <a title=\"LBE\" href=\"http:\/\/littlebirdelectronics.com\/\" target=\"_blank\">Little Bird Electronics<\/a><\/li>\n<li>Cat-5 network cable to connect the roof sensor<\/li>\n<\/ul>\n<p>Since the monitoring was only to be carried out for a short time, I powered the Arduino from a computer USB port. Connections to the sensors were done on a breadboard and the whole lot was just left sitting on the study desk. \u00a0Messy, but functional.<\/p>\n<h2>Arduino wiring<\/h2>\n<p>There were just 3 major connections made to the Arduino:<\/p>\n<ul>\n<li>USB for power and programming<\/li>\n<li>Ethernet cable for networking<\/li>\n<li>Cat 5 cable for the sensors &#8212; connected to Analogue pins 4 (SDA) and 5 (SCL), 3.3V power and ground<\/li>\n<\/ul>\n<h2>Putting it together<\/h2>\n<p>The main loop of the Arduino&#8217;s code sampled the two sensors and then built a URL to request on the web server. \u00a0The URLs looked something like <em>host.com\/temp.php?t1=298&amp;t2=507<\/em>. \u00a0After the web site responded (the response itself was meaningless and ignored by the Arduino), the Arduino waited 10 minutes and then did it all over again.<\/p>\n<p>PHP coding in the web page extracted the two temperature readings (t1 &amp; t2) from the URL requested and inserted these into a MySQL database along with the date and time the request was received.<\/p>\n<p>When it was time to read data back, a different php page queried the temperature table and sent back a table of values and a graph (using\u00a0<a title=\"JpGraph\" href=\"http:\/\/jpgraph.net\/\" target=\"_blank\">jpGraph<\/a>). If I were to do this project again, I&#8217;d probably save myself the effort that went into coding the PHP and instead use a service such as <a title=\"Xively\" href=\"https:\/\/xively.com\/\" target=\"_blank\">Xively<\/a> or <a title=\"ThingSpeak\" href=\"https:\/\/www.thingspeak.com\/\" target=\"_blank\">ThingSpeak<\/a> &#8212; &#8216;Internet of Things&#8217; services which allow anyone to upload sensor data and graph it with a minimum of effort.<\/p>\n<p>Connecting the sensor in the roof looked like it would be a bit tricky. \u00a0This was strictly a temporary setup, so no new holes were allowed in the walls or ceiling. \u00a0It had to run for weeks, so stringing wires across rooms wasn&#8217;t an option. \u00a0To top it off, forums on the net suggested that I2C would probably not function if the connecting cable was more than a couple of metres long.<\/p>\n<p>A couple of years ago, I pulled a Cat 5 networking cable through the walls up into the roof space, but still hadn&#8217;t got around to putting it into service. \u00a0It was at least 20 metres long, but it had the advantage of both its ends being in exactly the right places &#8212; the study and roof space.\u00a0I decided to have a go at connecting the sensor this way, despite it being ten times longer than anyone thought would work &#8212; nothing to lose by trying&#8230;<\/p>\n<p>I used a couple of pairs of wires from the network cable (network cables have 8 wires, twisted together as 4 pairs): one pair for data, another for power. \u00a0It worked perfectly first time. \u00a0I believe this might be due to the twisted pairs naturally reducing electrical noise and interference.<\/p>\n<div id=\"attachment_191\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/bandetech.com\/blog\/wp-content\/uploads\/tmp102_roof_2.jpg\" rel=\"lightbox[146]\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-191\" class=\"size-medium wp-image-191\" alt=\"Cat-5 run to TMP102 in roof\" src=\"http:\/\/bandetech.com\/blog\/wp-content\/uploads\/tmp102_roof_2-300x220.jpg\" width=\"300\" height=\"220\" \/><\/a><p id=\"caption-attachment-191\" class=\"wp-caption-text\">Cat-5 run to TMP102 in roof<\/p><\/div>\n<h2>The code<\/h2>\n<p>Here&#8217;s the Arduino code I wrote:<\/p>\n<pre class=\"brush: arduino; title: ; notranslate\" title=\"\">\r\n#include &lt;Wire.h&gt;\r\n#include &lt;Ethernet.h&gt;\r\n#include &lt;SPI.h&gt;\r\n\r\n\/\/ set variables, including TMP102 i2c addresses\r\nconst int tmp102a = 0x48;\r\nconst int tmp102b = 0x49;\r\nbyte MSB,LSB;\r\nint tempA, tempB;\r\n\r\n\/\/ set ethernet MAC address and hard code server's IP\r\nbyte mac&#x5B;] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xEE };\r\nbyte server&#x5B;] = { nnn, nnn, nnn, nnn };\r\n\r\n\/\/ set strings for base URL and HTTP request\r\nconst String urla = &quot;GET \/temps.php?t1=&quot;;\r\nconst String urlb = &quot; HTTP\/1.1&quot;;\r\nconst String host = &quot;Host: hostedsite.com&quot;;\r\n\r\nEthernetClient client;\r\n\r\n\/\/ initialise ethernet and wire libraries\r\nvoid setup() {\r\n \u00a0 Wire.begin();\r\n \u00a0\u00a0Ethernet.begin(mac);\r\n }\r\n\r\nvoid loop() {\r\n\/\/ read sensor 1, two bytes, combine into a single integer value\r\n  Wire.requestFrom(tmp102a, 2);\r\n  \u00a0 MSB = Wire.read();\r\n  \u00a0 LSB = Wire.read();\r\n  \u00a0 tempA = (((MSB &lt;&lt; 8) | LSB ) &gt;&gt; 4);\r\n\r\n\/\/ read sensor 2, two bytes, combine into a single integer value\r\n  Wire.requestFrom(tmp102b, 2);\r\n  \u00a0 MSB = Wire.read();\r\n  \u00a0 LSB = Wire.read();\r\n  \u00a0 tempB = (((MSB &lt;&lt; 8) | LSB ) &gt;&gt; 4);\r\n\r\n\/\/ send values to server PHP page\r\n  sendtemp();\r\n}\r\n\r\nvoid sendtemp() {\r\n  String url2snd = urla;\r\n\r\n\/\/ form up the full URL into string url2snd\r\n  url2snd += tempA;\r\n  url2snd += &quot;t2=&quot;;\r\n  url2snd += tempB;\r\n\r\n\/\/ start port 80 connection, send HTTP headers and URL\r\n  if (client.connect(server, 80)) {\r\n    client.print(url2snd);\r\n    client.println(urlb);\r\n    client.println(host);\r\n    client.println();\r\n  }\r\n  else {\r\n    Serial.println(&quot;connect failed&quot;);\r\n  }\r\n\r\n\/\/ stop ethernet connection\r\n  client.stop();\r\n\r\n\/\/ wait 10 minutes\r\n  delay(600000);\r\n}\r\n<\/pre>\n<p>Notes:<\/p>\n<ol>\n<li>The I2C slave address for the temperature sensor is 7 bits long. It took me a while to work out exactly how to address the sensors since the data sheet gives only the 7-bit number (i.e. 0b1001000) &#8212; Turns out this needs to be right-aligned in a full byte, which gives 0b01001000 or 0x48.<\/li>\n<li>The TMP102 returns a 12-bit reading in two bytes, hence the bit-shifting code to reassemble them into a 16-bit integer value.<\/li>\n<li>The integer read from the TMP102 needs to be multiplied by 0.0625 for the reading to be in degrees celsius. \u00a0I chose to do this in PHP on the server rather than on the Arduino. \u00a0When it&#8217;s 20 degrees, the sensor gives a value of 320.<\/li>\n<\/ol>\n<div id=\"attachment_346\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/bandetech.com\/blog\/wp-content\/uploads\/temp_bench_test.jpg\" rel=\"lightbox[146]\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-346\" class=\"size-medium wp-image-346\" alt=\"temp_bench_test\" src=\"http:\/\/bandetech.com\/blog\/wp-content\/uploads\/temp_bench_test-300x172.jpg\" width=\"300\" height=\"172\" \/><\/a><p id=\"caption-attachment-346\" class=\"wp-caption-text\">Arduino prototyping: quick and effective, but not necessarily pretty.<\/p><\/div>\n<p style=\"text-align: left;\">The PHP code below has been altered a little from the version that was used for uploading, but the essential functionality is still shown here. \u00a0To be completely honest, I can&#8217;t remember what all the shenanigans with the URL arguments are all about, but it worked fine!<\/p>\n<p style=\"text-align: left;\">Also, the PHP web page was for the purposes of this project and my information only, not for public use &#8212; there&#8217;s no parameter or range checking, no authentication, basically no safeguards to ensure the data is correct and from a legitimate source. A public page would need much better coding than what I&#8217;ve published here.<\/p>\n<pre class=\"brush: php; html-script: true; title: ; notranslate\" title=\"\">\r\n&lt;?php\r\n\/\/ create a database handle\r\n$dbh = mysql_connect (&quot;localhost&quot;, &quot;temps_db&quot;, &quot;password&quot;);\r\nmysql_select_db (&quot;temps_db&quot;, $dbh);\r\n\r\n\/\/ if an argument is supplied to the script,\r\n\/\/ extract details into sensible hash values\r\n\r\nif ($argv) {\r\n  foreach ($argv as $k=--&gt;$v) {\r\n    if ($k==0) continue;\r\n    $it = explode(&quot;=&quot;,$argv&#x5B;$i]);\r\n    if (isset($it&#x5B;1])) $_GET&#x5B;$it&#x5B;0]] = $it&#x5B;1];\r\n  }\r\n}\r\n\r\n\/\/ if an argument called t1 is present,\r\n\/\/ assume it's a legit call to add new readings\r\n\r\nif ($_GET&#x5B;'t1']) {\r\n  $tmp1 = $_GET&#x5B;'t1']*0.0625;\r\n  $tmp2 = $_GET&#x5B;'t2']*0.0625;\r\n  $qry = &quot;INSERT INTO tbl (temp1, temp2) VALUES ($tmp1, $tmp2)&quot;;\r\n  mysql_query($qry);\r\n}\r\n?&gt;\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>This is a more technical post relating to my earlier one about monitoring roof-space temperatures &#8212; where I considered whether I might be able to move my computer gear into the roof space.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[17],"tags":[8,21,35,23,22,24],"class_list":["post-146","post","type-post","status-publish","format-standard","hentry","category-projects","tag-arduino","tag-logging","tag-php","tag-roof-space","tag-temperature","tag-tmp102"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p8H2X3-2m","_links":{"self":[{"href":"https:\/\/bandetech.com\/blog\/wp-json\/wp\/v2\/posts\/146","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/bandetech.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/bandetech.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/bandetech.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/bandetech.com\/blog\/wp-json\/wp\/v2\/comments?post=146"}],"version-history":[{"count":92,"href":"https:\/\/bandetech.com\/blog\/wp-json\/wp\/v2\/posts\/146\/revisions"}],"predecessor-version":[{"id":688,"href":"https:\/\/bandetech.com\/blog\/wp-json\/wp\/v2\/posts\/146\/revisions\/688"}],"wp:attachment":[{"href":"https:\/\/bandetech.com\/blog\/wp-json\/wp\/v2\/media?parent=146"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/bandetech.com\/blog\/wp-json\/wp\/v2\/categories?post=146"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/bandetech.com\/blog\/wp-json\/wp\/v2\/tags?post=146"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}