【问题标题】:Embedded DHT11, temperature turns to 0 after first print内嵌 DHT11,首次打印后温度变为 0
【发布时间】:2019-10-08 16:49:34
【问题描述】:

所以,我正在尝试在 C 环境中设置一个 DHT11,以尝试学习更多的嵌入式软件编程。

我在 other sourcesdocumentation 的帮助下创建了这个,温度只显示一次,然后默认为 0。

我使用 Arduino 作为微控制器(因为它是我唯一拥有的)并使用 Linux Ubuntu 环境将程序加载到微控制器中。

最后,代码是这样的:

#include <avr/io.h>
#include <stdio.h>
#include <stdlib.h>
#include <util/delay.h>

#include "dht.h"

// Trying to set up the DHT11 so it can be used in this project
void read() {

  // The bits are for to get the temperature values in.
  // reqCounter is for the request later on.
  uint8_t bits[5];

  // Setting up the DDRD as OUTPUT and PORTD as HIGH
  DDRD |= (1 << DDD5);
  PORTD |= (1 << PORTD5);
  _delay_ms(100);

  /*
   * Makes an request to get the data from the DHT11
   * Set the the PORTD5 as LOW
  */
  PORTD &= ~(1 << PORTD5);
  _delay_ms(18);
  // Setting it back to high and DDRD as an input
  PORTD |= (1 << PORTD5);
  _delay_us(1);
  DDRD &= ~(1 << DDD5);

  /*
   * Checking to see if the ACK is happening
  */
  _delay_us(39);
  if ((PIND & (1 << PIND5))) {
    return;
  }
  _delay_us(80);
  if (!(PIND & (1 << PIND5))) {
    return;
  }
  _delay_us(80);

  // Holds the temperature 
  uint8_t temp;

  // Reading the data
  for (uint8_t i = 0; i < 5; i++) {
    // Create a for loop that looks in to every 8 bits
    for (uint8_t j = 0; j < 8; j++) {
      // While it isn`t high, loop this while loop
      while (!(PIND & (1 << PIND5)))
              ;
        _delay_us(30);
        // Looking if the input is still high after 30us
        if (PIND & (1 << PIND5)) {
          temp |= (1 << (7-i));
        }
        // Wait until the input is low.
        while (PIND & (1 << PIND5))
          ;
    }
      // Put the temperature in the bit array
      bits[i] = temp;
  }

  // Resets the pins
  DDRD |= (1 << DDD5);
  PORTD |= (1 << PORTD5);
  _delay_ms(100);

  uint8_t temperature ;
  //checks the sum and gets the temperature 
  if (bits[0] + bits[1] + bits[2] + bits[3] == bits[4]) {
    temperature = bits[2];
  }

  printf("temperature : %d\n", temperature );
  /*printf("%d", bits[0]);
  printf("%d", bits[1]);
  printf("%d", bits[2]);
  printf("%d", bits[3]);
  printf("%d\n", bits[4]);*/
}

这只会产生 15 次,然后记录更多。我试图吹它以提高温度,但没有任何反应。

这可能是什么问题?

提前致谢

【问题讨论】:

  • 请在第一个 while 循环后仔细检查缩进,它不一致且在逻辑上具有误导性。
  • 我对这个temp |= (1 &lt;&lt; (7-i)); 有一种不好的感觉,感觉它想要一个j 而不是i。它最初还使用未初始化的temp。我认为您想在内部for 之前将外部for 中的温度初始化为0。
  • 让我知道我的 cmets 是否解决了这个问题(在这里写一个评论,其中包括“@Yunnosch”)。然后我会给他们一些解释的答案。
  • 我知道在等待反馈时我应该耐心等待。但是问一个问题然后上床睡觉是一种习惯,通常会对我的情绪产生一定的影响......
  • 我的回答可能无法解决您的问题,但无论如何它在语义上都是不正确的。我不知道bits[0] + bits[1] + bits[2] + bits[3] == bits[4] 的表达方式是什么,或者即使它会起作用,但我正在努力解决这个似是而非的问题——奇怪的代码。指向温度传感器数据表的链接和有关其连接方式的信息会很有帮助,并且会链接到神秘的“其他来源和文档”。很多人都可以在不熟悉 DHT11 或读取它所需的 I/O 和处理的情况下提供帮助。

标签: c embedded


【解决方案1】:

这里:

  uint8_t temperature ;
  //checks the sum and gets the temperature 
  if (bits[0] + bits[1] + bits[2] + bits[3] == bits[4]) {
    temperature = bits[2];
  }

  printf("temperature : %d\n", temperature );

如果 bits[0] + bits[1] + bits[2] + bits[3] == bits[4]false,则温度会被初始化(并且可以是任何值 - 包括 0 或 15,其中一个值是垃圾)。

也许:

static uint8_t temperature = 0 ;

这样当bits[0] + bits[1] + bits[2] + bits[3] != bits[4] 时,将使用最后一个有效温度。

或者更简单地说,如果temperature 不会在其他地方使用:

  //checks the sum and gets the temperature 
  if (bits[0] + bits[1] + bits[2] + bits[3] == bits[4]) 
  {
      printf( "temperature : %d\n", bits[2] ) ;
  }

我想在这里发生的是 temperature 的未初始化值恰好是 15 并且您打印它,然后 bits[0] + bits[1] + bits[2] + bits[3] == bits[4] 变为 true 并且 bits[2] 始终为零。在这种情况下,错误在于输入和放在bits[] 中的值,此解决方案将导致值始终为零。

【讨论】:

  • 这里也有同样的错误:uint8_t temp; ... temp |= (1 &lt;&lt; (7-i));
  • @Lundin 是的,我不怀疑,Yunnosch 已经提到过,但这是一个明显的总是不正确的问题,不需要任何知识或分析代码旨在工作。根据我的经验,如果犯了一个根本性的错误,很可能还有其他错误。从 user3629249 的 cmets 来看,无论如何,整个部分都坏了。
  • 嘿。谢谢你。因此,我将其更改为 static uint8_t temp = 0;static uint8_t temperature = 0 ;,现在我得到 160,然后是 184。它似乎朝着正确的方向发展。但是,我仍然遇到即使我吹它也无法改变温度的情况。同样,我在嵌入式或软件开发方面不是最好的(非常初级),所以我想问一下您是否还有其他问题。
  • 另外一点:我试着自己打印所有的位,看看它的样子。我得到的是所有位首先具有不同的值,然后它们都具有 184。
  • @Ravoos temp 也需要初始化,但它不需要是静态的,事实上这是一个错误。确定算法是否有效需要了解传感器,如我的 cmets 中所述。其他 cmets 表明它存在缺陷。在我进一步考虑之前,您需要在问题中包含所要求的信息。也就是说,如果您通过改进问题来回应 cmets 对问题的改进,您更有可能得到答案。
【解决方案2】:

所以,谢谢大家的帮助,但我已经设法找到一种方法让它发挥作用。 如果你想知道怎么做,我已经把它放在pastebin 让大家看看。

但简而言之,我做了一个更改,使它在 for 循环中看起来更像这样:

    // Reading the data and starts with bits 0 up to 4
  for (j = 0; j < 5; j++) {
        uint8_t result = 0;
    // I read every bit in the system to be able to get it in to the bits.
        for (i = 0; i < 8; i++) {
            while (!(PIND & (1 << PIND5)))
                ; //wait for an HIGH input
        // delay for 30us
            _delay_us(30);
      //if the input is HIGH then I will put the data in result
            if (PIND & (1 << PIND5))
                result |= (1 << (7 - i));
            while (PIND & (1 << PIND5))
                ; //wait until input get LOW
        }
    //Put the result in the bit
        bits[j] = result;
    }

很抱歉给您带来不便,谢谢大家。

【讨论】:

  • 多一点还是完全这样? 多一点有什么用?我需要做很多工作才能看到这与您的原始代码或您在原始代码中作为源链接的代码有何不同/在哪里不同。一个很好的回答你的亮点并解释这些差异。
【解决方案3】:

不清楚您为什么选择重写(并中断)“other sources”处的代码,而不是简单地按原样使用它:

void read( void )
{
    printf("temperature : %d\n", (int)DHT11_GetData(DHT11_DATA_TEMPERATURE)) ;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多