以前、秋月電子で購入した温湿度センサモジュールAM2320、
改めて仕様等を理解した上で利用してみました。
温湿度センサ モジュール AM2320

実際の製品はこんな感じです。

端子は左から(VCC、SDA、GND、SCL)となります。
3.1V~5.5Vに対応、I2C またはシングルバス(1-wireライク)に対応
I2C対応のため、以前使ったDHT11よりも使いやすいです。
今回はI2Cインタフェースで使ってみました。
仕様関連
・測定できる情報
湿度 符号付16ビット 単位 摂氏(℃ )
温度 符号付16ビット 相対湿度 単位 %
モジュールから取得する生データは、実際の値に10をかけた値です。
ですので、小数第一位の単位まで測定できます。
・コマンド

・レジスタ

使い方
湿度・温度を読み取るだけであれば、
ファンクションコード0x03(レジスタからの読み込み)の利用だけとなりますが、
読み取る前にウェイク・アップさせる必要があります。
手順
1) スレーブアドレスを送って、モジュールをウェイク・アップさせます
800μsec 以上待ちが必要、3msec以内に次の要求を送信ですが、
Arduinoの実行側ででは、待ちは不要でも動作しました。
補足
スレーブアドレスを送信した場合、一般的なプロトコルとしては
スレーブアドレスに該当するスレーブデバイスはACKを返します。
ところが、このデバイスはスリープ状態のためか、ACKを返せないため
I2Cバス的には、”該当するデバイス無し”となり、NAKが帰ってきます。
ウェイク・アップでは、NAKが帰ってきた場合に、デバイス不在として判断せず、
それ以降のデータ送信のNAKで”該当するデバイス無し”を判断する必要があります。
2) ファンクションコード0x03(レジスタからの読み取り)コマンドとその引数を送信する
次の3バイトを送信します
0x03(レジスタからの読み取り)
読み取り開始レジスタ番号(1バイト)
読み込みデータ数(1バイト)
3)モジュールからのデータを読み取ります
読み取りデータは、次の表のように
指定したデータの他に先頭に2バイト、末尾に2バイトのデータが付加されます。
4バイト余分にデータを取得する必要があります。

実際にArduino Unoでサンプルスケッチを作成して、動作確認してみました。
結線
センサー端子 Arduino Uno
1: VCC 5V
2: SDA A4(SDA)
3: GND GND
4: SCL A5(SCL)
I2C接続ではプルアップ抵抗が必要ですが、Wireライブラリではマイコン内部にて
プルアップが行われるためこの構成では不要となります。
1秒間隔でデータを読み取って表示します。
センサーモジュールのウェイク・アップさせるのがミソです。
スケッチ
//
// 湿温度センサー AM2320 I2C接続サンプル
//
#include <Wire.h>
#define DEV_ADR 0x5c // AM2320スレーブアドレス
uint8_t data[8];
void setup() {
Wire.begin();
Serial.begin(115200);
}
void loop() {
// AM2320センサーのウェイクアップ
Wire.beginTransmission(DEV_ADR);
Wire.endTransmission();
// 湿度・温度データ取得要求
Wire.beginTransmission(DEV_ADR);
Wire.write(0x03); // レジスタ読み取りコマンド
Wire.write(0x00); // 読み取り開始レジスタ番号
Wire.write(0x04); // 読み取りデータ数
Wire.endTransmission();
// データの取得
Wire.requestFrom(DEV_ADR,8);
if (Wire.available() >= 8) {
for (uint8_t i=0; i<8; i++) {
data[i] = Wire.read();
}
float rh = ((float)(data[2]*256+data[3]))/10; // 湿度
float tp = ((float)(data[4]*256+data[5]))/10; // 温度
// 湿度・温度の表示
Serial.print("T=");
Serial.print(tp);
Serial.print("c");
Serial.print(" H=");
Serial.print(rh);
Serial.println("%");
}
delay(1000);
}
実行結果
部屋にある室温計と比較すると、まあまあの精度の値が読めています。
折角なので、豊四季タイニーBASIC for Arduino機能拡張版(+ VFD MW25616L対応)
でも試してみました。
使うハードウェア写真の構成のまま、スケッチを書き換えて利用しました。
BASICのプログラム
10 'AM2320
20 CLS
30 A=$5C
40 B=MEM
50 POKE B,$03,$00,$04
60 W=I2CW(A,B,0,B,0)
70 R=I2CR(A,B,3,B+3,8)
80 IF R ?"ERROR":GOTO 60
90 H=PEEK(B+5)*256+PEEK(B+6)
100 T=PEEK(B+7)*256+PEEK(B+8)
110 ?"湿度 ";DMP$(H,1);"% ";
120 ?"温度 ";DMP$(T,1);"℃"
130 WAIT 1000
140 GOTO 60
実際のプログラム

実行結果
BASICでも問題なく動作しました。
I2Cを使う際の事前にPOKEコマンドでメモリーに値をセットするのが
若干使い勝手が悪いです。
I2CW、I2CRコマンドの引数に直接送信するデータを記述する形式の方が
使いやすかもしれません。ちょっと検討してみます。
最近のコメント