How to use the DHT11/22 sensor to log data to Google Sheets

By this time, you’d probably want a temperature sensor in the house – one less than $25. If you have one, you are probably wanting a better one. Here is an easy solution to this problem.

Things that you’ll need – Hardware

Things that you’ll need – Software

Creating And Deploying The Script

Create a new spreadsheet as shown below:

Once you have got that down go to Tools > Script Editor. We’ll continue from there.

Name the sheet below TempSheet

In the script editor, copy and paste the code given here. Edit the script ID in the code. The script ID is found in the place where “vbn” is in the given URL:

URL

https://docs.google.com/spreadsheets/d/vbn/edit#gid=0

Now go to Publish > Deploy as a web app. The “Project version” will be “New”. Select “your email id” in the “Execute the app as” field. Choose “Anyone, even anonymous” in the “Who has access to the app” field. And then click on “Deploy”. Note that When republishing please select the latest version and then Deploy again. Type “New Script Created” in the “Project Version” field.

You will have to give Google permission to deploy it as a web app. Just click on “Review Permissions”. Then choose your Email ID here using which you have created the spreadsheet.

Click on “Advanced”.

And then click on Go to your_script_name(unsafe). Here in my case, it is “TempLog_Script”.

Click on “Allow” and this will give permission to deploy it as a web app.

Now you can see the new screen with a given link and named “Current web app URL”. This URL contains Google Script ID. Just copy the URL and save it somewhere.

Testing the DHT11/22

Use the given circuit diagram and code:

Diagram:

Code:

C#, C++, C

#include "DHT.h"

#define dht_apin A0

DHT dht;

#define DHTTYPE DHT22 //Change this to any type of DHT Sensor you're Using!

DHT(dht_apin, DHTTYPE);

void setup() {

// put your setup code here, to run once:

Serial.begin(9600); //Starts serial

delay(5000); //Waits before reading from sensor

Serial.println("DHT22 Temp. And Humi. Test"); //Prints the intro

}

void loop() {

// put your main code here, to run repeatedly:

dht.read11(dht_apin); //Reads from the sensor

Serial.println("Humi. ---------- "); //Prints humidity

Serial.print(DHT.humidity); //Prints humidity

Serial.print("% "); //Marks the humidity as %

Serial.print("Temp. ------------ "); //Prints temperature

Serial.print(DHT.temperature); //Prints temperature

Serial.print("℃") //Marks the temperature unit

delay(2000); //Waits 2 seconds before doing the loop again fastest is once evrey 2 seconds

} //end loop

It should be printing the temperature and humidity. If it is not, try running this code at rate 9600 that will print “Hello!” every second to see if you are getting any serial communication at all:

C#, C++, C

#define one_second 1000

#define the_word_hello "Hello!"

void setup() {

// put your setup code here, to run once:

Serial.begin(9600);

delay(5000);

}

void loop() {

// put your main code here, to run repeatedly:

Serial.print(the_word_hello);

delay(one_second);

}

If it is all working, we can move on.

Sign up for our newsletter!

Schematics

As you can see in the picture:

  • D4 pin on the NODEMCU > DATA pin on the DHT11/22
  • GND pin on the NODEMCU > GND pin on the DHT11/22
  • 5V pin on the NODEMCU > VCC pin on the DHT11/22

Using the Arduino IDE, upload the following code:

Programming language(s) C#, C++, C: ***{Code starts after this line}***

#include <ESP8266WiFi.h>
#include "HTTPSRedirect.h"
#include "DebugMacros.h"
#include <DHT.h>

#define DHTPIN D4                                                           // what digital pin we're connected to
#define DHTTYPE DHT11                                                       // select dht type as DHT 11 or DHT22
DHT dht(DHTPIN, DHTTYPE);

float h;
float t;
String sheetHumid = "";
String sheetTemp = "";

const char* ssid = "";                //replace with our wifi ssid
const char* password = "";         //replace with your wifi password

const char* host = "script.google.com";
const char *GScriptId = "AKfycbxy9wAZKoPIpPq5AvqYTFFn5kkqK_-avacf2NU_w7ycoEtlkuNt"; // Replace with your own google script id
const int httpsPort = 443; //the https port is same

// echo | openssl s_client -connect script.google.com:443 |& openssl x509 -fingerprint -noout
const char* fingerprint = "";

//const uint8_t fingerprint[20] = {};

String url = String("/macros/s/") + GScriptId + "/exec?value=Temperature";  // Write Teperature to Google Spreadsheet at cell A1
// Fetch Google Calendar events for 1 week ahead
String url2 = String("/macros/s/") + GScriptId + "/exec?cal";  // Write to Cell A continuosly

//replace with sheet name not with spreadsheet file name taken from google
String payload_base =  "{\"command\": \"appendRow\", \
                    \"sheet_name\": \"TempSheet\", \
                       \"values\": ";
String payload = "";

HTTPSRedirect* client = nullptr;

// used to store the values of free stack and heap before the HTTPSRedirect object is instantiated
// so that they can be written to Google sheets upon instantiation

void setup() {
  delay(1000);
  Serial.begin(115200);
  dht.begin();     //initialise DHT11

  Serial.println();
  Serial.print("Connecting to wifi: ");
  Serial.println(ssid);
  
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  // Use HTTPSRedirect class to create a new TLS connection
  client = new HTTPSRedirect(httpsPort);
  client->setInsecure();
  client->setPrintResponseBody(true);
  client->setContentTypeHeader("application/json");
  Serial.print("Connecting to ");
  Serial.println(host);          //try to connect with "script.google.com"

  // Try to connect for a maximum of 5 times then exit
  bool flag = false;
  for (int i = 0; i < 5; i++) {
    int retval = client->connect(host, httpsPort);
    if (retval == 1) {
      flag = true;
      break;
    }
    else
      Serial.println("Connection failed. Retrying...");
  }

  if (!flag) {
    Serial.print("Could not connect to server: ");
    Serial.println(host);
    Serial.println("Exiting...");
    return;
  }
// Finish setup() function in 1s since it will fire watchdog timer and will reset the chip.
//So avoid too many requests in setup()

  Serial.println("\nWrite into cell 'A1'");
  Serial.println("------>");
  // fetch spreadsheet data
  client->GET(url, host);
  
  Serial.println("\nGET: Fetch Google Calendar Data:");
  Serial.println("------>");
  // fetch spreadsheet data
  client->GET(url2, host);

 Serial.println("\nStart Sending Sensor Data to Google Spreadsheet");

  
  // delete HTTPSRedirect object
  delete client;
  client = nullptr;
}

void loop() {

  h = dht.readHumidity();                                              // Reading temperature or humidity takes about 250 milliseconds!
  t = dht.readTemperature();                                           // Read temperature as Celsius (the default)
  if (isnan(h) || isnan(t)) {                                                // Check if any reads failed and exit early (to try again).
    Serial.println(F("Failed to read from DHT sensor!"));
    return;
  }
  Serial.print("Humidity: ");  Serial.print(h);
  sheetHumid = String(h) + String("%");                                         //convert integer humidity to string humidity
  Serial.print("%  Temperature: ");  Serial.print(t);  Serial.println("°C ");
  sheetTemp = String(t) + String("°C");

  static int error_count = 0;
  static int connect_count = 0;
  const unsigned int MAX_CONNECT = 20;
  static bool flag = false;

  payload = payload_base + "\"" + sheetTemp + "," + sheetHumid + "\"}";

  if (!flag) {
    client = new HTTPSRedirect(httpsPort);
    client->setInsecure();
    flag = true;
    client->setPrintResponseBody(true);
    client->setContentTypeHeader("application/json");
  }

  if (client != nullptr) {
    if (!client->connected()) {
      client->connect(host, httpsPort);
      client->POST(url2, host, payload, false);
      Serial.print("Sent : ");  Serial.println("Temp and Humid");
    }
  }
  else {
    DPRINTLN("Error creating client object!");
    error_count = 5;
  }

  if (connect_count > MAX_CONNECT) {
    connect_count = 0;
    flag = false;
    delete client;
    return;
  }

//  Serial.println("GET Data from cell 'A1':");
//  if (client->GET(url3, host)) {
//    ++connect_count;
//  }
//  else {
//    ++error_count;
//    DPRINT("Error-count while connecting: ");
//    DPRINTLN(error_count);
//  }

  Serial.println("POST or SEND Sensor data to Google Spreadsheet:");
  if (client->POST(url2, host, payload)) {
    ;
  }
  else {
    ++error_count;
    DPRINT("Error-count while connecting: ");
    DPRINTLN(error_count);
  }

  if (error_count > 3) {
    Serial.println("Halting processor...");
    delete client;
    client = nullptr;
    Serial.printf("Final free heap: %u\n", ESP.getFreeHeap());
    Serial.printf("Final stack: %u\n", ESP.getFreeContStack());
    Serial.flush();
    ESP.deepSleep(0);
  }
  
  delay(3000);    // keep delay of minimum 2 seconds as dht allow reading after 2 seconds interval and also for google sheet
}