他的代码如何计算温度?
特别是这个程序的一部分我正在寻找解释(我不知道为什么他正在做(& 0x7F)并乘以256):
if ((j >= 40) &&
(dht22_dat[4] == ((dht22_dat[0] + dht22_dat[1] + dht22_dat[2] + dht22_dat[3]) & 0xFF)) ) {
float t, h;
h = (float)dht22_dat[0] * 256 + (float)dht22_dat[1];
h /= 10;
t = (float)(dht22_dat[2] & 0x7F)* 256 + (float)dht22_dat[3];
t /= 10.0;
if ((dht22_dat[2] & 0x80) != 0) t *= -1;
sicher = 0;
dsicher = false;
temp = t;
printf("Humidity = %.2f %% Temperature = %.2f *C \n", h, t );
如果有人可以评论上面的代码,我会非常感激。 整个程序可以在这里找到:http://pastebin.com/zkaTjQiS
答案 0 :(得分:1)
正如您在DHT22 datasheet中看到的那样,当被问到时,传感器通过1线输出40位数据。前16位将相对湿度编码为十分之一的百分比,接下来的16位将温度编码为十分之一的摄氏度,最后的八位是校验和。
所有这些都以MSBit顺序发生,因此转录的5个字节中的数字以big endian编码。此外,正如您可以在数据表中看到的那样,温度数据被编码为带符号的幅度而不是二进制补码。
所以:
if ((j >= 40) &&
(dht22_dat[4] == ((dht22_dat[0] + dht22_dat[1] + dht22_dat[2] + dht22_dat[3]) & 0xFF)) ) {
检查40位是否已计时,校验和是否有效。
h = (float)dht22_dat[0] * 256 + (float)dht22_dat[1];
h /= 10;
不必要地使用浮点运算,以便将湿度保持在百分比而不是promille,但除此之外,它只是将高位字节向上移动到其合法位置并将低值添加到其中。你也可以写
h = dht22_dat[0] << 8 | dht22_dat[1];
如果你喜欢那种符号;关键是要从两个单独的字节中得出它们所代表的16位整数值。
想一想,如果你愿意的话,好像传感器给你两个小数位2
和3
,你必须从它们重建值。如果您知道2
是更重要的数字,您将计算2 * 10 + 3
以获得实际值23.此处适用相同的原则,除了传感器没有给出十进制数字但是256 - 而不是a * 10 + b
而是计算a * 256 + b
。
类似地,
t = (float)(dht22_dat[2] & 0x7F)* 256 + (float)dht22_dat[3];
t /= 10.0;
将高字节的低7位和低字节组合成温度的绝对值。隔离较高字节的低7位是必要的,因为它的最高位是用于表示负温度的符号位,而不是温度绝对值的一部分。
然后
if ((dht22_dat[2] & 0x80) != 0) t *= -1;
检查该符号位是否已设置,如果是,则调整结果的符号,
printf("Humidity = %.2f %% Temperature = %.2f *C \n", h, t );
打印转换结果。