All projects
06Live

Temperature & Humidity

Read temperature and humidity from a DHT11 over a one-wire protocol.

1-Wire
01

What you learn

Timing-sensitive single-wire comms: you send a command, the sensor replies with 40 bits encoded as pulse lengths. You decode each bit with a timer.

02

Parts you need

03

Wiring

ModuleBoardNote
+ / VCC3.3VDATA is 3.3V too, safe.
OUT / DATAPA2Bidirectional data line
- / GNDGND—
04

Code

main.c
1#include <stdint.h>
2#include <stdbool.h>
3#include "inc/hw_memmap.h"
4#include "driverlib/sysctl.h"
5#include "driverlib/gpio.h"
6#include "driverlib/timer.h"
7 
8#define LED_ALL (GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3)
9#define DHT_PORT GPIO_PORTA_BASE
10#define DHT_PIN GPIO_PIN_2 // PA2
11#define PWM_STEPS 256
12 
13static void showColor(uint8_t r, uint8_t g, uint8_t b, uint32_t periods) {
14 volatile uint32_t p, i;
15 for (p = 0; p < periods; p++)
16 for (i = 0; i < PWM_STEPS; i++) {
17 uint8_t out = 0;
18 if (i < r) out |= GPIO_PIN_1;
19 if (i < g) out |= GPIO_PIN_3;
20 if (i < b) out |= GPIO_PIN_2;
21 GPIOPinWrite(GPIO_PORTF_BASE, LED_ALL, out);
22 SysCtlDelay(2);
23 }
24}
25 
26static void delayMs(uint32_t ms) { SysCtlDelay((SysCtlClockGet() / 3000) * ms); }
27static void delayUs(uint32_t us) { SysCtlDelay((SysCtlClockGet() / 3000000) * us); }
28 
29static void dhtPinOut(void) { GPIOPinTypeGPIOOutput(DHT_PORT, DHT_PIN); }
30static void dhtPinIn(void) {
31 GPIOPinTypeGPIOInput(DHT_PORT, DHT_PIN);
32 GPIOPadConfigSet(DHT_PORT, DHT_PIN, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);
33}
34static int dhtLevel(void) { return GPIOPinRead(DHT_PORT, DHT_PIN) ? 1 : 0; }
35 
36// Read 5 bytes from the DHT11. Returns 1 on success, 0 on error/timeout.
37static int dhtRead(uint8_t data[5]) {
38 uint32_t i, start, us, timeout;
39 for (i = 0; i < 5; i++) data[i] = 0;
40 
41 dhtPinOut(); // start: hold low >= 18 ms
42 GPIOPinWrite(DHT_PORT, DHT_PIN, 0);
43 delayMs(20);
44 GPIOPinWrite(DHT_PORT, DHT_PIN, DHT_PIN);
45 delayUs(30);
46 dhtPinIn();
47 
48 timeout = 100000; while (dhtLevel() != 0) if (--timeout == 0) return 0; // ack low
49 timeout = 100000; while (dhtLevel() == 0) if (--timeout == 0) return 0; // ack high
50 timeout = 100000; while (dhtLevel() != 0) if (--timeout == 0) return 0; // bit0 low
51 
52 for (i = 0; i < 40; i++) {
53 timeout = 100000; while (dhtLevel() == 0) if (--timeout == 0) return 0; // 50us low ends
54 start = TimerValueGet(TIMER0_BASE, TIMER_A);
55 timeout = 100000; while (dhtLevel() != 0) if (--timeout == 0) return 0; // measure high
56 us = (TimerValueGet(TIMER0_BASE, TIMER_A) - start) / 50; // 50 MHz -> us
57 data[i / 8] <<= 1;
58 if (us > 45) data[i / 8] |= 1; // long high = 1
59 }
60 if ((uint8_t)(data[0] + data[1] + data[2] + data[3]) != data[4]) return 0; // checksum
61 return 1;
62}
63 
64int main(void) {
65 SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL |
66 SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);
67 
68 SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
69 while (!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOF)) {}
70 GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, LED_ALL);
71 
72 SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
73 while (!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOA)) {}
74 dhtPinIn();
75 
76 SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0); // free-running us timer
77 while (!SysCtlPeripheralReady(SYSCTL_PERIPH_TIMER0)) {}
78 TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC_UP);
79 TimerLoadSet(TIMER0_BASE, TIMER_A, 0xFFFFFFFF);
80 TimerEnable(TIMER0_BASE, TIMER_A);
81 
82 while (1) {
83 uint8_t d[5];
84 if (dhtRead(d)) {
85 int32_t tmp = d[2]; // d[0]=humidity%, d[2]=temp C
86 if (tmp < 18) tmp = 18; // map 18..40 C
87 if (tmp > 40) tmp = 40;
88 int32_t lv = ((tmp - 18) * 255) / 22; // 0..255
89 if (lv < 128) showColor(0, lv * 2, 255 - lv * 2, 40); // cool -> blue
90 else showColor((lv - 128) * 2, 255 - (lv - 128) * 2, 0, 40); // warm -> red
91 } else {
92 showColor(60, 25, 0, 10); // read failed -> amber blink
93 showColor(0, 0, 0, 5);
94 }
95 delayMs(1500); // DHT11 is slow: >= 1 s between reads
96 }
97}
05

Output

The simulation below runs in your browser — it mimics the real board.

temp
24 °C
humidity
45 %