{"id":293,"date":"2016-02-17T03:00:05","date_gmt":"2016-02-17T01:00:05","guid":{"rendered":"http:\/\/pori.hacklab.fi\/wordpress\/?p=293"},"modified":"2017-05-03T16:16:14","modified_gmt":"2017-05-03T13:16:14","slug":"sparkfun-esp8266-thing-ds18b20-langaton-sauna-lampomittari-proggis","status":"publish","type":"post","link":"https:\/\/pori.hacklab.fi\/wordpress\/?p=293","title":{"rendered":"Sparkfun ESP8266 Thing + DS18B20 langaton sauna l\u00e4mp\u00f6mittari proggis."},"content":{"rendered":"<p>Jo muutama vuosi sitten mietein k\u00e4mppiksen kanssa, ett\u00e4 olisi ihan siisti\u00e4 piha saunaan rakentaa langaton l\u00e4mp\u00f6mittari. En silloin hirve\u00e4sti elektroniikasta ollut perill\u00e4 vaikka pitk\u00e4\u00e4n olen ohjelmointia harrastanut.<\/p>\n<p>Tammikuussa tilasin huvikseni yhden <a href=\"https:\/\/www.sparkfun.com\/products\/13231\">Sparkfun ESP8266 Thing<\/a>\u00a0kehityskortin ja harmikseni huomasin, ett\u00e4 tarvitsen my\u00f6s ohjelmointi laitteen. Sparkfun suosittelee Thingin kanssa k\u00e4ytett\u00e4v\u00e4ksi\u00a0<a href=\"https:\/\/www.sparkfun.com\/products\/9873\">SparkFun FTDI Basic Breakout<\/a> korttia.<\/p>\n<p>Samalla tajusin, ett\u00e4 tuon ESP8266 kehityskortin kanssa olisi aika helppo rakentaa l\u00e4mp\u00f6mittari. Hacklab kaverit puhunut noista ESP8266 korteista ja DS18B20 l\u00e4mp\u00f6mittareista jonkun aikaa joten p\u00e4\u00e4tin katsoa millain tuollaisen kytkenn\u00e4n saisi tehty\u00e4.<\/p>\n<p>Pistin siis tilaukseen ohjelmointikortin, DS18B20 anturin ja v\u00e4h\u00e4n johtoa. Aloin lueskelemaan Thingin dokumentaatiota ja sitten piirsin oman kaltaisen kytkent\u00e4 kaavion.\u00a0Kysyin tietenkin H\u00e4m\u00e4l\u00e4isen Markolta menik\u00f6 kytkent\u00e4 suunnitelma yht\u00e4\u00e4n oikein. H\u00e4n kertoi, ett\u00e4 se n\u00e4ytt\u00e4\u00e4 aikalailla oikealta. Ei kun siis odottamaan, ett\u00e4 osat tulee postilaatikkoon. Harmikseni 170 euron Sparkfun tilaus j\u00e4i tulliinkin hetkeksi.<\/p>\n<p><a href=\"http:\/\/mussukka.org\/files\/esp8266thingDS18B20.jpg\"><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter wp-image-255 \" src=\"http:\/\/mussukka.org\/files\/esp8266thingDS18B20.jpg\" alt=\"Sparkfun ESP8266 Thing + DS18B20 kytkent\u00e4kaavio\" width=\"500\" height=\"275\" \/><\/a><\/p>\n<p>K\u00e4mppiksen vaimo vastaanotti paketin tiistaina 16.2.2016 ja min\u00e4 tietenkin t\u00f6ihin l\u00e4htiess\u00e4 otin paketin mukaan. Jonkin aikaa t\u00f6it\u00e4 tehdess\u00e4 alkoi into kolvailuun. Sain kolvattua Arduino headerin ohjelmointikortin liitt\u00e4mist\u00e4 varten kun minun kolvini hajosi.<\/p>\n<p>Sitten juttelin hetken Markon kanssa ja tultiin siihen p\u00e4\u00e4t\u00f6kseen, ett\u00e4 k\u00e4yn h\u00e4nen luonaan pikaiseen kolvaamassa kytkenn\u00e4n ennen Hacklab miitti\u00e4. Kolvailu onnistui sujuvasti kun kunnon juotin. En min\u00e4 pist\u00e4isi noin 300 euroa juottimeen.<\/p>\n<p>P.S. Pistettiin Hacklab miitiss\u00e4 yhteis\u00f6keskuksella tavaraa muutto valmiiksi.<\/p>\n<p>Miitin j\u00e4lkeen tulin kotiin. Joskus aikoinaan on tullut Arduinoa ohjelmoitua, mutta jostain syyst\u00e4 IDE oli koneeltani hukassa. Meni pari tuntia Arch Linuxissa, ett\u00e4 sain tuon Arduino IDE:n asennettua. Sen j\u00e4lkeen tietenkin varmistin, ett\u00e4 ohjelman l\u00e4hett\u00e4minen onnistuu pist\u00e4m\u00e4ll\u00e4 Sparkfunin sivuilta l\u00f6ytyv\u00e4n Blink koodin py\u00f6rim\u00e4\u00e4n.<\/p>\n<p>Jonkun aikaa koodailtuani tulin taisin saada l\u00e4mm\u00f6n mittaamisen toimintaan.<\/p>\n<pre class=\"prettyprint\">#include \r\n\r\n#define ESP8266_LED 5\r\n#define DS18B20 0\r\n\r\nOneWire oneWire(DS18B20);\r\n\r\nvoid setup() \r\n{\r\n  pinMode(ESP8266_LED, OUTPUT);\r\n}\r\n\r\nvoid loop() \r\n{\r\n  byte i;\r\n  byte present = 0;\r\n  byte type_s;\r\n  byte data[12];\r\n  byte addr[8];\r\n  float celsius, fahrenheit;\r\n\r\n  if (!oneWire.search(addr)) {\r\n    oneWire.reset_search();\r\n    delay(250);\r\n    return;\r\n  }\r\n\r\n  if(OneWire::crc8(addr, 7) != addr[7]) {\r\n    return;\r\n  }\r\n  Serial.println();\r\n\r\n  switch (addr[0]) {\r\n    case 0x10: \/\/ Chip = DS18S20\r\n      type_s = 1;\r\n      break;\r\n    case 0x28: \/\/ Chip = DS18B20\r\n      type_s = 0;\r\n      break;\r\n    case 0x22: \/\/ Chip = DS1822\r\n      type_s = 0;\r\n      break;\r\n    default: \/\/ Device is not a DS18 family Device\r\n      return;\r\n  }\r\n\r\n  oneWire.reset();\r\n  oneWire.select(addr);\r\n  oneWire.write(0x44, 1);\r\n\r\n  delay(1000);\r\n  \r\n  present = oneWire.reset();\r\n  oneWire.select(addr);\r\n  oneWire.write(0xBE);\r\n\r\n  for (i = 0; i &lt; 9; i++) {\r\n    data[i] = oneWire.read();\r\n  }\r\n\r\n  int16_t raw = (data[1] &lt;&lt; 8) | data[0];\r\n  if (type_s) {\r\n    raw = raw &lt;&lt; 3;\r\n    if (data[7] == 0x10) {\r\n      raw = (raw &amp; 0xFFF0) + 12 - data[6];\r\n    }\r\n  } else {\r\n    byte cfg = (data[4] &amp; 0x60);\r\n    if (cfg == 0x00) raw = raw &amp; ~7;\r\n    else if(cfg == 0x20) raw = raw &amp; ~3;\r\n    else if(cfg == 0x40) raw = raw &amp; ~1;\r\n  }\r\n  celsius = (float)raw \/ 16.0;\r\n  fahrenheit = celsius * 1.8 + 32.0;\r\n\r\n  for(i = 0; i &lt; (int)celsius; i++) {\r\n    digitalWrite(ESP8266_LED, HIGH);\r\n    delay(500);\r\n    digitalWrite(ESP8266_LED, LOW);\r\n    delay(500);\r\n  }\r\n  delay(2000);\r\n}<\/pre>\n<p>Tuossa on siis t\u00e4m\u00e4n hetkinen koodip\u00e4tk\u00e4 jota debuggaan seuraavalla Youtube videolla.<\/p>\n<p><iframe loading=\"lazy\" src=\"https:\/\/www.youtube.com\/embed\/lNUTVCDa4ak\" width=\"560\" height=\"315\" frameborder=\"0\" allowfullscreen=\"allowfullscreen\"><\/iframe><\/p>\n<p>Kirjoitan projektista t\u00e4nne lis\u00e4\u00e4 kun saan ohjelmoitua l\u00e4mp\u00f6tilan l\u00e4hett\u00e4misen palvelimelle. Kuten videolla sanon, en jaksa ohjelmoida juuri nyt enemp\u00e4\u00e4. Kello on 2:33 ja p\u00e4\u00e4t\u00e4n t\u00e4lt\u00e4 y\u00f6lt\u00e4 t\u00e4m\u00e4n proggiksen t\u00e4h\u00e4n. \ud83d\ude09<\/p>\n<p>Edit: 24.02:<\/p>\n<p>J\u00e4\u00e4nyt kirjoittamatta loput kun Hacklabin WordPress v\u00e4h\u00e4n sekoillut. Jos huomaatte poistin vahingossa kaikista artikkeleista kuvatkin.<\/p>\n<p>Seuraava l\u00e4hdekoodi py\u00f6rii itse ESP8266 Thingiss\u00e4.<\/p>\n<pre class=\"prettyprint\">#include <OneWire.h>\r\n#include <ESP8266WiFi.h>\r\n\r\n#define ESP8266_LED 5\r\n#define DS18B20 0\r\n\r\nOneWire oneWire(DS18B20);\r\n\r\nconst char WiFiSSID[] = \"SSID\";\r\nconst char WiFiPSK[] = \"PSK\";\r\n\r\nconst char Host[] = \"Hostname\";\r\nconst int Port = 443;\r\nString Sensor = \"SparkfunESP8266+DS18B20+1\";\r\nconst char* fingerprint = \"86 A5 43 FB 57 17 94 6D 5E F3 84 BD 5B 3C 33 C5 2C 68 1F 4A\";\r\n\r\nconst int toSeconds = 1000000;\r\n\r\nvoid setup() {\r\n  pinMode(ESP8266_LED, OUTPUT);\r\n  \r\n  WiFi.mode(WIFI_STA);\r\n  WiFi.begin(WiFiSSID, WiFiPSK);\r\n  while (WiFi.status() != WL_CONNECTED) {\r\n    delay(500);\r\n  }\r\n  \r\n  byte i;\r\n  byte present = 0;\r\n  byte type_s;\r\n  byte data[12];\r\n  byte addr[8];\r\n  float celsius, fahrenheit;\r\n\r\n  if (!oneWire.search(addr)) {\r\n    oneWire.reset_search();\r\n    delay(250);\r\n    return;\r\n  }\r\n\r\n  if(OneWire::crc8(addr, 7) != addr[7]) {\r\n    return;\r\n  }\r\n  Serial.println();\r\n\r\n  switch (addr[0]) {\r\n    case 0x10: \/\/ Chip = DS18S20\r\n      type_s = 1;\r\n      break;\r\n    case 0x28: \/\/ Chip = DS18B20\r\n      type_s = 0;\r\n      break;\r\n    case 0x22: \/\/ Chip = DS1822\r\n      type_s = 0;\r\n      break;\r\n    default: \/\/ Device is not a DS18 family Device\r\n      return;\r\n  }\r\n\r\n  oneWire.reset();\r\n  oneWire.select(addr);\r\n  oneWire.write(0x44, 1);\r\n\r\n  delay(1000);\r\n  \r\n  present = oneWire.reset();\r\n  oneWire.select(addr);\r\n  oneWire.write(0xBE);\r\n\r\n  for (i = 0; i < 9; i++) {\r\n    data[i] = oneWire.read()\r\n  }\r\n\r\n  int16_t raw = (data[1] << 8) | data[0];\r\n  if (type_s) {\r\n    raw = raw << 3;\r\n    if (data[7] == 0x10) {\r\n      raw = (raw &#038; 0xFFF0) + 12 - data[6];\r\n    }\r\n  } else {\r\n    byte cfg = (data[4] &#038; 0x60);\r\n    if (cfg == 0x00) raw = raw &#038; ~7;\r\n    else if(cfg == 0x20) raw = raw &#038; ~3;\r\n    else if(cfg == 0x40) raw = raw &#038; ~1;\r\n  }\r\n  celsius = (float)raw \/ 16.0;\r\n  fahrenheit = celsius * 1.8 + 32.0;\r\n\r\n  for(i = 0; i < (int)celsius; i++) {\r\n    digitalWrite(ESP8266_LED, HIGH);\r\n    delay(500);\r\n    digitalWrite(ESP8266_LED, LOW);\r\n    delay(500);\r\n  }\r\n\r\n  WiFiClientSecure client;\r\n  if (!client.connect(Host, Port)) {\r\n    return;\r\n  }\r\n\r\n  if (!client.verify(fingerprint, Host)) {\r\n    return;\r\n  }\r\n\r\n  String url = \"\/insert.php?table=temperatures&#038;from=\" + Sensor + \"&#038;temperature=\" + celsius;\r\n\r\n  client.print(String(\"GET \") + url + \" HTTP\/1.1\\r\\n\" +\r\n                \"Host: \" + Host + \"\\r\\n\" + \r\n                \"Connection: Close\\r\\n\\r\\n\");\r\n  delay(10);\r\n  \r\n  digitalWrite(ESP8266_LED, HIGH);\r\n  delay(500);\r\n  digitalWrite(ESP8266_LED, LOW);\r\n  delay(500);\r\n\r\n  if (celsius < 20.0) {\r\n    ESP.deepSleep(600 * toSeconds);\r\n  } else {\r\n    ESP.deepSleep(30 * toSeconds);\r\n  }\r\n}\r\n\r\nvoid loop() {\r\n  \r\n}\r\n<\/pre>\n<p>Jos huomaat kaikki koodi on siirtynyt setup() funktioon ESP.deepSleep() funktio kutsun takia. ESP.deepSleep on ESP8266 Thingille ominainen syv\u00e4uni joka v\u00e4hent\u00e4\u00e4 virran kulutusta. Ja l\u00e4het\u00e4n Temperaturen palvelimelle HTTP GET kutsulla. NGINX palvelimella py\u00f6rii PHP seuraava PHP scripti.<\/p>\n<pre class=\"prettyprint\">&lt;?php\r\n\r\n$database_location = \"database\/\";\r\n\r\nif(!is_dir($database_location)) {\r\n        mkdir($database_location, 755);\r\n}\r\n\r\n$database = $database_location . $_GET['table'];\r\n$table = json_decode(\"[]\", true);\r\n\r\nif(file_exists($database)) {\r\n        $table = json_decode(file_get_contents($database), true);\r\n}\r\n\r\nunset($_GET['table']);\r\n\r\n$_GET['created'] = date(\"d-m-Y H:i:s\");\r\narray_push($table, $_GET);\r\n\r\n$table = json_encode($table, JSON_PRETTY_PRINT);\r\nfile_put_contents($database, $table);\r\n\r\n?&gt;\r\n\r\n<\/pre>\n<p>T\u00e4m\u00e4 PHP scripti tallentaa vastaanotetun l\u00e4mp\u00f6tilan JSON tiedostoon, josta voin my\u00f6hemmin lukea l\u00e4mp\u00f6tila arvon.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter wp-image-305\" src=\"https:\/\/pori.hacklab.fi\/wordpress\/wp-content\/uploads\/2016\/02\/20160224_174743-300x169.jpg\" alt=\"ESP8266 + DS18B20 langaton l\u00e4mp\u00f6mittari\" width=\"500\" height=\"282\" srcset=\"https:\/\/pori.hacklab.fi\/wordpress\/wp-content\/uploads\/2016\/02\/20160224_174743-300x169.jpg 300w, https:\/\/pori.hacklab.fi\/wordpress\/wp-content\/uploads\/2016\/02\/20160224_174743-768x433.jpg 768w, https:\/\/pori.hacklab.fi\/wordpress\/wp-content\/uploads\/2016\/02\/20160224_174743-1916x1080.jpg 1916w\" sizes=\"(max-width: 500px) 85vw, 500px\" \/><\/p>\n<p>Olen v\u00e4h\u00e4n niputtanut DS18B20 johtoa, koska se on t\u00e4ll\u00e4 hetkell\u00e4 niin paljon tiell\u00e4. Se on pari metri\u00e4 pitk\u00e4 saunaa varten. Seuraavaksi tarvis tehd\u00e4 tuolle kotelo ja p\u00e4\u00e4st\u00e4\u00e4n asentamaan se saunaan.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Jo muutama vuosi sitten mietein k\u00e4mppiksen kanssa, ett\u00e4 olisi ihan siisti\u00e4 piha saunaan rakentaa langaton l\u00e4mp\u00f6mittari. En silloin hirve\u00e4sti elektroniikasta ollut perill\u00e4 vaikka pitk\u00e4\u00e4n olen ohjelmointia harrastanut. Tammikuussa tilasin huvikseni yhden Sparkfun ESP8266 Thing\u00a0kehityskortin ja harmikseni huomasin, ett\u00e4 tarvitsen my\u00f6s ohjelmointi laitteen. Sparkfun suosittelee Thingin kanssa k\u00e4ytett\u00e4v\u00e4ksi\u00a0SparkFun FTDI Basic Breakout korttia. Samalla tajusin, ett\u00e4 tuon &hellip; <a href=\"https:\/\/pori.hacklab.fi\/wordpress\/?p=293\" class=\"more-link\">Jatka lukemista<span class=\"screen-reader-text\"> &#8221;Sparkfun ESP8266 Thing + DS18B20 langaton sauna l\u00e4mp\u00f6mittari proggis.&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[2],"tags":[],"_links":{"self":[{"href":"https:\/\/pori.hacklab.fi\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/293"}],"collection":[{"href":"https:\/\/pori.hacklab.fi\/wordpress\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/pori.hacklab.fi\/wordpress\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/pori.hacklab.fi\/wordpress\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/pori.hacklab.fi\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=293"}],"version-history":[{"count":10,"href":"https:\/\/pori.hacklab.fi\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/293\/revisions"}],"predecessor-version":[{"id":498,"href":"https:\/\/pori.hacklab.fi\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/293\/revisions\/498"}],"wp:attachment":[{"href":"https:\/\/pori.hacklab.fi\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=293"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/pori.hacklab.fi\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=293"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/pori.hacklab.fi\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=293"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}