I2C仕様の湿度センサー AM2321をarduinoに接続してみましたので、忘れないよう
メモします。
AM2321自体は 秋月電子にて購入可能です。ついでに アップされているデータシート(中国語)に目を通しておきます。
接続は 下記の通りで I2C(Wire)で接続します。
なお、リードピッチが1.27mmと狭いので、無理やりリードを曲げて通常の
2.54mmピッチに変換しました。
AM2321 arduino
1pin(VDD) ーーー VDD(3.3Vor5V) 今回は3.3Vで使用
2pin(SDA) ーーー analog in 4pin(I2C:SDA)
3pin(GND) ーーー GND
4pin(SCL) ーーー analog in 5pin(I2C:SCL)
今回のarduinoは3.3V動作ですので、内蔵クロック8MHz設定としました。
使用した開発環境は、Arduino 1.0.6です。
arduinoとAM2321とのI2C(Wire)での通信手順は、データシートから下記のような
概要となると思われます。
1、AM2321を起こしに行く
2、800μS待つ
3、データ読込指令を送信する。
4、1.5mS待つ
5、データを読込する。
以上の手順に基づいてプログラムを作成してみます。
そのまえに、データシート上でのI2C アドレスの表記が
標準表記と異なるので、I2Cアドレスを再確認します。
ということで、I2Cアドレスは 5Cとなります。
以下、arduinoのI2Cライブラリー wireライブラリーを使用します。
#include <Wire.h>
必要な定数、変数を定義します。
unsigned char data[7]; //AM2321から読み込みデータを格納します(8バイト)
unsigned int byte_no = 0; //データ位置のポインター
int situdo=0; //湿度データ
int kion=0; //温度データ
unsigned char am2321_I2C_adr = 0x5c; // b8 >>1 and 7f I2Cアドレス
セットアップルーチンで、I2Cライブラリの使用開始と、デバックのための
シリアル通信をセットアップします。
void setup(){
Wire.begin();
Serial.begin(9600);
}
以下 メインループの中に記述します
void loop(){
ステップ1 : AM2321を起こしに行く
ダミーの読み出しを行います。(NACKが帰ってきます。)
Wire.beginTransmission(am2321_I2C_adr);
Wire.write(0x00);
Wire.endTransmission();
ステップ2 :800μS待つ
delayMicroseconds(800);
ステップ3 :データ読込指令を送信する。
データシートに記載されたデータを送信
0x03:レジスターを読み込みます
0x00:レジスターのスタートアドレスは 0x00から
0x04:レジスターの読み込み個数は 4レジスター
Wire.beginTransmission(am2321_I2C_adr);
Wire.write(0x03);
Wire.write(0x00);
Wire.write(0x04);
Wire.endTransmission();
ステップ4 :1.5mS待つ
delayMicroseconds(1500);
ステップ5 :データを読込する。
データシートに記載された順番でデータを受信
0x03:レジスターを読み込みます
0x04:4つのレジスター内容を4バイトで返します。
0x??:湿度の高位バイトを返します
0x??:湿度の低位バイトを返します
0x??:温度の高位バイトを返します
0x??:温度の低位バイトを返します
0xCRC1: CRCを2バイトに分けて返します
0xCRC2:
Wire.requestFrom(0x5c, 0x08); //8バイト読込
byte_no=0; //ポインターをクリアー
while(Wire.available())
{
data[byte_no]= Wire.read(); //配列に格納
Serial.println(data[byte_no],HEX); //シリアルで送信
byte_no++; //ポインター更新
}
湿度、温度を計算して シリアルに出力
Serial.println(":");
situdo = (data[2]*0xff+data[3])/10;
Serial.print("situdo=");
Serial.print(situdo);
Serial.println(" %");
if (data[4] & 0x80){
kion=((data[4] & 0x7f)*0xff) + data[5];
} else{
kion=(data[4] * 0xff) + data[5];
}
Serial.print("kion=");
Serial.print(kion);
Serial.println(" do");
delay(8000);
} // loop
シリアル通信結果
プログラムまとめ(参考にしてください。でも間違いも潜んるかも^^;)
#include <Wire.h>
unsigned char data[7];
unsigned int byte_no = 0;
int situdo=0;
int kion=0;
unsigned char am2321_I2C_adr = 0x5c; // b8 >>1 and 7f
void setup(){
Wire.begin();
Serial.begin(9600);
}
void loop(){
Wire.beginTransmission(am2321_I2C_adr);
Wire.write(0x00);
Wire.endTransmission();
delayMicroseconds(800);
Wire.beginTransmission(am2321_I2C_adr);
Wire.write(0x03);
Wire.write(0x00);
Wire.write(0x04);
Wire.endTransmission();
delayMicroseconds(1500);
Wire.requestFrom(0x5c, 0x08);
byte_no=0;
while(Wire.available())
{
data[byte_no]= Wire.read();
Serial.println(data[byte_no],HEX);
byte_no++;
}
Serial.println(":");
situdo = (data[2]*0xff+data[3])/10;
Serial.print("situdo=");
Serial.print(situdo);
Serial.println(" %");
if (data[4] & 0x80){
kion=((data[4] & 0x7f)*0xff) + data[5];
} else{
kion=(data[4] * 0xff) + data[5];
}
Serial.print("kion=");
Serial.print(kion);
Serial.println(" do");
delay(8000);
} // loop