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

STM32 + DHT11

DIY или Сделай сам
Попал мне в руки датчик температуры и влажности 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 здесь.
Теги:STM32DHT11
Хабы: DIY или Сделай сам
Всего голосов 28: ↑23 и ↓5 +18
Просмотры54.7K

Похожие публикации

Программист микроконтроллеров (embedded)
до 80 000 ₽ГК «ЭКОМЕР»Новосибирск
C Разработчик (Embedded)
от 120 000 ₽Flipper Devices Inc.МоскваМожно удаленно
Веб-разработчик (Backend или Fullstack)
от 80 000 до 200 000 ₽PlenexyМожно удаленно
Дизайнер UI\UX (уверенный Junior или Middle)
от 70 000 ₽Red Circle AIМожно удаленно
PHP-разработчик (стажер, удаленно или офис)
от 50 000 до 150 000 ₽Aveds.ruМожно удаленно

Лучшие публикации за сутки