AM2320 传感器:CRC 不匹配,来自传感器的 CRC(0)

Posted

技术标签:

【中文标题】AM2320 传感器:CRC 不匹配,来自传感器的 CRC(0)【英文标题】:AM2320 Sensor: CRCs doesn't match, CRC from sensor(0) 【发布时间】:2019-07-06 05:32:28 【问题描述】:

注意:代码在 windows 10 中交叉编译。

代码:

package main

import (
    "fmt"
    "io"
    "log"
    "net/http"

    aosong "github.com/d2r2/go-aosong"
    i2c "github.com/d2r2/go-i2c"
)

const i2CAddress = 0x5c
const i2CBus = 1

// Server struct
type Server struct 
    Sensor *aosong.Sensor
    I2C    *i2c.I2C

func main() 
        var err error
    s := ServerSensor: aosong.NewSensor(aosong.AM2320)
    s.I2C, err = i2c.NewI2C(i2CAddress, i2CBus)
    if err != nil 
        log.Printf(err.Error())
    
    fmt.Println(s.Sensor.ReadRelativeHumidityAndTemperature(s.I2C))
    defer s.I2C.Close()

调试信息:

2019-02-12T10:29:19.692 [     i2c] DEBUG  Write 3 hex bytes: [030004]
2019-02-12T10:29:19.697 [     i2c] DEBUG  Read 8 hex bytes: [0304012500d92045]
2019-02-12T10:29:19.698 [     i2c] DEBUG  Read 8 hex bytes: [0000000000000000]
CRCs doesn't match: CRC from sensor(0) != calculated CRC(6912).

知道为什么传感器的 CRC 为 0 吗?

我可以使用 python 脚本读取同一总线上具有相同地址的传感器。

#!/usr/bin/python
import posix
from fcntl import ioctl
import time
class AM2320:
        I2C_ADDR = 0x5c
        I2C_SLAVE = 0x0703
        def __init__(self, i2cbus = 1):
                self._i2cbus = i2cbus
        @staticmethod
        def _calc_crc16(data):
                crc = 0xFFFF
                for x in data:
                        crc = crc ^ x
                        for bit in range(0, 8):
                                if (crc & 0x0001) == 0x0001:
                                        crc >>= 1
                                        crc ^= 0xA001
                                else:
                                        crc >>= 1
                return crc
        @staticmethod
        def _combine_bytes(msb, lsb):
                return msb << 8 | lsb
        def readSensor(self):
                fd = posix.open("/dev/i2c-%d" % self._i2cbus, posix.O_RDWR)
                ioctl(fd, self.I2C_SLAVE, self.I2C_ADDR)
# wake AM2320 up, goes to sleep to not warm up and affect the humidity sensor
# This write will fail as AM2320 won't ACK this write
                try:
                        posix.write(fd, b'\0x00')
                except:
                        pass
                time.sleep(0.001) #Wait at least 0.8ms, at most 3ms
# write at addr 0x03, start reg = 0x00, num regs = 0x04 */
                posix.write(fd, b'\x03\x00\x04')
                time.sleep(0.0016) #Wait at least 1.5ms for result
# Read out 8 bytes of result data
# Byte 0: Should be Modbus function code 0x03
# Byte 1: Should be number of registers to read (0x04)
# Byte 2: Humidity msb
# Byte 3: Humidity lsb
# Byte 4: Temperature msb
# Byte 5: Temperature lsb
# Byte 6: CRC lsb byte
# Byte 7: CRC msb byte
                data = bytearray(posix.read(fd, 8))
# Check data[0] and data[1]
                if data[0] != 0x03 or data[1] != 0x04:
                        raise Exception("First two read bytes are a mismatch")
# CRC check
                if self._calc_crc16(data[0:6]) != self._combine_bytes(data[7], data[6]):
                        raise Exception("CRC failed")
# Temperature resolution is 16Bit,
# temperature highest bit (Bit15) is equal to 1 indicates a
# negative temperature, the temperature highest bit (Bit15)
# is equal to 0 indicates a positive temperature;
# temperature in addition to the most significant bit (Bit14 ~ Bit0)
# indicates the temperature sensor string value.
# Temperature sensor value is a string of 10 times the
# actual temperature value.
                temp = self._combine_bytes(data[4], data[5])
                if temp & 0x8000:
                        temp = -(temp & 0x7FFF)
                        temp /= 10.0
                humi = self._combine_bytes(data[2], data[3]) / 10.0
                return (temp, humi)

am2320 = AM2320(1)
(t,h) = am2320.readSensor()
print t, h

【问题讨论】:

【参考方案1】:

似乎库本身存在问题,它进行了两次读取,但由于未发送读取代码,因此值变为 0,如日志中所示:

2019-02-12T10:29:19.692 [     i2c] DEBUG  Write 3 hex bytes: [030004]
2019-02-12T10:29:19.697 [     i2c] DEBUG  Read 8 hex bytes: [0304012500d92045] (first read that was ignored)
2019-02-12T10:29:19.698 [     i2c] DEBUG  Read 8 hex bytes: [0000000000000000] (second one that came a 0)
CRCs doesn't match: CRC from sensor(0) != calculated CRC(6912)

提交了一个 PR 来解决这个问题:https://github.com/d2r2/go-aosong/pull/3

【讨论】:

以上是关于AM2320 传感器:CRC 不匹配,来自传感器的 CRC(0)的主要内容,如果未能解决你的问题,请参考以下文章

BISS-C 8通道采集renishaw传感器及其CRC校验

STM32读取温湿度传感器DHT11和DHT21(AM2301)系列问题

SLAM细碎内容积累_来自各种技术交流群_持续更新

model3轮胎换位胎压传感器匹配

特斯拉model3胎压传感器无法匹配

称重仪表modbus协议