フォト
2017年8月
    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31    
無料ブログはココログ

« aitendoのこどもパソコン「ai.Jam-T」キット を組み立てました | トップページ | LEDドットマトリックスを使ったメッセージ表示デバイスを作成中 »

2016年9月13日 (火)

IchigoJamのI2Cインタフェースについて

IchigoJamのI2Cインタフェースに関するまとめです。
(対象はファームウェア 1.2.1です)

IchigoJamのI2Cインタフェース利用時の注意点

  1)3.3V対応であること
    I2Cデバイスの中には5V利用が前提で3.3Vに対応していないものがあります。
    ただし、仕様上3.3Vに対応していなくても3.3Vで動くものもあります。
    8x8ドットLEDマトリックスを制御するHT16K33は4.5~5.5Vが利用範囲ですが
    利用出来  ています。

  2)IchigoJam BASICの I2CR、I2CWコマンド仕様で利用可能なデバイスであること
     IchigoJam BASICの I2CR、I2CWコマンドの仕様により、
     一部のI2Cデバイスの制御が出来ません(そう多くないです)。

     I2Cアドレスのみを送信してデータ取得を行うような通信が出来ません。
     (Wiiヌンチャク、タッチセンサーなんかは利用出来ませんでした)

  3)I2Cスレーブアドレスが同時利用するデバイスと同じでないこと
    例:秋月電子 液晶キャラクターディスプレイ(ACM1602NI-FLW-FBW-M01)
        アドレスが0x50なのでEEPROMの0x50と競合して使えないです。

  4)I2Cアドレスは7ビット長

  5)プルアップ抵抗は必須(ボード上の搭載・MPU内部プルアップなし)

      
利用ピン


図の紫色の5番ピンSDA27番ピン SCLをデータの2ピンをデータ通信に利用します。
また必要に応じて、VCC、GNDをIchigoJamに結線します。
5番ピン、純正品のラベルはIN3のみしか書いていないのでちょっと分かりにくいですね。

  Ichigojam121

IchigoJam Tの場合、 マイクロUSBコネクタの近くにある端子の利用も可能です。

 

接続方法

一般的な接続方法

I2Cはバスですので複数のI2Cデバイス(スレーブ)が接続出来ます。
注意点としてSDAとSCLにプルアップ抵抗(2.2kΩ~10kΩ、図では4.7kΩを利用)が必要です。

ただし、I2Cデバイスにあらかじめプルアップ抵抗が搭載されている場合があります。
この場合は、そのプルアップ抵抗を利用するため回路図の抵抗は省略出来ます。
(省略しなくても利用可能)

Photo

「プアップ抵抗って何? 何で必要なの?」、「なんで出力が競合しないん?」的な解説
(内容が間違えているかもしれません)

I2Cバスの電気的性質

(読み返すと若干、内容が怪しいかも..後で修正します)

I2CのSDAとSCLは双方向の信号ラインです。
普通に考えると、それぞれのデバイスで入出力の方向が異なる可能性があり、
なんで上手く動いているのだろう?って疑問に思います。

通常のH(ハイ 3.3V)、L(ロー 0V)の状態を持つ線を共通配線にした場合、
それぞれが出力状態かつ、出力値が異なる場合、厄介なことが発生します。

例えば、SDA接続で1つがH(3.3V)、別の1つがL(0V)を出力するとこれはもう、
ショート状態です。H→L間で大きな電流が流れICが破損する可能性もあります。
また、ショートしなくてもSDAのバス的に信号がHなのかLなのか不定です。

そこでI2CバスではワイヤードAND接続が採用されています。
この場合、SDA、SCL端子はオープンドレインという状態で利用します。

この時の出力の取り得る状態はH(1、ハイ 3.3V)、L(0、ロー 0V)ではなく、
H(Hi-Z:ハイインピータンス=絶縁状態)、L(0、ロー 0V)となります。

ハイインピータンスは高抵抗値を意味し、端子には電流が流れない状態です。
この状態であれば、バス上で各デバイスの出力状態でHとLが重なっても
問題となりません。
絶縁状態の端子に0Vの端子を接続しても電流は流れませんね。
当然、ショートも発生しません。

ただしこの場合、1つ厄介なことが発生します。
下の図は共通配線SDA、各スイッチがI2CデバイスのSDA出力を等価的に表しています。
スイッチOFF時がハイインピータンス(絶縁状態)、スイッチON(接続時)がLです。

   Photo_2

全てのデバイスがH(ハイインピータンス=スイッチが開いている状態)、
共通配線SDAは、電圧が不定て右端のSDA出力端子からは
状態(H? L?どっち?)を読むことが出来ません。

そこで、プルアップ抵抗を入れて
SDAがH(ハイインピータンス)の場合は、プルアップ抵抗経由の電圧が出力され、
ロジックとして"1"をとるようにします。
SDAがL(0V)の場合は、そのまま0Vでロジックとして"0"と判定出来ます。

  __2

もしも、それぞれが好き勝手に出力した場合ですが、
1つでもL(0V)があればSDAの状態はLになります。
上図は全てがHですが、どれか1つスイッチを閉じるとSDAが0Vになるは明白です。

論理的にはANDをとってどれか1つでも0ならばSDAのバスは0、
全部がHなら1となります(= ワイヤードAND (論理積))。
(ちなみにI2Cでは、SDA、SCLともHの場合にバスがフリーな状態と規定しています)


IchigiJamのI2C利用コマンド

例としてRTCモジュール(DS3231搭載)を使って説明します。
RTCモジュールは時計機能を持つモジュールで時刻設定、時刻参照、アラーム設定、
アラーム通知が主な機能です。

 
   (このデバイスはプルアップ抵抗搭載なのでIchigoJamに直結で利用出来ます)

IchigoJamにはデータ送信用とデータ受信用の2つのコマンドが用意されています。

  ・ データ送信
      I2CW(I2Cアドレス、 コマンド、コマンド長、送信データ、データ長)

  ・ データ受信
      I2CR(I2Cアドレス、 コマンド、コマンド長、受信データ、データ長)

引数のI2Cアドレスは利用するI2Cスレーブのアドレスを指定します。
このアドレスの指定方法は7ビット、8ビット、10ビット等がちょっと混乱しすが
IchigoJamでは7ビットアドレスを指定します。

まず、利用するI2CデバイスのI2Cアドレスを知る必要があります。
通常は添付の解説書または、商品情報HPのリンク先の資料に記載されています。
大抵は下図のような通信データのレイアウトが記載されています。

I2c

この図で<SLAVEADDRESS>がI2Cアドレスとなります。
(0と1の羅列が7個あるので7ビットだと分かります。系によっては<R/W>を含めて
8ビットで指定する場合もあります)

2進数表記 1101000  をIchigoJamでそのまま指定する場合は、
`1101000   となります(` はキーボードの[@]キーを[Shift]キーを押しながら入力)。
  メモリー的&読書きにおいて無駄なので16進数に直して#68 で指定することにします。
(IchigoJam上で ?HEX$(`1101000) を実装すれば楽に求められますね)

I2CWI2CRコマンドの引数、
コマンドはI2Cデバイスに送るコマンドの格納アドレス、コマンド長はその長さです。
IchigoJamの変数では可変長のデータを直接扱うことが出来ません。
そのため、アドレスでの指定となります。

ここで、RTCモジュールに時刻設定する場合を考えます。
設定にはI2CWコマンドを使います。

RTCモジュールの場合、引数のコマンドにはRTCモジュール内のレジスタアドレスを指定します。

次の表がレジスタアドレスに割りつけられている機能です。
引数のコマンドにはこの表のアドレスを指定し、書きこみたいアドレスを指定します。

<レジスタアドレス表>
Photo_3

引数の送信データには上記の表に設定する内容を指定します。
ここでは年、月、日、曜日、時、分、秒 の7つの値を1回の送信で設定したいと思います。

2016年9月13日(火) 20時30分00秒 を設定することにします。
この場合、アドレス00h~06hにだけ値を設定します。

まず、設定値は次のようになります。データ長は7バイトです。
アドレス 設定値   補足
00h:   #00         秒
01h:   #30         分
02h:   #20         時
03h:   #03         曜日(01:日、02:月、03:火 ... 06:土)
04h:   #13         日
05h:   #09         月
06h:   #16         西暦年下2桁

16進数BCD表記ではほぼ見た目のままの数字の指定となります。

以上のコマンドと設定データの実際の送信を行うプログラムと実行結果です。

10 POKE #700,#00,#00,#30,#20,#03,#13,#09,#16
20 R=I2CW(#68,#700,1,#701,7)
30 ?R

1

10行のPOKEコマンドでIchigoJamのアドレス#700から#00#00#30..#16
順番に格納しています。最初の#00はコマンドとして送信するデータ1バイト、
次の#00#16が設置値7バイトです。

#700からの領域はPCG定義用の領域です。フォント定義を利用しない場合は、
自由に利用出来ます(256バイト)。

20行ではI2CWコマンドを使って実際にI2Cデバイスのデータを送信しています。
変数Rは送信結果が返されます(0で正常、1で異常)。

#68はI2Cデバイスのアドレス、#700がコマンド格納アドレス、1がコマンド長、
#701が送信データの格納アドレス、7が送信データの長さです。

実行すると次のような感じになります。
正常動作の0が表示されます。

次にI2CWコマンドを使って現在時刻を読みだしてみます。

    I2CR(I2Cアドレス、 コマンド、コマンド長、受信データ、データ長)

やりたいことは、I2Cデバイスのレジスタアドレス表の00h~06hに格納されている、
ここでは年、月、日、曜日、時、分、秒 の7つの値を取得することです。

I2CRの引数のI2CアドレスはI2CRと同じ#68を指定します。
コマンドおよびコマンド長にはレジスタアドレス表の00hを指定します。
受信データおよびデータ長は取得したデータを格納するアドレスとして#710、長さ7を指定します。

以下が実際のプログラムと実行結果です。
10 POKE #700,0
20 R=I2CR(#68,#700,1,#710,7)
30 ?R
40 FOR I=0 TO 6
50 ?HEX$(PEEK(#710+I),2)
60 NEXT

2

10行はコマンドを#700に設定
20行はI2Cアドレス#68、コマンド格納アドレスとして#700、その長さとして1を指定、
受信したデータ格納アドレスとして#710、その長さとして7を指定しています。
30行がI2CRの実行結果の表示
40~60行は#710#706に格納されている取得データを16進数2桁で表示しています。


IchigoJamのI2CW、I2CRのバグ(不具合)について


2つのコマンド、
  I2CW(I2Cアドレス、 コマンド、コマンド長、送信データ、データ長)
  I2CR(I2Cアドレス、 コマンド、コマンド長、受信データ、データ長)

において次のバグ(不具合)があります。
・コマンドにて送信するデータはコマンド長0を指定すると意味不明なデータが
  I2Cデバイスに送信されます。この時、データ長も固定ではないようです。

・コマンドにて5バイト以上のデータを送信するとI2Cデバイスには
  正しくないデータが送信されます。

(本不具合は開発者に連絡済です)
なのでコマンドは1~4バイトの範囲で利用しましょう。

2017/04/03 追記
最新のβファームでは上記不具合は対応済みです。
(facebook IchigoJam-FANにて公開 IchigoJam 1.2 beta 42)

以前試した、Wii用ヌンチャク等も利用可能になりました。

« aitendoのこどもパソコン「ai.Jam-T」キット を組み立てました | トップページ | LEDドットマトリックスを使ったメッセージ表示デバイスを作成中 »

IchigoJam」カテゴリの記事

コメント

コメントを書く

(ウェブ上には掲載しません)

トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/571408/64197816

この記事へのトラックバック一覧です: IchigoJamのI2Cインタフェースについて:

« aitendoのこどもパソコン「ai.Jam-T」キット を組み立てました | トップページ | LEDドットマトリックスを使ったメッセージ表示デバイスを作成中 »