Пользователь
0,0
рейтинг
24 ноября 2012 в 03:27

STM32 + DHT11

Попал мне в руки датчик температуры и влажности 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 здесь.
@tarasii
карма
23,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое

Комментарии (33)

  • +38
    Datashit. Ради бога, не исправляйте опечатку, скольким людям она радости принесет!
    • +4
      Судя по самому датчику и его точности, у него реально — datashit. :)
      • 0
        А что посоветуете как аналог для измерения влажности?
        • 0
          Хотя бы старшего «брата» DHT22 или hs1101
        • 0
          Если интересно, могу выложить проект регулятора влажности на SHT75.
    • 0
      После чтения этого по ссылке, я пожалуй соглашусь что переименовывать не стоит — там в поверпоинте нарисован даташит и сверстан в ворде, ну и добивает техподдержка на hotmail…
  • +7
    А где собственно сравнение показаний и точности???
    • +1
      видимо автор уснул (см время публикации) и не дописал %)
    • 0
      Результаты сравнений: устройство на HCH1000 ведет себя динамичней, но калибровать шкалу по DHT11 я не стал. DHT11 уже месяц показывает 33% хотя на HCH1000 меняется от 30% до 45%. Разница в показаниях DS18B20 и DHT11 при комнатных температурах в среднем 2°С. Температура на DHT11 выглядит более правдоподобной хотя менее точной (совпадает с бытовым спиртовым термометром). Поиск и сравнение возникли от того что интуитивно кажется что DS18B20 подверает где-то на 2°С. Только включенный DS18B20 при первом считывании отдает ниже температуру чем при следующих. Купил LM35 тогда будут тесты.
      • 0
        Простите меня но ваше сравнение — чисто субъективно, это болезнь всех авторов, но вы просто вы просто в несколько десятков раз возвели все в степень, ладно с поверкой влажности, но что мешало проверить 0 и 100 температуры на датчиках и скажем взять 3 прибор — мультиметр, показания которого точны и известна его погрешность?

        Простите но ваша статья не о чем. хотя нет смысл есть, вы открыли новый датчик для меня, но сравнение тут на 0.
        • 0
          совершенно верно, потому сравнений нет в статье, я как раз работаю над методологией тестов.
      • 0
        DS18B20 при частых обращениях к нему саморазогревается и начинает завышать температуру. Поэтому сразу после включения отдает температуру ниже.
        • 0
          Минута хватит остыть? Будет ли разница между измерениями с интервалом в минуту и 10 минут?
          • 0
            Должно хватить по-моему.
  • +1
    DHT11,DHt22 или hs1101:
    где и почём взять?

    Хочу замерить ситуацию на работе и сравнить с САНПИН.
    • 0
      Буквально позавчера заказал на buyincoins.com именно DHT11 для комнаты и DHT22 для наружного применения (и если не ошибаюсь там они самые дешевые, но про качество ничего не скажу, так как еще не видел в живую).
    • 0
      DHT11 DHT22 STH21 — одно семейство, DHT22 немного лучше (есть отрицательный диапазон температур, да точность до десятых), STH21 тоже самое ток с i2c. hs1101 не знаю не пробовал. А вот HCH1000 фирменный от honeywell, купил в магазине IMRAD (в Киеве есть на радрынке) — он дешевый, но требует доп обвязки.
      • 0
        DHT22 пока лидирует в рейтинге, но он еще не приехал…
  • 0
    Вот блин, достаточно 3 дня только подумать 'как бы решить задачку терморегулирования кулером' как хабросообщество потихоньку стало отвечать :).

    Задачка примитивная, нужно регулировать вращение 1 или лучше двух кулеров (220вольт, 10-20ват, канальный вентилятор) от температуры (если температура выше границы — включать) а так же избежать дребезга (чтобы включение и выключение кулера не происходило слишком часто (пол минуты норм), мне нужен аналоговое решение (как то странно цифровое сюда втыкать), покрутить ручкой чтобы настроить граничную температуру. Работа в пределах -15...+30, граничная температура +10..+15, ошибки +-10 градусов некритичны.

    Сначала думал о бюджете в 500р, но когда увидел статьи о цифровых устройствах за 1т.р. думаю что моя задачка может оказаться дешевле….есть решения готовые?
    • 0
      DHT11 (Датчик) = 1.5$
      MSP430 Launchpad (Плата с МК) = 4.5$
      BT138 (симистор) = 1$
      MOC3063 (оптрон) = 1$
      Мелочевка(кучка резисторов и парочка разъемов) 50 рублей
      Итого имеем 8$ (250 рублей) + 50 = 300 рублей. Запрограммировать можно что угодно и как угодно. Питание это отдельный вопрос.
      • 0
        P.S. Ждать месяц если всё заказывать на ebay и ti
        • 0
          P.s умножаем на примерно 2, получаем примерно 500-600 покупаем тут, не ждем не чего)
  • 0
    Может тут кто сможет подсказать альтернативу DS18B20, чтобы а) в таком же корпусе(SO 92) б) время считывания температуры не 750 мс, а хотя бы 250
    • +2
      у этого же датчика время преобразования 94 мс, ели понизить разрешение до 9 бит
      188 мс — 10 бит
      • 0
        LM35 тотже корпус аналоговый сигнал
        • 0
          Если вам важна скорость считывания, и скорость изменения температуры датчика относительно изменения температуры внешней среды, то только аналоговые датчики — NTC-Thermistor — по сути резисторы меняющие сопротивление от температуры.
        • 0
          Аналоговые датчики не подходят для моего случая, поскольку они чувствительны к контакту и к случаям, если датчик залило водой, например. В цифровых или есть данные и они точны с определенной погрешностью, или их нет вообще.
      • 0
        Спасибо, вник в даташиты — решение приемлемо и вполне помогло ) Хотя не очень понятно зачем там 12битная точность в принципе, если погрешность 0.5 градуса
  • +1
    Хотя характеристики DHT11 более чем скромные, по опыту использования могу сказать, что температуру и влажность он замеряет с достаточной точностью для большинства домашних проектов. Судя по показаниям мультиметра точность моих экземпляров близка к одному градусу и влажность довольно хорошо измеряет — на показания метеостанции похоже и скачков на 5% не наблюдается. Конечно всегда хочется большего, но тут именно тот случай, когда под большинство «умнодомных» задач этот датчик самое оно.
    • 0
      я грешу на показания DS18B20 хотя точность велика но не совпадают с DHT11
  • +1
    Я недавно реализовал обмен с DHT22 посредством PWMI режима таймера STM32. Код тут, если интересно: pastebin.com/mY6XXVdR Завязано на FreeRTOS, но можно перенести и на голое железо.
    • 0
      спасибо, все хотел сделать — руки не доходят
  • 0
    Жалко, что нельзя несколько датчиков посадить на одну шину и обращаться к ним по адресу, а для каждого нужно использовать отдельный пин и отдельный провод.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.