Edited at

I2C通信温湿度センサーモジュールAM2320をESPr Developerで使う

More than 1 year has passed since last update.


能書き

秋月電子で衝動買いしたAM2320ですが、ネットに転がってるコードがどうも微妙なので自前でドライバ?ライブラリ?を書きました。


環境


使い方

ESPr Developerとセンサーを繋ぎます。プルアップ抵抗等は不要です。

AM2320のピン配置はデータシート参照。

ESPr側はSDAが4、SCLが5だった気がする。不安なら指定しておきましょう。


コード解説



  1. CWireAM2320 sensorでオブジェクト生成。


  2. sensor.init()Wire.beginをします。



    • sensor.init(4, 5)と書くとWire.begin(4, 5)となりI2C通信におけるSDAピンとSCLピンを指定できます。




  3. sensor.fetch()でセンサーから温度と湿度を拾います。拾った温度と湿度はメンバ変数sensor.humidsensor.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;
}