{"id":470,"date":"2015-05-01T10:12:57","date_gmt":"2015-05-01T17:12:57","guid":{"rendered":"http:\/\/internetofhomethings.com\/homethings\/?p=470"},"modified":"2015-05-01T10:12:57","modified_gmt":"2015-05-01T17:12:57","slug":"using-javascript-ajax-to-read-esp8266-data","status":"publish","type":"post","link":"https:\/\/internetofhomethings.com\/homethings\/?p=470","title":{"rendered":"Using Javascript AJAX to read ESP8266 data"},"content":{"rendered":"<p>Okay, so you got your ultra low-cost\u00a0ESP8266 workhorse setup to read some sensors. And you have an awesome webpage built to\u00a0visually display the readings. But how do you get the data from the ESP8266 to your website?<\/p>\n<p>PHP and\/or Javascript are the two most popular methods. I have used both.<\/p>\n<p>This writing presents a simple Javascript solution. I have also posted an approach to this task using <a href=\"http:\/\/wp.me\/p5NRQ8-7M\" target=\"_blank\">PHP here.<\/a><\/p>\n<p>My need came about while developing a mobile app to monitor and control devices in my home. My personal IoTs. Using the Apache Cordova API with the Eclipse IDE. I was\u00a0developing my App with just HTML, CSS, and JavaScript. Yet it will compile and install onto my Android device like any other application. It is my understanding that the\u00a0same code can be built into an iOS App as well&#8230;but&#8230;being strictly a PC user, I have not attempted\u00a0that.<\/p>\n<p>And let&#8217;s get back to using Javascript to pull information from an ESP8266 based web server.<\/p>\n<p>The thing was, I needed to pull my weather, sprinkler, garage and other sensor data from the ESP8266 circuit that\u00a0monitors\u00a0these devices to my App. I\u00a0also\u00a0wanted maintain control of the data. To be free from a cloud middleman such as <strong>ThingsSpeak<\/strong>.<\/p>\n<p>With this in mind, we have two sides to this solution; The micro-controller unit (MCU), which is the ESP8266 in this case, and the client App. The ESP8266 must read all the devices connected to it and then send this data, on request, to the App client. The preferred format is either JSON or XML.<\/p>\n<p>I use\u00a0JSON strings.<\/p>\n<p><a href=\"http:\/\/wp.me\/p5NRQ8-7C\" target=\"_blank\">Here is an\u00a0example<\/a> of a short function that can be used to\u00a0create a JSON string in\u00a0an Arduino IDE sketch. It is critical to include\u00a0the http header information provided in this example. The header authorizes your domain, allowing the Javascript AJAX to retrieve the ESP8266 http response.<\/p>\n<p>Here is the\u00a0Javascript with AJAX code used to request\u00a0a JSON string from the\u00a0\u00a0ESP8266, decode it, and display the values on a webpage.<\/p>\n<pre>function updateWeatherSensorData() {\r\n    requestURL = \"http:\/\/myrouterdomain.com:9999\/?request=GetSensors\";\r\n    if ( typeof updateWeatherSensorData.timeout == 'undefined' ) {\r\n        \/\/ It has not... perform the initialization\r\n        updateWeatherSensorData.timeout = 0;\r\n    }\r\n    \/\/Get Weather Sensor Value\r\n    $.ajax({\r\n        url: requestURL,\r\n        error: function(error){\r\n            if(updateWeatherSensorData.timeout++ &lt;10) {\r\n                setTimeout(updateWeatherSensorData, 1000);\r\n            }\r\n            else {\r\n                updateWeatherSensorData.timeout = 0;\r\n            }\r\n        },\r\n        success: function(thedata){\r\n            $(\"#baro\").html(thedata.B_Pressure + \" inHg\");\r\n            $(\"#tempIn\").html(thedata.DS_TempInside + \" F\");\r\n            $(\"#tempOut\").html(thedata.DS_TempOutside + \" F\");\r\n            $(\"#tempAttic\").html(thedata.DS_TempAttic + \" F\");\r\n            $(\"#humidity\").html(thedata.DH_Humidity + \" %\");\r\n            updateWeatherSensorData.timeout = 0;\r\n        },\r\n        timeout: 7000 \/\/ sets timeout to 7 seconds\r\n    });\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<p>I am assuming you have a domain name pointed to your router and your router is configured to port forward internet requests. For reference, <a href=\"http:\/\/wp.me\/p5NRQ8-7U\" target=\"_blank\">here is how to set this up<\/a>.<\/p>\n<p>How this Javascript code\u00a0works:<\/p>\n<p>First, the URL used to send the http GET request to the ESP8266 is defined. This URL has 3 parts<\/p>\n<ol>\n<li>The domain name:\u00a0http:\/\/myrouterdomain.com<\/li>\n<li>The port your ESP8266 web server is listening on: 9999<\/li>\n<li>The request string recognized by the web server: \/?request=GetSensors<\/li>\n<\/ol>\n<p>Then we need to define a timeout property for this function. The timeout is actually used to store the number of attempts to retrieve the JSON from the ESP8266 before successful.<\/p>\n<p>And now, the AJAX call. As you can see, the code is structured like a JSON string, with 4 keys and 4 values:<\/p>\n<ol>\n<li>url: This defines where to send the request.<\/li>\n<li>error: In case the request fails, the call is repeated, up to 10 times<\/li>\n<li>success: When successful, the webpage elements with the indicated ID are filled with the value retrieved from the ESP8266<\/li>\n<li>timeout: Up to 7 seconds is allowed before a timeout error is declared.<\/li>\n<\/ol>\n<p>That&#8217;s it! This is what I have been using to retrieve JSON strings from my ESP8266 using an AJAX call.<\/p>\n<h3 style=\"text-align: center;\"><strong>In Summary<\/strong><\/h3>\n<p>Here are a few closing thoughts of my observations for your information&#8230;<\/p>\n<ul>\n<li>The error handling is essential. This call fails frequently, perhaps every 2 or 3 requests.<\/li>\n<li>Most of the time, the error is because a blank string is filled from this call. I do not know if that is an ESP8266 issue or a problem with AJAX.<\/li>\n<li>The timeout was set to 7 seconds because I have seen it take up to 4 seconds to get a response.<\/li>\n<\/ul>\n<p>Hope you find this information useful for your ESP8266, Arduino\u00a0and other MPU projects.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Okay, so you got your ultra low-cost\u00a0ESP8266 workhorse setup to read some sensors. And you have an awesome webpage built to\u00a0visually display the readings. But how do you get the &hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1,10],"tags":[],"class_list":["post-470","post","type-post","status-publish","format-standard","hentry","category-alltheposts","category-esp8266"],"_links":{"self":[{"href":"https:\/\/internetofhomethings.com\/homethings\/index.php?rest_route=\/wp\/v2\/posts\/470","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/internetofhomethings.com\/homethings\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/internetofhomethings.com\/homethings\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/internetofhomethings.com\/homethings\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/internetofhomethings.com\/homethings\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=470"}],"version-history":[{"count":15,"href":"https:\/\/internetofhomethings.com\/homethings\/index.php?rest_route=\/wp\/v2\/posts\/470\/revisions"}],"predecessor-version":[{"id":527,"href":"https:\/\/internetofhomethings.com\/homethings\/index.php?rest_route=\/wp\/v2\/posts\/470\/revisions\/527"}],"wp:attachment":[{"href":"https:\/\/internetofhomethings.com\/homethings\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=470"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/internetofhomethings.com\/homethings\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=470"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/internetofhomethings.com\/homethings\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=470"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}