#能書き
秋月電子で衝動買いしたAM2320ですが、ネットに転がってるコードがどうも微妙なので自前でドライバ?ライブラリ?を書きました。
#環境
- ESPr Developer
- https://www.switch-science.com/catalog/2500/
- AM2320
- http://akizukidenshi.com/catalog/g/gM-08663/
#使い方
ESPr Developerとセンサーを繋ぎます。プルアップ抵抗等は不要です。
AM2320のピン配置はデータシート参照。
ESPr側はSDAが4、SCLが5だった気がする。不安なら指定しておきましょう。
GitHubに上げておきました。
https://github.com/ihatomorio/AM2320
#コード解説
-
CWireAM2320 sensor
でオブジェクト生成。 -
sensor.init()
でWire.begin
をします。
-
sensor.init(4, 5)
と書くとWire.begin(4, 5)
となりI2C通信におけるSDAピンとSCLピンを指定できます。
-
sensor.fetch()
でセンサーから温度と湿度を拾います。拾った温度と湿度はメンバ変数sensor.humid
、sensor.temp
に格納されています。
#サンプルコード
以下の3つのコードを同じフォルダAM2320test
に入れるとArduino IDEで動くと思います。
AM2320test.ino
#include "WireAM2320.h"
CWireAM2320 sensor;
void setup() {
Serial.begin(115200); //for debug
sensor.init();
}
void loop() {
sensor.fetch();
Serial.print(" Humidity=");
Serial.print(sensor.humid, 1);
Serial.print(" ");
Serial.print(" Temperature=");
Serial.println(sensor.temp, 1);
delay(5000);
}
WireAM2320.h
#ifndef WIREAM2320_H
#define WIREAM2320_H
#include <Arduino.h>
enum AM2320_Register : word {
HUMI_MSB = 0x00,
HUMI_LSB = 0x01,
TEMP_MSB = 0x02,
TEMP_LSB = 0x03,
MODEL_MSB = 0x08,
MODEL_LSB = 0x09,
VER_NUM = 0x0A,
STATUS_AM2320 = 0x0F,
USER_REG_MSB = 0x10,
USER_REG_LSB = 0x11,
USER_REG2_MSB = 0x12,
USER_REG2_LSB = 0x13
};
enum AM2320_Function : word {
READ = 0x03, //Read multiple registers
WRITE = 0x10 //Write multiple registers
};
class CWireAM2320
{
public:
CWireAM2320();
void init();
void init(int pinSDA, int pinSCL);
int fetch(); //refresh sensor value
float humid; //Humidity
float temp; //Temperature
private:
word addr = 0x5c;
static const int AM2320_ADDR = 0x5C;
unsigned long lastFetchTime = 0;
};
#endif
WireAM2320.cpp
#include "WireAM2320.h"
#include <Arduino.h>
#include <Wire.h>
CWireAM2320::CWireAM2320() {
humid = 0.0;
temp = 0.0;
}
void CWireAM2320::init() {
Wire.begin();
}
void CWireAM2320::init(int pinSDA, int pinSCL) {
Wire.begin(pinSDA, pinSCL);
}
int CWireAM2320::fetch() {
//minimal interval 2s
unsigned long elapsed = millis() - lastFetchTime;
if (elapsed < 2000) delay(2000 - elapsed); //wait for 2s max
lastFetchTime = millis(); //get last fetch time
//Wake Sensor
Wire.beginTransmission(AM2320_ADDR); //START + addr (+ wait 800us-3ms (auto?))
Wire.endTransmission(); //STOP
//Send the read command or send written instructions
Wire.beginTransmission(AM2320_ADDR);//START + addr + W
Wire.write(READ); //function code
Wire.write(HUMI_MSB); //start address
Wire.write(4); //number of registers
int nEnd = Wire.endTransmission(); //STOP
if (nEnd != 0) {
return -1;
}
//To return the data read or confirmation signal
delayMicroseconds(1500); //delay at least 1.5ms
int ans = Wire.requestFrom(AM2320_ADDR, 6); //START + addr + R
delayMicroseconds(30);
if ( ans != 6) {
return -1;
}
int H1, H2, T1, T2 = 0;
for (int i = 1; i < ans + 1; i++) {
int c = Wire.read();
switch (i) {
case 3:
H1 = c;
break;
case 4:
H2 = c;
break;
case 5:
T1 = c;
break;
case 6:
T2 = c;
break;
default:
break;
}
}
humid = (H1 * 256 + H2) / 10.0;
temp = (T1 * 256 + T2) / 10.0;
return 0;
}