今日は、CHIRIMENからI2Cデバイスを使ってみたいと思います。
I2Cとは?
I2Cと書いて「アイ・スクエア・シー」と読んだり「アイ・ツー・シー」と読んだりします。
まぁ、私はいい加減な人なので、どっちでもいいです。
で、これは何か?というと、シリアル通信規格の一種です。
I2Cと同じようによく使われるシリアル通信に、UARTやSPIなどがありますが、I2Cは2本の線(SCL/SDA)で構成する1つのバスに複数のモジュールを接続できるのが最大の特徴と思います。配線が少なくて済むのでいろいろ楽です。
参考:
I2Cでは「Master」から複数の「Slave」を制御します。例外もありますが、基本的にホストコンピュータ側が「Master」となり、デバイス側が「Slave」として動作します。CHIRIMENはI2C「Master」として動作します。
I2Cに対応したモジュール
I2Cに対応したセンサーやアクチュエータなどは、その多くがI2C Slaveとして動作するデバイスです。
CHIRIMENに接続するI2Cデバイスを選ぶには?
上記スイッチサイエンスや秋月電子で購入できるI2C対応デバイスが全てすぐにCHIRIMENで使えれば良いのですが、残念ながら現時点では「すぐに利用可能」なデバイスは限られています。
CHIRIMENで利用可能なI2C機器は、下記条件を満たしたものに限定される認識です。
-
- 対象デバイスのI2Cバス上でのデータ送受信の仕様が、Web I2C APIがサポート可能な仕様であること
-
- I2Cバスライン(SDL/SCA)の電圧が3.3Vに対応した機器であること
上記条件を満たした機器であっても、すぐに使えるわけではありません。下記のような作業が必要になります。
-
- デバイスを利用するためのドライバーを入手する。あるいは自作する
-
- ドライバーを経由してI2Cデバイスを制御するWebアプリを書く
なんだか大変そうですね。確かに全部自分でやろうとすると結構大変です。
そこで最初は、CHIRIMENコミュニティのexamplesに登録されたデバイスから使ってみると良いと思います。
examplesには、CHIRIMENコミュニティ有志によって動作確認されたデバイスのサンプルコードが登録されています。
Web I2C APIを使ってみる → I2CデバイスをCHIRIMENに対応させてみる
それでは、examplesに登録されているデバイスをCHIRIMENにつないでみましょう!
。。。という風に進めたかったのですが、ポカをしてしまい、なぜか現在手元にexamplesに登録されているデバイスが1つもありません。。。。。
なぜか手元のI2Cデバイスは?というと、Arduino、Canzasi、そしてMCP4018(デジタルポテンショメータ)という状況。
いきなりハードル高めで申し訳ありませんが、MCP4018をCHIRIMENで使ってみようと思います。
つまり、最初はexampleを使ってみよう!ということができず、最初っから上記1〜4全部やってみよう!というスパルタ記事です。ええ、書いてる私も泣きそうw
1. Web I2C API に対応できるか? をデータシートで調べる
I2C対応デバイスをCHIRIMENで使えるようにするために、最初の条件を確認してみます。
現時点で Web I2C API が対応しているAPIを知る
現時点のWeb I2C APIは、まだドラフト段階のため、様々なI2C機器のデータ送受信仕様が実現できるようにAPIが網羅されているわけではありません。
現在Web I2C APIで、I2C Slaveデバイスへのデータ書き込みや読み込みに利用可能なAPIは5.5 The I2CSlaveDevice interface
に記載のある下記APIです。
interface I2CSlaveDevice {
readonly attribute unsigned short slaveAddress;
Promise read8(unsigned short registerNumber);
Promise read16(unsigned short registerNumber);
Promise write8(unsigned short registerNumber, octet value);
Promise write16(unsigned short registerNumber, unsigned short value);
};
上記は全てCHIRIMENで利用可能です。
上記APIを呼び出した時にI2Cバスに流れるデータは下図のようになります。
これをよく覚えておきましょう。
MCP4018のデータシートを読む
MCP4018のデータシートを読んでいきます。
MCP4018はデジタルポテンショメータというもので、デジタルで制御可能な可変抵抗です。
今回買ったのは、10kΩのものです。127段階で10kΩを最大とした抵抗値に変更可能です。
I2Cがどうとか以前に、SC70-6というパッケージサイズが、非常にハンダ付けハードルが高いですが、変換基板等へのハンダ付けの話はここではしませんw
SC70-6の変換基板が入手できればそれが一番ですが、SOT23-8の変換基板でもなんとかなるでしょう。私はaitendoのSOT23-8の変換基板を使いました。
少なくとも、下記を読む必要があります。
- P.1。概要と各ピンの機能把握。
- P.36〜 I2Cのコマンドプロトコルについて書かれている
ここで確認することは2つ。
- I2Cスレーブアドレス
これは、P.36 Figure 5-9 を見ると、7bitで 0101111
となっていますので、0x2F
であることがわかりました。
- I2Cコマンド
続いてI2Cコマンドも確認します。
重要なのは、5.4.1 WRITE OPERATION
です。
デジタルポテンショメーターの機能を使う目的では、これに対応するだけでも問題ないでしょう。
ここで気になる部分が。
Data bytes may be written after each Acknowledge.
The command is terminated once a Stop (P) condition
occurs. Refer to Figure 5-12 for the write sequence.
For a single byte write, the master sends a STOP or
RESTART condition after the 1st data byte is sent.
The MSb of each Data Byte is a don’t care, since the
wiper register is only 7-bits wide.
確かに、7bitの分解能しかないMCP4018がシングルバイトのみの書き込みで十分です。
しかし、ここで言うMSb
が、何byte目を指すのか。実はこの仕様を正確に把握することが重要になります。
前に書いたように、現行のWeb I2C APIは「1byteだけの書き込み」はサポートしませんが、MCP4018側が下記のような動作を行ってくれれば、2byteを書き込むI2CSlave.write8()
がつかえそうです。
- 最初に来た1byte(I2CSlave.write8()を使った場合、registerNumberパラメータ)を有効な値として取り扱う。
- Stopコンディションの直前に来たデータ(I2CSlave.write8()を使った場合、valueパラメータ)が有効になる
いずれの動作であっても、I2CSlave.write8()
がつかえそうです。(書き方は変わりますが)
検証してみたところ、2. の動作となるようです。
さて、MCP4018は5.4.2 READ OPERATIONS
にあるように、データReadにも対応しているようですが、正直何に使うのか?なので、ここでは無視することにします。
I2Cバスライン(SDL/SCA)の電圧が3.3Vに対応したデバイスか? をデータシートで調べる
こちらもMCP4018のデータシートを確認する作業です。
P.4 AC/DC CHARACTERISTICS
によると、2.7〜5.5Vという電圧に対応しています。
まずは、電源ラインはクリアになりました。3.3Vにも対応しています。
もう1箇所確認が必要なページがP.8です。Digital Inputs/Outputs (SDA, SCK)
の項です。
大事な箇所なので、下記にキャプチャーを置きます。
これを見ると、
- HIGH = VDDの電圧の70%以上であること
- LOW = -0.5V〜VDDの電圧の30%以下の範囲であること
となっています。
CHIRIMENのI2Cポートの電圧は3.3Vですので、MCP4018のVDDを3.3Vから供給すれば問題ないはずです。
CHIRIMENの5VからMCP4018のVDDには接続しないでください。
上記の通り、MCP4018がI2CのラインでのHIGHの検出に「VDDの電圧の70%以上」が必要です。
5VをVDDとしてしまうと、MCP4018側がHIGHである、と認識する閾値電圧は 5 * 0.7 = 3.5Vとなり、3.3Vより高くなってしまいます。つまり、CHIRIMEN側がHIGHにしたつもりで3.3Vまで上げたとしても、MCP4018側がHIGHになってないと認識してしまう原因となります。MCP4018に限らず、「VDDの電圧の70%以上をHIGHとする」という仕様はI2Cバス仕様中(3.1.2章)にも記載のある設計仕様ですので、覚えておきましょう。
3. デバイスを利用するためのドライバーを書く
仕様がだいたい理解できましたので、MCP4018をWeb I2C APIから使うコードを書いてみましょう。
i2c-VEML6070のサンプルをベースに書いてみます。
下記のようになりました。
var mcp4018 = function(i2cPort){
this.i2cPort = i2cPort;
this.slaveAddress = 0x2F;
this.i2cSlave = null;
};
mcp4018.prototype = {
init: function(){
return new Promise((resolve, reject) => {
this.i2cPort.open(this.slaveAddress).then((i2cSlave) => {
this.i2cSlave = i2cSlave;
console.log("i2cPort.open");
resolve();
});
});
},
set: function(value){
if(this.i2cSlave){
console.log("mcp4018.set("+value+")");
if(value > 127) value = 127;
if(value < 0) value = 0;
this.i2cSlave.write8(0,value);
}else{
console.log("i2cSlave has gone.....");
}
}
};
少し解説
T.B.D. 解説は後日書く予定
4. ドライバーを経由してI2Cデバイスを制御するWebアプリを書く
MCP4018を制御するドライバーができましたので、引き続きWebアプリを作って完成です。
今回は、下記のような回路を作って、LEDを「ふわふわ」と点滅させてみます。
PWMと違い、アナログ電圧で「ふわふわ」やってますので、精神的な「ふわふわ」感も向上してるはず!?w
残りのWebアプリのコードは下記の通り、今回はUIなどぜんぜんありませんw
<!doctype html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1">
<title>mcp4018 Test</title>
<script src="./webi2c.js"></script>
<script src="./mcp4018.js"></script>
<script src="./main.js"></script>
</head>
<body>
<p>mcp4018 TEST</p>
</body>
</html>
そして、こちらが先ほど作ったmcp4018.jsを使って、LEDの抵抗値を少しづつ変えることで明るさを変更している部分です。
navigator.requestI2CAccess().then((i2cAccess) => {
var port = i2cAccess.ports.get(0);
var value = 0;
var mode = 0;
var digipot = new mcp4018(port);
digipot.init().then(() => {
console.log("digipot.init() done!");
setInterval(() => {
if(mode){
value -=4;
if(value < 0){
value = 0;
mode = 0;
}
}else{
value +=4;
if(value > 127){
value = 127;
mode = 1;
}
}
digipot.set(value);
},30);
},(v) => {
console.log("digipot init error:"+v);
});
}).catch((e) => {
console.error("digipot I2C bus error!", e);
});
上記ファイルに加え、@MSakamakiさんによるpolyfillから、
- webi2c.js
- worker.js
をindex.htmlと同じフォルダに入れる必要があります。
最終的なWebアプリのフォルダの中に必要なファイルは下記になります。
- index.html
- main.js
- mcp4018.js
- webi2c.js
- worker.js
上記をWebサーバに置けば完成です!
動作サンプル(CHIRIMENのブラウザからMCP4018との回路組んでからアクセス)
今回はここまで!
今回は、市販のI2Cデバイスの中からCHIRIMENに対応可能なデバイスの見つけ方(データシートの読み方)と、Web I2C APIへの対応手順について記載してみました。
Web I2C APIへの対応手順については、少し記載が足りないので後日補足予定です。ようするに途中で疲れましたw
次回は、CanzasiというArduinoを利用してI2Cデバイスを作る環境を紹介します。