3. I2C 応用編 (その他のセンサー)

概要

CHIRIMEN for Raspberry Pi 3(以下 「CHIRIMEN Raspi3」) を使ったプログラミングを通じて、Web I2C API の使い方を学びます。

前回は温度センサーを使いながら Web I2C API の基本的な利用方法を学びました。今回は温度センサー以外のI2Cセンサーの使い方を見ていきましょう。

(※1) CHIRIMEN for Raspberry Pi 3とは

Raspberry Pi 3(以下「Raspi3」)上に構築したIoTプログラミング環境です。

Web GPIO API (Draft)や、Web I2C API (Draft)といったAPIを活用したプログラミングにより、WebアプリからRaspi3に接続した電子パーツを直接制御することができます。

CHIRIMEN Open Hardware コミュニティにより開発が進められています。

前回までのおさらい

本チュートリアルを進める前に前回までのチュートリアルを進めておいてください。

前回までのチュートリアルで学んだことは下記のとおりです。

1.準備

複数のI2Cモジュールを接続するために

前回は Raspberry Pi と温度センサーを4本のジャンパケーブルで直接接続しました。

I2Cバスには複数のモジュールが接続できますので、今回は複数の I2C モジュールを容易に追加・削除できるように Grove I2C Hub を利用することにします。

Grove I2C Hub は、4つの Grove コネクタを備えた I2C モジュールを接続するためのハブです。

4ピンの Grove 4ピン ケーブルを経由すれば、後述するGrove Digital Light SensorなどGroveコネクタを備えたI2Cモジュールを直接接続することができます。

Raspi 3 や前回のADT7410などピンヘッダを備えた(あるいは事前にスルーホールにピンヘッダをはんだ付けしてある)モジュールとの接続には、Grove 4ピン ジャンパ メスケーブル 経由で接続することができます。

用意するもの

ここでは、1つのGroveコネクタつきI2Cモジュールと1つのピンヘッダつきI2Cモジュールを接続することを想定し、下記を用意しておきましょう。

ハブとケーブル

上記に加え今回紹介するセンサーが必要となりますが、センサーについては各センサーの説明のパートに記載します。

1/10 追加

測距センサーをSRF02からGP2Y0E03にしました。

この変更に伴い、下記が追加で必要になります。

2.光センサーを使ってみる

光の強度に反応するセンサーを使ってみましょう。

a. 部品と配線について

「1.準備」のパートに記載したものに加え、下記を用意してください。

Raspberry Pi 3との接続方法については、下記回路図を参照ください。

/home/pi/Desktop/gc/i2c/i2c-grove-light/schematic.png

回路図

このセンサーモジュールはGroveコネクタを備えていますので、接続方法に応じてコネクタを選んでください。

b. 接続確認とexampleの実行

i2cdetect で接続を確認しておきましょう。

$ i2cdetect -y -r 1

SlaveAddress 0x29 が見つかれば接続OKです。

次に example を動かします。

/home/pi/Desktop/gc/i2c/i2c-grove-light/index.html

画面の回路図の下の数値が明るさの値です。

センサーに当たる光を遮断してみてください。数値が小さくなるはずです。

逆にセンサーに LED の光を直接当てると数値が大きくなることが確認できるでしょう。

c.コード解説

example のコードから、光センサーに関係する部分を見ていきます。

今回はドライバーライブラリの中までは深入りせずに、アプリケーションの流れを追ってみましょう。

ADT7410 の時とほとんど同じであることがわかるはずです。

c-1. index.html

下記がindex.htmlの中から主要な部分を抜き出したコードです。

index.html

: 
  <script src="../../polyfill/polyfill.js"></script>
  <script src="../../drivers/i2c-grove-light.js"></script>
  <script src="./main.js"></script>
  :
  <body>
    :
    <p id="head">TEST</p>
    :
  </body>

HTML は ADT7410 の時とほとんど同じです。 ドライバーライブラリが、i2c-grove-light.js に変わりました。

c-2. main.js

次に、main.jsを見てみましょう。(重要な部分以外は削っています)

main.js

	var i2cAccess = await navigator.requestI2CAccess();
	var port = i2cAccess.ports.get(1);
	var grovelight = new GROVELIGHT(port,0x29);
	await grovelight.init();
	while(1){
		var value = await grovelight.read();
		head.innerHTML = value ? value : head.innerHTML;
		await sleep(200);
	}

main.js も温度センサーとほとんど同じです。

var grovelight = new GROVELIGHT(port,0x29)

ここで光センサー用のドライバーライブラリのインスタンス生成を行なっています。

ライブラリ名が変わっただけで ADT7410 と同様に、port オブジェクトと、SlaveAddress をパラメータで渡しています。

grovelight.init()

init() では、インスタンス生成時に指定したportオブジェクトと slaveAddress(0x29) を用いて I2CPort.open() を行ない、返却される I2CSlaveDevice を保存後に resolve() で呼び出し元に処理を返しています。

grovelight.read()

Grove Digital Light Sensor の仕様に基づくデータ読み出し処理をここで実施しています。

3.測距センサーを使ってみる (11/10変更)

モノまでの距離を測定する測距センサーを使ってみましょう。

a. 部品と配線について

「1.準備」のパートに記載したものに加え、下記を用意してください。

Raspi 3 との接続方法については、下記回路図を参照ください。

/home/pi/Desktop/gc/i2c/i2c-GP2Y0E03/schematic.png

回路図2

このセンサーモジュールには、細い7本のケーブルが付属していますが、このままではRaspi 3 と接続することができません。

この細いケーブルを2.54mm のジャンパーピンにハンダづけするなどしてブレッドボード経由でRaspberry Piと接続できるよう、加工しておいてください。

ピンの加工例

加工例

b. 接続確認とexampleの実行

i2cdetect で接続を確認しておきましょう。

$ i2cdetect -y -r 1

SlaveAddress 0x40 が見つかれば接続OKです。

次にexampleを動かします。

/home/pi/Desktop/gc/i2c/i2c-GP2Y0E03/index.html

画面の回路図の下の数値が距離の値(cm)です。 センサーの前面(小さな目玉のような部品が着いた面)を障害物の方向に向けてみてください。障害物とセンサーの距離に応じて数字が変化するはずです。

GP2Y0E03 が計測できる距離は 60cm くらいまでです。

測定できる範囲を超えている場合、out of range と表示されます。

c.コード解説

example のコードから、測距センサーに関係する部分を見ていきます。

c-1. index.html

下記がindex.htmlの中から主要な部分を抜き出したコードです。

index.html

: 
  <script src="../../polyfill/polyfill.js"></script>
  <script src="../../drivers/i2c-GP2Y0E03.js"></script>
  <script src="./main.js"></script>
  :
  <body>
    :
    <p id="distance">init</p>
    :
  </body>

HTML は ADT7410 の時とほとんど同じです。 ドライバーライブラリが、i2c-GP2Y0E03.js に変わりました。

c-2. main.js

次に、main.js を見てみましょう。(重要な部分以外は削っています)

main.js

	var i2cAccess = await navigator.requestI2CAccess();
	var port = i2cAccess.ports.get(1);
	sensor_unit = new GP2Y0E03(port,0x40);
	await sensor_unit.init();
	
	while(1){
		try {
			var distance = await sensor_unit.read();
			if(distance != null){
				valelem.innerHTML = "Distance:"+distance+"cm";
			}else{
				valelem.innerHTML = "out of range";
			}
		} catch ( err ){
			console.log("READ ERROR:" + err);
		}
		await sleep(500);
	}

main.js も温度センサーとほとんど同じです。

var sensor_unit = new GP2Y0E03(port,0x40)

ドライバーライブラリのインスタンス生成処理です。

sensor_unit.init()

こちらも、内部で I2CSlaveDevice インタフェースを取得する処理で、他のセンサーと同様です。

sensor_unit.read()

測距センサー GP2Y0E03 の仕様に基づくデータ読み出し処理をここで実施しています。

4.三軸加速度センサーを使ってみる

傾きなどに反応するセンサーを使ってみましょう。

a. 部品と配線について

「1.準備」のパートに記載したものに加え、下記を用意してください。

Raspi 3 との接続方法については、下記回路図を参照ください。

/home/pi/Desktop/gc/i2c/i2c-grove-accelerometer/schematic.png

回路図

このセンサーモジュールはGroveコネクタを備えていますので、接続方法に応じてコネクタを選んでください。

b. 接続確認とexampleの実行

i2cdetect で接続を確認しておきましょう。

$ i2cdetect -y -r 1

SlaveAddress 0x53 が見つかれば接続OKです。

次に example を動かします。

/home/pi/Desktop/gc/i2c/i2c-grove-accelerometer/index.html

画面の回路図の下に表示されている3つの数値が加速度センサーの値です。

画面左から、X、Y、Zの値となっています。

加速度センサーの値

センサーを傾けると数値が変化するはずです。

c.コード解説

exampleのコードを見てみましょう。

c-1. index.html

下記がindex.htmlの中から主要な部分を抜き出したコードです。

index.html

  : 
  <script src="../../polyfill/polyfill.js"></script>
  <script src="../../drivers/i2c-grove-accelerometer.js"></script>
  <script src="./main.js"></script>
  :
  <body>
    :
      <div id="ax" class="inner">ax</div>
      <div id="ay" class="inner">ay</div>
      <div id="az" class="inner">az</div>
    :
  </body>

ドライバーライブラリが、i2c-grove-accelerometer.js に、そしてX、Y、Z、3つの値を表示するため要素が3つに変わりましたが、それ以外は今回もこれまでとほとんど同じです。

c-2. main.js

次に、main.js を見てみましょう。(重要な部分以外は削っています)

main.js

	var i2cAccess = await navigator.requestI2CAccess();
	var port = i2cAccess.ports.get(1);
	var groveaccelerometer = new GROVEACCELEROMETER(port,0x53);
	await groveaccelerometer.init();
	while(1){
		try {
			var values = await roveaccelerometer.read();
			ax.innerHTML = values.x ? values.x : ax.innerHTML;
			ay.innerHTML = values.y ? values.y : ay.innerHTML;
			az.innerHTML = values.z ? values.z : az.innerHTML;
		} catch ( err ){
			console.log("READ ERROR:" + err);
		}
		await sleep(1000);
	}

main.js も温度センサーとほとんど同じです。

var groveaccelerometer = new GROVEACCELEROMETER(port,0x53)

ここで加速度センサー用のドライバーライブラリのインスタンス生成を行なっています。

grovelight.init()

これまでのドライバーライブラリ同様に init() では、インスタンス生成時に指定した port オブジェクトと slaveAddress(0x29) を用いて I2CPort.open() を行ない、返却される I2CSlaveDevice を保存後にresolve()で呼び出し元に処理を返しています。

groveaccelerometer.read()

read() では、加速度センサーの X、Y、Zの値が一度に返却されます。

5.演習:複数のセンサーを組み合わせて使ってみよう

せっかく Grove I2C Hub を用意しましたので、これまでの復習と応用を兼ねて下記のような組み合わせで2つのセンサーを繋いで動かしてみましょう。

※この組み合わせなら、冒頭で用意したケーブルで足りるはずです。

オンライン版のドライバーライブラリは下記にあります。

まずはセンサーを繋いでから、jsbinjsfiddle を使ってコードを書いてみましょう。

6.他のI2Cモジュールも使ってみる

前回からこれまでに4つのI2Cセンサーを使ってみました。

本稿執筆中の CHIRIMEN Raspi3 には、他にも /home/pi/Desktop/gc/i2c/ 配下に下記のようなI2Cモジュールの examples が含まれています。

ご興味がありましたら、ぜひ触ってみてください。

I2Cデバイスを複数使う場合の注意事項

I2Cデバイスを同時に接続して使用するとき、重要な注意事項があります。それはI2Cアドレスの衝突です。チュートリアル2―2の図に書かれているようにI2Cデバイスはアドレスを持っています。このアドレスはI2Cデバイスの製品ごとに固有のアドレスが設定されています。そのためたまたま同じアドレスを持ったデバイスが販売されていることがあります。そしてアドレスが衝突しているデバイスは接続できません。このチュートリアルで使ったデバイスのアドレスを以下の表に掲載します。NativeAddrがそのデバイスのオリジナルの状態のアドレスです。すでに衝突しているものがいくつかあるのがわかると思います。

一方、I2Cデバイスのによってはこのアドレスを変更でき、アドレスの衝突を回避できる場合があります。ただしアドレスの変更はデバイスの基板上でハードウェア的(電気的)に設定するジャンパによって設定します。(ジャンパはピンヘッダとして用意され、ジャンパ線などで設定できるものもありますが、多くの場合は半田を盛ってジャンパとするタイプです。詳しくは各デバイスを購入すると付属しているデータシートを参照してください。)下表のChangedAddrはアドレス変更可能なデバイスでジャンパーを設定し、すべてのデバイスのアドレスを衝突しないようにした例です。

Device NativeAddr ChangedAddr
ADT7410 0x48 =>test brd:0x49
ADS1015 0x48  
VEML6070 0x38, 0x39  
S11059 0x2a  
PCA9685 0x40 =>test brd:0x41
grove-touch 0x5a  
grove-oledDisplay 0x3c  
grove-gesture 0x73  
grove-light 0x29  
grove-accelerometer 0x53  
GP2Y0E03 0x40  

まとめ

このチュートリアルでは 下記について学びました。

次のCHIRIMEN for Raspberry Pi 3 チュートリアルでは、『Web GPIO APIとWeb I2C APIを組み合わせたプログラミング』に挑戦します!