Как стать автором
Обновить

STM32 + DHT11

Время на прочтение 2 мин
Количество просмотров 106K
Попал мне в руки датчик температуры и влажности DHT11. Измеряет влажность в пределах 20-90% и температуру от 0 до 50°С. Погрешность измерения влажности 5%, температуры 2°С. Время захвата 1 сек. Интерфейс связи single wire (datashit). Столь скромные параметры ограничивают область применения датчика только бытовыми даже комнатными условиями.
image
Я хотел сравнить показания устройства на HCH1000+DS18B20 с DHT11.

Ошибочно я заключил что DHT11 и DS18B20 уживутся на одной шине. Оказалось протоколы у них совсем разные. После неудачного опыта, наспех собрал устройство для установления истины.
image
Готовой библиотеки DHT11 для STM32 не нашел. Для Arduino здесь. Протокол связи single wire не имеет ничего общего с 1-wire. Разница между 0 и 1 получается из разницы длительности импульса.
image
Сперва удерживаем порядка 20 мс низкий уровень шины, потом отпускаем ее, через 20 мс датчик зажимает ее в 0 сам и держит 80 мкс потом отпускает на 80 мкс (формирует сигнал присутствия) за ним следует 40 бит данных, с одинаковым стартом — зажатием шины на 50 мкс и битом. бит 0 где-то 28 мкс, бит 1 — 70 мкс. Ну и на прощание датчик зажимает и отпускает шину. 40 бит данных это 5 байт из которых первых два влажность, следующие 2 температура и байт четности. Байт четности равен сумме предыдущих байт. 1-й байт и 3-й байты передают значения, 2 и 4 я так понял зарезервированы под десятые доли.
Самый простой способ считать длительность импульсов и записывать их в массив. Потом этот массив трансформировать в массив байт.Так родилась библиотека dht11.c.
uint16_t read_cycle(uint16_t cur_tics, uint8_t neg_tic){
  uint16_t cnt_tics;
  
  if (cur_tics < MAX_TICS) cnt_tics = 0;
  if (neg_tic) {
    while (!GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_3)&&(cnt_tics<MAX_TICS)){
      cnt_tics++;
    }
  } else {
    while (GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_3)&&(cnt_tics<MAX_TICS)){
      cnt_tics++;
    }
  }
  return cnt_tics;
}

uint8_t read_DHT11(uint8_t *buf){
  uint16_t dt[42];
  uint16_t cnt;
  uint8_t i, check_sum;

  //reset DHT11
  Delay(500);
  GPIO_LOW(GPIOA,GPIO_Pin_2);
  Delay(20);
  GPIO_HIGH(GPIOA,GPIO_Pin_2);

  //start reading
  cnt = 0;
  for(i=0;i<83 && cnt<MAX_TICS;i++){
    if (i & 1){
      cnt = read_cycle(cnt, 1);
    } else {
      cnt = read_cycle(cnt, 0);
      dt[i/2]= cnt;
    }
  }

  //release line
  GPIO_HIGH(GPIOA,GPIO_Pin_2);

  if (cnt>=MAX_TICS) return DHT11_NO_CONN;

  //convert data
  for(i=2;i<42;i++){
    (*buf) <<= 1;
     if (dt[i]>20) (*buf)++;
     if (!((i-1)%8) && (i>2)) buf++; 
  }

  //calculate checksum
  buf -= 5;
  check_sum = 0;
  for(i=0;i<4;i++){
    check_sum += *buf;
    buf++;
  }

  if (*buf != check_sum) return DHT11_CS_ERROR;

  return DHT11_OK;	
}

Проект содержащий библиотеку dht11.c здесь.
Теги:
Хабы:
+18
Комментарии 33
Комментарии Комментарии 33

Публикации

Истории

Ближайшие события

Московский туристический хакатон
Дата 23 марта – 7 апреля
Место
Москва Онлайн
Геймтон «DatsEdenSpace» от DatsTeam
Дата 5 – 6 апреля
Время 17:00 – 20:00
Место
Онлайн
PG Bootcamp 2024
Дата 16 апреля
Время 09:30 – 21:00
Место
Минск Онлайн
EvaConf 2024
Дата 16 апреля
Время 11:00 – 16:00
Место
Москва Онлайн