#include "DHT.h"
#define DHTPIN 2 // Digital pin connected to the DHT sensor
// Uncomment whatever type you're using!
//#define DHTTYPE DHT11 // DHT 11
#define DHTTYPE DHT11 // DHT 11 (AM2302), AM2321
//#define DHTTYPE DHT21 // DHT 21 (AM2301)
DHT dht(DHTPIN, DHTTYPE);
void setup() {
Serial.begin(9600);
Serial.println(F("DHTxx test!"));
dht.begin();
}
void loop() {
// Wait a few seconds between measurements.
delay(2000);
// Reading temperature or humidity takes about 250 milliseconds!
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
float h = dht.readHumidity();
// Read temperature as Celsius (the default)
float t = dht.readTemperature();
// Read temperature as Fahrenheit (isFahrenheit = true)
float f = dht.readTemperature(true);
// Check if any reads failed and exit early (to try again).
if (isnan(h) || isnan(t) || isnan(f)) {
Serial.println(F("Failed to read from DHT sensor!"));
return;
}
// Compute heat index in Fahrenheit (the default)
float hif = dht.computeHeatIndex(f, h);
// Compute heat index in Celsius (isFahreheit = false)
float hic = dht.computeHeatIndex(t, h, false);
Serial.print(F("Humidity: "));
Serial.print(h);
Serial.print(F("% Temperature: "));
Serial.print(t);
Serial.print(F("°C "));
Serial.print(f);
Serial.print(F("°F Heat index: "));
Serial.print(hic);
Serial.print(F("°C "));
Serial.print(hif);
Serial.println(F("°F"));
}
아두이노 우노와 연결해서 시리얼 모니터에 온/습도 측정
#ifndef F_CPU
#define F_CPU 16000000UL // 16MHz 클럭 설정
#endif
#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>
#include <string.h>
#include "UART0.h" //기존에 했던 헤더파일, uart통신 관련 선언이 들어있음 UART0.c와 함께 사용
// --- 설정: DHT11 연결 핀 (아두이노 D2 = PORTD 2) ---
#define DHT_PIN PD2
#define DHT_DDR DDRD
#define DHT_PORT PORTD
#define DHT_PIN_REG PIND
uint8_t bits[5]; // 습도 정수, 습도 소수, 온도 정수, 온도 소수, 체크섬 저장
// [4] DHT11 데이터 수신 로직
int8_t dht11_read() {
uint8_t j = 0, i = 0;
memset(bits, 0, sizeof(bits));
// 1. Start Signal
DHT_DDR |= (1 << DHT_PIN); // 출력 모드
DHT_PORT &= ~(1 << DHT_PIN); // LOW로 내림
_delay_ms(18); // 최소 18ms 유지
DHT_PORT |= (1 << DHT_PIN); // HIGH로 올림
_delay_us(40); // 20~40us 대기
DHT_DDR &= ~(1 << DHT_PIN); // 입력 모드로 전환 (Pull-up에 의해 HIGH 유지)
// 2. Sensor Response 확인
_delay_us(40);
if (DHT_PIN_REG & (1 << DHT_PIN)) return -1; // Response LOW가 안 오면 에러
_delay_us(80);
if (!(DHT_PIN_REG & (1 << DHT_PIN))) return -1; // Response HIGH가 안 오면 에러
_delay_us(80);
// 3. 40비트 데이터 읽기
for (j = 0; j < 5; j++) {
for (i = 0; i < 8; i++) {
while (!(DHT_PIN_REG & (1 << DHT_PIN))); // HIGH가 될 때까지 대기
_delay_us(30); // 30us 대기 후 핀 상태 확인
if (DHT_PIN_REG & (1 << DHT_PIN)) {
bits[j] |= (1 << (7 - i)); // 30us 후에도 HIGH면 비트 '1'
}
while (DHT_PIN_REG & (1 << DHT_PIN)); // 다시 LOW가 될 때까지 대기
}
}
// 4. 체크섬 확인 (바이트 0+1+2+3 == 바이트 4)
if (bits[0] + bits[1] + bits[2] + bits[3] == bits[4]) return 0;
return -2; // 체크섬 오류
}
int main(void) {
char buf[64];
UART0_init();
UART0_print_string("--- DHT11 AVR System Start ---\r\n");
while (1) {
int8_t result = dht11_read();
if (result == 0) {
// 성공 시 출력 (정수 부분만 사용해도 DHT11은 충분합니다)
sprintf(buf, "Hum: %d.%d%% Temp: %d.%dC\r\n",
bits[0], bits[1], bits[2], bits[3]);
UART0_print_string(buf);
} else if (result == -1) {
UART0_print_string("Sensor No Response!\r\n");
} else {
UART0_print_string("Checksum Error!\r\n");
}
_delay_ms(2000); // 센서 안정화를 위해 2초 대기
}
}
#include "UART0.h"
void UART0_init(void)
{
UBRR0H = 0x00;
UBRR0L = 207; // 9,600 보율 설정
UCSR0A |= _BV(U2X0); // 2배속 모드
UCSR0C = 0x06; // 비동기, 8비트 데이터, 패리티 없음, 1비트 정지 비트
UCSR0B |= _BV(RXEN0); // 수신 가능
UCSR0B |= _BV(TXEN0); // 송신 가능
}
void UART0_transmit(char data)
{
while(!(UCSR0A & (1<<UDRE0))); // 송신 대기
UDR0 = data;
}
unsigned char UART0_receive(void)
{
while(!(UCSR0A & (1<<RXC0))); // 수신 대기
return UDR0;
}
void UART0_print_string(char *str)
{
for(int i = 0; str[i]; i++)
UART0_transmit(str[i]);
}
void UART0_print_1_byte_number(uint8_t n)
{
char numString[4] = "0";
int i, index = 0;
if(n > 0) {
for(i = 0; n != 0; i++) {
numString[i] = n % 10 + '0';
n = n / 10;
}
numString[i] = '\0';
index = i - 1;
}
for(i = index; i >= 0; i--)
UART0_transmit(numString[i]);
}