首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我看不懂使用RaspberryPi的温湿度传感器的源代码

我看不懂使用RaspberryPi的温湿度传感器的源代码
EN

Stack Overflow用户
提问于 2020-09-11 20:30:58
回答 2查看 75关注 0票数 0

我试图理解这个代码的含义和规则,它是湿度和温度模块。我想用C和RaspberryPi运行它。然而,即使我试图弄清楚这一点,我也不明白* part在做什么。

为什么MAXTIMINGS是85?如果句子与255相比,为什么?你能告诉我*部分是什么意思吗?

这是一个时间表和数据表链接。

(https://www.mouser.com/datasheet/2/758/DHT11-Technical-Data-Sheet-Translated-Version-1143054.pdf#search='DHT11+datasheet') enter image description here

代码语言:javascript
复制
#include <stdio.h>
#include <wiringPi.h>

#define MAXTIMINGS  85
#define DHTPIN      15  //DHT connect to TxD
int dht11_dat[5] ={0,0,0,0,0};//store DHT11 data

void read_dht11_dat()
{
    uint8_t laststate = HIGH;
    uint8_t counter = 0;
    uint8_t j = 0,i;
    float f;//fahrenheit

    dht11_dat[0] = dht11_dat[1] = dht11_dat[2] = dht11_dat[3] = dht11_dat[4] = 0;

    //pull pin down to send start signal
    pinMode( DHTPIN, OUTPUT );
    digitalWrite( DHTPIN, LOW );
    delay( 18 );
    //pull pin up and wait for sensor response
    digitalWrite( DHTPIN, HIGH );
    delayMicroseconds( 40 );
    //prepare to read the pin
    pinMode( DHTPIN, INPUT );
    ***************************************************************
    //detect change and read data
    for ( i = 0; i < MAXTIMINGS; i++ ) { 
        counter = 0; 
        while ( digitalRead( DHTPIN ) == laststate ) { 
            counter++; 
            delayMicroseconds( 1 ); 
            if ( counter == 255 ) { break; }
        }

        laststate = digitalRead( DHTPIN ); 
        if ( counter == 255 ) break; 
         //ignore first 3 transitions if ( (i >= 4) && (i % 2 == 0) )
        {
            //shove each bit into the storage bytes
            dht11_dat[j / 8] <<= 1; 
            if ( counter > 16 )dht11_dat[j / 8] |= 1;
            j++;
        }
    }
    **************************************************************************
    //check we read 40 bits(8bit x 5) +verify checksum in the last byte
    //print it out if data is good
    if ( (j >= 40) &&
         (dht11_dat[4] == ( (dht11_dat[0] + dht11_dat[1] + dht11_dat[2] + dht11_dat[3]) & 0xFF) ) )
    {
        f = dht11_dat[2] * 9. / 5. + 32;
        printf( "Humidity = %d.%d %% Temperature = %d.%d C (%.1f F)\n",
            dht11_dat[0], dht11_dat[1], dht11_dat[2], dht11_dat[3], f );
    }
    else
    {
        printf( "Data not good, skip\n" );
    }
}

int main( void )
{
    if ( wiringPiSetup() == -1 )
    {
        fprintf(stderr,"Can't init wiringPi: %s\n",strerror(errno));
        exit(EXIT_FAILURE);
    }
    print_info();
    while ( 1 )
    {
        read_dht11_dat();
        delay(1000);//wait ls to refresh
    }

    return(0);
}
EN

回答 2

Stack Overflow用户

发布于 2020-09-11 21:09:12

while ( digitalRead( DHTPIN ) == laststate )检查引脚的数字状态长达255us,如果没有发现变化,则中断外部for循环。我认为255这个数字并不重要,它只是一个超时的上限。这是一个原始的黑客使用,而不是正确地使用片上硬件计时器的输入捕获。

显然,计数器对算法也有意义,因此它似乎是在测量PWM脉冲或类似脉冲的占空比。再一次,以一种非常粗糙的方式。

我认为硬件计时器在Rasp PI“伪装的PC”上可能不容易访问-如果有一个裸机微控制器,整个事情会容易得多,也更漂亮。

//ignore first 3 transitions if ( (i >= 4) && (i % 2 == 0) )这一行是代码嗅觉。这是故意注释掉的,还是只是某人调试尝试的残留物?

台词

代码语言:javascript
复制
dht11_dat[j / 8] <<= 1; 
if ( counter > 16 )dht11_dat[j / 8] |= 1;

根据计数器是否大于16us,用1或0填充位域/字节数组。移位将先前的数据向上移动,然后LSB要么设置为1,要么保持为0。

票数 0
EN

Stack Overflow用户

发布于 2020-09-11 21:48:47

程序将引脚设置为高电平,同时向设备发送信号以进行传输。该设备传输40比特的数据,“1”和“0”由引脚保持高电平的时间长度来表示。程序只是对引脚状态进行采样,直到它检测到85个边沿转换(这只是实际应该有的几个),或者直到255微秒过去而没有边沿。边缘之间的循环周期数用于确定在数据数组中是移位“1”还是移位“0”。

数据分为五个字节,最后一个字节是前四个字节的校验和。

对于像这样的循环采样来说,通信速度可能太快了,我的印象是程序中的一些参数可能是通过反复试验得出的。在股票Pi上做这件事是相当安全的,至少对于一个特定的模型来说是这样,因为它们之间几乎没有变化。

然而,我不禁想到,一种更好的方法是捕获GPIO固件中提供的上升沿中断,然后在固定延迟后进行一次采样。只需重复此操作40次,直到读取完所有40位。我想你需要一些后备,以防通讯中断。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63847147

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档