Some time ago my DHT22 sensor, connected to the RPi1, died (humidity always was showing 99%), so I decided to replace it. I found a cheap AM2320 sensor that was in the same case as my old DHT, so I ordered it. When it arrived I found that its used 4 PINS instead of 3 and I2C protocol instead of simple 1-Wire in DHT. So I had to spend some time learning how to get the data from it.
Enabling I2C bus and connecting sensor.
config.txt located on FAT partition
dtparam=i2c_arm=on line if its not there and reboot RPi. You should see something like that in the
root@rpi:/home/freebsd/ # dmesg | grep -i i2c iicbus0: on iichb0 iic0: on iicbus0
If you see these lines it means that FreeBSD enabled RPi I2C bus on pins 3 (SDA) and 5 (SCL). You will also need to connect GND and VCC pins, I was using 3.3V, the chip should accept both according to the spec. See pinout on the picture:
Once connected you can run the scan command. This chip has an automatic sleep feature and does not respond to commands in this state, so the scan needs to be run twice:
root@rpi:~ # i2c -s ; i2c -s Hardware may not support START/STOP scanning; trying less-reliable read method. Scanning I2C devices on /dev/iic0: Hardware may not support START/STOP scanning; trying less-reliable read method. Scanning I2C devices on /dev/iic0: 5c
As you could see – on the second run we got
0x5c address used by AM2320B.
Finally getting data from the sensor
As chip requires very strict timing before requests we cant use the i2c tool to get actual values from it. Also, the protocol has a checksum which we should calculate and data is collected as 16-bit integers. To get it in the human-readable form code needs to be written. And I found one for Linux at github.com/Gozem/am2320 repository. FreeBSD uses a slightly different way to work with I2C from userland (we need to use I2CRDWR ioctl) so I ported it to BSD and left all the logic the same. And it now finally works as expected:
root@rpi:~freebsd/libi2c # ./am2320 Temperature 16.1 [C] Humidity 58.8 [%]
To work with domoticz i am using LUA scripting. I think I am going to port github.com/robbie-cao/i2c-lua to the FreeBSD to avoid calling external binary on every reading. It is also possible to do a tiny kernel driver for that, but it is not something I like, IMO userspace is a better space for it.
Update: 1-Wire mode and datasheet
After finishing this article and i2c code I found a datasheet for this chip. Chip support both i2c and old, legacy 1-wire when SCL is connected to Ground and SDA used as "data" line. Anyway, i2c seems to me more standard solution.