- PVSM.RU - https://www.pvsm.ru -

STM32 + DHT11

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

Ошибочно я заключил что DHT11 и DS18B20 уживутся на одной шине. Оказалось протоколы у них совсем разные. После неудачного опыта, наспех собрал устройство для установления истины.
image
Готовой библиотеки DHT11 для STM32 не нашел. Для Ardino здесь [3]. Протокол связи 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 здесь [4].

Автор: tarasii

Источник [5]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/stm32/20928

Ссылки в тексте:

[1] datashit: http://www.micro4you.com/files/sensor/DHT11.pdf

[2] устройства на HCH1000+DS18B20: http://habrahabr.ru/post/153395/

[3] здесь: http://embedded-lab.com/blog/?p=4333

[4] здесь: https://github.com/tarasii/DTH11.git

[5] Источник: http://habrahabr.ru/post/160017/