DTH11_온습도센서 드라이버 만들기
DTH11_온습도센서 드라이버 만들기
DTH11
온습도 센서
📌 동작원리 (Datasheet기반)
1. 기본 구조
data 라인 하나로 MCU와 DHT11간 통신
2. 전압
3.5V ~ 5V DC 공급 필요
3. 통신 방식
Single Wire 양방향 Serial 통신
한 전송에 40bit
- 8bit : 습도 정수부
- 8bit : 습도 소수부
- 8bit : 온도 정수부
- 8bit : 온도 소수부
- 8bit : 체크섬
1
2
3
4
5
6
7
typedef struct{
uint8_t humidity_int;
uint8_t humidity_dec;
uint8_t temperature_int;
uint8_t temperature_dec;
uint8_t checksum;
}DHT11_Data; //40bit
4. 통신전 사전설정
- Low 전압 최소 18ms 공급
- High 전압 공급 후 20 ~ 40us 대기
5. 센서값 받기
dht11에서 LOW -> HIGH -> LOW 값을 보내오는 것을 대기
dht11로부터 수신 시작
1바이트씩 보냄 바이트당 송신 전 LOW신호를 보내옴
dht11에서 0을 보낼 때 : HIGH 신호 26 ~ 28 us 보내옴
dht11에서 1을 보낼 때 : HIGH 신호 70 us 보내옴
📌 코드
코드 보기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
void delay_us(uint32_t us) {
Ifx_TickTime ticks = IfxStm_getTicksFromMicroseconds(BSP_DEFAULT_TIMER, us);
waitTime(ticks);
}
uint8_t DHT11_ReadByte(void) {
uint8_t result = 0;
for (int i = 0; i < 8; i++) {
while (IfxPort_getPinState(DHT11_PORT.port, DHT11_PORT.pinIndex) == 0); // LOW면 대기
delay_us(30); // 26~28us면 '0', 70us면 '1'
if (IfxPort_getPinState(DHT11_PORT.port, DHT11_PORT.pinIndex)) { //70us이상일 때 High기록
result |= (1 << (7 - i)); //MSB부터 write
}
while (IfxPort_getPinState(DHT11_PORT.port, DHT11_PORT.pinIndex) == 1); // HIGH면 대기
}
return result;
}
int DHT11_process(DHT11_Data *data) {
uint8_t buffer[5] = {0};
// MCU → DHT11: Start Signal
IfxPort_setPinModeOutput(DHT11_PORT.port, DHT11_PORT.pinIndex, IfxPort_OutputMode_pushPull, IfxPort_OutputIdx_general);
IfxPort_setPinLow(DHT11_PORT.port, DHT11_PORT.pinIndex);
delay_us(18000); // 최소 18ms 동안 LOW 유지
IfxPort_setPinHigh(DHT11_PORT.port, DHT11_PORT.pinIndex);
delay_us(40); // 20~40us 동안 HIGH 유지
// MCU ← DHT11: 응답 대기
IfxPort_setPinModeInput(DHT11_PORT.port, DHT11_PORT.pinIndex, IfxPort_Mode_inputPullUp);
//DHT11에서 Low -> High -> Low 보내옴
uint32_t timeout = TIMEOUT;
while (IfxPort_getPinState(DHT11_PORT.port, DHT11_PORT.pinIndex) == 1) {
if (--timeout == 0) return -1; // 응답 없음
}
timeout = TIMEOUT;
while (IfxPort_getPinState(DHT11_PORT.port, DHT11_PORT.pinIndex) == 0) {
if (--timeout == 0) return -1;
}
timeout = TIMEOUT;
while (IfxPort_getPinState(DHT11_PORT.port, DHT11_PORT.pinIndex) == 1) {
if (--timeout == 0) return -1;
}
// 데이터 수신 (40비트 = 5바이트)
for (int i = 0; i < 5; i++) {
buffer[i] = DHT11_ReadByte();
}
// 체크섬 검증
if (buffer[4] != (buffer[0] + buffer[1] + buffer[2] + buffer[3])) {
return -2; // 체크섬 오류
}
// 데이터 저장
data->humidity_int = buffer[0];
data->humidity_dec = buffer[1];
data->temperature_int = buffer[2];
data->temperature_dec = buffer[3];
data->checksum = buffer[4];
return 0;
}