鍬形です。HM-StarterKitでマイクロマウスを始めようの連載Part 7です。前回はAD変換についてご紹介しました。今回はサンプルプログラムStep 4を用いてI2C通信の解説と、IOエキスパンダによるLED点灯制御をご紹介します。
プログラムの書き込みと動作
step4_i2c_ioをビルドしてマイコンに書き込みます。HM-StarterKit/Sample_software/step4_i2c_ioにあるプロジェクトファイルHM_StarterKit.mtpjをCS+で開いてビルド、書き込みを行います。ビルドと書き込み方法は第2回に解説があるのでご覧ください。
書き込み基板をRUNモードに切り替えてからリセットスイッチを押すと4つの赤色LEDが点灯します。Tera TermなどでPCとシリアル通信をしている場合はHM-StarterKitのスイッチ入力も取得できるのですが詳細は次回ブログにて解説します。お楽しみに。

4つの赤色LEDが点灯します
IOエキスパンダの役割
今回LEDの点灯やスイッチ入力の取得はIOエキスパンダを使用しています。もちろんPart 3でブザーを鳴らしたときと同様にマイコンのGPIOピンで同じことができるのですが、LEDやスイッチの数が多いのでGPIOピンの数が足りません。そこで同じくIOピンが搭載されたIOエキスパンダを用いて入出力(input, output)を拡張(expand)しています。身近なものに例えるとPCのUSBポートが足りないときにUSBハブを接続することと同様のことをしています。

上の赤枠がIOエキスパンダ、下の赤枠がLEDです
IOエキスパンダとマイコンの連携
マイコンに書き込んだプログラムでIOエキスパンダが動作する仕組みは、マイコンとIOエキスパンダがI2C通信を行うことで実現しています。I2C通信によってマイコンがIOエキスパンダに「○○ピンから3.3Vを出力」や「○○ピンの入力を取得」などの指令を送っています。
I2C通信の仕組み
I2C通信でやり取りするデータは0と1の2進数で表現されます。通信に用いるピンの電圧がHIGH(3.3V)になったとき1、LOW(0V)になったとき0と認識されます。マイコンの設定をレジスタに書き込むように、どの命令がどんなデータで表現されるかはIOエキスパンダのマニュアルに記載されています。
I2C通信ではデータを送受信するSDA(シリアルデータ)信号と、通信のテンポを決めるSCL(シリアルクロック)信号の二つを用いています。SCL信号が0と1を交互に送り続けるのでそのテンポに合わせてSDA信号を受信すれば送受信の速度を連携させることができます。人間も複数人でランニングをするさい「いちに、いちに」と掛け声をかけますが、I2C通信においては「いちぜろ、いちぜろ」と掛け声をかけていると考えることができます。

このようにアドレスを指定してからデータを送信します
マイコンと周辺機器の通信において通信速度は非常に重要な要素です。例えば「0100」というデータを1秒に1bitずつ送信しても、受信側が1秒に2bitずつ受信すると「00110000」と倍に引き伸ばされたデータになってしまいます。1秒間に何bit送受信するかはそれぞれのICが把握している必要があります。
本連載Part 2でシリアル通信の文字化けが生じたことを覚えていますか?これはシリアル通信の通信速度であるボーレートがマイコン側とPC側で異なる値になっていたことで生じていました。もしIOエキスパンダがI2C通信でなくシリアル通信であった場合、IOエキスパンダに合わせてマイコンにボーレートをプログラムする必要が生じます。
I2C通信のもう一つの特徴として、同じ信号線を共有することでマイコンと複数のICが通信できます。データを送る前にデータの宛先であるアドレスを指定することで、ICが自分宛てのデータか判断することができます。アドレスも他の送受信するデータと同様にマニュアルに書かれていますし、アドレスが被ることを防ぐために後から変更もできます。
I2C通信にはほかにも様々な工夫や決め事があるので興味がある際は下記サイトをご覧ください。
I2C通信プログラム解説
IOエキスパンダとI2C通信し、LEDを光らせるプログラムについて解説します。本記事の解説内容はマニュアルの「マイクロマウス HM StarterKit パート3 『取扱説明書』 ソフトウェア解説編」 P11と対応しています。(※マニュアルの閲覧には製品に同梱されたパスワードが必要です)
I2C通信の初期化
まずはマイコンのI2C通信機能を有効化するためにレジスタの設定を行います。サンプルプログラムではinit_I2C関数に定義されており、ひたすらレジスタに値を設定しています。何をしているか気になる際は本連載のPart 3でご紹介したレジスタの設定方法を基に読み解いてみてください。
このようにある作業の準備をすることを初期化といいます。特にプログラムにおいてはしばしばinit(initialize)という略称が用いられます。
IOエキスパンダの設定
IOエキスパンダの初期設定を行います。サンプルプログラムではIOex_SETTINGに定義されています。ちなみにサンプルプログラムに「//sleep解除」などコメントが入ってるのですがジャイロセンサ用のコメントがコピペでついてきてしまったみたいです。気にせず下記解説をご覧ください。
void IOex_SETTING(void){ //ポーリングによる設定 //* I2C_START(); I2C_PUT((0x18<<1)); I2C_PUT(0x03); I2C_PUT(0xF0); I2C_STOP(); }
I2C_START()はスタートコンディションとよばれるI2C通信を始める合図を送信しています。
I2C_PUT((0x18<<1))では送り先であるIOエキスパンダのアドレスを指定しています。0x18がアドレスです。IOエキスパンダのマニュアルP7によるとアドレスはA0~A2ピンにHIGHやLOWを入力することで変更できるようです。HM-StarterKitではすべてLOWに接続されているため、アドレスはデフォルトの0x18です。回路に改造が必要になりますがたとえばA0ピンにHIGHを入力するとアドレスは1増えて0x19になるはずです。
アドレスの指定ができたのでいよいよ送るデータを指定します。IOエキスパンダはIO0~7までの合計8つのIOピンが搭載されています。例えばすべてのピンを出力用に設定した後に0b11110000(0xF0)のようなデータを送れば上位4bitに対応するIO4~7の出力がHIGH、下位4bitに対応するIO0~3の出力がLOWになります。このように8つのピンの設定を8bitのデータが対応することになっています。ちなみに数字の先頭に「0b」とつけると2進数(binary number)、「0x」をつけると16進数(hexadecimal number)を表現するルールがプログラミングにおいてはよく用いられています。

ピンと送信データの対応のイメージ
I2C_PUT(0x03)はIOエキスパンダの入出力を設定するレジスタのアドレスを指定しています。その次のI2C_PUT(0xF0)がレジスタに書き込むデータです。1が入力、0が出力を指定するので0xF0は上位4bitに対応するIO4~7を入力、下位4bitに対応するIO0~3を出力に設定しています。
I2C_STOP()はI2C_START()の逆でストップコンディションとよばれるI2C通信を終了させる合図です。これらの合図によってIOエキスパンダ以外のI2C通信している周辺機器が通信の開始と終了を把握することができます。人間もいきなり話を振られると誰に対して話してるか混乱しますよね。
IOエキスパンダからLEDを点灯
IOエキスパンダにLEDを点灯させるデータをI2C通信で送信します。サンプルプログラムではIOex_LED関数に定義されています。
void IOex_LED(short led_num){ //ポーリングによる設定 //* I2C_START(); I2C_PUT((0x18<<1)); I2C_PUT(0x01); I2C_PUT(0x00 | led_num); I2C_STOP(); }
スタートの合図、アドレスの指定、終了の合図は先ほどと同様です。
I2C_PUT(0x01)はIOエキスパンダの出力を設定するレジスタのアドレスを指定しています。この次に送るデータでどのピンの出力をHIGHまたはLOWにするか指定します。
I2C_PUT(0x00 | led_num)でLEDの点滅を制御します。メインプログラムで引数に0xF0を入力することですべてのLEDを点灯させています。IO4~7は入力に設定しているのでHIGHでもLOWでも問題ないのですが、間違えて出力に設定しても電流が流れないよう上位4bitを0xF(0b1111)に設定しています(IO4~7は3.3Vに接続されているのでHIGHで電流が流れなくなります)。IO0~3はLEDに接続されており入力された下位4bitが0x0(0b0000)なのですべてLOWです。回路図を見てみるとIOエキスパンダはLEDのカソード側に接続されているので、LOWになったとき点灯します。

配線を目で追うとLEDのカソード側とIOエキスパンダのピンがつながっていることがわかります
ちなみに0x00 | led_numとは0x00とled_numの桁を同じにするという処理です。例えばI2C_PUT(led_num)というプログラムだった場合、led_numに0xFFFのように2桁より多い数値を入力するとビルド時にエラーが出るはずです。「|」のような記号をビット演算子というのですが詳しくは下記サイトをご覧ください。
I2C通信の使いどころ
I2Cは2本の線のみでマイコンと様々な周辺機器を接続することができます。HM-StarterKitではIOエキスパンダやジャイロセンサを接続しています。IOがたくさんあるマイコンを使うことも解決策の一つになりますが、ロボットはたくさんのセンサやアクチュエータと接続するためこのような通信手段はよく使います。
また前回のフォトトランジスタのように単純なアナログセンサでなく、複雑な文字列などをやりとりする周辺機器にもよく用いられています。個人的にはLCDをよく使ってますがロボットの状態を確認するのにとても便利です。
まとめ
I2C通信の仕組みとIOエキスパンダについてご紹介しました。具体的な使用方法もサンプルプログラムに沿って簡単に解説したので、キーワードについて深く調べていくとI2C通信が使いこなせるのではないでしょうか。
HM-StarterKitキャンペーン価格のお知らせ
手のひらサイズのマイクロマウスキット「HM-StarterKit」
33%OFFの特別価格で販売中!
製品ページはこちら

アールティロボットショップで購入する
また、6月10日(木)からは学生マイクロマウスサークルを対象としたプレゼントキャンペーンを開催予定です!詳細をお楽しみに!