liminfo

Arduino Sensor Data Serial Communication

A hands-on guide to connecting a DHT22 temperature and humidity sensor to an Arduino, transmitting sensor data to a PC via serial communication, and implementing automatic data collection and CSV storage with Python.

arduino sensor dataserial communicationDHT22 temperature humidity sensorSerial.printlnarduino projectArduino UnoArduino NanoIoT projectPython serialpyserialCSV data loggingUART communication

Problem

In an IoT project, you need to read DHT22 temperature and humidity sensor data with an Arduino and transmit it to a PC. You need to build a data logging system that displays sensor data in real-time on the serial monitor, automatically collects it with a Python script, and saves it to a CSV file with timestamps. In the future, you plan to analyze temperature and humidity trends and add alert notifications when thresholds are exceeded.

Required Tools

Arduino IDE

An integrated development environment for programming Arduino boards. Provides sketch writing, compilation, uploading, and serial monitor functionality.

Arduino Uno/Nano

ATmega328P-based microcontroller boards. Support digital/analog I/O pins and USB serial communication.

DHT22 Sensor

A digital temperature and humidity sensor. Capable of measuring temperature from -40 to 80 degrees Celsius (accuracy +/-0.5 degrees) and humidity from 0 to 100% (accuracy +/-2-5%).

USB Cable

A USB-B (Uno) or Mini-USB/Micro-USB (Nano) cable to connect the Arduino to a PC. Provides both power supply and serial communication simultaneously.

Solution Steps

1

Circuit wiring and pin layout

The DHT22 sensor comes in a 4-pin or 3-pin (module) form. Connect it to the Arduino as follows: [DHT22 Pin Layout - from left when facing front] - Pin 1 (VCC): Connect to Arduino 5V - Pin 2 (DATA): Connect to Arduino digital pin 2 + 10K ohm pull-up resistor (between VCC and DATA) - Pin 3 (NC): Not used (4-pin model only) - Pin 4 (GND): Connect to Arduino GND If using a 3-pin module-type DHT22, the pull-up resistor is built in, so no separate resistor is needed. Connect using jumper wires on a breadboard.

// === Circuit Wiring Diagram (ASCII) ===
//
//  Arduino Uno          DHT22 Sensor
//  +-----------+       +--------+
//  |           |       | 1(VCC) |----+---- 5V
//  |     5V  --+-------+--------+    |
//  |           |       | 2(DATA)|----+---- 10K resistor ---- 5V
//  |     D2  --+-------+--------+
//  |           |       | 3(NC)  |
//  |           |       +--------+
//  |    GND  --+-------| 4(GND) |-------- GND
//  +-----------+       +--------+
//
// Note: 3-pin module DHT22 has built-in pull-up resistor -> resistor can be omitted
2

Install DHT library in Arduino IDE

Install the Adafruit DHT sensor library for easy handling of the DHT22 sensor. In Arduino IDE: 1. Click Tools > Manage Libraries 2. Type "DHT sensor library" in the search box 3. Install "DHT sensor library by Adafruit" (also install the dependency "Adafruit Unified Sensor") 4. Alternatively, you can install via CLI.

# Install libraries via Arduino CLI
arduino-cli lib install "DHT sensor library"
arduino-cli lib install "Adafruit Unified Sensor"

# Verify installed libraries
arduino-cli lib list | grep -i dht
3

Write and upload the Arduino sketch

Write a sketch that reads temperature and humidity from the DHT22 and transmits it over the serial port. Data is sent in CSV format (temperature,humidity) to make parsing easy in Python. The 2-second reading interval is because the DHT22's minimum sampling interval is 2 seconds.

#include <DHT.h>

#define DHTPIN 2        // DHT22 data pin
#define DHTTYPE DHT22   // DHT22 (AM2302) sensor type

DHT dht(DHTPIN, DHTTYPE);

void setup() {
  Serial.begin(9600);   // Start serial communication (9600 baud)
  dht.begin();          // Initialize DHT sensor

  // Print CSV header
  Serial.println("temperature,humidity");

  // Wait for sensor stabilization
  delay(2000);
}

void loop() {
  // Read humidity (%)
  float humidity = dht.readHumidity();
  // Read temperature (Celsius)
  float temperature = dht.readTemperature();

  // Check for read failure
  if (isnan(humidity) || isnan(temperature)) {
    Serial.println("ERROR,ERROR");
    delay(2000);
    return;
  }

  // Serial output in CSV format
  Serial.print(temperature, 1);  // 1 decimal place
  Serial.print(",");
  Serial.println(humidity, 1);

  // DHT22 minimum sampling interval: 2 seconds
  delay(2000);
}
4

Verify data with the serial monitor

After uploading the sketch, open the Arduino IDE serial monitor (Tools > Serial Monitor or Ctrl+Shift+M) to verify that data is being output correctly. The baud rate must be set to 9600, matching the value in the code. Expected output example: temperature,humidity 23.5,45.2 23.6,45.0 23.5,44.8 If you see garbled characters, the baud rate setting does not match. If "ERROR,ERROR" appears continuously, check the sensor wiring.

# Check serial monitor via Arduino CLI
arduino-cli monitor -p /dev/ttyACM0 -b arduino:avr:uno

# Or use minicom on Linux
minicom -b 9600 -D /dev/ttyACM0

# Use screen on macOS
screen /dev/cu.usbmodem14201 9600
5

Automatic serial data collection and CSV storage with Python

Use the pyserial library to read Arduino serial data in Python and save it to a CSV file with timestamps. Data collection continues until interrupted with Ctrl+C, and warning messages are printed to the console when thresholds are exceeded.

#!/usr/bin/env python3
"""Arduino DHT22 sensor data collection script"""

import serial
import csv
import time
from datetime import datetime

# === Configuration ===
SERIAL_PORT = '/dev/ttyACM0'  # Windows: 'COM3', macOS: '/dev/cu.usbmodem14201'
BAUD_RATE = 9600
OUTPUT_FILE = f'sensor_data_{datetime.now():%Y%m%d_%H%M%S}.csv'
TEMP_THRESHOLD = 30.0   # Temperature alert threshold (degrees)
HUMID_THRESHOLD = 70.0  # Humidity alert threshold (%)

def main():
    # Connect to serial port
    ser = serial.Serial(SERIAL_PORT, BAUD_RATE, timeout=5)
    time.sleep(2)  # Wait for Arduino reset

    # Skip first line (header)
    header = ser.readline().decode('utf-8').strip()
    print(f"Sensor header: {header}")

    print(f"Data collection started... (output file: {OUTPUT_FILE})")
    print(f"Temp alert: > {TEMP_THRESHOLD} degrees, Humidity alert: > {HUMID_THRESHOLD}%")
    print("-" * 50)

    with open(OUTPUT_FILE, 'w', newline='') as csvfile:
        writer = csv.writer(csvfile)
        writer.writerow(['timestamp', 'temperature', 'humidity'])

        try:
            while True:
                line = ser.readline().decode('utf-8').strip()
                if not line or line.startswith('ERROR'):
                    print(f"[{datetime.now():%H:%M:%S}] Sensor read error")
                    continue

                parts = line.split(',')
                if len(parts) != 2:
                    continue

                temp, humid = float(parts[0]), float(parts[1])
                timestamp = datetime.now().isoformat()

                # Write to CSV file
                writer.writerow([timestamp, temp, humid])
                csvfile.flush()  # Write immediately

                # Console output
                alert = ""
                if temp > TEMP_THRESHOLD:
                    alert += " [HIGH TEMP WARNING!]"
                if humid > HUMID_THRESHOLD:
                    alert += " [HIGH HUMIDITY WARNING!]"

                print(f"[{datetime.now():%H:%M:%S}] "
                      f"Temp: {temp:.1f} deg | Humidity: {humid:.1f}%{alert}")

        except KeyboardInterrupt:
            print(f"\nCollection stopped. Data saved to: {OUTPUT_FILE}")
        finally:
            ser.close()

if __name__ == '__main__':
    main()

Core Code

Core code for the Arduino sketch and Python serial collector. Transmits DHT22 sensor data in CSV format and saves it to a file with timestamps.

// ===== Arduino Sketch (Core Code) =====
#include <DHT.h>

#define DHTPIN 2
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);

void setup() {
  Serial.begin(9600);
  dht.begin();
  Serial.println("temperature,humidity");
  delay(2000);
}

void loop() {
  float h = dht.readHumidity();
  float t = dht.readTemperature();
  if (isnan(h) || isnan(t)) {
    Serial.println("ERROR,ERROR");
  } else {
    Serial.print(t, 1);
    Serial.print(",");
    Serial.println(h, 1);
  }
  delay(2000);
}

// ===== Python Collector (Core Code) =====
// pip install pyserial
//
// import serial, csv
// from datetime import datetime
//
// ser = serial.Serial('/dev/ttyACM0', 9600, timeout=5)
// ser.readline()  # Skip header
//
// with open('data.csv', 'w', newline='') as f:
//     w = csv.writer(f)
//     w.writerow(['time', 'temp', 'humid'])
//     while True:
//         line = ser.readline().decode().strip()
//         if line and 'ERROR' not in line:
//             t, h = line.split(',')
//             w.writerow([datetime.now().isoformat(), t, h])
//             f.flush()

Common Mistakes

Unstable sensor data due to missing pull-up resistor

You must connect a 10K ohm pull-up resistor between the DHT22 DATA pin and VCC. Without a pull-up resistor, the data line enters a floating state, causing frequent NaN values. Using a 3-pin module-type DHT22 board eliminates the need for a separate resistor since it has a built-in pull-up.

Baud rate mismatch between Arduino and Python

The Serial.begin() value in the Arduino code and the serial.Serial() baud rate value in Python must be identical (e.g., both 9600). A mismatch will display garbled characters (b'\xff\xfe...') in the serial monitor. Typically 9600 or 115200 is used.

Sensor not working properly due to insufficient USB power

The DHT22 operates at 3.3V-5V, but current may be insufficient when connected through a USB hub. Connect directly to a PC USB port, or connect an external 5V power adapter to the Arduino barrel jack. Power issues are especially common when using multiple sensors simultaneously.

Trying to open the serial port from two programs simultaneously

A serial port can only be used by one program at a time. Close the Arduino IDE serial monitor before running the Python script. If you get a "Permission denied" or "Access is denied" error, check whether another program is occupying the port.

Related liminfo Services