关于#arduino#的问题,如何解决?

问题遇到的现象和发生背景

我在用温度湿度传感器时,出现问题

用代码块功能插入代码,请勿粘贴截图
#include 
#include 

//温湿度
class dht11
{
  public:
    int dht11_read();
    void show();
  private:
    //连接引脚
    const char dht11_Pin = 8;
    uint8_t bits[5];//接受数据
    double humidity;   //湿度
    double temperature;//温度

};
void dht11::show()
{
  int chk = dht11_read();
  Serial.print("Read sensor: ");
  switch (chk)
  {
    case 0:
      Serial.println("OK");
      break;
    case -1:
      Serial.println("Checksum error");
      break;
    case -2:
      Serial.println("Time out error");
      break;
    default:
      Serial.println("Unknown error");
      break;
  }

  Serial.print("Humidity (%): ");
  Serial.println((float)humidity, 2);

  Serial.print("Temperature (oC): ");
  Serial.println((float)temperature, 2);

}
int dht11::dht11_read()
{
  int idx = 0;
  int cnt = 7;
  const char ok = 0;
  const char sum_error = -1;
  const char time_error = -2;

  pinMode(dht11_Pin, OUTPUT);//引脚设置为输出模式
  digitalWrite(dht11_Pin, LOW);//由于空闲时为高电平状态,需拉低等待DHT11相应
  delay(18);  //需要拉低必须大于18毫秒
  digitalWrite(dht11_Pin, HIGH);//再拉高
  delayMicroseconds(40);//需要等待20~40微秒后
  pinMode(dht11_Pin, INPUT);//这时DHT11开始接收主机的开始信号,故需设置为输入模式
  //确认或超时
  unsigned int loopCnt = 10000;
  while (digitalRead(dht11_Pin) == LOW)
    if (loopCnt-- == 0) return time_error;
  loopCnt = 10000;
  while (digitalRead(dht11_Pin) == HIGH)
    if (loopCnt-- == 0) return time_error;
  //从下面开始读取数据,因为40位,所以要循环40次,每次一位
  for (int i = 0; i < 40; i++)
  {
    loopCnt = 10000;
    while (digitalRead(dht11_Pin) == LOW)
      if (loopCnt-- == 0) return time_error;  //同样有可能超时失效。
    unsigned long t = micros(); //micros()记录板子上电的时间(微秒)
    loopCnt = 10000;
    while (digitalRead(dht11_Pin) == HIGH) //这里就把高电平读出来了
      if (loopCnt-- == 0) return time_error;
    if ((micros() - t) > 40) bits[idx] |= (1 << cnt);
    if (cnt == 0)   //cnt为0。
    {
      cnt = 7;    // restart at MSB
      idx++;      // next byte!
    }
    else cnt--;
    //如果cnt不为0就表示这个八位的数据还没有读完,这时只需要让cnt-1,来填充下一位数据就可以了。
    //注意,在初始化的过程中我们把这40位的数据都初始化为0了,所以只有当有1出现时才需要进行改变。
  }
  humidity    = bits[0];  //湿度,第1个8位是湿度的整数部分
  temperature = bits[2];  //温度,第3个8位是温度的整数部分
  uint8_t sum = bits[0] + bits[2];//总和
  if (bits[4] != sum) return sum_error;
  Serial.print(5);
  return ok;
}



void setup() {
  // put your setup code here, to run once:
  //设置主机
  Wire.begin();
  //串口通信9600比特率
  Serial.begin(9600);
}

void loop() {
 

  //温湿度
  dht11 t_h;
  t_h.show();
  Serial.print(t_h.dht11_read());

  Serial.println();


}

运行结果及报错内容

编译成功,未出错

我的解答思路和尝试过的方法

与它对照

const int dht11Pin = 8;   //连接2号引脚
//定义湿度传感器的几种状态和版本
#define DHTLIB_OK        0
#define DHTLIB_ERROR_CHECKSUM -1
#define DHTLIB_ERROR_TIMEOUT  -2
#define DHT11LIB_VERSION "0.4.1"
int humidity;
int temperature;

//dht11Read函数中的变量
uint8_t bits[5];  //一次完整的数据传输为40bit,每8bit为一个数据,即:数组个数为5
uint8_t cnt = 7; //这个是用来给每一个数据的每一位输入值时计数用的。
uint8_t idx = 0; //这个是给5个数组计数用的。

double Fahrenheit(double celsius) //摄氏温度度转化为华氏温度
{
  return 1.8 * celsius + 32;
}   

double Kelvin(double celsius)     //摄氏温度转化为开氏温度
{
  return celsius + 273.15;
}    

// 露点(点在此温度时,空气饱和并产生露珠)
// 参考: http://wahiduddin.net/calc/density_algorithms.htm
double dewPoint(double celsius, double humidity)
{
  double A0 = 373.15 / (273.15 + celsius);
  double SUM = -7.90298 * (A0 - 1);
  SUM += 5.02808 * log10(A0);
  SUM += -1.3816e-7 * (pow(10, (11.344 * (1 - 1 / A0))) - 1) ;
  SUM += 8.1328e-3 * (pow(10, (-3.49149 * (A0 - 1))) - 1) ;
  SUM += log10(1013.246);
  double VP = pow(10, SUM - 3) * humidity;
  double T = log(VP / 0.61078); // temp var
  return (241.88 * T) / (17.558 - T);
}

// 快速计算露点,速度是5倍dewPoint()
// 参考: http://en.wikipedia.org/wiki/Dew_point
double dewPointFast(double celsius, double humidity)
{
  double a = 17.271;
  double b = 237.7;
  double temp = (a * celsius) / (b + celsius) + log(humidity / 100);
  double Td = (b * temp) / (a - temp);
  return Td;
}

//根据时序图定义函数,用来读取具体数值
int dht11Read(int pin){
  pinMode(dht11Pin, OUTPUT);//引脚设置为输出模式
  digitalWrite(dht11Pin, LOW);//由于空闲时为高电平状态,需拉低等待DHT11相应
  delay(18);  //需要拉低必须大于18毫秒
  digitalWrite(dht11Pin, HIGH);//再拉高
  delayMicroseconds(40);//需要等待20~40微秒后
  pinMode(dht11Pin, INPUT);//这时DHT11开始接收主机的开始信号,故需设置为输入模式

//确认或超时
  unsigned int loopCnt = 10000;
  while (digitalRead(dht11Pin) == LOW)//从时序图中可以看出,接受数据一开始首先要读取80微秒的低电平,这里是一个等待,要把这80微秒等过去,但是有时候也有可能是传感器出现了故障,他一直发低电平,如果你持续等待不就相当于死机了,所以在这里要设置一个超时,也就是说要等待,但时间长了,就认为出问题了,返回一个异常信息。
    if (loopCnt-- == 0) return DHTLIB_ERROR_TIMEOUT;
  loopCnt = 10000;
  while (digitalRead(dht11Pin) == HIGH)//从时序图中可以看出,在80微秒的低电平之后是80微秒的高电平,这里仍然要等待,超时的原理与上面的低电平一样。
    if (loopCnt-- == 0) return DHTLIB_ERROR_TIMEOUT;
//从下面开始读取数据,因为40位,所以要循环40次,每次一位
  for (int i = 0; i < 40; i++)
  {
    loopCnt = 10000;
    while (digitalRead(dht11Pin) == LOW)//这句是等待低电平过去.根据时序图,可以看出,对于每一个bite位数据,都是由一个低电平和一个高电平组成,区分这一位数据是1还是0取决于高电平的时常,如果高电平的时常为70微秒则表示1,如果高电平的时常为26~28微秒则表示0,因此读取每一位数据时,都是先等待把50微秒的低电平等过去,然后判断高电平的时常,根据这个时常来判断这bite的数据是1还是0.
      if (loopCnt-- == 0) return DHTLIB_ERROR_TIMEOUT;  //同样有可能超时失效。
    unsigned long t = micros(); //micros()记录板子上电的时间(微秒)
    loopCnt = 10000;
    while (digitalRead(dht11Pin) == HIGH) //这里就把高电平读出来了
      if (loopCnt-- == 0) return DHTLIB_ERROR_TIMEOUT;
    if ((micros() - t) > 40) bits[idx] |= (1 << cnt);//然后再次使用micros()函数获取当前时间,减去读取高电平之前的时间点,也就是这个高电平的时常了,然后看这个时常是否大于40微秒,如果大于就认为是1,否则就认为这位是0.那么这里又是怎么运算的呢?分析下:bits[idx]表示一个8位的数组,假设他是0000 0000,运算符“|=”表示按位进行或运算,然后再把运算的结果赋给运算符左边的变量。而(1 << cnt)表示把数字1的二进制表示法向左移动cnt位,移动后的空位用0来填充。因此,对于一个八位的1可以表示为:0000 0001,刚才的初始化过程中我们知道cnt的值为7,所以,把这个0000 0001左移七位就变成了:1000 0000.然后将这个数与0000 0000进行|=运算,之后bits[idx]中的值就是1000 0000。可见这段代码实现的功能就是如果的到的这位数据是1,就将他存储到bits[idx]相应的位上去。
    if (cnt == 0)   //cnt为0表示一个8位的数组已经装满了,要换到下一个八位的数组上去,于是就把cnt复原为7,idx++让idx直到bits的下一个八位的数组上去。
    {
      cnt = 7;    // restart at MSB
      idx++;      // next byte!
    }
    else cnt--;
    //如果cnt不为0就表示这个八位的数据还没有读完,这时只需要让cnt-1,来填充下一位数据就可以了。
    //注意,在初始化的过程中我们把这40位的数据都初始化为0了,所以只有当有1出现时才需要进行改变。
  }
  humidity    = bits[0];  //湿度,第1个8位是湿度的整数部分
  temperature = bits[2];  //温度,第3个8位是温度的整数部分
  uint8_t sum = bits[0] + bits[2];//总和
  if (bits[4] != sum) return DHTLIB_ERROR_CHECKSUM;
  return DHTLIB_OK;
}

void setup() {
  Serial.begin(9600);
  Serial.println("DHT11 TEST PROGRAM ");
  Serial.print("LIBRARY VERSION: ");
  Serial.println(DHT11LIB_VERSION);
  Serial.println();

}

void loop() {
  Serial.println("\n");
  int chk = dht11Read(dht11Pin);
  Serial.print("Read sensor: ");
  switch (chk)
  {
    case DHTLIB_OK:
      Serial.println("OK");
      break;
    case DHTLIB_ERROR_CHECKSUM:
      Serial.println("Checksum error");
      break;
    case DHTLIB_ERROR_TIMEOUT:
      Serial.println("Time out error");
      break;
    default:
      Serial.println("Unknown error");
      break;
  }

  Serial.print("Humidity (%): ");
  Serial.println((float)humidity, 2);

  Serial.print("Temperature (oC): ");
  Serial.println((float)temperature, 2);

  Serial.print("Temperature (oF): ");
  Serial.println(Fahrenheit(temperature), 2);

  Serial.print("Temperature (K): ");
  Serial.println(Kelvin(temperature), 2);

  Serial.print("Dew Point (oC): ");
  Serial.println(dewPoint(temperature, humidity));

  Serial.print("Dew PointFast (oC): ");
  Serial.println(dewPointFast(temperature, humidity));

  delay(2000);
}

我想要达到的结果

输出正常结果即ok