{"id":12561,"date":"2016-11-23T11:48:18","date_gmt":"2016-11-23T16:48:18","guid":{"rendered":"http:\/\/embedded-lab.com\/blog\/?p=12561"},"modified":"2017-12-14T11:21:16","modified_gmt":"2017-12-14T16:21:16","slug":"post-data-google-sheets-using-esp8266","status":"publish","type":"post","link":"https:\/\/embedded-lab.com\/blog\/post-data-google-sheets-using-esp8266\/","title":{"rendered":"How to post data to Google sheets using ESP8266"},"content":{"rendered":"<p>In the past couple years, the ESP8266 platform has flourished dramatically and emerged as one of the most popular hardware tools among electronics hobbyists and IoT enthusiasts. Packed with a 32-bit RISC CPU running at 80 MHz, a fully integrated WiFi radio with TCP\/IP protocol stack, serial peripherals (I2C, SPI, and UART), an ADC channel, and general purpose I\/O pins, the ESP8266 is the most integrated and affordable WiFi solution available in the current IoT market space. An ESP8266 hardware, like NodeMCU and ESP-01, can directly interface with sensors using its peripherals and upload the sensor measurements to a local or a remote web server via internet. Right now, there are already quite a bit of cloud IoT platforms (ThingSpeak, thinger.io, TESPA.io, Xively, \u2026 the list is getting bigger everyday) that provides APIs and tools to allow the ESP8266 users to directly upload their sensor readings online for real-time visualization and global access. If you are a regular user of Google Drive, like me, you would find a Google sheet more approachable than all those IoT cloud platforms. In this tutorial, I will describe a method of connecting the ESP8266 device directly to a Google sheet for storing\u00a0the sensor data without using any third party plugin. For illustration, I am\u00a0using a <strong><a href=\"https:\/\/www.tindie.com\/products\/rajbex\/nodemcu-esp8266-development-board\/\" target=\"_blank\">NodeMCU<\/a><\/strong> board that reads the analog output from a soil moisture sensor inserted into one my flower pots and directly connects to\u00a0a spreadsheet on my Google Drive for storing the data.<\/p>\n<div id=\"attachment_12565\" style=\"width: 725px\" class=\"wp-caption alignnone\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2016\/11\/SoilMoistureToGoogleSheet1.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-12565\" class=\"wp-image-12565 size-full\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2016\/11\/SoilMoistureToGoogleSheet1.png\" alt=\"Soil Moisture to Google Sheets\" width=\"715\" height=\"477\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2016\/11\/SoilMoistureToGoogleSheet1.png 715w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2016\/11\/SoilMoistureToGoogleSheet1-580x387.png 580w\" sizes=\"auto, (max-width: 715px) 100vw, 715px\" \/><\/a><p id=\"caption-attachment-12565\" class=\"wp-caption-text\">ESP8266 data logging to Google spreadsheets<\/p><\/div>\n<table>\n<tbody>\n<tr>\n<td bgcolor=\"#dedeee\">\n<h3>Related Posts<\/h3>\n<\/td>\n<\/tr>\n<tr>\n<td bgcolor=\"#eeeeee\">\nCheck out <strong><a href=\"http:\/\/embedded-lab.com\/blog\/send-email-text-messages-using-esp8266\/\" target=\"_blank\">How to send email and text messages using ESP8266<\/a><\/strong>.<br \/>\nCheck out our <strong><a href=\"http:\/\/embedded-lab.com\/blog\/making-simple-weather-web-server-using-esp8266-bme280\/\" target=\"_blank\">weather web server project<\/a><\/strong> for local web hosting of the sensor readings using ESP8266.<br \/>\nCheck out our <strong><a href=\"http:\/\/embedded-lab.com\/blog\/esp8266-temperature-humidity-logger-deep-sleep-enabled\/\" target=\"_blank\">ThingSpeak temperature and humidity logger project<\/a><\/strong> for remote server data logging example using ESP8266<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><!--more--><\/p>\n<p>Basically there are two parts to\u00a0this project. The first part is setting\u00a0up the ESP8266 hardware to read the soil moisture sensor output. The second part involves creating a Google sheet and configuring it\u00a0to accept the sensor data sent by the ESP8266 module over the\u00a0internet using a Google App Script\u00a0that is provided with this tutorial.<\/p>\n<h3>Hardware setup<\/h3>\n<p>This project uses a very simple and inexpensive\u00a0soil moisture sensor (one you can buy on <strong>eBay<\/strong> or <strong>Aliexpress<\/strong> for\u00a0$1) kit consisting\u00a0of two exposed metal pads and an instrumentation circuit board. The exposed pads act\u00a0as probes for sensing the moisture level within the soil. The more water in the soil means higher conductivity between the two pads, and vice-versa. The accompanying instrumentation board provides an analog output voltage that varies with the moisture level of the soil. The instrumentation circuit is powered with a 3.3V supply and its\u00a0output is fed to the\u00a0analog input channel (A0) of the NodeMCU.<\/p>\n<div id=\"attachment_12664\" style=\"width: 955px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2016\/11\/moisture.jpg\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-12664\" class=\"size-full wp-image-12664\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2016\/11\/moisture.jpg\" alt=\"Soil moisture sensor consisting of exposed metal pads and an instrumentation circuit\" width=\"945\" height=\"424\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2016\/11\/moisture.jpg 945w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2016\/11\/moisture-580x260.jpg 580w\" sizes=\"auto, (max-width: 945px) 100vw, 945px\" \/><\/a><p id=\"caption-attachment-12664\" class=\"wp-caption-text\">Soil moisture sensor consisting of exposed metal pads and an instrumentation circuit<\/p><\/div>\n<p><span style=\"color: #ff0000;\"><strong>Note:<\/strong><\/span> The ESP8266 analog input can handle the maximum input voltage\u00a0of 1V. However, the NodeMCU implements a voltage divider circuit on board to expand the range of input voltage to 3.3V.<\/p>\n<h3>Software<\/h3>\n<p>Let&#8217;s first try to understand what really happens when we try to send data to Google&#8217;s end. We will obviously be sending data using a GET request over an URL which has a pattern of <strong>https:\/\/script.google.com\/<\/strong>\u2026.. When you enter this URL in a web browser, the Google&#8217;s server responds back asking the browser to redirect to another URL with domain <strong>script.googleusercontent.com<\/strong>\u00a0with a\u00a0new GET request. For a web browser, the URL redirection\u00a0is a very common thing and it works without any problem. However, for ESP8266, this is not straight forward. The ESP8266 needs to correctly decode the header information received from the first server to\u00a0extract the redirect URL and make a second GET request to the new server.\u00a0To make this redirection simpler, <a href=\"https:\/\/github.com\/electronicsguy\" target=\"_blank\">Sujay Phadke<\/a>, aka\u00a0<em>electronicsguy<\/em>, has shared on GitHub a beautiful piece of code in the form of Arduino Library named <strong><a href=\"https:\/\/github.com\/electronicsguy\/ESP8266\" target=\"_blank\">HTTPSRedirect<\/a><\/strong>. There are other <a href=\"http:\/\/www.instructables.com\/id\/Post-to-Google-Docs-with-Arduino\/\" target=\"_blank\">examples<\/a> of Arduino posting data to Google spreadsheets using a third party API service, like <strong><a href=\"http:\/\/pushingbox.com\" target=\"_blank\">pushingbox<\/a><\/strong>,\u00a0for handling Google&#8217;s\u00a0https requirement and URL redirection. The use of\u00a0<strong><a href=\"https:\/\/github.com\/electronicsguy\/ESP8266\" target=\"_blank\">HTTPSRedirect<\/a>\u00a0<\/strong>library makes the task much simpler by avoiding the need of any third party service. So, the first thing you need to do is to copy the HTTPSRedirect library files from GitHub and install into your Arduino libraries folder. I have also posted\u00a0the zipped library files at the following link for convenience.<\/p>\n<div>\n<strong><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2016\/11\/HTTPSRedirect1.zip\">Download HTTPSRedirect Library<\/a><\/p>\n<div style=\"color:red;\">Update: The above library is outdated.<\/div>\n<p> Please go to <a href=\"https:\/\/github.com\/electronicsguy\/ESP8266\">GitHub Sujay Phadke<\/a> and download the updated library. Thanks Sujay.<\/strong><\/div>\n<p>In order to install it on your machine, simply download the above zipped file, unzip it, and move the folder named\u00a0<strong>HTTPSRedirect<\/strong> into your Arduino&#8217;s libraries location. On Windows PC, it typically goes to <strong>C:\\Users\\\\Documents\\Arduino\\libraries\\\u000b<\/strong>.<\/p>\n<h5><\/h5>\n<div id=\"attachment_12567\" style=\"width: 842px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2016\/11\/LibraryPath.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-12567\" class=\"size-full wp-image-12567\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2016\/11\/LibraryPath.png\" alt=\"Arduino IDE Library Path\" width=\"832\" height=\"219\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2016\/11\/LibraryPath.png 832w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2016\/11\/LibraryPath-580x153.png 580w\" sizes=\"auto, (max-width: 832px) 100vw, 832px\" \/><\/a><p id=\"caption-attachment-12567\" class=\"wp-caption-text\">Arduino IDE Library Path on a Windows PC<\/p><\/div>\n<p>Make sure both HTTPSRedirect.cpp and HTTPSRedirect.h files exist inside the copied library folder as shown above.<\/p>\n<h5>Program ESP8266 to send data to Google Sheets<\/h5>\n<p>Posted below is the ESP8266 code written using Arduino IDE for reading the soil moisture sensor output and posting it to a\u00a0Google Sheet on your Google Drive. In order to make it work for your case, you will need to update the <em><strong>ssid<\/strong><\/em> and <em><strong>password<\/strong><\/em> matching to your WiFi network. Also, you will also need to get the\u00a0<em><strong>*GScriptId<\/strong>,<\/em>\u00a0which can only be obtained after publishing the required Google App Scripts. The process of obtaining the\u00a0<strong><em>*GScriptId<\/em><\/strong> is explained towards the bottom of this tutorial. The sensor data are\u00a0posted to the Google sheet every 15 minutes.<\/p>\n<p><span class=\"anir_code_comment\">\/\/ BY: Akshaya Niraula<\/span> <br \/>\n<span class=\"anir_code_comment\">\/\/ ON: Nov 11, 2016<\/span> <br \/>\n<span class=\"anir_code_comment\">\/\/ AT: <\/span><u><span class=\"anir_code_comment\">http:\/\/www.embedded-lab.com\/<\/span><\/u><span class=\"anir_code_comment\"><\/span> <\/p>\n<p><span class=\"anir_code_define\">#include<\/span> <span class=\"anir_code_comment\">&lt;<\/span><span class=\"anir_code_braces\">ESP8266WiFi<\/span><span class=\"anir_code_comment\">.<\/span><span class=\"anir_code_braces\">h<\/span><span class=\"anir_code_comment\">&gt;<\/span> <br \/>\n<span class=\"anir_code_define\">#include<\/span> <span class=\"anir_code_string\">&#8220;HTTPSRedirect.h&#8221;<\/span> <\/p>\n<p><span class=\"anir_code_modifiers\">const<\/span> <span class=\"anir_code_modifiers\">char<\/span><span class=\"anir_code_comment\">*<\/span> <span class=\"anir_code_braces\">ssid<\/span> <span class=\"anir_code_comment\">=<\/span> <span class=\"anir_code_string\">&#8220;&#8211;Your-SSID&#8211;&#8220;<\/span><span class=\"anir_code_braces\">;<\/span> <br \/>\n<span class=\"anir_code_modifiers\">const<\/span> <span class=\"anir_code_modifiers\">char<\/span><span class=\"anir_code_comment\">*<\/span> <span class=\"anir_code_braces\">password<\/span> <span class=\"anir_code_comment\">=<\/span> <span class=\"anir_code_string\">&#8220;&#8211;Your-Password&#8211;&#8220;<\/span><span class=\"anir_code_braces\">;<\/span> <\/p>\n<p><span class=\"anir_code_comment\">\/\/ The ID below comes from Google Sheets.<\/span> <br \/>\n<span class=\"anir_code_comment\">\/\/ Towards the bottom of this page, it will explain how this can be obtained<\/span> <br \/>\n<span class=\"anir_code_modifiers\">const<\/span> <span class=\"anir_code_modifiers\">char<\/span> <span class=\"anir_code_comment\">*<\/span><span class=\"anir_code_braces\">GScriptId<\/span> <span class=\"anir_code_comment\">=<\/span> <span class=\"anir_code_string\">&#8220;&#8212;Your-Google-Script-ID&#8211;=&#8221;<\/span><span class=\"anir_code_braces\">;<\/span> <\/p>\n<p><span class=\"anir_code_comment\">\/\/ Push data on this interval<\/span> <br \/>\n<span class=\"anir_code_modifiers\">const<\/span> <span class=\"anir_code_modifiers\">int<\/span> <span class=\"anir_code_braces\">dataPostDelay<\/span> <span class=\"anir_code_comment\">=<\/span> <span class=\"anir_code_braces\">900000<\/span><span class=\"anir_code_braces\">;<\/span> &nbsp;&nbsp;&nbsp;&nbsp;<span class=\"anir_code_comment\">\/\/ 15 minutes = 15 * 60 * 1000<\/span> <\/p>\n<p><span class=\"anir_code_modifiers\">const<\/span> <span class=\"anir_code_modifiers\">char<\/span><span class=\"anir_code_comment\">*<\/span> <span class=\"anir_code_braces\">host<\/span> <span class=\"anir_code_comment\">=<\/span> <span class=\"anir_code_string\">&#8220;script.google.com&#8221;<\/span><span class=\"anir_code_braces\">;<\/span> <br \/>\n<span class=\"anir_code_modifiers\">const<\/span> <span class=\"anir_code_modifiers\">char<\/span><span class=\"anir_code_comment\">*<\/span> <span class=\"anir_code_braces\">googleRedirHost<\/span> <span class=\"anir_code_comment\">=<\/span> <span class=\"anir_code_string\">&#8220;script.googleusercontent.com&#8221;<\/span><span class=\"anir_code_braces\">;<\/span> <\/p>\n<p><span class=\"anir_code_modifiers\">const<\/span> <span class=\"anir_code_modifiers\">int<\/span> <span class=\"anir_code_braces\">httpsPort<\/span> <span class=\"anir_code_comment\">=<\/span> &nbsp;&nbsp;&nbsp;&nbsp;<span class=\"anir_code_braces\">443<\/span><span class=\"anir_code_braces\">;<\/span> <br \/>\n<span class=\"anir_code_braces\">HTTPSRedirect<\/span> <span class=\"anir_code_braces\">client<\/span><span class=\"anir_code_braces\">(<\/span><span class=\"anir_code_braces\">httpsPort<\/span><span class=\"anir_code_braces\">)<\/span><span class=\"anir_code_braces\">;<\/span> <\/p>\n<p><span class=\"anir_code_comment\">\/\/ Prepare the url (without the varying data)<\/span> <br \/>\n<span class=\"anir_code_modifiers\">String<\/span> <span class=\"anir_code_braces\">url<\/span> <span class=\"anir_code_comment\">=<\/span> <span class=\"anir_code_modifiers\">String<\/span><span class=\"anir_code_braces\">(<\/span><span class=\"anir_code_string\">&#8220;\/macros\/s\/&#8221;<\/span><span class=\"anir_code_braces\">)<\/span> <span class=\"anir_code_comment\">+<\/span> <span class=\"anir_code_braces\">GScriptId<\/span> <span class=\"anir_code_comment\">+<\/span> <span class=\"anir_code_string\">&#8220;\/exec?&#8221;<\/span><span class=\"anir_code_braces\">;<\/span> <\/p>\n<p><span class=\"anir_code_modifiers\">const<\/span> <span class=\"anir_code_modifiers\">char<\/span><span class=\"anir_code_comment\">*<\/span> <span class=\"anir_code_braces\">fingerprint<\/span> <span class=\"anir_code_comment\">=<\/span> <span class=\"anir_code_string\">&#8220;F0 5C 74 77 3F 6B 25 D7 3B 66 4D 43 2F 7E BC 5B E9 28 86 AD&#8221;<\/span><span class=\"anir_code_braces\">;<\/span> <\/p>\n<p><span class=\"anir_code_comment\">\/\/ We will take analog input from A0 pin <\/span> <br \/>\n<span class=\"anir_code_modifiers\">const<\/span> <span class=\"anir_code_modifiers\">int<\/span> <span class=\"anir_code_braces\">AnalogIn<\/span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"anir_code_comment\">=<\/span> <span class=\"anir_code_braces\">A0<\/span><span class=\"anir_code_braces\">;<\/span>  <\/p>\n<p><span class=\"anir_code_modifiers\">void<\/span> <span class=\"anir_code_define\">setup<\/span><span class=\"anir_code_braces\">(<\/span><span class=\"anir_code_braces\">)<\/span> <span class=\"anir_code_braces\">{<\/span> <br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;<b><span class=\"anir_code_methods\">Serial<\/span><\/b><span class=\"anir_code_comment\">.<\/span><span class=\"anir_code_methods\">begin<\/span><span class=\"anir_code_braces\">(<\/span><span class=\"anir_code_braces\">115200<\/span><span class=\"anir_code_braces\">)<\/span><span class=\"anir_code_braces\">;<\/span> <br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;<b><span class=\"anir_code_methods\">Serial<\/span><\/b><span class=\"anir_code_comment\">.<\/span><span class=\"anir_code_methods\">println<\/span><span class=\"anir_code_braces\">(<\/span><span class=\"anir_code_string\">&#8220;Connecting to wifi: &#8220;<\/span><span class=\"anir_code_braces\">)<\/span><span class=\"anir_code_braces\">;<\/span> <br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;<b><span class=\"anir_code_methods\">Serial<\/span><\/b><span class=\"anir_code_comment\">.<\/span><span class=\"anir_code_methods\">println<\/span><span class=\"anir_code_braces\">(<\/span><span class=\"anir_code_braces\">ssid<\/span><span class=\"anir_code_braces\">)<\/span><span class=\"anir_code_braces\">;<\/span> <br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;<b><span class=\"anir_code_methods\">Serial<\/span><\/b><span class=\"anir_code_comment\">.<\/span><span class=\"anir_code_methods\">flush<\/span><span class=\"anir_code_braces\">(<\/span><span class=\"anir_code_braces\">)<\/span><span class=\"anir_code_braces\">;<\/span> <\/p>\n<p> &nbsp;&nbsp;&nbsp;&nbsp;<b><span class=\"anir_code_methods\">WiFi<\/span><\/b><span class=\"anir_code_comment\">.<\/span><span class=\"anir_code_methods\">begin<\/span><span class=\"anir_code_braces\">(<\/span><span class=\"anir_code_braces\">ssid<\/span><span class=\"anir_code_comment\">,<\/span> <span class=\"anir_code_braces\">password<\/span><span class=\"anir_code_braces\">)<\/span><span class=\"anir_code_braces\">;<\/span> <br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;<span class=\"anir_code_define\">while<\/span> <span class=\"anir_code_braces\">(<\/span><b><span class=\"anir_code_methods\">WiFi<\/span><\/b><span class=\"anir_code_comment\">.<\/span><span class=\"anir_code_methods\">status<\/span><span class=\"anir_code_braces\">(<\/span><span class=\"anir_code_braces\">)<\/span> <span class=\"anir_code_comment\">!=<\/span> <span class=\"anir_code_braces\">WL_CONNECTED<\/span><span class=\"anir_code_braces\">)<\/span> <span class=\"anir_code_braces\">{<\/span> <br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"anir_code_methods\">delay<\/span><span class=\"anir_code_braces\">(<\/span><span class=\"anir_code_braces\">500<\/span><span class=\"anir_code_braces\">)<\/span><span class=\"anir_code_braces\">;<\/span> <br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b><span class=\"anir_code_methods\">Serial<\/span><\/b><span class=\"anir_code_comment\">.<\/span><span class=\"anir_code_methods\">print<\/span><span class=\"anir_code_braces\">(<\/span><span class=\"anir_code_string\">&#8220;.&#8221;<\/span><span class=\"anir_code_braces\">)<\/span><span class=\"anir_code_braces\">;<\/span> <br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;<span class=\"anir_code_braces\">}<\/span> <br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;<b><span class=\"anir_code_methods\">Serial<\/span><\/b><span class=\"anir_code_comment\">.<\/span><span class=\"anir_code_methods\">println<\/span><span class=\"anir_code_braces\">(<\/span><span class=\"anir_code_string\">&#8221; IP address: &#8220;<\/span><span class=\"anir_code_braces\">)<\/span><span class=\"anir_code_braces\">;<\/span> <br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;<b><span class=\"anir_code_methods\">Serial<\/span><\/b><span class=\"anir_code_comment\">.<\/span><span class=\"anir_code_methods\">println<\/span><span class=\"anir_code_braces\">(<\/span><b><span class=\"anir_code_methods\">WiFi<\/span><\/b><span class=\"anir_code_comment\">.<\/span><span class=\"anir_code_methods\">localIP<\/span><span class=\"anir_code_braces\">(<\/span><span class=\"anir_code_braces\">)<\/span><span class=\"anir_code_braces\">)<\/span><span class=\"anir_code_braces\">;<\/span> <\/p>\n<p> &nbsp;&nbsp;&nbsp;&nbsp; <br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;<b><span class=\"anir_code_methods\">Serial<\/span><\/b><span class=\"anir_code_comment\">.<\/span><span class=\"anir_code_methods\">print<\/span><span class=\"anir_code_braces\">(<\/span><span class=\"anir_code_modifiers\">String<\/span><span class=\"anir_code_braces\">(<\/span><span class=\"anir_code_string\">&#8220;Connecting to &#8220;<\/span><span class=\"anir_code_braces\">)<\/span><span class=\"anir_code_braces\">)<\/span><span class=\"anir_code_braces\">;<\/span> <br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;<b><span class=\"anir_code_methods\">Serial<\/span><\/b><span class=\"anir_code_comment\">.<\/span><span class=\"anir_code_methods\">println<\/span><span class=\"anir_code_braces\">(<\/span><span class=\"anir_code_braces\">host<\/span><span class=\"anir_code_braces\">)<\/span><span class=\"anir_code_braces\">;<\/span> <\/p>\n<p> &nbsp;&nbsp;&nbsp;&nbsp;<span class=\"anir_code_modifiers\">bool<\/span> <span class=\"anir_code_braces\">flag<\/span> <span class=\"anir_code_comment\">=<\/span> <span class=\"anir_code_modifiers\">false<\/span><span class=\"anir_code_braces\">;<\/span> <br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;<span class=\"anir_code_define\">for<\/span> <span class=\"anir_code_braces\">(<\/span><span class=\"anir_code_modifiers\">int<\/span> <span class=\"anir_code_braces\">i<\/span><span class=\"anir_code_comment\">=<\/span><span class=\"anir_code_braces\">0<\/span><span class=\"anir_code_braces\">;<\/span> <span class=\"anir_code_braces\">i<\/span><span class=\"anir_code_comment\">&lt;<\/span><span class=\"anir_code_braces\">5<\/span><span class=\"anir_code_braces\">;<\/span> <span class=\"anir_code_braces\">i<\/span><span class=\"anir_code_comment\">++<\/span><span class=\"anir_code_braces\">)<\/span><span class=\"anir_code_braces\">{<\/span> <br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"anir_code_modifiers\">int<\/span> <span class=\"anir_code_braces\">retval<\/span> <span class=\"anir_code_comment\">=<\/span> <span class=\"anir_code_braces\">client<\/span><span class=\"anir_code_comment\">.<\/span><span class=\"anir_code_methods\">connect<\/span><span class=\"anir_code_braces\">(<\/span><span class=\"anir_code_braces\">host<\/span><span class=\"anir_code_comment\">,<\/span> <span class=\"anir_code_braces\">httpsPort<\/span><span class=\"anir_code_braces\">)<\/span><span class=\"anir_code_braces\">;<\/span> <br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"anir_code_define\">if<\/span> <span class=\"anir_code_braces\">(<\/span><span class=\"anir_code_braces\">retval<\/span> <span class=\"anir_code_comment\">==<\/span> <span class=\"anir_code_braces\">1<\/span><span class=\"anir_code_braces\">)<\/span> <span class=\"anir_code_braces\">{<\/span> <br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"anir_code_braces\">flag<\/span> <span class=\"anir_code_comment\">=<\/span> <span class=\"anir_code_modifiers\">true<\/span><span class=\"anir_code_braces\">;<\/span> <br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"anir_code_define\">break<\/span><span class=\"anir_code_braces\">;<\/span> <br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"anir_code_braces\">}<\/span> <br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"anir_code_define\">else<\/span> <br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b><span class=\"anir_code_methods\">Serial<\/span><\/b><span class=\"anir_code_comment\">.<\/span><span class=\"anir_code_methods\">println<\/span><span class=\"anir_code_braces\">(<\/span><span class=\"anir_code_string\">&#8220;Connection failed. Retrying&#8230;&#8221;<\/span><span class=\"anir_code_braces\">)<\/span><span class=\"anir_code_braces\">;<\/span> <br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;<span class=\"anir_code_braces\">}<\/span> <\/p>\n<p> &nbsp;&nbsp;&nbsp;&nbsp;<span class=\"anir_code_comment\">\/\/ Connection Status, 1 = Connected, 0 is not.<\/span> <br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;<b><span class=\"anir_code_methods\">Serial<\/span><\/b><span class=\"anir_code_comment\">.<\/span><span class=\"anir_code_methods\">println<\/span><span class=\"anir_code_braces\">(<\/span><span class=\"anir_code_string\">&#8220;Connection Status: &#8220;<\/span> <span class=\"anir_code_comment\">+<\/span> <span class=\"anir_code_modifiers\">String<\/span><span class=\"anir_code_braces\">(<\/span><span class=\"anir_code_braces\">client<\/span><span class=\"anir_code_comment\">.<\/span><span class=\"anir_code_methods\">connected<\/span><span class=\"anir_code_braces\">(<\/span><span class=\"anir_code_braces\">)<\/span><span class=\"anir_code_braces\">)<\/span><span class=\"anir_code_braces\">)<\/span><span class=\"anir_code_braces\">;<\/span> <br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;<b><span class=\"anir_code_methods\">Serial<\/span><\/b><span class=\"anir_code_comment\">.<\/span><span class=\"anir_code_methods\">flush<\/span><span class=\"anir_code_braces\">(<\/span><span class=\"anir_code_braces\">)<\/span><span class=\"anir_code_braces\">;<\/span> <br \/>\n &nbsp;&nbsp;&nbsp;&nbsp; <br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;<span class=\"anir_code_define\">if<\/span> <span class=\"anir_code_braces\">(<\/span><span class=\"anir_code_comment\">!<\/span><span class=\"anir_code_braces\">flag<\/span><span class=\"anir_code_braces\">)<\/span><span class=\"anir_code_braces\">{<\/span> <br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b><span class=\"anir_code_methods\">Serial<\/span><\/b><span class=\"anir_code_comment\">.<\/span><span class=\"anir_code_methods\">print<\/span><span class=\"anir_code_braces\">(<\/span><span class=\"anir_code_string\">&#8220;Could not connect to server: &#8220;<\/span><span class=\"anir_code_braces\">)<\/span><span class=\"anir_code_braces\">;<\/span> <br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b><span class=\"anir_code_methods\">Serial<\/span><\/b><span class=\"anir_code_comment\">.<\/span><span class=\"anir_code_methods\">println<\/span><span class=\"anir_code_braces\">(<\/span><span class=\"anir_code_braces\">host<\/span><span class=\"anir_code_braces\">)<\/span><span class=\"anir_code_braces\">;<\/span> <br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b><span class=\"anir_code_methods\">Serial<\/span><\/b><span class=\"anir_code_comment\">.<\/span><span class=\"anir_code_methods\">println<\/span><span class=\"anir_code_braces\">(<\/span><span class=\"anir_code_string\">&#8220;Exiting&#8230;&#8221;<\/span><span class=\"anir_code_braces\">)<\/span><span class=\"anir_code_braces\">;<\/span> <br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b><span class=\"anir_code_methods\">Serial<\/span><\/b><span class=\"anir_code_comment\">.<\/span><span class=\"anir_code_methods\">flush<\/span><span class=\"anir_code_braces\">(<\/span><span class=\"anir_code_braces\">)<\/span><span class=\"anir_code_braces\">;<\/span> <br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"anir_code_define\">return<\/span><span class=\"anir_code_braces\">;<\/span> <br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;<span class=\"anir_code_braces\">}<\/span> <\/p>\n<p> &nbsp;&nbsp;&nbsp;&nbsp;<span class=\"anir_code_comment\">\/\/ Data will still be pushed even certification don&#8217;t match.<\/span> <br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;<span class=\"anir_code_define\">if<\/span> <span class=\"anir_code_braces\">(<\/span><span class=\"anir_code_braces\">client<\/span><span class=\"anir_code_comment\">.<\/span><span class=\"anir_code_braces\">verify<\/span><span class=\"anir_code_braces\">(<\/span><span class=\"anir_code_braces\">fingerprint<\/span><span class=\"anir_code_comment\">,<\/span> <span class=\"anir_code_braces\">host<\/span><span class=\"anir_code_braces\">)<\/span><span class=\"anir_code_braces\">)<\/span> <span class=\"anir_code_braces\">{<\/span> <br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b><span class=\"anir_code_methods\">Serial<\/span><\/b><span class=\"anir_code_comment\">.<\/span><span class=\"anir_code_methods\">println<\/span><span class=\"anir_code_braces\">(<\/span><span class=\"anir_code_string\">&#8220;Certificate match.&#8221;<\/span><span class=\"anir_code_braces\">)<\/span><span class=\"anir_code_braces\">;<\/span> <br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;<span class=\"anir_code_braces\">}<\/span> <span class=\"anir_code_define\">else<\/span> <span class=\"anir_code_braces\">{<\/span> <br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b><span class=\"anir_code_methods\">Serial<\/span><\/b><span class=\"anir_code_comment\">.<\/span><span class=\"anir_code_methods\">println<\/span><span class=\"anir_code_braces\">(<\/span><span class=\"anir_code_string\">&#8220;Certificate mis-match&#8221;<\/span><span class=\"anir_code_braces\">)<\/span><span class=\"anir_code_braces\">;<\/span> <br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;<span class=\"anir_code_braces\">}<\/span> <br \/>\n<span class=\"anir_code_braces\">}<\/span> <\/p>\n<p><span class=\"anir_code_comment\">\/\/ This is the main method where data gets pushed to the Google sheet<\/span> <br \/>\n<span class=\"anir_code_modifiers\">void<\/span> <span class=\"anir_code_braces\">postData<\/span><span class=\"anir_code_braces\">(<\/span><span class=\"anir_code_modifiers\">String<\/span> <span class=\"anir_code_braces\">tag<\/span><span class=\"anir_code_comment\">,<\/span> <span class=\"anir_code_modifiers\">float<\/span> <span class=\"anir_code_braces\">value<\/span><span class=\"anir_code_braces\">)<\/span><span class=\"anir_code_braces\">{<\/span> <br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;<span class=\"anir_code_define\">if<\/span> <span class=\"anir_code_braces\">(<\/span><span class=\"anir_code_comment\">!<\/span><span class=\"anir_code_braces\">client<\/span><span class=\"anir_code_comment\">.<\/span><span class=\"anir_code_methods\">connected<\/span><span class=\"anir_code_braces\">(<\/span><span class=\"anir_code_braces\">)<\/span><span class=\"anir_code_braces\">)<\/span><span class=\"anir_code_braces\">{<\/span> <br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b><span class=\"anir_code_methods\">Serial<\/span><\/b><span class=\"anir_code_comment\">.<\/span><span class=\"anir_code_methods\">println<\/span><span class=\"anir_code_braces\">(<\/span><span class=\"anir_code_string\">&#8220;Connecting to client again&#8230;&#8221;<\/span><span class=\"anir_code_braces\">)<\/span><span class=\"anir_code_braces\">;<\/span>  <br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"anir_code_braces\">client<\/span><span class=\"anir_code_comment\">.<\/span><span class=\"anir_code_methods\">connect<\/span><span class=\"anir_code_braces\">(<\/span><span class=\"anir_code_braces\">host<\/span><span class=\"anir_code_comment\">,<\/span> <span class=\"anir_code_braces\">httpsPort<\/span><span class=\"anir_code_braces\">)<\/span><span class=\"anir_code_braces\">;<\/span> <br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;<span class=\"anir_code_braces\">}<\/span> <br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;<span class=\"anir_code_modifiers\">String<\/span> <span class=\"anir_code_braces\">urlFinal<\/span> <span class=\"anir_code_comment\">=<\/span> <span class=\"anir_code_braces\">url<\/span> <span class=\"anir_code_comment\">+<\/span> <span class=\"anir_code_string\">&#8220;tag=&#8221;<\/span> <span class=\"anir_code_comment\">+<\/span> <span class=\"anir_code_braces\">tag<\/span> <span class=\"anir_code_comment\">+<\/span> <span class=\"anir_code_string\">&#8220;&#038;value=&#8221;<\/span> <span class=\"anir_code_comment\">+<\/span> <span class=\"anir_code_modifiers\">String<\/span><span class=\"anir_code_braces\">(<\/span><span class=\"anir_code_braces\">value<\/span><span class=\"anir_code_braces\">)<\/span><span class=\"anir_code_braces\">;<\/span> <br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;<span class=\"anir_code_braces\">client<\/span><span class=\"anir_code_comment\">.<\/span><span class=\"anir_code_braces\">printRedir<\/span><span class=\"anir_code_braces\">(<\/span><span class=\"anir_code_braces\">urlFinal<\/span><span class=\"anir_code_comment\">,<\/span> <span class=\"anir_code_braces\">host<\/span><span class=\"anir_code_comment\">,<\/span> <span class=\"anir_code_braces\">googleRedirHost<\/span><span class=\"anir_code_braces\">)<\/span><span class=\"anir_code_braces\">;<\/span> <br \/>\n<span class=\"anir_code_braces\">}<\/span> <\/p>\n<p><span class=\"anir_code_comment\">\/\/ Continue pushing data at a given interval<\/span> <br \/>\n<span class=\"anir_code_modifiers\">void<\/span> <span class=\"anir_code_define\">loop<\/span><span class=\"anir_code_braces\">(<\/span><span class=\"anir_code_braces\">)<\/span> <span class=\"anir_code_braces\">{<\/span> <br \/>\n &nbsp;&nbsp;&nbsp;&nbsp; <br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;<span class=\"anir_code_comment\">\/\/ Read analog value, in this case a soil moisture<\/span> <br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;<span class=\"anir_code_modifiers\">int<\/span> <span class=\"anir_code_braces\">data<\/span> <span class=\"anir_code_comment\">=<\/span> <span class=\"anir_code_braces\">1023<\/span> <span class=\"anir_code_comment\">&#8211;<\/span> <span class=\"anir_code_methods\">analogRead<\/span><span class=\"anir_code_braces\">(<\/span><span class=\"anir_code_braces\">AnalogIn<\/span><span class=\"anir_code_braces\">)<\/span><span class=\"anir_code_braces\">;<\/span> <\/p>\n<p> &nbsp;&nbsp;&nbsp;&nbsp;<span class=\"anir_code_comment\">\/\/ Post these information<\/span> <br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;<span class=\"anir_code_braces\">postData<\/span><span class=\"anir_code_braces\">(<\/span><span class=\"anir_code_string\">&#8220;SoilMoisture&#8221;<\/span><span class=\"anir_code_comment\">,<\/span> <span class=\"anir_code_braces\">data<\/span><span class=\"anir_code_braces\">)<\/span><span class=\"anir_code_braces\">;<\/span> <br \/>\n &nbsp;&nbsp;&nbsp;&nbsp; <br \/>\n &nbsp;&nbsp;&nbsp;&nbsp;<span class=\"anir_code_methods\">delay<\/span> <span class=\"anir_code_braces\">(<\/span><span class=\"anir_code_braces\">dataPostDelay<\/span><span class=\"anir_code_braces\">)<\/span><span class=\"anir_code_braces\">;<\/span> <br \/>\n<span class=\"anir_code_braces\">}<\/span> <\/p>\n<p>You can also download the NodeMCU code from the following link.<\/p>\n<h5><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2016\/11\/PostDataToGoogleSheet1.zip\">Download NodeMCU code<\/a><\/h5>\n<h5>Create Google Sheets<\/h5>\n<p>Create a Google spreadsheet in your\u00a0Google Drive and name it something like <strong>DataCollector<\/strong>. Rename the current\/active sheet to <strong>Summary <\/strong>and add a second sheet, call it <strong>DataLogger<\/strong>. From the URL address bar of the sheet, copy the string between d\/ and \/edit and save it somewhere. This is your spreadsheet&#8217;s unique sharing key, which will be needed in the Google Apps scripts later.<\/p>\n<div id=\"attachment_12678\" style=\"width: 888px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2016\/11\/datasheetURL.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-12678\" class=\"size-full wp-image-12678\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2016\/11\/datasheetURL.png\" alt=\"Spreadsheet URL \" width=\"878\" height=\"191\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2016\/11\/datasheetURL.png 878w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2016\/11\/datasheetURL-580x126.png 580w\" sizes=\"auto, (max-width: 878px) 100vw, 878px\" \/><\/a><p id=\"caption-attachment-12678\" class=\"wp-caption-text\">Unique sharing key for your Google spreadsheet can be found in the URL<\/p><\/div>\n<p><span style=\"color: #ff0000;\"><strong>Note: <\/strong><\/span> The name of the Google spreadsheet does not matter much because\u00a0we will be using the sharing key\u00a0of\u00a0the sheet, which is unique, in the Google Apps Scripts to access it. However, the sheets name (<strong>Summary <\/strong>and<strong> DataLogger<\/strong>) have to match with what you put in your\u00a0Google Apps Scripts (described later).<\/p>\n<p>In the Summary sheet, type <em><strong>Last Modified On<\/strong><\/em>\u00a0on cell\u00a0<strong>A1<\/strong>, <em><strong>DataLogger Count<\/strong><\/em> on <strong>A2<\/strong>, and <em><strong>Next Read Time<\/strong><\/em> on <strong>A3<\/strong>. In cell\u00a0<strong>B2<\/strong>, type a formula that will give us the data count &#8216;<em>=counta(DataLogger!D:D) -1<\/em>&#8216; In <strong>B3<\/strong>, type this equation, <em>=B1 + TimeValue(&#8220;00:15&#8221;)<\/em>, which will simply add 15 minute to last modified date time. To support a gauge chart in Google Sheets, some information from A6 to B7 has been added, as showing in the image below<\/p>\n<div id=\"attachment_12624\" style=\"width: 678px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2016\/11\/GoogleSheets1.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-12624\" class=\"size-full wp-image-12624\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2016\/11\/GoogleSheets1.png\" alt=\"Goolge Sheets - Summary tag\" width=\"668\" height=\"335\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2016\/11\/GoogleSheets1.png 668w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2016\/11\/GoogleSheets1-580x291.png 580w\" sizes=\"auto, (max-width: 668px) 100vw, 668px\" \/><\/a><p id=\"caption-attachment-12624\" class=\"wp-caption-text\">Goolge Sheets &#8211; Summary tag<\/p><\/div>\n<p>In the <strong>DataLogger <\/strong>sheet, type\u00a0<strong>ID, DateTime, Tag, and Value<\/strong> in <strong>A1, B1, C1 and D1<\/strong>, respectively.<\/p>\n<div id=\"attachment_12625\" style=\"width: 785px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2016\/11\/GoogleSheets_DataLogger.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-12625\" class=\"size-full wp-image-12625\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2016\/11\/GoogleSheets_DataLogger.png\" alt=\"Google Sheets Data Logger Tab\" width=\"775\" height=\"326\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2016\/11\/GoogleSheets_DataLogger.png 775w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2016\/11\/GoogleSheets_DataLogger-580x244.png 580w\" sizes=\"auto, (max-width: 775px) 100vw, 775px\" \/><\/a><p id=\"caption-attachment-12625\" class=\"wp-caption-text\">Google Sheets Data Logger Tab<\/p><\/div>\n<h5>Google Apps Scripts<\/h5>\n<p>To create a Google App Scripts, go to <strong>Tools &gt; Script Editor<\/strong> from the Google Sheets. In the code section, paste the code below. The code or script can be saved under any name.<\/p>\n\n<div class=\"wp_syntax\"><table><tr><td class=\"code\"><pre class=\"javascript\" style=\"font-family:monospace;\"><span style=\"color: #006600; font-style: italic;\">\/\/ BY: Akshaya Niraula<\/span>\n<span style=\"color: #006600; font-style: italic;\">\/\/ ON: 2016 November 12th.<\/span>\n<span style=\"color: #006600; font-style: italic;\">\/\/ AT: http:\/\/www.embedded-lab.com\/.....<\/span>\n&nbsp;\n&nbsp;\n<span style=\"color: #006600; font-style: italic;\">\/\/ Steps are valid as of 2016 November 12th.<\/span>\n<span style=\"color: #006600; font-style: italic;\">\/\/ 0) From Google spreadsheet, Tools &amp;gt; Scriipt Editor...<\/span>\n<span style=\"color: #006600; font-style: italic;\">\/\/ 1) Write your code<\/span>\n<span style=\"color: #006600; font-style: italic;\">\/\/ 2) Save and give a meaningful name<\/span>\n<span style=\"color: #006600; font-style: italic;\">\/\/ 3) Run and make sure &quot;doGet&quot; is selected<\/span>\n<span style=\"color: #006600; font-style: italic;\">\/\/    You can set a method from Run menu<\/span>\n<span style=\"color: #006600; font-style: italic;\">\/\/ 4) When you run for the first time, it will ask <\/span>\n<span style=\"color: #006600; font-style: italic;\">\/\/    for the permission. You must allow it.<\/span>\n<span style=\"color: #006600; font-style: italic;\">\/\/    Make sure everything is working as it should.<\/span>\n<span style=\"color: #006600; font-style: italic;\">\/\/ 5) From Publish menu &amp;gt; Deploy as Web App...<\/span>\n<span style=\"color: #006600; font-style: italic;\">\/\/    Select a new version everytime it's published<\/span>\n<span style=\"color: #006600; font-style: italic;\">\/\/    Type comments next to the version<\/span>\n<span style=\"color: #006600; font-style: italic;\">\/\/    Execute as: &quot;Me (your email address)&quot;<\/span>\n<span style=\"color: #006600; font-style: italic;\">\/\/    MUST: Select &quot;Anyone, even anonymous&quot; on &quot;Who has access to this script&quot;<\/span>\n<span style=\"color: #006600; font-style: italic;\">\/\/    For the first time it will give you some prompt(s), accept it.<\/span>\n<span style=\"color: #006600; font-style: italic;\">\/\/    You will need the given information (url) later. This doesn't change, ever!<\/span>\n&nbsp;\n<span style=\"color: #006600; font-style: italic;\">\/\/ Saving the published URL helps for later.<\/span>\n<span style=\"color: #006600; font-style: italic;\">\/\/ https:\/\/script.google.com\/macros\/s\/---Your-Script-ID--Goes-Here---\/exec<\/span>\n<span style=\"color: #006600; font-style: italic;\">\/\/ https:\/\/script.google.com\/macros\/s\/---Your-Script-ID--Goes-Here---\/exec?tag=test&amp;amp;value=-1<\/span>\n&nbsp;\n<span style=\"color: #006600; font-style: italic;\">\/\/ This method will be called first or hits first  <\/span>\n<span style=\"color: #000066; font-weight: bold;\">function<\/span> doGet<span style=\"color: #009900;\">&#40;<\/span>e<span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #009900;\">&#123;<\/span>\n  Logger.<span style=\"color: #660066;\">log<\/span><span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #3366CC;\">&quot;--- doGet ---&quot;<\/span><span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #339933;\">;<\/span>\n&nbsp;\n <span style=\"color: #000066; font-weight: bold;\">var<\/span> tag <span style=\"color: #339933;\">=<\/span> <span style=\"color: #3366CC;\">&quot;&quot;<\/span><span style=\"color: #339933;\">,<\/span>\n     value <span style=\"color: #339933;\">=<\/span> <span style=\"color: #3366CC;\">&quot;&quot;<\/span><span style=\"color: #339933;\">;<\/span>\n&nbsp;\n  <span style=\"color: #000066; font-weight: bold;\">try<\/span> <span style=\"color: #009900;\">&#123;<\/span>\n&nbsp;\n    <span style=\"color: #006600; font-style: italic;\">\/\/ this helps during debuggin<\/span>\n    <span style=\"color: #000066; font-weight: bold;\">if<\/span> <span style=\"color: #009900;\">&#40;<\/span>e <span style=\"color: #339933;\">==<\/span> <span style=\"color: #003366; font-weight: bold;\">null<\/span><span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #009900;\">&#123;<\/span>e<span style=\"color: #339933;\">=<\/span><span style=\"color: #009900;\">&#123;<\/span><span style=\"color: #009900;\">&#125;<\/span><span style=\"color: #339933;\">;<\/span> e.<span style=\"color: #660066;\">parameters<\/span> <span style=\"color: #339933;\">=<\/span> <span style=\"color: #009900;\">&#123;<\/span>tag<span style=\"color: #339933;\">:<\/span><span style=\"color: #3366CC;\">&quot;test&quot;<\/span><span style=\"color: #339933;\">,<\/span>value<span style=\"color: #339933;\">:<\/span><span style=\"color: #3366CC;\">&quot;-1&quot;<\/span><span style=\"color: #009900;\">&#125;<\/span><span style=\"color: #339933;\">;<\/span><span style=\"color: #009900;\">&#125;<\/span>\n&nbsp;\n    tag <span style=\"color: #339933;\">=<\/span> e.<span style=\"color: #660066;\">parameters<\/span>.<span style=\"color: #660066;\">tag<\/span><span style=\"color: #339933;\">;<\/span>\n    value <span style=\"color: #339933;\">=<\/span> e.<span style=\"color: #660066;\">parameters<\/span>.<span style=\"color: #660066;\">value<\/span><span style=\"color: #339933;\">;<\/span>\n&nbsp;\n    <span style=\"color: #006600; font-style: italic;\">\/\/ save the data to spreadsheet<\/span>\n    save_data<span style=\"color: #009900;\">&#40;<\/span>tag<span style=\"color: #339933;\">,<\/span> value<span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #339933;\">;<\/span>\n&nbsp;\n&nbsp;\n    <span style=\"color: #000066; font-weight: bold;\">return<\/span> ContentService.<span style=\"color: #660066;\">createTextOutput<\/span><span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #3366CC;\">&quot;Wrote:<span style=\"color: #000099; font-weight: bold;\">\\n<\/span>  tag: &quot;<\/span> <span style=\"color: #339933;\">+<\/span> tag <span style=\"color: #339933;\">+<\/span> <span style=\"color: #3366CC;\">&quot;<span style=\"color: #000099; font-weight: bold;\">\\n<\/span>  value: &quot;<\/span> <span style=\"color: #339933;\">+<\/span> value<span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #339933;\">;<\/span>\n&nbsp;\n  <span style=\"color: #009900;\">&#125;<\/span> <span style=\"color: #000066; font-weight: bold;\">catch<\/span><span style=\"color: #009900;\">&#40;<\/span>error<span style=\"color: #009900;\">&#41;<\/span> <span style=\"color: #009900;\">&#123;<\/span> \n    Logger.<span style=\"color: #660066;\">log<\/span><span style=\"color: #009900;\">&#40;<\/span>error<span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #339933;\">;<\/span>    \n    <span style=\"color: #000066; font-weight: bold;\">return<\/span> ContentService.<span style=\"color: #660066;\">createTextOutput<\/span><span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #3366CC;\">&quot;oops....&quot;<\/span> <span style=\"color: #339933;\">+<\/span> error.<span style=\"color: #660066;\">message<\/span> \n                                            <span style=\"color: #339933;\">+<\/span> <span style=\"color: #3366CC;\">&quot;<span style=\"color: #000099; font-weight: bold;\">\\n<\/span>&quot;<\/span> <span style=\"color: #339933;\">+<\/span> <span style=\"color: #000066; font-weight: bold;\">new<\/span> <span style=\"\">Date<\/span><span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #009900;\">&#41;<\/span> \n                                            <span style=\"color: #339933;\">+<\/span> <span style=\"color: #3366CC;\">&quot;<span style=\"color: #000099; font-weight: bold;\">\\n<\/span>tag: &quot;<\/span> <span style=\"color: #339933;\">+<\/span> tag <span style=\"color: #339933;\">+<\/span>\n                                            <span style=\"color: #339933;\">+<\/span> <span style=\"color: #3366CC;\">&quot;<span style=\"color: #000099; font-weight: bold;\">\\n<\/span>value: &quot;<\/span> <span style=\"color: #339933;\">+<\/span> value<span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #339933;\">;<\/span>\n  <span style=\"color: #009900;\">&#125;<\/span>  \n<span style=\"color: #009900;\">&#125;<\/span>\n&nbsp;\n<span style=\"color: #006600; font-style: italic;\">\/\/ Method to save given data to a sheet<\/span>\n<span style=\"color: #000066; font-weight: bold;\">function<\/span> save_data<span style=\"color: #009900;\">&#40;<\/span>tag<span style=\"color: #339933;\">,<\/span> value<span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #009900;\">&#123;<\/span>\n  Logger.<span style=\"color: #660066;\">log<\/span><span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #3366CC;\">&quot;--- save_data ---&quot;<\/span><span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #339933;\">;<\/span> \n&nbsp;\n&nbsp;\n  <span style=\"color: #000066; font-weight: bold;\">try<\/span> <span style=\"color: #009900;\">&#123;<\/span>\n    <span style=\"color: #000066; font-weight: bold;\">var<\/span> dateTime <span style=\"color: #339933;\">=<\/span> <span style=\"color: #000066; font-weight: bold;\">new<\/span> <span style=\"\">Date<\/span><span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #339933;\">;<\/span>\n&nbsp;\n    <span style=\"color: #006600; font-style: italic;\">\/\/ Paste the URL of the Google Sheets starting from https thru \/edit<\/span>\n    <span style=\"color: #006600; font-style: italic;\">\/\/ For e.g.: https:\/\/docs.google.com\/....\/edit <\/span>\n    <span style=\"color: #000066; font-weight: bold;\">var<\/span> ss <span style=\"color: #339933;\">=<\/span> SpreadsheetApp.<span style=\"color: #660066;\">openByUrl<\/span><span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #3366CC;\">&quot;https:\/\/docs.google.com\/spreadsheets\/d\/---Your-Google-Sheet-ID--Goes-Here---\/edit&quot;<\/span><span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #339933;\">;<\/span>\n    <span style=\"color: #000066; font-weight: bold;\">var<\/span> summarySheet <span style=\"color: #339933;\">=<\/span> ss.<span style=\"color: #660066;\">getSheetByName<\/span><span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #3366CC;\">&quot;Summary&quot;<\/span><span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #339933;\">;<\/span>\n    <span style=\"color: #000066; font-weight: bold;\">var<\/span> dataLoggerSheet <span style=\"color: #339933;\">=<\/span> ss.<span style=\"color: #660066;\">getSheetByName<\/span><span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #3366CC;\">&quot;DataLogger&quot;<\/span><span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #339933;\">;<\/span>\n&nbsp;\n&nbsp;\n    <span style=\"color: #006600; font-style: italic;\">\/\/ Get last edited row from DataLogger sheet<\/span>\n    <span style=\"color: #000066; font-weight: bold;\">var<\/span> row <span style=\"color: #339933;\">=<\/span> dataLoggerSheet.<span style=\"color: #660066;\">getLastRow<\/span><span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #009900;\">&#41;<\/span> <span style=\"color: #339933;\">+<\/span> <span style=\"color: #CC0000;\">1<\/span><span style=\"color: #339933;\">;<\/span>\n&nbsp;\n&nbsp;\n    <span style=\"color: #006600; font-style: italic;\">\/\/ Start Populating the data<\/span>\n    dataLoggerSheet.<span style=\"color: #660066;\">getRange<\/span><span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #3366CC;\">&quot;A&quot;<\/span> <span style=\"color: #339933;\">+<\/span> row<span style=\"color: #009900;\">&#41;<\/span>.<span style=\"color: #660066;\">setValue<\/span><span style=\"color: #009900;\">&#40;<\/span>row <span style=\"color: #339933;\">-<\/span><span style=\"color: #CC0000;\">1<\/span><span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #339933;\">;<\/span> <span style=\"color: #006600; font-style: italic;\">\/\/ ID<\/span>\n    dataLoggerSheet.<span style=\"color: #660066;\">getRange<\/span><span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #3366CC;\">&quot;B&quot;<\/span> <span style=\"color: #339933;\">+<\/span> row<span style=\"color: #009900;\">&#41;<\/span>.<span style=\"color: #660066;\">setValue<\/span><span style=\"color: #009900;\">&#40;<\/span>dateTime<span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #339933;\">;<\/span> <span style=\"color: #006600; font-style: italic;\">\/\/ dateTime<\/span>\n    dataLoggerSheet.<span style=\"color: #660066;\">getRange<\/span><span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #3366CC;\">&quot;C&quot;<\/span> <span style=\"color: #339933;\">+<\/span> row<span style=\"color: #009900;\">&#41;<\/span>.<span style=\"color: #660066;\">setValue<\/span><span style=\"color: #009900;\">&#40;<\/span>tag<span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #339933;\">;<\/span> <span style=\"color: #006600; font-style: italic;\">\/\/ tag<\/span>\n    dataLoggerSheet.<span style=\"color: #660066;\">getRange<\/span><span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #3366CC;\">&quot;D&quot;<\/span> <span style=\"color: #339933;\">+<\/span> row<span style=\"color: #009900;\">&#41;<\/span>.<span style=\"color: #660066;\">setValue<\/span><span style=\"color: #009900;\">&#40;<\/span>value<span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #339933;\">;<\/span> <span style=\"color: #006600; font-style: italic;\">\/\/ value<\/span>\n&nbsp;\n&nbsp;\n    <span style=\"color: #006600; font-style: italic;\">\/\/ Update summary sheet<\/span>\n    summarySheet.<span style=\"color: #660066;\">getRange<\/span><span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #3366CC;\">&quot;B1&quot;<\/span><span style=\"color: #009900;\">&#41;<\/span>.<span style=\"color: #660066;\">setValue<\/span><span style=\"color: #009900;\">&#40;<\/span>dateTime<span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #339933;\">;<\/span> <span style=\"color: #006600; font-style: italic;\">\/\/ Last modified date<\/span>\n    <span style=\"color: #006600; font-style: italic;\">\/\/ summarySheet.getRange(&quot;B2&quot;).setValue(row - 1); \/\/ Count <\/span>\n  <span style=\"color: #009900;\">&#125;<\/span>\n&nbsp;\n  <span style=\"color: #000066; font-weight: bold;\">catch<\/span><span style=\"color: #009900;\">&#40;<\/span>error<span style=\"color: #009900;\">&#41;<\/span> <span style=\"color: #009900;\">&#123;<\/span>\n    Logger.<span style=\"color: #660066;\">log<\/span><span style=\"color: #009900;\">&#40;<\/span>JSON.<span style=\"color: #660066;\">stringify<\/span><span style=\"color: #009900;\">&#40;<\/span>error<span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #339933;\">;<\/span>\n  <span style=\"color: #009900;\">&#125;<\/span>\n&nbsp;\n  Logger.<span style=\"color: #660066;\">log<\/span><span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #3366CC;\">&quot;--- save_data end---&quot;<\/span><span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #339933;\">;<\/span> \n<span style=\"color: #009900;\">&#125;<\/span><\/pre><\/td><\/tr><\/table><\/div>\n\n<p><strong><span style=\"color: #ff0000;\">Important Note:<\/span><\/strong> In the above script, the sheet names should\u00a0match to those we want to be populated.<\/p>\n\n<div class=\"wp_syntax\"><table><tr><td class=\"code\"><pre class=\"javascript\" style=\"font-family:monospace;\">    <span style=\"color: #000066; font-weight: bold;\">var<\/span> summarySheet <span style=\"color: #339933;\">=<\/span> ss.<span style=\"color: #660066;\">getSheetByName<\/span><span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #3366CC;\">&quot;Summary&quot;<\/span><span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #339933;\">;<\/span>\n    <span style=\"color: #000066; font-weight: bold;\">var<\/span> dataLoggerSheet <span style=\"color: #339933;\">=<\/span> ss.<span style=\"color: #660066;\">getSheetByName<\/span><span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #3366CC;\">&quot;DataLogger&quot;<\/span><span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #339933;\">;<\/span><\/pre><\/td><\/tr><\/table><\/div>\n\n<p>Similarly, you would also need to edit the spreadsheet sharing key in the script\u00a0to match with yours (one you copied from the spreadsheet URL earlier).<\/p>\n\n<div class=\"wp_syntax\"><table><tr><td class=\"code\"><pre class=\"javascript\" style=\"font-family:monospace;\"><span style=\"color: #000066; font-weight: bold;\">var<\/span> ss <span style=\"color: #339933;\">=<\/span> SpreadsheetApp.<span style=\"color: #660066;\">openByUrl<\/span><span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #3366CC;\">&quot;https:\/\/docs.google.com\/spreadsheets\/d\/---Your-Google-Sheet-ID--Goes-Here---\/edit&quot;<\/span><span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #339933;\">;<\/span><\/pre><\/td><\/tr><\/table><\/div>\n\n<p>Download\u00a0<strong><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2016\/11\/GoolgeAppScripts.zip\">Goolge App Scripts<\/a><\/strong><\/p>\n<h5>Deploy the contents as Web app<\/h5>\n<p>Next step is to\u00a0publish the script so that it is accessible through\u00a0an URL. In order to do that, <strong>Publish &gt; Deploy as Web App<\/strong>.<\/p>\n<p><strong>Note: <\/strong> Whenever you modify your code, you have to create a &#8220;New&#8221; Project version and publish it otherwise you will still be hitting the same old code.<\/p>\n<p>Copy the <em><strong>Current web app URL<\/strong><\/em> and save\u00a0it somewhere as we will need it for extracting the <strong>GScriptID<\/strong>. I usually save it in my\u00a0code as a comment. The web app URL would look like this:<\/p>\n<p>https:\/\/script.google.com\/macros\/s\/&#8211;Your Google Script ID&#8211;\/exec?tag=test&amp;value=-1<\/p>\n<p>The string between s\/ and \/exec? is your\u00a0<strong>GScriptID<\/strong>.<\/p>\n<div id=\"attachment_12634\" style=\"width: 454px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2016\/11\/DeployAsWebApp.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-12634\" class=\"size-full wp-image-12634\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2016\/11\/DeployAsWebApp.png\" alt=\"Deploy As Web App\" width=\"444\" height=\"516\" \/><\/a><p id=\"caption-attachment-12634\" class=\"wp-caption-text\">Deploy As Web App<\/p><\/div>\n<p>During publishing, Google will ask to grant some of the permissions and you need\u00a0to allow those.<\/p>\n<h5>Test the Progress<\/h5>\n<p>If things been followed properly, the following test should go successful. Copy the web app\u00a0URL that you received\u00a0during publishing, format it like shown above and paste this string in your web browser URL field. You should see the following information populated in the <strong>DataLogger<\/strong> sheet as shown below.<\/p>\n<div id=\"attachment_12676\" style=\"width: 519px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2016\/11\/data.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-12676\" class=\"size-full wp-image-12676\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2016\/11\/data.png\" alt=\"Test data posted to Google sheet\" width=\"509\" height=\"238\" \/><\/a><p id=\"caption-attachment-12676\" class=\"wp-caption-text\">Test data posted to Google sheet<\/p><\/div>\n<p>So far so good? If not, double check the steps. If the URL entered in your browser populated the values in your sheet then update your <strong>GScriptID<\/strong> in the ESP8266 code posted earlier.<\/p>\n<h3>Output<\/h3>\n<p>I added a line chart to visualize the time series of sensor data posted on the <strong>DataLogger<\/strong> sheet. The source range for the chart is big enough to cover any new data sent by ESP8266. You can also\u00a0add a gauge to display the most recent soil moisture data.<\/p>\n<div id=\"attachment_12622\" style=\"width: 718px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2016\/11\/GoogleSheetPreView.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-12622\" class=\"size-full wp-image-12622\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2016\/11\/GoogleSheetPreView.png\" alt=\"Charts based on data from ESP8266 on Google Sheets\" width=\"708\" height=\"601\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2016\/11\/GoogleSheetPreView.png 708w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2016\/11\/GoogleSheetPreView-580x492.png 580w\" sizes=\"auto, (max-width: 708px) 100vw, 708px\" \/><\/a><p id=\"caption-attachment-12622\" class=\"wp-caption-text\">Charts based on data posted on DataLogger sheet by NodeMCU<\/p><\/div>\n<p>Here&#8217;s a quick view of the <strong>DataLogger<\/strong> sheet. The moisture data are recorded with time stamps.<\/p>\n<div id=\"attachment_12627\" style=\"width: 663px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2016\/11\/GoogleSheets_DataLogger_Results.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-12627\" class=\"size-full wp-image-12627\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2016\/11\/GoogleSheets_DataLogger_Results.png\" alt=\"Google Sheets Data Logger Tag with data from ESP8266\" width=\"653\" height=\"328\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2016\/11\/GoogleSheets_DataLogger_Results.png 653w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2016\/11\/GoogleSheets_DataLogger_Results-580x291.png 580w\" sizes=\"auto, (max-width: 653px) 100vw, 653px\" \/><\/a><p id=\"caption-attachment-12627\" class=\"wp-caption-text\">Sensor data posted by ESP8266 with a minute interval<\/p><\/div>\n","protected":false},"excerpt":{"rendered":"<p>In the past couple years, the ESP8266 platform has flourished dramatically and emerged as one of the most popular hardware tools among electronics hobbyists and IoT enthusiasts. Packed with a 32-bit RISC CPU running at 80 MHz, a fully integrated WiFi radio with TCP\/IP protocol stack, serial peripherals (I2C, SPI, and UART), an ADC channel, and general purpose I\/O pins, the ESP8266 is the most integrated and affordable WiFi solution available in the current IoT market space. An ESP8266 hardware, like NodeMCU and ESP-01, can directly interface with sensors using its peripherals and upload the sensor measurements to a local<\/p>\n","protected":false},"author":4,"featured_media":12562,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1044,1464,958],"tags":[1321,1569,1570],"class_list":["post-12561","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-esp8266","category-featured","category-internet-of-things","tag-esp8266","tag-google-sheet","tag-moisture-sensor"],"_links":{"self":[{"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/posts\/12561","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/comments?post=12561"}],"version-history":[{"count":41,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/posts\/12561\/revisions"}],"predecessor-version":[{"id":13949,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/posts\/12561\/revisions\/13949"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/media\/12562"}],"wp:attachment":[{"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/media?parent=12561"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/categories?post=12561"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/tags?post=12561"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}