EdisonでI2C温度計測

Edison with ADT7410

Edison with ADT7410

Intel EdisonのBreakout boardを昨年買ってきたのだが、なかなか手につかなかった。この正月休みに、他の仕事の合間に、とりあえず、説明書を読み、動かしてみた。秋月電子通商で売っている、I2C温度計測デバイス「ADT7410」を使って、インターネットの向こう側から部屋の温度がわかるようにしてみた。Edisonはアナログ値の入力や出力などもあるので、温度計測の場合はそこにつなげることもできるが、Edisonの作りを見ると、どうやらI2Cデバイスを標準で使うようになっていて、これからのIoTではI2Cバスの理解が非常に大切であることがわかってきたので、今回は特にアナログ入力を使わず、I2Cバス経由でI2Cのバスへのデータ出力を持った温度計測ICを使うことにした。

●ハードウエア
まず、ハードウエアだが、難しいことはない。普通のI2Cバスに、普通にADT7410を接続する。もちろん、接続する線はVdd、GNDの他、SCL、SDAである。バスの引き回しがほとんど無いくらい短いので、SDAのプルアップ抵抗は10kΩにして、ADT7410側につけた。ADT7410側のバス線はこの4本だけだが、Edison breakout boardの同じ名前の線は、それぞれ、VddがV_3P30(J20-2)、GND(J19-3)、I2C_1_SCL(J18-6)、I2C_1_SDA(J17-8)、となる。これらのピンアサインのデータはすべてIntel Edisonのホムページから取ってこれる。これらの同じ名前の線のEdison側とADT7410側をそれぞれ接続し、プルアップ抵抗も忘れないようにつける。同じ秋月電子のADT7410のボードを使うと、これらの細かい部品をハンダ付けする手間もなく、簡単だ。私はそれを使った。また、ADT7410はバスアドレス0x49-0x4Cが使えるが、私はボードのジャンパの設定で、0x4Aに設定した。

上記写真がそのハードウエアの様子だが、さすがにこれだけの接続だとかなり簡単になる。今回はブレッドボードは使わず、適当にハンダ付けして作った。

●ソフトウエア
ハードウエアの接続ができたら、今度はソフトウエアだが、Intelはmraaというライブラリを用意してくれていて、これを使うとプログラムが非常に簡単になる。以下の手順でmraaライブラリをインストールする。この作業はrootになって行う。ただし、Edisonの発売時期によってだが、既にインストールしてあるものもある。

●ソフトウエア開発前の環境作り

—-

# echo “src mraa-upm http://iotdk.intel.com/repos/1.1/intelgalactic” > /etc/opkg/mraa-upm.conf
# opkg update
# opkg install libmraa0
# opkg upgrade

—-

これで、I2CによるIoT開発環境ができあがる。次に、mraaライブラリの関数を使ったプログラムを書く。今回のプログラムは実験用なので、非常に簡単なものにした。しかし、自分で見ても悲しいくらい簡単すぎるプログラム。

●プログラムを組む

以下のプログラムリストは、WordPressが勝手にインデントのTABやスペースを無用に消してくれてしまっているので、読みにくいが、C言語をわかっている方は、コピーして自分なりにインデントなど復活させて、読みやすいようにすると良いだろう。

—-

#include <stdio.h>
#include <unistd.h>
#include <mraa.h>                 /* Edison mraa library */

#define ADT7410 (0x4A)       /* I2C ADT7410 ddress */
#define I2CCH (1)                   /* Use Edison’s I2C channel is 1 */
#define SLEEPTIME (2)       /* Loop interval time is 2secs. */
void main(int argc, char **argv)
{
mraa_i2c_context i2c;            /* For mraa lib. valiables */
uint8_t data[2];                        /* Input buffer */
int i;
int lasttemp;

mraa_init();                               /* Initial mraa library */
i2c = mraa_i2c_init(I2CCH);   /* Initial i2c bus */
mraa_i2c_address(i2c,ADT7410);  /* Set i2c address */

printf(“Bus initialized.\n”);

for(i = 0,lasttemp = 0 ;; ++i)
{
int tmpl,tmph,tmp,th,tl;
int tmh,tml;

if(0 > mraa_i2c_read(i2c,data,2))
{
printf(“Read Word Failed.\n”);
exit(1);
}

tmph = ((int)(data[0])); /* First is MSB */
tmpl = ((int)(data[1])); /* 2nd is LSB */
tmp = tmph * 256 + tmpl; /* tmp is real value */

if(tmp == lasttemp)
{
sleep(SLEEPTIME);
continue;
}

lasttemp = tmp;

tmh = tmp / 128; /* Get left of the floating point */

tml = tmp % 128; /* Get right of the floating point */
tml *= 100;
tml /= 128;

printf(“I2C read[%05d][%03d.%02d]\n”,i,tmh,tml); /* Display */

sleep(SLEEPTIME); /* Sleep */
}
}

—-

mraaライブラリを使うことによって、実に簡単にI2Cのプログラムが書けるのはすばらしい。

で、このプログラムは以下の行でコンパイルする。プログラム名は長いが「gettemp.c」、できるbinaryファイルは「gettemp」となっていて、途中でmraaのライブラリをロード時にくっつける。

●コンパイルをする

—-
# cc gettemp.c -lmraa -o gettemp
—-

で、実行すると、

—-
# ./gettemp
Bus initialized.
I2C read[00000][020.50]
I2C read[00004][020.56]
I2C read[00005][020.50] ….
—-

となる。このプログラムでは、2秒ごとに温度を計測し、温度変化があると、変化した温度を表示するが、温度変化が無いとループするだけで表示をしない。行の表示の最初の4桁はループ回数、次の小数点を伴った表示が℃の温度表示である。実に簡単なプログラムだ。このプログラムは簡単すぎて、0度以下の温度表示に対応していないので、0度以下の温度表示をさせるときは、違うプログラムを組む必要があるが、それはADT7410のデータシートを参照してプログラムを組む。

●さいごに

この手のIoTのプログラムを組むとき、一番問題なのが、ハードウエアなどの資料探しだ。どのピンになにを接続すればいいのか、などの情報、ソフトウエアでハードウエアをアクセスするときのデバイスやポートへのアクセス方法など、非常にクリティカルな情報はやはりメーカーのホームページなどで探すしかない。これらの情報が揃えば、あとはプログラム作りなんてのは簡単にできる。IoTが流行るのはいいのだが、デバイスそのものよりも、デバイスに関する資料が充実していて、すぐに見つかる、ということや、その資料と実際の動きがちゃんと一致していることなどがいかに大切か、と思う。資料の正確さがちゃんとしていないデバイスは開発現場が混乱するだけで、いいことが全くない。メーカーにはこういったドキュメントをしっかりとすることに力を入れてほしいものだ。

 


パソコン・周辺機器