Collecting Temperature and Humidity Data with Arduino ESP32

힘센캥거루
2025년 7월 7일(수정됨)
1
96
arduino

Today, we will create a Wi-Fi Stevenson screen that measures temperature and humidity and transmits data using Arduino ESP32.

This content is based on a script for a +1 session that will be conducted at school.

1. Materials

The materials are simple.

ESP32, DHT-22, three wires
Materials

First, to briefly explain the ESP32, it is an Arduino with a built-in Wi-Fi module.

However, it is much smaller than a standard Arduino.

2. ESP32 Pin Map

Materials

Uh oh?? The pin numbers seem odd?

This was also explained in the previous article; it is because the pin mapping changed when including the Wi-Fi module.

Here is the pin mapping for the ESP32 Arduino.

Fortunately, this one seems to almost match the GPIO pin numbers and names.

We plan to run the DHT-22 using the safe D4 pin among the following pins.

Arduino Pin Map

Arduino D pin

GPIO Number

Precautions

Function & Description

D0

GPIO0

strapping: requires LOW or floating at boot

affects flash mode entry ([randomnerdtutorials.com][1])

D1

GPIO1 (TX0)

USB serial conflict caution

UART0 TX for upload and debugging

D2

GPIO2

strapping: requires LOW/floating at boot

on-board LED → affects boot

D3

GPIO3 (RX0)

USB serial conflict caution

UART0 RX, HIGH at boot

D4

GPIO4

★ Safe

Digital I/O, ADC2_CH0, touch enabled

D5

GPIO5

strapping: requires HIGH at boot

PWM output during boot

D6D11

GPIO6–11

Absolutely Prohibited

Internal SPI Flash Pins

D12

GPIO12

strapping: requires LOW at boot

ADC2_CH5, touch, affects boot

D13

GPIO13

Safe

ADC2_CH4, touch enabled

D14

GPIO14

Outputs PWM at boot, boot strapping possible

ADC2_CH6, touch enabled

D15

GPIO15

strapping: requires HIGH at boot, PWM output

ADC2_CH3, touch enabled

D16

GPIO16

Caution for PSRAM with Wrover module

UART2 default TX/RX (17/16)

D17

GPIO17

Caution with Wrover module

UART2 default TX/RX (17/16)

D18, D19, D21–D23, D25–D27, D32–D33

Omitted

Safe

Supports digital, PWM, I2C, SPI, ADC/DAC

D34, D35, D36(VP), D39(VN)

34,35,36,39

Input only, no pullup/pulldown

ADC1 channel (no additional features)

3. DHT-11 vs DHT-22

Generally, the temperature and humidity sensor that comes with an Arduino is the DHT-11.

It is the one with the blue color, and it has a large error range of about 2 degrees.

Below is a summarized table of the performance of DHT-11 and DHT-22.

Item

DHT-11

DHT-22 (AM2302)

Appearance

dth-11dth-22

Temperature range

0 to 50°C

-40 to +80°C

Temperature accuracy

±2°C

±0.5°C

Humidity range

20 to 80% RH

0 to 100% RH

Humidity accuracy

±5% RH

±2~3% RH

Resolution

Temperature: 1°C, Humidity: 1% RH

Temperature: 0.1°C, Humidity: 0.1% RH

Measurement frequency

More than 1 second

More than 2 seconds

Data transmission

Low speed

Low speed

Size

Small

Slightly larger

Price

Inexpensive

More expensive than DHT-11

Operating voltage

3 to 5V

3 to 5V

Since a large error range makes the data unreliable, we decided to use the DHT-22 with lesser error.

If you want even more accurate temperature measurement, you can use a PT-100 thermometer, but it seems unnecessary for this purpose.

4. Installing CH340 Driver

Materials

You can see a chip inside the red circle in the photo above.

This is a chipset called CH340 made in China, and you can think of it as corresponding to the CPU in a computer.

Here's the official site link that provides the CH340 chip driver.

Download it and install it by just following the next buttons.

The above file includes drivers for all the following chips.

Note that MacBooks provide the driver for this chipset by default, so there is no need to install it.

CH340G, CH340T, CH340C, CH340N, CH340K, CH340E, CH340B, CH341A, CH341F, CH341T, CH341B, CH341C, CH341U

5. Setting Up the Arduino IDE Board Manager

Now let's set up the board manager in the Arduino IDE.

Go to File > Preferences in Arduino IDE.

Arduino ESP32 Board Manager Setting

Copy and enter the following address in the Additional Board Manager URLs.

https://espressif.github.io/arduino-esp32/package_esp32_index.json
Arduino ESP32 Board Manager SettingArduino ESP32 Board Manager Setting

Then search for ESP32 in the board manager and install the one provided by Espressif Systems.

alt text

When you connect the Arduino to the USB port, the port is automatically detected.

Select the corresponding Arduino board for that port.

Arduino esp32

6. Connecting to Wi-Fi

Let's upload a simple example now.

Select File -> Examples -> HttpClient -> BasicHttpsClient to find the HTTP request example.

Example

Now change only the SSID and PASSWORD sections in this example.

void setup() {

 USE_SERIAL.begin(115200);

 USE_SERIAL.println();
 USE_SERIAL.println();
 USE_SERIAL.println();

 for (uint8_t t = 4; t > 0; t--) {
 USE_SERIAL.printf("[SETUP] WAIT %d...\n", t);
 USE_SERIAL.flush();
 delay(1000);
 }
// Enter the Wi-Fi name in SSID, password in PASSWORD
 wifiMulti.addAP("SSID", "PASSWORD");
}

If the upload fails, try adjusting the upload speed.

Change Upload Speed to a slightly lower value in Tools for stable operation.

upload

Now, make it connect to the example site, and it prints HTML on the serial monitor.

By this point, you should be about one-third done.

https Test

7. Connecting the DHT-22 Sensor

Now let's connect the DHT-22 sensor to the Arduino and receive temperature and humidity values.

First, find and install the library.

Search for the DHT sensor library and get the one made by Adafruit.

Uploaded image

Open the examples from File->Examples, and find the temperature and humidity sensor example.

Try testing the sensor from among these examples.

The core code, excluding comments, is as follows.

Example
#include "DHT.h"

#define DHTPIN 4 // Designate pin number
#define DHTTYPE DHT22 // DHT 22 
DHT dht(DHTPIN, DHTTYPE);

void setup() {
 Serial.begin(115200); // Serial communication speed. Change to 115200
 Serial.println(F("DHTxx test!"));
 dht.begin();
}

void loop() {
 delay(2000);
 float h = dht.readHumidity();
 float t = dht.readTemperature();
 float f = dht.readTemperature(true); // Becoming Fahrenheit with true

 if (isnan(h) || isnan(t) || isnan(f)) {
 Serial.println(F("Failed to read from DHT sensor!"));
 return;
 }

 float hif = dht.computeHeatIndex(f, h); // Sensible temperature
 float hic = dht.computeHeatIndex(t, h, false);

 Serial.print(F("Humidity: "));
 Serial.print(h);
 Serial.print(F("% Temperature: "));
 Serial.print(t);
 Serial.print(F("°C "));
 Serial.print(f);
 Serial.print(F("°F Heat index: "));
 Serial.print(hic);
 Serial.print(F("°C "));
 Serial.print(hif);
 Serial.println(F("°F"));
}

After transmitting with Arduino, confirm the temperature output on the serial monitor.

Just by blowing on it, the humidity soared up to 100%.

serialMonitor

Since we have solved the Arduino Wi-Fi and sensor connection, let's move on to setting up Google Sheets next.

8. Setting Up Google Sheets

Usually, I write posts myself, but setting up Google Sheets would make the article too long, so I’ll attach an article I wrote before.

Check the link below.

9. Sending a GET Request from Arduino

Now that the Google Sheets setup is complete, it's time to send a GET request from Arduino.

Use the example from the Wi-Fi connection above.

Just change the request address to the Google script.

The middle part is omitted for brevity.

#include <Arduino.h>
#include <WiFi.h>
#include <WiFiMulti.h>
#include <HTTPClient.h>
#include <NetworkClientSecure.h>

...

String host = "https://script.google.com/";
String googleScriptID = "my Google script ID";
String scriptUrl = "macros/s/"+googleScriptID+"/exec";
String queryString = "?value1='Hello'&value2='Testing!'";
String getReqUrl = host + scriptUrl + queryString;

void setup() {
 
 ...

 WiFiMulti.addAP("Wi-Fi name", "Wi-Fi password");

 ...
}

void loop() {
 NetworkClientSecure *client = new NetworkClientSecure;
 if (client) {
 client->setCACert(rootCACertificate);
 {
 HTTPClient https;
 Serial.print("[HTTPS] begin...\n");
 if (https.begin(*client, getReqUrl)) { // Modify this part
 
 ...

 }
 }}
}

Executing this shows data flowing to the spreadsheet.

The final step is to retrieve and transmit data from the DHT-22

reqTest

10. Combining the Code

Uploaded image

Now let's combine the two codes.

If combining the code is too difficult, handing it over to AI without complicating it is also recommended.

First, I changed the loop code of DHT-22 to a function that returns a structure called Weather.

#include "DHT.h"

#define DHTPIN 4   
#define DHTTYPE DHT22   

DHT dht(DHTPIN, DHTTYPE);

void setup() {
  Serial.begin(115200);
  dht.begin();
}

struct WeatherData {
  float humi;
  float temp;
  float heat;
  bool valid;
};

WeatherData getWeather() {
  WeatherData data;
  data.humi = dht.readHumidity();
  data.temp = dht.readTemperature();

  if (isnan(data.humi) || isnan(data.temp)) {
    Serial.println(F("Failed to read from DHT sensor!"));
    data.valid = false;
    return data;
  }
  data.valid = true;
  data.heat = dht.computeHeatIndex(data.temp, data.humi, false);

  Serial.print(F("Humidity: "));
  Serial.print(data.humi);
  Serial.print(F("%  Temperature: "));
  Serial.print(data.temp);
  Serial.print(F("°C "));
  Serial.print(F("°Heat index: "));
  Serial.print(data.heat);
  Serial.print(F("°C "));
  return data;
}

Properly distribute the required parts and merge them into the httpsClient code.

Let's combine them now.

#include <Arduino.h>
#include <WiFi.h>
#include <WiFiMulti.h>
#include <HTTPClient.h>
#include <NetworkClientSecure.h>
#include "DHT.h"

...
Certificate omitted
...

void setClock() {
  ...
}

#define DHTPIN 4   
#define DHTTYPE DHT22   

WiFiMulti WiFiMulti;
DHT dht(DHTPIN, DHTTYPE);
char* SSID = "Wi-Fi name";
char* PASSWORD = "Wi-Fi password";
String host = "https://script.google.com/";
String googleScriptID = "my Google script ID";
String scriptUrl = "macros/s/"+googleScriptID+"/exec";

struct WeatherData {
  ...
};

WeatherData getWeather(); // Declared in advance to avoid errors


void setup() {
  dht.begin();
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  WiFiMulti.addAP(SSID, PASSWORD);
  Serial.print(F("Waiting for WiFi to connect..."));
  while ((WiFiMulti.run() != WL_CONNECTED)) {
    Serial.print(F("."));
  }
  Serial.println(F(" connected"));
  setClock();
}

WeatherData getWeather() {
    ...
}


void loop() {
  NetworkClientSecure *client = new NetworkClientSecure;
  if (client) {
    client->setCACert(rootCACertificate);
    {
      HTTPClient https;
      WeatherData data = getWeather();
      if (!data.valid){
        Serial.println(F("Cannot obtain weather information."));
        Serial.println("Waiting 10s before the next round...");
        delay(10000);
        return;
      };
      Serial.print("[HTTPS] begin...\n");
      String queryString = "?value1=" + String(data.humi) + "&value2=" + String(data.temp) ;
      String getReqUrl = host + scriptUrl + queryString;
      if (https.begin(*client, getReqUrl)) {  // HTTPS
        Serial.print("[HTTPS] GET...\n");

        int httpCode = https.GET();

        if (httpCode > 0) {
          Serial.printf("[HTTPS] GET... code: %d\n", httpCode);
        } else {
          Serial.printf("[HTTPS] GET... failed, error: %s\n", https.errorToString(httpCode).c_str());
        }
        https.end();
      } else {
        Serial.printf("[HTTPS] Unable to connect\n");
      }
    }
    delete client;
  } else {
    Serial.println("Unable to create client");
  }
  Serial.println();
  Serial.println("Waiting 10s before the next round...");
  delay(10000);
}

After doing this, if the humidity, temperature, and Get request code 200 show up on the serial monitor, it's successful.

Then you can check it by accessing the spreadsheet.

Spreadsheet

11. Additional Tasks

If you also want to record the apparent temperature, modify the Google script.

You can add variables or change variable names in the parameter parsing section.

...
for (var param in e.parameter) {
  Logger.log('In for loop, param=' + param);
  var value = stripQuotes(e.parameter[param]);
  Logger.log(param + ':' + e.parameter[param]);
  switch (param) {
    case 'humi':
    rowData[2] = value; // value1 in column C
    result = 'Humidity recorded'; 
    break;
    case 'temp':
    rowData[3] = value; // Humidity in column D
    result += ', Temperature recorded'; 
    break;
    case 'heat':
    rowData[4] = value;
    result += ", Apparent temperature recorded";
    break

    default:
    result = "Unsupported parameter.";
  }
...

Of course, this requires changing the query string in the Arduino code as well.

Since it is a personal project, doing this is for future maintenance or just personal preference.

12. Review

In previous experiments with students, we had the following data:

Data gaps in the middle were caused by power being cut off at night...

Nonetheless, having an automatic data collection system like this is immensely beneficial as we only need to analyze the data.

Past Data

It looks empty when you see only the results, but writing it out in detail makes the article extremely long.

We plan for the first 3 hours of the 16+1 session to cover C language, followed by 2 hours of Arduino temperature and humidity sensor, and the rest for a personal project. I am worried about whether time will be enough.

I hope the well-prepared class ends successfully and we welcome the summer break.

댓글을 불러오는 중...