AM2302(DHT22)温度低于0℃时读数异常问题求助
问题
当温度高于0℃时,AM2302(DHT22)传感器读数正常;但温度低于0℃时,出现异常读数。
原始二进制数据:[0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1]
解析信息:
- 湿度字节:
[0,0,0,0,0,0,1,1](值3)、[0,1,1,1,1,0,0,1](值121),计算得湿度88.9% - 温度字节:
[0,0,0,0,1,1,1,1](值15)、[1,1,1,0,1,0,1,0](值234),按现有解码逻辑计算得温度407.4℃,但实际环境温度约为-1.5℃ - 校验和:
[0,1,1,1,0,1,0,1](值117),校验和验证通过
根据AM2302规格书,温度低于0℃时,温度第一个字节的最高位应为1,但本次数据中是第二个字节的最高位为1。
用于解码的Rust代码:
pub struct Reading { pub temperature: f32, pub humidity: f32, } impl Reading { pub fn from_binary_vector(data: &[u8]) -> Result<Self, CreationError> { if data.len() != 40 { return Err(CreationError::WrongBitsCount); } let bytes: Result<Vec<u8>, ConversionError> = data .chunks(8) .map(|chunk| -> Result<u8, ConversionError> { convert(chunk) }) .collect(); let bytes = match bytes { Ok(this_bytes) => this_bytes, Err(_e) => return Err(CreationError::MalformedData), }; let check_sum: u8 = bytes[..4] .iter() .fold(0 as u8, |result, &value| result.overflowing_add(value).0); if check_sum != bytes[4] { return Err(CreationError::ParityBitMismatch); } let raw_humidity: u16 = (bytes[0] as u16) * 256 + bytes[1] as u16; let raw_temperature: i16 = if bytes[2] >= 128 { bytes[3] as i16 * -1 } else { (bytes[2] as i16) * 256 + bytes[3] as i16 }; let humidity: f32 = raw_humidity as f32 / 10.0; let temperature: f32 = raw_temperature as f32 / 10.0; println!("{} {} {} {} {}, {}H, {}T",bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], humidity, temperature); if !(-41.0..=81.0).contains(&temperature) { return Err(CreationError::OutOfSpecValue); } if !(0.0..=99.9).contains(&humidity) { return Err(CreationError::OutOfSpecValue); } Ok(Reading { temperature, humidity, }) } }
请问该异常是传感器故障导致,还是其输出不符合规格要求?
分析与结论
这个异常属于传感器输出不符合规格要求,而非单纯硬件故障,理由如下:
- 传感器在0℃以上读数正常,说明基础采样、通讯功能正常,不存在完全故障的情况。
- 规格书明确规定低温时温度第一个字节最高位为1,但本次数据中是第二个字节最高位为1,且校验和验证通过,说明传感器确实输出了不符合规范的帧格式。
- 结合实际温度-1.5℃,正确的温度原始值应为-15(对应-1.5℃),按规格书格式应是第一个字节最高位为1,即温度字节应为
[1,0,0,0,0,0,0,0](128)和[0,0,0,0,1,1,1,1](15),但当前传感器输出的温度字节与该规范完全不符。
另外需要注意:现有解码逻辑对低温的处理也存在问题——当前代码假设低温时只取第二个字节取反,但实际上AM2302的低温表示是整个16位温度值取补码,第一个字节最高位是符号位。不过这和本次异常的根源无关,本次异常的核心是传感器输出不符合规格书定义的帧格式。
内容的提问来源于stack exchange,提问作者d3im
相关产品推荐
相关产品推荐

