#include #include // Определения портов и битов #define DHT_PORT PORTD #define DHT_DDR DDRD #define DHT_PIN PIND #define DHT_BIT 4 // Глобальные переменные unsigned char data[5]; float temperature, humidity; // Флаг прерывания volatile unsigned char interrupt_flag = 0; // Таймер для задержки volatile unsigned int timer_counter = 0; // Прерывание таймера ISR(TIMER1_COMPA_vect) { // Увеличиваем счетчик таймера timer_counter++; // Проверяем, достигли ли мы нужной задержки if (timer_counter == 180000) { // Сбрасываем счетчик таймера timer_counter = 0; // Устанавливаем флаг прерывания interrupt_flag = 1; } } // Функция чтения данных с DHT unsigned int read_dht_hum() { int temp; unsigned char i, j; ReLoad: // Выставляем пин как выход и устанавливаем низкий уровень DHT_DDR |= (1 << DHT_BIT); DHT_PORT &= ~(1 << DHT_BIT); // Задержка 18 мс //timer_counter = 18000; timer_counter = 0; while(timer_counter < 18000) timer_counter++; //for (volatile unsigned int i = 0; i < timer_counter; i++); // Отпускаем линию и переводим пин как вход DHT_PORT |= (1 << DHT_BIT); DHT_DDR &= ~(1 << DHT_BIT); // Задержка 50 мкс //timer_counter = 50; timer_counter = 0; while(timer_counter < 50) timer_counter++; //for (volatile unsigned int i = 0; i < timer_counter; i++); // Проверяем, ответил ли датчик if (DHT_PIN & (1 << DHT_BIT)) { Serial.println("No init"); //goto ReLoad; } // Задержка 80 мкс //timer_counter = 50; timer_counter = 0; while(timer_counter < 50) timer_counter++; //for (volatile unsigned int i = 0; i < timer_counter; i++); // Принимаем 40 бит данных while (DHT_PIN & (1 << DHT_BIT)); for (j = 0; j < 5; j++) { data[j] = 0; for (i = 0; i < 8; i++) { while (!(DHT_PIN & (1 << DHT_BIT))); // Задержка 30 мкс timer_counter = 0; while(timer_counter < 30) timer_counter++; //for (volatile unsigned int i = 0; i < timer_counter; i++); if (DHT_PIN & (1 << DHT_BIT)) data[j] |= 1 << (7 - i); while (DHT_PIN & (1 << DHT_BIT)); } } // Проверяем контрольную сумму if ((unsigned char)(data[0] + data[1] + data[2] + data[3]) != data[4]) { Serial.println("Check summ error"); //goto ReLoad; } } // Установка таймера void setup_timer() { // Настраиваем таймер 1 в режиме CTC TCCR1A = (1 << WGM12); TCCR1B = (1 << CS12) | (1 << WGM13); // Устанавливаем значение сравнения для частоты 1 Гц OCR1A = 15624; // Разрешаем прерывание сравнения A TIMSK1 |= (1 << OCIE1A); } // Настройка void setup() { // Инициализируем UART Serial.begin(9600); // Настраиваем таймер setup_timer(); // Разрешаем прерывания sei(); } // Основной цикл void loop() { // Ожидаем прерывания while (interrupt_flag); // Сбрасываем флаг прерывания interrupt_flag = 0; // Читаем данные с DHT read_dht_hum(); // Вычисляем температуру и влажность temperature = (data[3] * 0.1) + ((data[2] & 0b01111111) * 25.6); if (data[2] & 0b10000000) temperature *= -1; humidity = (data[1] * 0.1) + (data[0] * 25.6); // Выводим данные на UART Serial.print(humidity); Serial.print("% "); Serial.print(temperature); Serial.println("C"); }