В данном уроке мы подключим датчик DHT11 к микроконтроллеру Atmega8 и выведем его данные на экран.
Датчик DHT11 имеет следующий вид:
Краткий алгоритм работы датчика:
Формат данных:
Данные от датчика передаются в виде посылки, состоящих из 40 бит данных:
первые два байта влажность, следующие два температура и байт четности.
5 байт из которых первых два влажность, следующие 2 температура и байт четности:
Подключать его вывод DATA будем на порт С вывод 3.
Выводить данные будем на экран WH1604 через I2C шину.
Программный код:
#define F_CPU 4000000UL
#define DHT_PORT PORTC
#define DHT_DDR DDRC
#define DHT_PIN PINC
#define DHT_PIN_nomer 3
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include
#include
#endif /* MAIN_H_ */
рабочий файл:
#include "main.h"
typedef struct temphumi { // структура данных для DHT11
uint8_t temp;
uint8_t humi;
} temphumi_t;
int DHT_read(uint8_t _PIN, temphumi_t* _DATA);// читаем данные с датчика
void setup() {
// настраиваем порты
DDRB = 0x00;
PORTB = 0x00;
DDRC = 0x00;
PORTC = 0x00;
DDRD = 0x00;
PORTD = 0x00;
// включаем I2C шину и экран
I2C_init();
LCD_ini();
}
int main(void) {
char buff[3]; // переменная для хранения данных которые выводим на экран
temphumi_t DHT_DATA = {0 ,0}; //переменная для хранения данных которые считываем с датчика
setup();
setpos(0, 0);
str_lcd("TEMP");
setpos(0, 2);
str_lcd("HUMI");
while (1) {
if (DHT_read(DHT_PIN_nomer, &DHT_DATA) == 1) {// если данные пришли
sprintf(buff, "%d", DHT_DATA.temp);
setpos(5, 0);
str_lcd(buff);// выводим температуру
sprintf(buff, "%d", DHT_DATA.humi);
setpos(5, 2);
str_lcd(buff);// выводим влажность
}
else {// если ответа от датчика нет
setpos(5, 0);
str_lcd("----");
setpos(5, 2);
str_lcd("----");
}
_delay_ms(5000);
}
}
int DHT_read(uint8_t _PIN, temphumi_t* _DATA) {
// обнуляем переменную
uint8_t DHT_RESPONSE[5] = {0, 0, 0, 0, 0};
// формируем задержки для старта датчика
DHT_DDR |= (1 << _PIN);
DHT_PORT &= ~(1 << _PIN);
_delay_ms(18);
DHT_PORT |= (1 << _PIN);
DHT_DDR &= ~(1 << _PIN);
_delay_us(40);
//смотрим, что пришло через 54us и 80us
if(DHT_PIN & (1 << _PIN)) {
return 0;
}
_delay_us(54);
if(!DHT_PIN & (1 << _PIN)) {
return 0;
}
_delay_us(80);
//если датчик готов с нами работать - читаем 5 байт
uint8_t _bit, _byte;
while (DHT_PIN & (1 << _PIN));
for (_byte = 0; _byte < 5; _byte++) {
DHT_RESPONSE[_byte] = 0;
for (_bit = 0; _bit < 8; _bit++) {
while (!(DHT_PIN & (1 << _PIN))); // ждем ....
_delay_us(30);
if (DHT_PIN & (1 << _PIN)) { // если пришла 1, записываем ее в нужное место
DHT_RESPONSE[_byte] |= 1 << (7 - _bit);
}
while (DHT_PIN & (1 << _PIN)); // ждем окончания сигнала
}
}
// если пришли все 0 - ошибка приема данных
if (DHT_RESPONSE[0] + DHT_RESPONSE[1] + DHT_RESPONSE[2] + DHT_RESPONSE[3] == 0) { return 0; }
// проверяем данные на ликвидность
if (DHT_RESPONSE[0] + DHT_RESPONSE[1] + DHT_RESPONSE[2] + DHT_RESPONSE[3] != DHT_RESPONSE[4]) { return 0; }
// если проверка на ликвидность прошла - читаем данные.
_DATA -> humi = DHT_RESPONSE[0]; // влажность
_DATA -> temp = DHT_RESPONSE[2];// температура
return 1;
}