measurement-and-instrumentation
How to Create a Digital Temperature and Humidity Data Logger
Table of Contents
Introduction
Environmental monitoring is a cornerstone of both scientific research and everyday life. Whether you are tracking the climate in a greenhouse, ensuring safe storage conditions for sensitive materials, or simply exploring the world of microcontrollers, a digital temperature and humidity data logger is a practical and educational project. This comprehensive guide walks you through building a reliable data logger using an Arduino Uno, a DHT22 sensor, and an SD card module. You will learn not only how to assemble the hardware and write the code but also how to troubleshoot common issues, calibrate your sensor, and expand the project for more advanced applications. By the end, you will have a fully functional logger that records environmental data over time, ready for analysis in any spreadsheet or data visualization tool.
Understanding the Components
The Microcontroller: Arduino Uno
The Arduino Uno is an excellent entry-level microcontroller board based on the ATmega328P. It provides 14 digital input/output pins, 6 analog inputs, a USB connection, and a 16 MHz quartz crystal. Its simplicity and vast community support make it ideal for logging projects. If you prefer a smaller footprint, consider the Arduino Nano or the ESP32, which adds built-in Wi-Fi and a faster processor. However, for this guide, we stick with the Uno due to its straightforward wiring.
Temperature & Humidity Sensor: DHT22
The DHT22 (also known as AM2302) is a digital sensor that outputs calibrated temperature and humidity values. It has a temperature range of -40°C to 80°C with an accuracy of ±0.5°C, and a humidity range of 0% to 100% with an accuracy of ±2%. Unlike the cheaper DHT11, the DHT22 offers higher precision and a wider range. The sensor uses a single-wire digital protocol to communicate, requiring careful timing in the code.
Data Storage: SD Card Module
An SD card module (often using the SPI interface) allows the Arduino to write data to a standard microSD card. The module typically operates at 3.3V logic but includes a voltage regulator and level shifter to work with 5V Arduino boards. Choose a high‑quality card (Class 10 or above) to avoid data corruption. The library Arduino SD library handles file operations seamlessly.
Power Supply
For stationary logging, a USB cable connected to a computer or a USB wall adapter works fine. For portable operation, use a 9V battery or a battery pack (e.g., 4xAA) connected to the Arduino’s Vin pin. Keep in mind that the DHT22 and SD card module draw only a few milliamperes, so battery life can be extended with sleep modes in the code.
Circuit Assembly
Wiring the DHT22
Place the DHT22 on the breadboard. Connect its VCC pin to the Arduino’s 5V rail, GND to ground, and the data pin to digital pin 2. Some DHT22 modules include a built‑in pull‑up resistor on the data line; if not, add a 4.7 kΩ resistor between the data pin and VCC.
Wiring the SD Card Module
The SD card module uses SPI communication. Connect as follows:
- VCC ─ to Arduino 5V
- GND ─ to ground
- CS (Chip Select) ─ to digital pin 10
- MOSI (SDI) ─ to digital pin 11 (Uno’s SPI MOSI)
- MISO (SDO) ─ to digital pin 12 (SPI MISO)
- SCK ─ to digital pin 13 (SPI SCK)
Double‑check the pin labels on your specific module; some modules mark MOSI as “DI” or “SDI.” If you use an Arduino board other than Uno, refer to its SPI pinout.
Breadboard Layout Tips
Keep jumper wires short to reduce noise. Use a separate power rail for the sensor and SD card module. A ceramic capacitor (100 nF) between the VCC and GND of the DHT22 can help stabilize the supply. After testing on a breadboard, consider soldering the components onto a perforated board for a permanent, robust logger.
Programming the Data Logger
Open the Arduino IDE and ensure you have installed the DHT sensor library by Adafruit (version 1.4.4 or later) and the built‑in SD and SPI libraries. The following code reads humidity and temperature every two seconds and saves a comma‑separated value (CSV) line to a file on the SD card.
#include <DHT.h>
#include <SPI.h>
#include <SD.h>
#define DHTPIN 2
#define DHTTYPE DHT22
#define CHIPSELECT 10
DHT dht(DHTPIN, DHTTYPE);
File dataFile;
void setup() {
Serial.begin(9600);
while (!Serial) { ; } // Wait for USB Serial (for boards with native USB)
dht.begin();
Serial.println("DHT22 initialized.");
if (!SD.begin(CHIPSELECT)) {
Serial.println("SD card initialization failed!");
while (1);
}
Serial.println("SD card initialized.");
// Create or open file and write header
dataFile = SD.open("datalog.csv", FILE_WRITE);
if (dataFile) {
dataFile.println("timestamp,temperature_C,humidity_pct");
dataFile.close();
} else {
Serial.println("Error opening datalog.csv");
}
}
void loop() {
float humidity = dht.readHumidity();
float temperature = dht.readTemperature(); // Celsius
// Check if any reads failed
if (isnan(humidity) || isnan(temperature)) {
Serial.println("Failed to read from DHT sensor!");
delay(2000);
return;
}
dataFile = SD.open("datalog.csv", FILE_WRITE);
if (dataFile) {
// Build a timestamp (milliseconds since start)
unsigned long now = millis();
dataFile.print(now);
dataFile.print(",");
dataFile.print(temperature);
dataFile.print(",");
dataFile.println(humidity);
dataFile.close();
Serial.print("Logged: ");
Serial.print(temperature);
Serial.print(" °C, ");
Serial.print(humidity);
Serial.println(" %");
} else {
Serial.println("Error opening file for writing");
}
delay(2000); // Wait 2 seconds before next reading
}
Understanding the Code
The setup() function initializes the serial monitor, the DHT sensor, and the SD card. It then creates a new CSV file (or appends to an existing one) and writes a header row with column names. The loop() function takes a reading, checks for errors, logs the data with a millisecond timestamp, and waits two seconds. The millis() timestamp is relative to the Arduino power‑on; for absolute timestamps, consider adding an RTC module (see “Advanced Enhancements”).
Error Handling
The code uses isnan() to detect sensor communication failures—common if the wiring is loose or the sensor is faulty. The SD card operations also include status checks; the program halts if the SD card cannot be initialized. In a production logger, you might want to log errors to a separate file or flash an LED.
Testing and Calibration
Upload the code to the Arduino, open the Serial Monitor (Tools → Serial Monitor, set baud rate to 9600). You should see messages confirming initialization and logged data. If you get “Failed to read from DHT sensor!”, check the wiring and pull‑up resistor. If the SD card fails, ensure the card is formatted to FAT32 and that the chip select pin matches your wiring.
To calibrate the DHT22, compare its readings with a trusted reference sensor (e.g., a mercury thermometer and a sling psychrometer). The DHT22 is factory‑calibrated, but slight offsets can occur. If needed, apply a correction factor in the code, for example:
temperature = temperature + 0.5; // if your reference is 0.5°C higher
Data Collection and Analysis
After letting the logger run for a few hours or days, power off the device and remove the microSD card. Insert it into your computer and open the datalog.csv file. You can import this into Microsoft Excel, Google Sheets, or any data analysis tool. Plot temperature and humidity over time using the timestamp as the x‑axis. For a more automated approach, write a Python script using pandas and matplotlib to generate charts.
Example Python snippet (run on your computer, not on Arduino):
import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_csv('datalog.csv')
df['timestamp'] = pd.to_numeric(df['timestamp']) / 1000 # convert ms to seconds
plt.figure(figsize=(10,5))
plt.plot(df['timestamp'], df['temperature_C'], label='Temperature (°C)')
plt.plot(df['timestamp'], df['humidity_pct'], label='Humidity (%)')
plt.xlabel('Time (s)')
plt.ylabel('Value')
plt.legend()
plt.title('Environment Data Logger')
plt.show()
Troubleshooting Common Issues
Sensor Reading Errors
If you see nan values repeatedly, the DHT22 data wire may be too long (over 20 cm without a shielded cable) or the pull‑up resistor is too weak. Reduce the wire length or use a 4.7 kΩ resistor. Also, ensure the sensor is not placed in direct sunlight or near heat sources.
SD Card Not Initializing
Check that the card is formatted as FAT32 and that the module’s logic level is compatible with the Arduino’s 5V. Some modules require 5V power but the data pins are 3.3V tolerant; the Uno’s SPI pins output 5V, which may stress the module. Add a logic level converter between the Uno’s pin and the module’s MISO pin, or use a 3.3V Arduino like the Pro Mini.
File Corruption
Always call close() after writing, as shown in the code. If you power off the Arduino while a file is open, the last data block may be lost. For critical applications, use a battery backup or a capacitor to allow the Arduino to finish the write before shutting down.
Advanced Enhancements
Real‑Time Clock (RTC) for Accurate Timestamps
Add an RTC module (e.g., DS3231) to record absolute date and time. Connect it via I²C (SDA to A4, SCL to A5 on the Uno). Include the RTClib library and modify the code to write a formatted timestamp instead of millis(). This makes the data directly usable without conversion.
Wireless Data Transmission
Replace the SD card with a Wi‑Fi module (ESP8266 or ESP32) to send data to a cloud platform like ThingSpeak or a local MQTT broker. This eliminates physical access to the logger and enables real‑time monitoring. This tutorial shows how to build an ESP32‑based DHT22 web server.
LCD Display for Live Readings
Attach a 16×2 I²C LCD to display current temperature and humidity on the device itself. The I²C version uses only two wires (SDA, SCL) plus power, keeping the wiring simple.
Multiple Sensors
You can connect several DHT22 sensors (each on a different digital pin) to log data from multiple locations simultaneously. Adjust the code to loop through each sensor and save the readings in separate columns.
Conclusion
Building a digital temperature and humidity data logger is a rewarding project that bridges electronics, programming, and environmental science. With the Arduino Uno, DHT22 sensor, and an SD card module, you have created a reliable tool that records data for hours, days, or even weeks. The skills you developed—reading sensor data, handling file I/O, and debugging hardware—are transferable to countless other microcontroller projects. As you grow more confident, consider adding an RTC for precise timestamps, a wireless module for remote monitoring, or an OLED screen for on‑the‑spot visualization. The possibilities are limited only by your curiosity and the large community of makers and engineers who share their work online. Start experimenting, and soon you will have a custom monitoring solution tailored to your specific environment.