ESP32驱动DHT11_dht11 esp32_bird1999625的博客-程序员宅基地

技术标签: esp32相关操作  ESP32 DHT11  ESP32温湿度传感器  

这篇文章讲一下ESP32如何驱动DHT11这一款常见的传感器,由于我也是吃的现成的,找的官方的驱动库,但是在这里做一个分享,简单教大家用法

直接贴代码:

这是DHT11.h
用法:
DHT dht(Pin_DHT11, DHT11); 这是创建温湿度传感器的控制类
程序开始之后调用这个类的dht.begin()函数初始化,就能用了,读取信息代码如下。

    float h = dht.readHumidity();           //  定义一个变量读取dht11的湿度值
    float t = dht.readTemperature();        //  定义一个变量读取dht11的温度值
    int hum = (int)h;
    if (isnan(h) || isnan(t))               //  温湿度数据校验
      Serial.println(F("******* Failed read from DHT sensor! *******"));
    else
    {
      Serial.printf("******* DHT11_T:%.1f , DHT11_H:%d *******\r\n" , t , hum);
      EQ_Demo.DHT11_T = t;
      EQ_Demo.DHT11_H = hum;
    }
/*!
 *  @file DHT.h
 *
 *  This is a library for DHT series of low cost temperature/humidity sensors.
 *
 *  You must have Adafruit Unified Sensor Library library installed to use this
 * class.
 *
 *  Adafruit invests time and resources providing this open source code,
 *  please support Adafruit andopen-source hardware by purchasing products
 *  from Adafruit!
 *
 *  Written by Adafruit Industries.
 *
 *  MIT license, all text above must be included in any redistribution
 */

#ifndef DHT_H
#define DHT_H

#include "Arduino.h"

/* Uncomment to enable printing out nice debug messages. */
//#define DHT_DEBUG

#define DEBUG_PRINTER                                                          \
  Serial /**< Define where debug output will be printed.                       \
          */

/* Setup debug printing macros. */
#ifdef DHT_DEBUG
#define DEBUG_PRINT(...)                                                       \
  { DEBUG_PRINTER.print(__VA_ARGS__); }
#define DEBUG_PRINTLN(...)                                                     \
  { DEBUG_PRINTER.println(__VA_ARGS__); }
#else
#define DEBUG_PRINT(...)                                                       \
  {} /**< Debug Print Placeholder if Debug is disabled */
#define DEBUG_PRINTLN(...)                                                     \
  {} /**< Debug Print Line Placeholder if Debug is disabled */
#endif

/* Define types of sensors. */
#define DHT11 11  /**< DHT TYPE 11 */
#define DHT12 12  /**< DHY TYPE 12 */
#define DHT22 22  /**< DHT TYPE 22 */
#define DHT21 21  /**< DHT TYPE 21 */
#define AM2301 21 /**< AM2301 */

#if defined(TARGET_NAME) && (TARGET_NAME == ARDUINO_NANO33BLE)
#ifndef microsecondsToClockCycles
/*!
 * As of 7 Sep 2020 the Arduino Nano 33 BLE boards do not have
 * microsecondsToClockCycles defined.
 */
#define microsecondsToClockCycles(a) ((a) * (SystemCoreClock / 1000000L))
#endif
#endif

/*!
 *  @brief  Class that stores state and functions for DHT
 */
class DHT {
public:
  DHT(uint8_t pin, uint8_t type, uint8_t count = 6);
  void begin(uint8_t usec = 55);
  float readTemperature(bool S = false, bool force = false);
  float convertCtoF(float);
  float convertFtoC(float);
  float computeHeatIndex(bool isFahrenheit = true);
  float computeHeatIndex(float temperature, float percentHumidity,
                         bool isFahrenheit = true);
  float readHumidity(bool force = false);
  bool read(bool force = false);

private:
  uint8_t data[5];
  uint8_t _pin, _type;
#ifdef __AVR
  // Use direct GPIO access on an 8-bit AVR so keep track of the port and
  // bitmask for the digital pin connected to the DHT.  Other platforms will use
  // digitalRead.
  uint8_t _bit, _port;
#endif
  uint32_t _lastreadtime, _maxcycles;
  bool _lastresult;
  uint8_t pullTime; // Time (in usec) to pull up data line before reading

  uint32_t expectPulse(bool level);
};

/*!
 *  @brief  Class that defines Interrupt Lock Avaiability
 */
class InterruptLock {
public:
  InterruptLock() {
#if !defined(ARDUINO_ARCH_NRF52)
    noInterrupts();
#endif
  }
  ~InterruptLock() {
#if !defined(ARDUINO_ARCH_NRF52)
    interrupts();
#endif
  }
};

#endif

这是DHT11.cpp

/*!
 *  @file DHT.cpp
 *
 *  @mainpage DHT series of low cost temperature/humidity sensors.
 *
 *  @section intro_sec Introduction
 *
 *  This is a library for DHT series of low cost temperature/humidity sensors.
 *
 *  You must have Adafruit Unified Sensor Library library installed to use this
 * class.
 *
 *  Adafruit invests time and resources providing this open source code,
 *  please support Adafruit andopen-source hardware by purchasing products
 *  from Adafruit!
 *
 *  @section author Author
 *
 *  Written by Adafruit Industries.
 *
 *  @section license License
 *
 *  MIT license, all text above must be included in any redistribution
 */

#include "DHT.h"

#define MIN_INTERVAL 2000 /**< min interval value */
#define TIMEOUT                                                                \
  UINT32_MAX /**< Used programmatically for timeout.                           \
                   Not a timeout duration. Type: uint32_t. */

/*!
 *  @brief  Instantiates a new DHT class
 *  @param  pin
 *          pin number that sensor is connected
 *  @param  type
 *          type of sensor
 *  @param  count
 *          number of sensors
 */
DHT::DHT(uint8_t pin, uint8_t type, uint8_t count) {
  (void)count; // Workaround to avoid compiler warning.
  _pin = pin;
  _type = type;
#ifdef __AVR
  _bit = digitalPinToBitMask(pin);
  _port = digitalPinToPort(pin);
#endif
  _maxcycles =
      microsecondsToClockCycles(1000); // 1 millisecond timeout for
                                       // reading pulses from DHT sensor.
  // Note that count is now ignored as the DHT reading algorithm adjusts itself
  // based on the speed of the processor.
}

/*!
 *  @brief  Setup sensor pins and set pull timings
 *  @param  usec
 *          Optionally pass pull-up time (in microseconds) before DHT reading
 *starts. Default is 55 (see function declaration in DHT.h).
 */
void DHT::begin(uint8_t usec) {
  // set up the pins!
  pinMode(_pin, INPUT_PULLUP);
  // Using this value makes sure that millis() - lastreadtime will be
  // >= MIN_INTERVAL right away. Note that this assignment wraps around,
  // but so will the subtraction.
  _lastreadtime = millis() - MIN_INTERVAL;
  DEBUG_PRINT("DHT max clock cycles: ");
  DEBUG_PRINTLN(_maxcycles, DEC);
  pullTime = usec;
}

/*!
 *  @brief  Read temperature
 *  @param  S
 *          Scale. Boolean value:
 *					- true = Fahrenheit
 *					- false = Celcius
 *  @param  force
 *          true if in force mode
 *	@return Temperature value in selected scale
 */
float DHT::readTemperature(bool S, bool force) {
  float f = NAN;

  if (read(force)) {
    switch (_type) {
    case DHT11:
      f = data[2];
      if (data[3] & 0x80) {
        f = -1 - f;
      }
      f += (data[3] & 0x0f) * 0.1;
      if (S) {
        f = convertCtoF(f);
      }
      break;
    case DHT12:
      f = data[2];
      f += (data[3] & 0x0f) * 0.1;
      if (data[2] & 0x80) {
        f *= -1;
      }
      if (S) {
        f = convertCtoF(f);
      }
      break;
    case DHT22:
    case DHT21:
      f = ((word)(data[2] & 0x7F)) << 8 | data[3];
      f *= 0.1;
      if (data[2] & 0x80) {
        f *= -1;
      }
      if (S) {
        f = convertCtoF(f);
      }
      break;
    }
  }
  return f;
}

/*!
 *  @brief  Converts Celcius to Fahrenheit
 *  @param  c
 *					value in Celcius
 *	@return float value in Fahrenheit
 */
float DHT::convertCtoF(float c) { return c * 1.8 + 32; }

/*!
 *  @brief  Converts Fahrenheit to Celcius
 *  @param  f
 *					value in Fahrenheit
 *	@return float value in Celcius
 */
float DHT::convertFtoC(float f) { return (f - 32) * 0.55555; }

/*!
 *  @brief  Read Humidity
 *  @param  force
 *					force read mode
 *	@return float value - humidity in percent
 */
float DHT::readHumidity(bool force) {
  float f = NAN;
  if (read(force)) {
    switch (_type) {
    case DHT11:
    case DHT12:
      f = data[0] + data[1] * 0.1;
      break;
    case DHT22:
    case DHT21:
      f = ((word)data[0]) << 8 | data[1];
      f *= 0.1;
      break;
    }
  }
  return f;
}

/*!
 *  @brief  Compute Heat Index
 *          Simplified version that reads temp and humidity from sensor
 *  @param  isFahrenheit
 * 					true if fahrenheit, false if celcius
 *(default true)
 *	@return float heat index
 */
float DHT::computeHeatIndex(bool isFahrenheit) {
  float hi = computeHeatIndex(readTemperature(isFahrenheit), readHumidity(),
                              isFahrenheit);
  return hi;
}

/*!
 *  @brief  Compute Heat Index
 *  				Using both Rothfusz and Steadman's equations
 *					(http://www.wpc.ncep.noaa.gov/html/heatindex_equation.shtml)
 *  @param  temperature
 *          temperature in selected scale
 *  @param  percentHumidity
 *          humidity in percent
 *  @param  isFahrenheit
 * 					true if fahrenheit, false if celcius
 *	@return float heat index
 */
float DHT::computeHeatIndex(float temperature, float percentHumidity,
                            bool isFahrenheit) {
  float hi;

  if (!isFahrenheit)
    temperature = convertCtoF(temperature);

  hi = 0.5 * (temperature + 61.0 + ((temperature - 68.0) * 1.2) +
              (percentHumidity * 0.094));

  if (hi > 79) {
    hi = -42.379 + 2.04901523 * temperature + 10.14333127 * percentHumidity +
         -0.22475541 * temperature * percentHumidity +
         -0.00683783 * pow(temperature, 2) +
         -0.05481717 * pow(percentHumidity, 2) +
         0.00122874 * pow(temperature, 2) * percentHumidity +
         0.00085282 * temperature * pow(percentHumidity, 2) +
         -0.00000199 * pow(temperature, 2) * pow(percentHumidity, 2);

    if ((percentHumidity < 13) && (temperature >= 80.0) &&
        (temperature <= 112.0))
      hi -= ((13.0 - percentHumidity) * 0.25) *
            sqrt((17.0 - abs(temperature - 95.0)) * 0.05882);

    else if ((percentHumidity > 85.0) && (temperature >= 80.0) &&
             (temperature <= 87.0))
      hi += ((percentHumidity - 85.0) * 0.1) * ((87.0 - temperature) * 0.2);
  }

  return isFahrenheit ? hi : convertFtoC(hi);
}

/*!
 *  @brief  Read value from sensor or return last one from less than two
 *seconds.
 *  @param  force
 *          true if using force mode
 *	@return float value
 */
bool DHT::read(bool force) {
  // Check if sensor was read less than two seconds ago and return early
  // to use last reading.
  uint32_t currenttime = millis();
  if (!force && ((currenttime - _lastreadtime) < MIN_INTERVAL)) {
    return _lastresult; // return last correct measurement
  }
  _lastreadtime = currenttime;

  // Reset 40 bits of received data to zero.
  data[0] = data[1] = data[2] = data[3] = data[4] = 0;

#if defined(ESP8266)
  yield(); // Handle WiFi / reset software watchdog
#endif

  // Send start signal.  See DHT datasheet for full signal diagram:
  //   http://www.adafruit.com/datasheets/Digital%20humidity%20and%20temperature%20sensor%20AM2302.pdf

  // Go into high impedence state to let pull-up raise data line level and
  // start the reading process.
  pinMode(_pin, INPUT_PULLUP);
  delay(1);

  // First set data line low for a period according to sensor type
  pinMode(_pin, OUTPUT);
  digitalWrite(_pin, LOW);
  switch (_type) {
  case DHT22:
  case DHT21:
    delayMicroseconds(1100); // data sheet says "at least 1ms"
    break;
  case DHT11:
  default:
    delay(20); // data sheet says at least 18ms, 20ms just to be safe
    break;
  }

  uint32_t cycles[80];
  {
    // End the start signal by setting data line high for 40 microseconds.
    pinMode(_pin, INPUT_PULLUP);

    // Delay a moment to let sensor pull data line low.
    delayMicroseconds(pullTime);

    // Now start reading the data line to get the value from the DHT sensor.

    // Turn off interrupts temporarily because the next sections
    // are timing critical and we don't want any interruptions.
    InterruptLock lock;

    // First expect a low signal for ~80 microseconds followed by a high signal
    // for ~80 microseconds again.
    if (expectPulse(LOW) == TIMEOUT) {
      DEBUG_PRINTLN(F("DHT timeout waiting for start signal low pulse."));
      _lastresult = false;
      return _lastresult;
    }
    if (expectPulse(HIGH) == TIMEOUT) {
      DEBUG_PRINTLN(F("DHT timeout waiting for start signal high pulse."));
      _lastresult = false;
      return _lastresult;
    }

    // Now read the 40 bits sent by the sensor.  Each bit is sent as a 50
    // microsecond low pulse followed by a variable length high pulse.  If the
    // high pulse is ~28 microseconds then it's a 0 and if it's ~70 microseconds
    // then it's a 1.  We measure the cycle count of the initial 50us low pulse
    // and use that to compare to the cycle count of the high pulse to determine
    // if the bit is a 0 (high state cycle count < low state cycle count), or a
    // 1 (high state cycle count > low state cycle count). Note that for speed
    // all the pulses are read into a array and then examined in a later step.
    for (int i = 0; i < 80; i += 2) {
      cycles[i] = expectPulse(LOW);
      cycles[i + 1] = expectPulse(HIGH);
    }
  } // Timing critical code is now complete.

  // Inspect pulses and determine which ones are 0 (high state cycle count < low
  // state cycle count), or 1 (high state cycle count > low state cycle count).
  for (int i = 0; i < 40; ++i) {
    uint32_t lowCycles = cycles[2 * i];
    uint32_t highCycles = cycles[2 * i + 1];
    if ((lowCycles == TIMEOUT) || (highCycles == TIMEOUT)) {
      DEBUG_PRINTLN(F("DHT timeout waiting for pulse."));
      _lastresult = false;
      return _lastresult;
    }
    data[i / 8] <<= 1;
    // Now compare the low and high cycle times to see if the bit is a 0 or 1.
    if (highCycles > lowCycles) {
      // High cycles are greater than 50us low cycle count, must be a 1.
      data[i / 8] |= 1;
    }
    // Else high cycles are less than (or equal to, a weird case) the 50us low
    // cycle count so this must be a zero.  Nothing needs to be changed in the
    // stored data.
  }

  DEBUG_PRINTLN(F("Received from DHT:"));
  DEBUG_PRINT(data[0], HEX);
  DEBUG_PRINT(F(", "));
  DEBUG_PRINT(data[1], HEX);
  DEBUG_PRINT(F(", "));
  DEBUG_PRINT(data[2], HEX);
  DEBUG_PRINT(F(", "));
  DEBUG_PRINT(data[3], HEX);
  DEBUG_PRINT(F(", "));
  DEBUG_PRINT(data[4], HEX);
  DEBUG_PRINT(F(" =? "));
  DEBUG_PRINTLN((data[0] + data[1] + data[2] + data[3]) & 0xFF, HEX);

  // Check we read 40 bits and that the checksum matches.
  if (data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF)) {
    _lastresult = true;
    return _lastresult;
  } else {
    DEBUG_PRINTLN(F("DHT checksum failure!"));
    _lastresult = false;
    return _lastresult;
  }
}

// Expect the signal line to be at the specified level for a period of time and
// return a count of loop cycles spent at that level (this cycle count can be
// used to compare the relative time of two pulses).  If more than a millisecond
// ellapses without the level changing then the call fails with a 0 response.
// This is adapted from Arduino's pulseInLong function (which is only available
// in the very latest IDE versions):
//   https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/cores/arduino/wiring_pulse.c
uint32_t DHT::expectPulse(bool level) {
#if (F_CPU > 16000000L)
  uint32_t count = 0;
#else
  uint16_t count = 0; // To work fast enough on slower AVR boards
#endif
// On AVR platforms use direct GPIO port access as it's much faster and better
// for catching pulses that are 10's of microseconds in length:
#ifdef __AVR
  uint8_t portState = level ? _bit : 0;
  while ((*portInputRegister(_port) & _bit) == portState) {
    if (count++ >= _maxcycles) {
      return TIMEOUT; // Exceeded timeout, fail.
    }
  }
// Otherwise fall back to using digitalRead (this seems to be necessary on
// ESP8266 right now, perhaps bugs in direct port access functions?).
#else
  while (digitalRead(_pin) == level) {
    if (count++ >= _maxcycles) {
      return TIMEOUT; // Exceeded timeout, fail.
    }
  }
#endif

  return count;
}

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/ailta/article/details/115582860

智能推荐

php内存设置,php如何设置内存大小_江边的石头房子的博客-程序员宅基地

php如何设置内存大小?在运行PHP程序,通常会遇到“Fatal Error: Allowed memory size of xxxxxx bytes exhausted”的错误, 这个意味着PHP脚本使用了过多的内存,并超出了系统对其设置的允许最大内存。解决这个问题,首先需要查看你的程序是否分配了过多的内存,在程序没有问题的情况下,你可以通过一下方法来增加PHP的内存限制(memory_limi..._服务器 3g内存 php 配置

ChatGPT深度研究:细探商业模式与供给端决定因素_人工智能学家的博客-程序员宅基地

来源:(报告出品方/作者:海通国际)1.ChatGPT:以GPT-3.5架构革新AI对话模型,商业化前景仍需探索ChatGPT 是美国 OpenAI 公司研发的对话 AI 模型,是由人工智能技术支持的自然语言 处理(NLP,Natural Language Processing)工具,于 2022 年 11 月 30 日正式发布。它 能够学习、理解人类语言,并结合对话上下文,与人类聊天互动,也可撰...

用C#对ADO.NET数据库完成简单操作_c#ado.net_abaowu的博客-程序员宅基地

用C#对ADO.NET数据库完成简单操作数据库访问是程序中应用最普遍的部分。随着C#和ADO.NET的引入,这种操作变得更简单。这篇文章将示范四种最基础的数据库操作。 ● 读取数据。其中包括多种数据类型:整型,字符串,日期型。 ● 写数据。如读数据一样,我们也需要写入多种类型的数据。这可以通过SQL语句来完成。 ● 更新或修改数据。我们将再次用到SQL语_c#ado.net

创建和使用动态链接库_singno116的博客-程序员宅基地

演练:创建和使用动态链接库 在本演练中,您将创建一个动态链接库 (DLL),其中包含可供其他应用程序使用的有用例程。使用 DLL 是一种重用代码的绝佳方式。您不必在自己创建的每个程序中重新实现这些例程,而只需对这些例程编写一次,然后从需要该功能的应用程序引用它们即可。 本演练使用本机 C++。有关使用本机 C++ 创建静态库的演练,请参见 演练:创建和使用静态库。有关使用面向公共语

【数据结构-栈】C语言实现链栈基本操作_栈如何连续输入_柘月十七的博客-程序员宅基地

C语言实现链栈基本操作链栈基本操作链栈储存结构初始化入栈出栈判断是否为空一次入栈n个元素遍历清空链栈测试代码整合链栈基本操作链栈储存结构//链栈储存结构 typedef struct StackNode{ ElemType data; struct StackNode *next;}StackNode,*LinkStack;初始化//初始化Status InitStack(LinkStack *S){ *S = NULL; //头指针置空 return OK;}入_栈如何连续输入

基于arduino的串口控制数码管(5611AH)显示数字(初学,入门级附代码)_异境入侵者的博客-程序员宅基地

基于arduino的串口控制数码管(5611AH)显示数字只有干货首先先要介绍一下数码管了,这里图片为5611AH,这种数码管主要分为共阴极和共阳极两种,这里用的是共阴极的。注意区分话不多说,直接上图片(此图为模拟图,当然我有实物,实物比较麻烦)。好了,上代码 ,当串口输入1~9是,数码管将显示相应数值。此代码较为简单易懂。(代码用到了数组),注意数组规定为几行几列但用的时候是从0行0列开始的。int ab=3;int bp=2;int cg=9;int db=10;int ep=11_5611ah

随便推点

c语言 大数加法(纯char实现)_c语言 char 相加_Asciphx的博客-程序员宅基地

作为再一次吃螃蟹不客气的天才,人狠话不多,于是咱们不废话了,直接开整。这次实现的是比cpp快100%的大数加法,纯char实现很牛币的。//最高性能大数加法char*BigPlus(char*m,char*n){ int i=0,l=0,x,y,z=0;char*j=(char*)calloc(999,sizeof(char)); while(m[++i]);while(n[++l]);x=y=i>l?i:l; while(y){if(i)j[y]+=m[--i];if(l)j[y._c语言 char 相加

TortoiseGit同步项目到gitee步骤_tortoisegit gitee_尼古拉丝的博客-程序员宅基地

1.准备工作:能够通过tortoiseGit提交代码到gitee,具体操作步骤参考文档tortoiseGit使用,文档中介绍了同步到gitlab的方法同样能用到gitee。2.进入gitee中新建的仓库,点击‘克隆/下载’,点击复制3.新建一个文件夹,打开,右键选择‘Git克隆’,将复制的url粘入,勾选加载Putty秘钥,选择对应的秘钥,点击确定按钮。4.此时会在目录下生成一个仓库的文件夹,打开文件夹可以看到有以下文件5.将项目文件夹粘贴到改文件夹下,右键点击add按钮,点击确定6.点击_tortoisegit gitee

【Day34 文献精读】Of magnitudes and metaphors: Explaining cognitive interactions between space, time,and.._余阿Adzuki的博客-程序员宅基地

阅读文献:Winter, B., Marghetis, T., & Matlock, T. (2015). Of magnitudes and metaphors: Explaining cognitive interactions between space, time, and number. cortex, 64, 209-224.文献链接:Of magnitudes and metaphors: Explaining cognitive interactions betwee..

51单片机开发 I2C读卡系统实验与IIC多机通信实验及proteus仿真_i2c多机通信_眰恦I的博客-程序员宅基地

51单片机开发 I2C读卡系统实验与IIC多机通信实验及proteus仿真_i2c多机通信

CJ01-创建项目BAPI_abap cj01 bapi_倔强的ABAPER的博客-程序员宅基地

*根据给出的流水号创建项目 DATA:ls_stru TYPE bapi_project_definition, lt_return TYPE TABLE OF bapi_meth_message WITH HEADER LINE.*FS上只标注了项目定义、描述、业务范围、成本控制范围、公司代码、工厂、负责人编号 ls_stru-project_definition =..._abap cj01 bapi

iOS个推消息推送的使用_来自南方的熊的博客-程序员宅基地

3分钟DEMO快速集成演示(iOS)转至元数据结尾转至元数据起始本文档介绍了如何利用SDK包中的Demo源码快速编译进行推送测试的简单步骤,如有更多疑问,请联系我们 第一步:创建个推开发者帐号第二步:登记新应用第三步:下载开发工具包第四步:把Demo(ios项目)在XCode中打开第五步:修改工程设置第六步:真机运行Dem

推荐文章

热门文章

相关标签