[トップページへ戻る]

I2C-EEPROM使用 湿度温度ロガーお試し版

2013年10月
マイコン-デバイス間の通信には1線式,2線式(I2C),3線式(SPI)の通信方式がよく使われます。それらの通信方式に慣れる目的で1線式の湿度温度センサーとI2CタイプのEEPROMを使い、湿度温度ロガーを作りました。


流れで作った湿度温度ロガー
「うちには湿度計がない、湿度センサーで作ってみよう」、というのが今回の工作の始まりです。
湿度・温度が測定できるセンサーDHT11を入手、手持ちのATmega88Pで動作確認できました。…すなわち湿度計完成なのですが、これでは以前に作った温度計(AVR ATmega88 A/Dコンバータ応用例 温度計 記事の最後)と同じなので面白くありません。そこでメモリーを付けてロガー(データロガー/logger)にすることを考えました。

最近、I2Cで操作する部品(モジュール)が増えてきています。湿度温度センサーの通信方式は1線式だった、3線式(SPI)は使用経験がある、2線式(I2C)は未体験だ。というわけでI2CタイプのEEPROMを使ってみることにしました。
Microchip社の24LC128を入手。データシートにはI2CでEEPROMを読み書きする方法が詳しく書かれています。
→24AAXX/24LCXX/24FCXX/24CXX I2C シリアルEEPROM ファミリ データシート (pdf)

I2Cの基本操作とEEPROM操作のプログラムを作成、DHT11のプログラムと合わせ、湿度温度ロガーになりました。通信方式に慣れることが目的なので、ブレッドボード上で動作したところで完成としています。記録したログはPCアプリで読み取り、PC画面に表示します。

通信方式
マスターとスレーブ
2つの機器で通信するとき、どちらが通信を制御する側か/される側かを指す「マスター」「スレーブ」という用語をよく使います。主人(制御する側)と従者(制御される側)です。
マイコンとセンサー間で通信する場合、マイコンがマスター、センサーがスレーブとなります。マイコン機器同士で通信する場合にどちらをマスター/スレーブと呼ぶかは、その時々の動作によります。マスター専用/スレーブ専用の機器であればその名の通りですし、互いにマスター/スレーブの立場を入れ替えながら動作するシステムもあります。

以下、SPI(3線式シリアル通信)、I2C(2線式シリアル通信)、1線式シリアル通信ついて簡単に説明します。
図ではマスター=マイコン、スレーブ=センサーやディスプレイなどのデバイス、としています。

3線式 (SPI: Serial Peripheral Interface)
SCK(Serial ClocK/クロック), MISO(Master In Slave Out/マスターから見て受信線), MOSI(Master Out Slave In/マスターから見て送信線)の3線で通信します。複数のデバイスをバス配線することができ、マスターからどのスレーブに対して通信するか選択する線(SS: Slave Select)を加えて4線式と呼ぶこともあります。
クロックの立ち上がり/立ち下がりでデータ(1/0)を送受信します。図のパターンでは、マスターがクロックの立ち上がりでデータを送信し、立ち下がりで受信しています。スレーブでは逆にクロックの立ち下がりでマスターへ向けてデータを送信し、立ち上がりでマスターから送られてきたデータを受信しています。

2線式 (I2C: Inter-Integrated Circuit) ※正確には2が上付で「I2C」 ※AVRではTWI(Two Wire Interface)機能。
SCL(Serial CLock/クロック), SDA(Serial DAta/送受信兼用)の2線で通信します。SCL/SDA線にはプルアップ抵抗を取り付けます。I2Cはバス配線で複数のスレーブを接続するのに向いています。バス上のスレーブは互いに重複しないスレーブアドレス(IDのようなもの)を持っていて、これによりマスターはスレーブを区別します。
まず自分がマスターになる宣言をし(スタートコンディション)、バスの所有権を得ます。次に通信相手となるスレーブアドレスを指定し、データを送受信します。最後に通信終了を宣言し(ストップコンディション)、バスを解放します。
I2Cの通信プロトコルは規格化されています。→NXP I2Cバス仕様およびユーザーマニュアル (pdf)

1線式
送受信兼用の1本の線で通信します。クロック線がないのでタイミング的に1/0を読み取る方法ではありません。Hi時間の長さで1/0を区別します。通信の仕様はデバイスが独自に決めています。
例として、デバイスから「1,0,1,0」というデータが送られてくるとしましょう。このデバイスは、「Hiが20ms続いてLoになったら'1'を表す」「Hiが10ms続いてLoになったら'0'を表す」「データの区切りは10msのLoである」という通信仕様だとします。
マイコンは通信線を監視し、Lo→Hiに変化した瞬間から15ms後、通信線がHi/Loどちらの状態であるか確認します。
Hiであれば'1'が到着している最中です。Loであれば'0'が到着した後です。
このようにして'1'と'0'どちらを受信したのか判定します。そして次のデータが届くLo→Hiの変化を待ちます。

用途によって使い分ける(一案)
SPI,I2C,1線式はどれも、同じ基板上や近い位置にあるIC同士の通信に使われます。離れた場所にある機器との通信には、お馴染みUSBやUART(COMポート)のシリアル通信があります。

SPIは、マスターとスレーブが1対1、大容量のデータを高速に通信したい、といった用途に向いていると思います。マイコンのSPIライターはまさにそうですし、EEPROMやグラフィック液晶モジュールにも使われています。
I2Cは、センサー、メモリー、ディスプレイ他、様々な機器と通信する、速さはそこそこでよい、といった用途に向いていると思います。容量と速度のバランスが取れた通信方式です。
1線式は、小容量のデータを通信する用途に向いていると思います。ハード的に見るとクロック生成回路が必要ないことが特徴です(タイマーは必要)。単純な機能の小型センサー…VCC/GND/Signal の3本足しかない温度センサーなどに使われています。マイコンのデバッガが1線式であることも合理的だと思います。

実装:ハードかソフトか
多機能なマイコンではSPI,I2Cは内蔵されています(例:ATmegaシリーズ)。ソフトで実装することもできますが、特に理由がない限り目的の機能を内蔵しているマイコンを選んだ方がよいでしょう。1線式はデバイスの仕様に合わせてソフトで実装します。

I2CタイプのEEPROM
本システムで使用したI2CタイプのEEPROMはMicrochip社の24LC128、容量は128Kbit(64KByte)です。EEPROMにはI2Cの他、SPIで通信するタイプもあります。いずれにしろマイコン内のEEPROM領域とは区別します。

スレーブアドレスとデバイスの個数
I2Cのバスには複数のデバイスを”ぶら下げる”ことができます。異なる種類のデバイスでも(例:センサーとディスプレイ)、同じ種類でも構いません。ただしスレーブアドレスが重複してはいけません。スレーブアドレスの具体値はデバイスのデータシートに記載されています。

I2Cのデバイスは7ビットのスレーブアドレスを持ちます。EEPROMの場合、7ビットは「制御コード4ビット」と「デバイスを区別する3ビット」に(意味的に)分かれています。メーカーやメモリ容量によらず上位4ビットは「1010」です。下位3ビットは開発者が回路的に決めます。これによりEEPROMはバスに8個までぶら下げることができます。
※下位3ビットが変更できない品種もあります(小容量のもの、小型パッケージのもの)。
※1MbitのEEPROMは事情が異なります(下記「メモリアドレス」の項を参照)。

スレーブアドレス
EEPROM
個数
SLA 7bit
固定値 A2 A1 A0
1個目 1 0 1 0 0 0 0
2個目 1 0 1 0 0 0 1
7個目 1 0 1 0 1 1 0
8個目 1 0 1 0 1 1 1
※A0/A1/A2ピンがない品種もある。
※スレーブアドレスは選べる範囲で自由に割り振ってよい。バス上の並び順も自由。

メモリアドレス
EEPROMへ読み書きするとき、マスターはメモリアドレスを指定します。値は0xFFFFまで、すなわち64KByteまでのメモリ空間にアクセスできます(64KByte=512Kbit)。これを超える容量になるとアクセス方法が変わります。詳しくはデータシートで確認してください。今のところ1Mbit(128KByte)が最大容量です。
→Microchip 24AA1026/24LC1026/24FC1026 1024K I2C CMOS シリアルEEPROM (pdf)

1MbitのEEPROMは1つのICの中に512KbitのICが2個入っているような構造をしています。ICにA0ピンがありませんが、プログラム上はスレーブアドレス内のA0ビットを0か1に設定します。0/1どちらに設定してもメモリアドレスは0xFFFFまでで指定します。これはまさに512KbitのEEPROM 2個にアクセスするのと同じ操作になっています。
1Mbit(128KByte)のEEPROMはバスに4個までぶら下げることができます(A1/A2ピンの組み合わせが4通り)。

回路図とプログラム
回路図


プログラム
ファームウェア
ダウンロード HuTemLogger.zip
HEXファイル、Cのソース他、プロジェクトのファイル一式
開発環境:Windows7/64bit, AtmelStudio6
PC側アプリ
ダウンロード I2cEepRomTool.zip
EXEファイル、C#のソース他、プロジェクトのファイル一式
開発環境:Windows7/64bit, .NetFramework4, VisualStudio2010Exp./C#

EEPROM 24LC128(24xxnnシリーズ)のデータシートにはSCL/SDA線のプルアップ抵抗に関する説明が載っています。
通常、100kHz では10kΩ、400kHz と1MHzでは2kΩ
回路図では4.7kΩにしていますが根拠はありません。データシートの説明に従った方がよいでしょう。
【参考】
本システムの実験中(写真で示される配線状況のもと)、
4.7kΩで50kHz,62.5kHz,100kHz,400kHzの通信が安定動作しました。

ファームウェアの説明
ATmegaシリーズにおけるI2Cの最高速度は400kHzです。24LC128は400kHzまで対応しています。
本システムのAVRは1MHz動作で、I2Cの通信速度は62.5kHzとなっています(AVR 1MHz動作での最高速)。
AVRを8MHz動作に変更すればI2Cの400kHzにも余裕で対応できます。
※本システムは当初、AVR 8MHz動作でI2Cは400kHzでした。後に電池駆動にしようかと考え、AVRを1MHz動作にしました(消費電力を抑える)。
 公開しているファームはAVR 1MHz動作のものです。…結局 電池駆動にはしなかったのですが。


湿度・温度の測定値はI2C-EEPROMに記録します。測定値はインデックスや経過時間の情報を含めたレコード形式で保存されます。レコードの保存位置(I2C-EEPROM上のメモリアドレス)や、本システムの動作に関する設定値(測定間隔や開始時刻、I2C-EEPROMのメモリサイズなど)は、AVR内のEEPROM領域に保存しています。このように分けることで、I2C-EEPROMは純粋に全領域を測定値(レコード)の記録だけに使うことができます。

ソースは使い回しがしやすいよう機能別に分かれています。DHT11にアクセスするライブラリ(そこまで大袈裟ではない)、I2C(TWI)の基本操作ライブラリ、I2C-EEPROMにアクセスするライブラリです。

PC側アプリの説明
コンソールアプリです。何を実行するにしても'-com'オプションは必須です。USB-シリアル変換モジュールが接続されているシリアルポート(仮想COMポート)を指定してください。

◆初期設定
ハードが完成して初めて動作開始するとき(またはI2C-EEPROMを差し替えたとき)、I2C-EEPROMのメモリサイズなどを本システムに設定する必要があります。'-m' '-p'オプションです。その他の設定('-t' '-d'オプション)は任意です。
・センサーの測定間隔('-t'オプション): 1分単位で指定します。1時間ごとに測定するなら'-t60'です。
・測定開始時刻('-d'オプション):ログ表示時に添える単なる覚え書きです。本システムに時計機能はありません。

◆ログの読み込み
本システムが動作し、時間が経ち、ある程度 湿度・温度の測定値が記録されたらPCにログを読み込んでみましょう。'r'コマンドで読み込みを開始します。※ここでも'-com'オプションは必須です。
I2C-EEPROMのメモリ領域全体を読み込むので時間がかかります。読み込みが完了すると内容が表示されます。

ヘルプ画面 設定状態確認画面 ログを読み込んだ様子
ログ表示画面で5分後あたりから湿度が下がっているのは、部屋の窓を開けて風通しをよくしたからです。センサーはちゃんと反応しているようですね。

通信速度について
AVRが1MHz動作のとき、安定したシリアル通信(UART)の速度は4800bpsです。それに合わせ、PCアプリ(USB-シリアルコンバータ)も4800bpsで本システムと通信するよう、プログラムは記述されています。
AVRを8MHz動作にすると、安定したシリアル通信の代表的な速度38400bpsで通信できるようになります。
通信速度を変更する場合、ファーム、PCアプリ、ともにソースの書き換えが必要です。

部品について
DHT11
通販サイトを探してみると、温度センサーが100円程度なのに対し、湿度センサーは1000円前後と比較的高価です。そんな中で安価な湿度・温度センサー「DHT11」を見付けました。ネット上の評判によると性能は価格なりのようです。

DHT11は4ピンですがモジュール化されたものは3ピンです。モジュールには基板デザインが何種類かあり、3ピンの並び順が違うこともあるので配線には注意が必要です。
【参考】 http://club.dx.com/reviews/photos/121350/252500
本記事で使用したモジュールと同じ製品です。
※AliExpressで購入したら商品ページの写真と違う基板のモジュールが届いたので(!)、紹介は他サイトからです。

DHT11 データシートより、通信データのフォーマット。
Data format:
8bit integral RH data + 8bit decimal RH data + 8bit integral T data + 8bit decimal T data + 8bit check sum.
If the data transmission is right, the check-sum should be the last 8bit of
"8bit integral RH data + 8bit decimal RH data + 8bit integral T data + 8bit decimal T data".
8bit integral RH data 8bit decimal RH data 8bit integral T data 8bit decimal T data 8bit check sum
湿度:整数部
1byte
湿度:小数部
1byte(常に0x00)
温度:整数部
1byte
温度:小数部
1byte(常に0x00)
チェックサム
←左記4byteの和の下位1byte
チェックサムは、湿度・温度のデータ4byteを合計した値の下位1byteの値です(0xFFでANDを取った値)。
湿度・温度とも受け取った整数部の値がそのまま湿度・温度を表しています。何か計算をする必要はありません。
湿度の単位は「%RH」(相対湿度)、温度の単位は「℃」(摂氏)です。※「℃」が文字化けしていますか?「度シー」('C)です。

EEPROM
I2CタイプのEEPROMを使用します。SPIタイプのものを間違えて購入しないよう注意してください。
本システムで使用した製品はMicrochip社の128Kbit(16KByte)のものですが、他社/他の容量でも動作します。ただしプログラムの都合上、容量は32Kbit(4KByte)〜512Kbit(64KByte)にしてください。
※プログラムを改造して対応範囲を広げるのは自由です。お好きなように改造してください!


◆ ◆ ◆
1線式と2線式(I2C)について理解を深めました。
3線式(SPI)はAVRのライター製作で度々使っているので今回は取り上げませんでした。
この記事を書いている現在、OLEDとRTCを加えた「湿度温度ロガー第2弾」に取り組み中です。


(C) 『昼夜逆転』工作室 [トップページへ戻る]
inserted by FC2 system