我试图理解这个代码的含义和规则,它是湿度和温度模块。我想用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
#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);
}发布于 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) )这一行是代码嗅觉。这是故意注释掉的,还是只是某人调试尝试的残留物?
台词
dht11_dat[j / 8] <<= 1;
if ( counter > 16 )dht11_dat[j / 8] |= 1;根据计数器是否大于16us,用1或0填充位域/字节数组。移位将先前的数据向上移动,然后LSB要么设置为1,要么保持为0。
发布于 2020-09-11 21:48:47
程序将引脚设置为高电平,同时向设备发送信号以进行传输。该设备传输40比特的数据,“1”和“0”由引脚保持高电平的时间长度来表示。程序只是对引脚状态进行采样,直到它检测到85个边沿转换(这只是实际应该有的几个),或者直到255微秒过去而没有边沿。边缘之间的循环周期数用于确定在数据数组中是移位“1”还是移位“0”。
数据分为五个字节,最后一个字节是前四个字节的校验和。
对于像这样的循环采样来说,通信速度可能太快了,我的印象是程序中的一些参数可能是通过反复试验得出的。在股票Pi上做这件事是相当安全的,至少对于一个特定的模型来说是这样,因为它们之间几乎没有变化。
然而,我不禁想到,一种更好的方法是捕获GPIO固件中提供的上升沿中断,然后在固定延迟后进行一次采样。只需重复此操作40次,直到读取完所有40位。我想你需要一些后备,以防通讯中断。
https://stackoverflow.com/questions/63847147
复制相似问题