0
2

More than 3 years have passed since last update.

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

Last updated at Posted at 2018-08-11

能書き

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

環境

使い方

ESPr Developerとセンサーを繋ぎます。プルアップ抵抗等は不要です。
AM2320のピン配置はデータシート参照。
ESPr側はSDAが4、SCLが5だった気がする。不安なら指定しておきましょう。

GitHubに上げておきました。
https://github.com/ihatomorio/AM2320

コード解説

  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;
}
0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2