CHIRIMEN I2C sensor 

（本記事は[fabble.cc](http://fabble.cc/chirimenedu/chirimeni2csensor)に掲載されていたものを一部改良したものです）

この記事では、コンピュータボードCHIRIMENからI2Cインタフェースを持った物理デバイスを制御する方法について記載しています。
CHIRIMENとは何か、開発環境の準備、アプリの開発方法などを知りたい方は[こちら](http://qiita.com/kotakagi/items/3a4f7865ab784cd88cdd)をご覧ください。
注：この記事は、CHIRIMENにインストールされたファームが20170301版の場合を想定して書いています。詳しくは[こちら](http://qiita.com/kotakagi/items/3a4f7865ab784cd88cdd)をご覧ください。

## この資料で学ぶこと
- I2Cとは何か？
- CHIRIMENでI2Cデバイスを触る方法（を温度センサを例として）
- CHIRIMENで触れる他のI2Cデバイス 

## 準備していただきたい機材
- CHIRIMEN 
- microUSBケーブル（CHIRIMEN-PCを接続するため）
- microHDMI-HDMIケーブル 
- CHIRIMEN用電源（通常CHIRIMENには電源ケーブル(USB-DC)が同梱されていますが、加えてUSB Aで5V 1A以上（2A以上推奨）を給電可能な電源が別途必要となります）
- HDMIディスプレイ 
- [ブレットボード](https://ja.wikipedia.org/wiki/%E3%83%96%E3%83%AC%E3%83%83%E3%83%89%E3%83%9C%E3%83%BC%E3%83%89) 
- I2Cセンサ（温度センサ(ADT7410)など）
- スルーホール用ジャンパワイヤ適量

## I2Cについて
### I2Cとは？ 
- I2Cとはシリアルデータ通信の方式でI2CまたはIICと標記し、「アイ・スクエア・シー、アイ・ ツー・シー」などと読みます。 
- GND(Ground、0V)、VDD(電源電圧3.3V/5V）とSDA（Serial DAta）、SCL（Serial CLock）という二つの信号線の計4本で接続します。 
- 異なるアドレスを持つI2Cデバイスであれば、一つのI2Cポートに複数のデバイスを接続することができます。（最大112個） 
- GPIOと異なり、0/1の信号だけだはなく、アドレスとデータを指定したデータ通信を行うことができます。 
- I2Cについて詳しく知りたい方はこちらをご参照ください：
  - [I2C - Wikipedia](https://ja.wikipedia.org/wiki/I2C) 
  - I2Cバス仕様書　最新版（[日本語](http://www.nxp.com/documents/user_manual/UM10204_JA.pdf)、[English](http://www.nxp.com/documents/user_manual/UM10204.pdf)）
  - [I2Cの使い方](http://www.picfun.com/i2cframe.html)（後閑哲也氏サイト)

### I2Cデバイスについて 
- I2Cインターフェースに対応したデバイスとして、温度センサ、加速度センサ、気圧センサなど様々なセンサや、液晶モジュール、モータドライバなど、様々なものが販売されています。 
- GND、VDD、SDA、SCL端子をつなぐことで制御できます。接続方法は共通なので簡単にI2Cデバイスを接続するためのコネクタも存在しています（grove systemなど）。 
- CHIRIMENはWebアプリからのI2C通信の読み書きに対応しているため、I2Cに対応したデバイスを制御することができます。 


## I2C温度センサデバイス(ADT7410)の制御およびアプリの実行 
ここでは、I2C対応デバイスの１つである温度センサ（ADT7410）を例として、その制御のためのアプリの実行方法、および同アプリのプログラムについて解説します。なお、ADT-7410を含んだ製品としては[こちら（プルアップ済み）](http://akizukidenshi.com/catalog/g/gM-06675/)があります。
 
### 温度センサアプリのダウンロード、読み込み
- [CHIRIMEN examples](https://github.com/chirimen-oh/examples)をダウンロード（「clone or download」ボタンを押下し、「Download zip」をクリックしダウンロード可能）して、任意のディレクトリに展開します。
- WebIDE左上の「パッケージ型アプリを開く」からi2c-ADT7410ディレクトリを読み込みます。
![WebIDE_OpenPackageApps](https://cloud.githubusercontent.com/assets/3125390/22399781/0dabe866-e5e8-11e6-875c-fff3a6569fe6.png)

### WebI2C polyﬁllの導入
WebI2C polyfillは以下(1)(2)の方法の**どちらか**で導入できます([そもそも「polyfillとは？」](http://qiita.com/kotakagi/items/3a4f7865ab784cd88cdd#note%E3%81%9D%E3%82%82%E3%81%9D%E3%82%82polyfill%E3%81%A3%E3%81%A6%E3%81%AA%E3%81%AB))。
(注：2017/7/7現在(2)の方法は利用できません。(1)でお試しください）

- (1) 以下2つのjsファイルを、上記で展開したディレクトリ配下の「i2c-ADT7410/js」ディレクトリにダウンロードします（下記2つのjsファイルのリンク先にそれぞれジャンプし（githubのサイトにジャンプします）、右上にある「RAW」ボタンを右クリック後「別名でリンク先を保存」を選択し、両ファイルを「i2c-ADT7410/js」ディレクトリに保存してください。）。その後、index.htmlからの参照先を以下のとおり書き換えます。worker.i2c.jsは webi2c.js内で参照されているため、webi2c.jsのパスのみ記載すればOKです。ただし、両ファイルは上述の通り同一ディレクトリに置かれている必要があります。
     - [webi2c.js](https://github.com/chirimen-oh/polyfills/blob/draft-20160125/dist/webi2c.js)
     - [worker.i2c.js](https://github.com/chirimen-oh/polyfills/blob/draft-20160125/dist/worker.i2c.js)

```html
<!-- 修正前（examplesをダウンロード直後は以下のようになっています） -->
<script src="./bower_components/webgpio/dist/webi2c.js"></script>

<!-- 修正後（以下のように書き換えます） -->
<script src="./js/webi2c.js"></script>
``` 
 
- (2) [bower](https://bower.io/)を使える場合、上記展開した「i2c-ADT7410」ディレクトリに移動し以下のコマンドを実行します（同ディレクトリにある[bower.json](https://github.com/chirimen-oh/examples/blob/master/i2c-ADT7410/bower.json)ファイルの指示で正しくインストールされます）。
 
```csh
$ bower install
```  

### 温度センサ回路の配線
- 配線図に従って温度センサを接続します。接続にはスルーホール用ジャンパ線を用います。 
- CHIRIMENのI2C0_SDA(CN2-12)、I2C0_SCL(CN2-11) と温度センサのSDA、SCL端子をそれぞれ接続します。
- CHIRIMENのGND(CN2-1)、VCC(CN2-18) と温度センサのGND、VDD端子をそれぞれ接続します。
![ADT7410_wiring](https://cloud.githubusercontent.com/assets/3125390/22399904/a65b938e-e5ea-11e6-8fb2-47096c3e77b5.png)


### アプリ実行
- 配線が正しいことを確認し、CHIRIMENとPCを接続、CHIRIMENの電源を入れます。 
- 上記で読み込んだアプリをインストールします。 
- 正しく動作すればディスプレイ上に温度が表示されていることが確認できるはずです。温度センサを（黒い部分を指で触るなどして）温めると、ディスプレイ上の表示温度も上昇していくことが確認できると思います。
- 上手く動かない場合は以下を参考にしてみてください。
  - [CHIRIMENにI2Cデバイスが繋がんない時に確認すること](http://qiita.com/tadfmac/items/8c3e79ed3d95c31ee72d)


## 温度センサプログラムの解説 
サンプルプログラムの[index.html](https://github.com/chirimen-oh/examples/blob/forCMN2015-1_B2GOS-20170301/i2c-ADT7410/index.html)、[main.js](https://github.com/chirimen-oh/examples/blob/forCMN2015-1_B2GOS-20170301/i2c-ADT7410/js/main.js)について解説します。 


### Index.htmlでpolyﬁllの読み込みを行います
- webI2Cを扱うためのpolyﬁll(webi2c.js) を読み込みます。

### I2CAccessインターフェースを取得します（おまじない）
- I2C端子の操作を行えるようにするため、requestI2CAccess()メソッドを使ってi2cAccessオブジェクトを取得します。 ここでは、以下のような感じでおまじない的に書くと覚えておけばいいでしょう。

```js:main.js
  navigator.requestI2CAccess()
    .then(function(i2cAccess){
// i2cAccessオブジェクト取得後の処理
    }).catch(e=> console.error('error', e));
```

### I2C端子の初期設定を行います
- `i2cAccess.ports.get(ピン番号)`でi2cAccessオブジェクト取得時にセットされたports属性に対し、`get()`メソッドを使って利用したい端子のピン番号を指定します。CHIRIMENにはI2C0(CN2側) 、I2C2(CN1側) の二つの端子が出ているため、ピン番号には0か2を指定します。サンプルではI2C0を利用しているため、0を指定しています。

```js:main.js
      var port = i2cAccess.ports.get(0);
```

### 温度センサの読み取り
- `new ADT7410(i2cPortオブジェクト, i2cデバイスアドレス)`でADT7410のコンストラクタ呼び出しを行います。ADT7410使用の温度センサのデバイスアドレスは初期値が0x48なので、これを指定します（通常、デバイスアドレスの初期値は各センサの説明書に掲載されています。念のため、そちらもご確認ください。）

```js:main.js
      var adt7410 = new ADT7410(port,0x48);
```

- `adt7410.read()`のように、呼び出したコンストラクタのreadメソッドを使用して温度センサの値の読み込みを行います。

```js:main.js
adt7410.read().then( function(value){  ...
```

### 温度センサ読み取り後の処理
- 温度センサの読み込み処理、`adt7410.read()` の結果はPromise型で帰ってきます。そのため、以下のように記述します。
- 温度センサの値は引数に指定した value という変数に格納されます。 

```js:main.js
adt7410.read().then( function(value){ 
  //温度センサ読み取り後の処理 
};
```

## CHIRIMENで他のI2Cセンサを読み取る方法(to be maintained)

### 距離センサ(SRF02)
距離センサ(SRF02)は例えば[こちら](http://akizukidenshi.com/catalog/g/gM-06685/)で販売しています。
#### 距離センサを読み取る
- 回路図に従って距離センサ回路を作成します。 
![SRF02_wiring](https://cloud.githubusercontent.com/assets/3125390/22399925/32b76fa6-e5eb-11e6-9fc7-d1d283133a34.png)
- 温度センサの場合と同様に距離センサアプリ（[i2c-SRF02](https://github.com/chirimen-oh/examples/tree/forCMN2015-1_B2GOS-20170301/i2c-SRF02)）をダウンロード、WebI2CPolyﬁllの設定を行います。 
- WebIDE上でi2c-SRF02ディレクトリを読み込み実行します。 
- 距離センサの値がディスプレイに表示されます。

#### 距離センサのサンプルコード
- Index.htmlでWebI2CPolyﬁll、SRF02.jsを読み込みます。
- 温度センサと同様にI2CAccessインターフェース、I2Cポートの初期化、距離センサのコンストラクタ呼び出しを行います。 
- `srf02.read()` で距離センサの値を読み込むことができます。
- 距離センサ(SRF02) のデバイスアドレスは0x70（初期設定）を使用します。

### 光センサ(grove-light)
光センサは例えば[こちら](https://www.switch-science.com/catalog/1174/)がございます。

#### 光センサを読み取る
- 回路図に従って光センサ回路を作成します。 

![GroveLight_wiring](https://cloud.githubusercontent.com/assets/3125390/22400001/1480dcbe-e5ed-11e6-9c12-35010c50c558.png)
- 温度センサの場合と同様に光センサアプリ（[i2c-grove-light](https://github.com/chirimen-oh/examples/tree/forCMN2015-1_B2GOS-20170301/i2c-grove-light)）をダウンロード、WebI2CPolyﬁllの設定を行います。 
- WebIDE上でi2c-grove-lightディレクトリを読み込み実行します。 
- 光センサの値がディスプレイに表示されます。

#### 光センサのサンプルコード
- Index.htmlでWebI2CPolyﬁll、i2c-grove-light.jsを読み込みます。
- 温度センサと同様にI2CAccessインターフェース、I2Cポートの初期化、光センサのコンストラクタ呼び出しを行います。
- `grovelight.init()` で光センサの初期化を行います。
- `grovelight.read()` で光センサの値を読み込むことができます。
- 光センサ(Grove digital light sensor) のデバイスアドレスは0x29（初期設定）を使用します。

### 加速度センサ(grove-accelerometer)
加速度センサは例えば[こちら](https://www.switch-science.com/catalog/972/)がございます。

#### 加速度センサを読み取る
- 回路図に従って加速度センサ回路を作成します。 

![GroveAccel_wiring](https://cloud.githubusercontent.com/assets/3125390/22400034/e765b3c0-e5ed-11e6-9007-a5bdcfc50caf.png)
- 温度センサの場合と同様に[加速度センサアプリ](https://github.com/chirimen-oh/examples/tree/forCMN2015-1_B2GOS-20170301/i2c-SRF02)をダウンロード、 WebI2CPolyﬁllの設定を行います。 
- WebIDE上でi2c-grove-acceleromterディレクトリを読み込み実行します。 
- 加速度センサの値がディスプレイに表示されます。

#### 加速度センサのサンプルコード
- Index.htmlでWebI2CPolyﬁll、i2c-grove-accelerometer.jsを読み込みます 
- 温度センサと同様にI2CAccessインターフェース、I2Cポートの初期化、加速度センサのコンストラクタ呼び出しを行います 
- `groveaccelerometer.init()` で加速度センサの初期化を行います
- `groveaccelerometer.read()` で加速度センサの値を読み込めます
- デバイスアドレスは0x53（初期設定）を使用します。 

## おわりに
いかがでしたでしょうか？ I2Cに対応したセンサとしては他にもサーボモータなどがあります。ぜひチェックしてみてください。