Skip to content

Raspberry Pi DHT22 Sensor with SiliconWit IO

In this tutorial, you will learn how to connect a DHT22 temperature and humidity sensor to a Raspberry Pi, read sensor data using Python, and publish the readings to the SiliconWit IO IoT platform via MQTT over a secure TLS connection.

The Raspberry Pi is a popular choice for IoT projects due to its GPIO pins, built-in WiFi, and ability to run full Python applications. Combined with the DHT22 sensor and SiliconWit IO, you can build a complete environmental monitoring system in minutes.

  • How to wire a DHT22 temperature and humidity sensor to a Raspberry Pi
  • How to read sensor data using the adafruit-circuitpython-dht library
  • How to establish a secure TLS MQTT connection to SiliconWit IO
  • How to publish real sensor readings as JSON telemetry
  • How to run the script as a background service using systemd
ComponentDescription
Raspberry PiAny model with GPIO headers (Pi 3, Pi 4, Pi 5, Pi Zero 2 W)
DHT22 SensorAlso known as AM2302; measures temperature and humidity
10K Ohm ResistorPull-up resistor for the data line (some DHT22 modules have this built in)
Jumper WiresFemale-to-female or female-to-male depending on your sensor module
MicroSD CardWith Raspberry Pi OS installed
Power SupplyAppropriate for your Pi model
WiFi or EthernetInternet connection for MQTT communication
SoftwarePurpose
Raspberry Pi OSBookworm or later (Lite or Desktop)
Python 3Pre-installed on Raspberry Pi OS
SiliconWit IO AccountFree IoT platform account

After registering a device on the SiliconWit IO dashboard, note down:

CredentialExampleDescription
Device IDxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxUnique device identifier (MQTT username)
Access Tokenyour_access_token_hereMQTT password
Publish Topicd/{device_id}/tTopic for sending sensor data (d = device, t = telemetry)

Keep your access token secure. Never share it publicly or commit it to version control.

Step 1: Wire the DHT22 Sensor to the Raspberry Pi

Section titled “Step 1: Wire the DHT22 Sensor to the Raspberry Pi”

The DHT22 sensor has 4 pins (or 3 if using a module with a built-in pull-up resistor):

DHT22 PinRaspberry Pi PinDescription
VCC (Pin 1)3.3V (Pin 1)Power supply
Data (Pin 2)GPIO 4 (Pin 7)Sensor data line
NC (Pin 3)Not connectedLeave unconnected
GND (Pin 4)GND (Pin 6)Ground
Raspberry Pi DHT22 Sensor
┌──────────────────┐ ┌───────────┐
│ │ │ │
│ 3.3V (Pin 1) ├─────────────────│ VCC │
│ │ ┌───┐ │ │
│ GPIO 4 (Pin 7) ├────────┤10K├───│ Data │
│ │ └─┬─┘ │ │
│ │ │ │ NC │
│ │ │ │ │
│ GND (Pin 6) ├──────────┴─────│ GND │
│ │ │ │
└──────────────────┘ └───────────┘
Note: The 10K resistor connects between VCC and the Data line
(pull-up). Many DHT22 breakout modules include this resistor
on the PCB — check your module before adding an external one.

Important notes:

  • Use the 3.3V pin, not 5V. The Raspberry Pi GPIO pins are 3.3V logic and the DHT22 works at 3.3V.
  • If your DHT22 is on a breakout module (3-pin board), it likely has a built-in pull-up resistor. You can skip the external 10K resistor.
  • GPIO 4 is used in this tutorial, but any available GPIO pin will work. Update the pin number in the code if you use a different one.

Update your system and install the necessary packages:

Terminal window
sudo apt update
sudo apt install -y python3-pip python3-venv libgpiod2

Create a project directory and virtual environment:

Terminal window
mkdir ~/siliconwit-sensor
cd ~/siliconwit-sensor
python3 -m venv venv
source venv/bin/activate

Install the Python libraries:

Terminal window
pip install paho-mqtt adafruit-circuitpython-dht
LibraryPurpose
paho-mqttMQTT client for connecting to SiliconWit IO
adafruit-circuitpython-dhtRead temperature and humidity from the DHT22 sensor

Before writing the full MQTT client, verify that the sensor is working:

import time
import board
import adafruit_dht
dht = adafruit_dht.DHT22(board.D4)
for i in range(5):
try:
temperature = dht.temperature
humidity = dht.humidity
print(f"Temp: {temperature:.1f}C Humidity: {humidity:.1f}%")
except RuntimeError as e:
print(f"Sensor read error (normal, retrying): {e}")
time.sleep(2)
dht.exit()

Save this as test_sensor.py and run it:

Terminal window
python test_sensor.py

The DHT22 occasionally returns read errors. This is normal behavior for this sensor. The full code below handles these errors gracefully by retrying.

Step 4: Write the Full MQTT Telemetry Script

Section titled “Step 4: Write the Full MQTT Telemetry Script”

Create a file called telemetry.py with the following code:

import ssl
import json
import time
import board
import adafruit_dht
import paho.mqtt.client as mqtt
# ========== SILICONWIT IO MQTT CONFIGURATION ==========
MQTT_BROKER = "mqtt.siliconwit.io"
MQTT_PORT = 8883
DEVICE_ID = "YOUR_DEVICE_ID"
ACCESS_TOKEN = "YOUR_ACCESS_TOKEN"
PUBLISH_TOPIC = f"d/{DEVICE_ID}/t"
# ========== SENSOR CONFIGURATION ==========
DHT_PIN = board.D4 # GPIO 4
TELEMETRY_INTERVAL = 30 # seconds
# ========== INITIALIZE SENSOR ==========
dht_sensor = adafruit_dht.DHT22(DHT_PIN)
# ========== CALLBACKS ==========
def on_connect(client, userdata, flags, reason_code, properties):
if reason_code == 0:
print("[MQTT] Connected to SiliconWit IO")
else:
print(f"[MQTT] Connection failed with code: {reason_code}")
def on_disconnect(client, userdata, flags, reason_code, properties):
print(f"[MQTT] Disconnected (code: {reason_code}). Reconnecting...")
def on_publish(client, userdata, mid, reason_code, properties):
print(f"[MQTT] Message {mid} delivered")
# ========== SENSOR READING ==========
def read_dht22(retries=3):
"""
Read temperature and humidity from the DHT22 sensor.
Retries on failure since the DHT22 occasionally returns errors.
"""
for attempt in range(retries):
try:
temperature = dht_sensor.temperature
humidity = dht_sensor.humidity
if temperature is not None and humidity is not None:
return {
"temperature": round(temperature, 1),
"humidity": round(humidity, 1),
}
except RuntimeError as e:
print(f"[SENSOR] Read error (attempt {attempt + 1}/{retries}): {e}")
time.sleep(2)
return None
# ========== MAIN ==========
def main():
print("=== Raspberry Pi DHT22 -> SiliconWit IO ===\n")
# Create MQTT client
client = mqtt.Client(
callback_api_version=mqtt.CallbackAPIVersion.VERSION2,
client_id=DEVICE_ID,
protocol=mqtt.MQTTv311,
)
# Set authentication
client.username_pw_set(DEVICE_ID, ACCESS_TOKEN)
# Configure TLS
client.tls_set(tls_version=ssl.PROTOCOL_TLS_CLIENT)
# Set callbacks
client.on_connect = on_connect
client.on_disconnect = on_disconnect
client.on_publish = on_publish
# Enable automatic reconnection
client.reconnect_delay_set(min_delay=1, max_delay=60)
# Connect to broker
print(f"[MQTT] Connecting to {MQTT_BROKER}:{MQTT_PORT}...")
try:
client.connect(MQTT_BROKER, MQTT_PORT, keepalive=60)
except Exception as e:
print(f"[ERROR] Connection failed: {e}")
return
# Start the network loop in a background thread
client.loop_start()
try:
while True:
if client.is_connected():
sensor_data = read_dht22()
if sensor_data:
payload = json.dumps(sensor_data)
client.publish(PUBLISH_TOPIC, payload, qos=1)
print(f"[TELEMETRY] Sent: {payload}")
else:
print("[SENSOR] Failed to read after retries, skipping...")
else:
print("[MQTT] Waiting for connection...")
time.sleep(TELEMETRY_INTERVAL)
except KeyboardInterrupt:
print("\n[INFO] Shutting down...")
finally:
dht_sensor.exit()
client.loop_stop()
client.disconnect()
print("[INFO] Sensor released. Disconnected. Goodbye.")
if __name__ == "__main__":
main()

Run the script:

Terminal window
python telemetry.py

Expected output:

=== Raspberry Pi DHT22 -> SiliconWit IO ===
[MQTT] Connecting to mqtt.siliconwit.io:8883...
[MQTT] Connected to SiliconWit IO
[TELEMETRY] Sent: {"temperature": 23.4, "humidity": 58.2}
[MQTT] Message 1 delivered
[TELEMETRY] Sent: {"temperature": 23.5, "humidity": 57.8}
[MQTT] Message 2 delivered

To keep the telemetry script running in the background and auto-start on boot, create a systemd service:

Terminal window
sudo nano /etc/systemd/system/siliconwit-sensor.service

Add the following content (adjust the User and paths to match your setup):

[Unit]
Description=SiliconWit IO DHT22 Telemetry
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=pi
WorkingDirectory=/home/pi/siliconwit-sensor
ExecStart=/home/pi/siliconwit-sensor/venv/bin/python telemetry.py
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target

Enable and start the service:

Terminal window
sudo systemctl daemon-reload
sudo systemctl enable siliconwit-sensor
sudo systemctl start siliconwit-sensor

Check the status:

Terminal window
sudo systemctl status siliconwit-sensor

View live logs:

Terminal window
journalctl -u siliconwit-sensor -f
  1. Log in to your SiliconWit IO dashboard.
  2. Navigate to your registered device.
  3. You should see temperature and humidity readings updating every 30 seconds.
  4. SiliconWit IO automatically displays charts and a data table for each field.
  5. You can configure alerts to notify you when values exceed thresholds.
SymptomCauseSolution
RuntimeError: DHT sensor not foundWrong GPIO pin or bad wiringCheck wiring matches the pin in code. Verify 3.3V and GND connections.
Constant RuntimeError on every readKernel driver conflictRun sudo apt install libgpiod2 and reboot.
Readings are NoneSensor not respondingCheck the pull-up resistor. Try a different GPIO pin.
Temperature reads 0.0Defective sensor or loose connectionRe-seat jumper wires. Try a different DHT22 module.
Permission denied on GPIOUser not in gpio groupRun sudo usermod -aG gpio $USER and log out/in.
SymptomCauseSolution
Connection refusedWrong broker address or portVerify MQTT_BROKER and MQTT_PORT (8883).
SSL: CERTIFICATE_VERIFY_FAILEDOutdated CA certificatesRun sudo apt update && sudo apt install ca-certificates.
Connection failed with code: 5Invalid credentialsVerify DEVICE_ID and ACCESS_TOKEN from your dashboard.
Connection timed outNo internet or firewall blockingCheck internet with ping 8.8.8.8. Verify port 8883 is open.
SymptomCauseSolution
Service fails to startWrong path in service fileVerify WorkingDirectory and ExecStart paths exist.
Service starts but sensor failsPermission issueEnsure the User in the service file has GPIO access.
Service restarts repeatedlyScript crashingCheck journalctl -u siliconwit-sensor for error details.

In this tutorial, you built a complete environmental monitoring system using:

  • Raspberry Pi as the computing platform
  • DHT22 sensor for temperature and humidity measurements
  • paho-mqtt for secure MQTT communication over TLS
  • SiliconWit IO as the cloud dashboard for data visualization and alerts
  • systemd for running the script as a reliable background service

The system reads real sensor data every 30 seconds and publishes it to the SiliconWit IO cloud, where you can monitor it from anywhere. This same pattern can be extended with additional sensors (barometric pressure, light level, soil moisture) by adding more fields to the JSON payload.