最終更新日:2019/02/04


法人向けのETC専用カード


はじめに

I2Cで接続するセンサやLCDなどのデバイスが増えてきました。
一般的にI2Cデバイスはマイコンなどからアクセスします。

しかしPCのシリアルポート(RS-232C/EIA-232)へI2Cデバイスを接続できれば、マイコンの開発環境が無くても手軽にI2Cデバイスを使えそうです。

そこで、PCのシリアルポートとI2Cの信号レベルを相互に変換するアダプタを作りました。

Windowsのアプリケーションから、I2C制御のDLLを介してI2Cデバイスを操作できます。

本機は下図のように使用します。

I2Cの通信速度の上限は、標準モードで100kbps、ファストモードで400kbps、高速モードで3.4Mbpsとなっています。が、このシリアルポート経由だと下は150bpsから、頑張っても40Kbps程度しか出ませんでした(汗

このように書くと使い物にならないようなイメージを持たれるかもしれませんが、センサから一定間隔でデータを取得する用途などでは十分実用になります。

最近はシリアルポートのないPCもあると思います。USB-シリアル変換ケーブルはこちら


注意

もし何らかの損害が発生しても当方は一切責任を負いませんので、あくまでも自己責任でお願いします。

ハードウェア製作

I2Cの通信には、入出力ができる双方向のポートが必要となります。
しかしシリアルポートは入力専用と出力専用の信号線しかないため、入力用のCTS、出力用のDTRとRTSの3本を使用します。

回路図

クリックで拡大します。

2019/02/04更新

当初はSCLとSDA供に双方向の作りにしていましたが、考えてみるとクロックのSCLはマスタからの片方向でよいので、SCLの信号を受ける回路を削除しました。この回路変更はソフト側へは影響ありません。DLLやアプリケーションはそのまま無変更で使用できます。

念のため旧回路図(2013/09/18版)を残しておきます。

回路の POWER にはI2Cデバイスの電源電圧と同じ電圧を供給します。

手元に秋月さんで買ったMOS-FET(2N7000)があったので、これで作りました。
2N7000以外でも、NchエンハンスメントのMOS-FETで、Vgs(th)が3V未満程度のものなら何でもいいかと思います。ただし入力容量が少ないものを選んでください。

動作確認

回路ができたら、アダプタが動作しているかチェックしてみましょう。

ますアダプタをPCのシリアルポートに接続し、電源を供給します。

次に、ダウンロード(後述)した SerialMon.exe を起動します。
SerialMonはシリアルポートの信号線を操作・表示するものです。

メニューの「ファイル→接続」でシリアルポートを選択し、回路が正しければ下記のような表示になるはずです。

SCLへテスタの + 端子を当て、GNDへテスタの - 端子を当てます。
DTRのチェックがONのときは0V、チェックをOFFにすると電源と同電圧になります。

同様にSDAへテスタの + 端子を当て、GNDへテスタの - 端子を当てます。
RTSのチェックがONのときは0V、チェックをOFFにすると電源と同電圧になります。

上記の操作をしてもSCLやSDAの電圧が変化しない場合は、アダプタの製作ミスの可能性があります。

接続例

配線イメージは下のようになります。
本アダプタから電源のVcc/GND、SCL/SDAの4本を引き出しておけば、I2Cデバイス基板(あるいはブレッドボード)へ簡単に接続できるので便利です。

本アダプタから電源を供給する例。


I2Cデバイス基板(ブレッドボード)側から電源を供給する例。


ライブラリ・サンプルソース

DLL

最新 i2c_dll100.zip 111KBytes 2016.02.22
i2c_dll.zip 95KBytes 2013.10.27

シリアルポートの状態表示ソフト

SerialMon100.zip 6KBytes 2016.02.22

デバイス別サンプルプログラム

i2c_sample100.zip 141KBytes 2016.02.22

I2C EEPROM(AT24C1024)書き込みソフト

I2CEEPRW.zip 23KBytes 2016.06.16
[注意]USB-シリアル変換では書き込み速度が極端に遅いです。

DLLの使い方

C/C++やVBなどからご利用いただけます。

VC++でダイナミックリンクをする場合は i2c.h をインクルードします。
スタティックリンクの場合は i2c_static.h をインクルードし、i2c.lib も必要となります。

VBの場合、I2C.bas がDLLをインポートするためのDeclare文や定数の定義です。
I2CTest.frm から実際にDLLの関数を使用しています。

GUI環境からDLLを使用するサンプルが入っていますので参考にどうぞ。


DLL関数一覧

i2c_connect(iPort)
シリアルポートに接続します。
一つ目のパラメータにシリアルポートの番号を指定します。
戻り値が IIC_SUCCESS なら成功、IIC_FAILURE なら失敗です。
i2c_start()
I2Cデバイスとの通信を開始します。
i2c_write(bDat)
I2CデバイスへbDatのデータを1バイト書き込みます。
また、デバイスからのAck/Nack状態をそれぞれ IIC_ACK / IIC_NACK で返します。
i2c_read(boAckFlg)
I2Cデバイスから1バイト読み込み、関数の戻り値として返します。
boAckFlgに IIC_ACK / IIC_NACK のいずれかを指定して、それぞれデバイスへAck/Nackを通知します。
i2c_stop()
I2Cデバイスとの通信を終了します。
i2c_disconnect()
シリアルポートを切断します。
戻り値が IIC_SUCCESS なら成功、IIC_FAILURE なら失敗です。

I2Cデバイス別サンプルプログラム

Visual C++ 6.0でコンパイルしています。動作確認はWinXP/8.1で行っています。
コンパイルしなおす際は、コマンドラインから下記のように行ってください。
cl LcdMain.cpp

ファイル一覧

LcdMain.cpp/exe
I2CのLCD(AQM0802A)に現在日時を一定間隔で表示させるサンプルです。
PressMain.cpp/exe
気圧センサのLPS331(AE-LPS331)から一定間隔で気圧と温度を読み出し、画面に表示するサンプルです。
PressLcdMain.cpp/exe
LPS331(AE-LPS331)から取得した気圧・温度をLCD(AQM0802A)に表示するサンプルです。
RtcMain.cpp/exe
RTC-8564NBから一定間隔で日時を読み出し、画面に表示するサンプルです。
RadioMain.cpp/exe
ラジオモジュール(TEA5767)の周波数を、キーボード操作でUp/Downして選局動作させるサンプルです。
FMTransmitterMain.cpp/exe
FMトランスミッタ(NS73M)の周波数を、キーボード操作でUp/Downして設定させるサンプルです。
周波数の計算はゆきさんが公開されているソースからいただきました。有用なソースを公開していただき、まことにありがとうございます。
ListDevice.cpp/exe
I2Cバスに接続されているI2Cデバイスをサーチし、見つかったデバイスを画面に表示するサンプルです。


I2Cデバイスのアドレス表記

I2Cデバイスのアドレスは、メーカによって表記方法が異なる場合があります。

I2C通信のアドレス指定例

上記を8bit分そのまま記載するメーカの場合は、2進数で10101010 になるため、デバイスアドレスは 0xAA と表記されます(Writeの場合)

一方、アドレスの7bit分のみを抜き出して記載するメーカの場合は、2進数で1010101 になるため、デバイスアドレスは 0x55 と表記されます。

この違いにご注意ください。


ベンチマーク

USB-シリアル変換器はREX-USB60と秋月さんの2つで動作確認しています。
共にPL2303チップで結果がほぼ同じだったため一つにまとめています。

Athlon64 3500+ 2.2GHz
マザーボードのシリアルポート

Read:42,553bps
Write:44,638bps
USB-シリアル変換器(PL2303)
Read:423bps
Write:330bps

Celeron 2GHz i845GL
マザーボードのシリアルポート

Read:24,939bps
Write:25,255bps
USB-シリアル変換器(PL2303)
Read:144bps
Write:108bps

マザーボードのシリアルポートは速いです。逆にUSB-シリアル変換器はかなり遅い結果になりました。
また、CPUパワーにも左右されています。


後書き・注意点

(2013.09.18)
PICkit2を購入し、簡易ロジアナ機能でデバッグしながらAck/Nackの処理を実装しました。
これで連続Read(シーケンシャルRead)も動作します。
ひとまず、当方の持っているI2Cデバイスはすべて制御できるようになりました。

更新履歴

2013/09/03 新規作成
2013/09/18 デバイスへAck/Nackの返信、デバイスからのAck/Nackの取得に対応。
2013/10/27 I2CライブラリのDLL版を作成。
2016/02/22 全面的に加筆訂正。
2016/06/02 接続例を追加。
2016/06/16 EEPROM(AT24C1024)の書き込みソフトを追加。
2017/02/10 RS-232C変換IC版の回路図を追加。
2017/02/16 ロジックIC版の回路図を追加。
2019/02/04 回路図の修正と文章の加筆。

当サイト内の検索