2017年11月8日水曜日

CHIRIMEN RPi3 にGrove圧力センサーを付けてみる


はじめに

前回はCHIRIMEN RPi3にADコンバータを付けてみましたが、今度はもう少し難しい圧力センサーを動かす方法について紹介いたします。

今回も魔改造なしです、簡単配線で初心者でも試せる内容にしました。

1.CHIRIMEN RPi3について

CHIRIMEN RPi3のインストール方法や基本的な利用方法については本家サイトを参照ください。
CHIRIMEN RPi3本家サイト: https://github.com/chirimen-oh/chirimen-raspi3


1-1.インストール方法
以下のページにインストール方法についての記載があります。
https://github.com/chirimen-oh/chirimen-raspi3/blob/master/env/setup-ja.md


とりあえず試してみたい方はビルド済みイメージがあります。
今回は10/19版イメージを利用しました。
https://drive.google.com/open?id=0B4k_ph7hQTADcVVlYzR6a0lqX3M

zipファイルを展開したものをmicroSDカードにddコマンドなどで書き込みを行うとすぐ使用することができます。

2.圧力センサーを接続

今回使用する圧力(大気圧)センサはGrove Barometerです。
Grove コネクタで繋がるのでお手軽にセンサー追加できます。国内では千石電商さんで取扱いがあります。
https://www.sengoku.co.jp/mod/sgk_cart/detail.php?code=EEHD-4YG6



搭載されているのはHP206というセンサーICです。センサーICのデータシートは次の場所からダウンロードすることができます。

http://www.hoperf.com/upload/sensor/HP206C_DataSheet_EN_V2.0.pdf

多少古典的なセンサーICですがデバイスの使い方を学ぶのには便利なICです。
圧力センサーは内部回路の補正のために温度センサーも内蔵しています。そのため温度値も取得できます。ただしセンサー表面温度であるためオマケとして扱ってください。

2-1.接続図

今回のサンプルの回路図は次の通りです。
RaspberryPiのI2Cと3.3V,GNDの4本を繋ぐだけです。





Groveセンサーを使うときの悩みどころはRaspberryPi等との結線だと思います。
電線に半田付けしたくないし、コネクタ圧着工具は高い・・・
そんな方にはGrove端子台がおすすめです。ドライバ1本で電線との繋ぐことができます。

https://www.seeedstudio.com/Grove-Screw-Terminal-p-996.html



Grove システムを扱っているお店ならば必ず在庫してますので、1個ぐらい部品箱に入れておくと便利でしょう。秋葉原では千石電商さんで扱っています。

https://www.sengoku.co.jp/mod/sgk_cart/detail.php?code=EEHD-4RLR


実際の結線はこのような感じになります、お手軽スマートですよね。


3.アプリとドライバ

今回作成したアプリとドライバは次の場所からダウンロード可能です。
https://drive.google.com/open?id=1cda6dVl3xzNIG6vcRzL9eUGNKN22-xEc

ダウンロードしたファイルをCHIRIMEN RPi3のデスクトップにあるgcフォルダ上で展開してください。


3-1.ドライバコード(drivers/i2c-HP206C.js)

今回作成したドライバコードを掲載します。

var HP206C = function(i2cPort,slaveAddress) {
  this.i2cPort = i2cPort;
  this.i2cSlave = null;
  this.slaveAddress = slaveAddress;
}

HP206C.prototype = {
  sleep: function(ms){
    return new Promise((resolve)=>{setTimeout(resolve,ms);});
  },
  init: function() {
    return new Promise((resolve, reject)=>{
      this.i2cPort.open(this.slaveAddress).then(async (i2cSlave)=>{
        this.i2cSlave = i2cSlave;
        await this.i2cSlave.writeByte(0x44);
        await this.sleep(10);
        resolve();
      }).catch((reason)=>{
        reject(reason);
      });
    });
  },
  compose: function(high, mid , low) {
    var val = ((high << 16) + (mid << 8)  + low)/100;
    return val;
  },

  // read  data
  read: function() {
    return new Promise(async (resolve, reject)=>{
      if(this.i2cSlave == null){
        reject("i2cSlave Address does'nt yet open!");
      }else{
        // ADC_CVT
        await this.i2cSlave.writeByte(0x44);
        await this.sleep(100);

        // READ_PT
        await this.i2cSlave.writeByte(0x10);
        this.i2cSlave.readBytes(6).then((v)=>{
            var temperature = this.compose(v[0],v[1],v[2]);
            var pressure = this.compose(v[3],v[4],v[5]);

//          console.log("read ok!");
          resolve([pressure,temperature]);

       },(err)=>{
          reject(err);

       });

      }
    });
  }
}


ドライバコード内で重要な部分について解説いたします。

初期化 init

polyfillに対してI2Cの使用を宣言します。また前回のADコンバータと違ってデバイスに初期設定を書き込む必要があるためI2C書き込みとエラー処理が追加されています。
  init: function() {
    return new Promise((resolve, reject)=>{
      this.i2cPort.open(this.slaveAddress).then(async (i2cSlave)=>{
        this.i2cSlave = i2cSlave;
        await this.i2cSlave.writeByte(0x44);
        await this.sleep(10);
        resolve();
      }).catch((reason)=>{
        reject(reason);
      });
    });
  },

データ正規化 compose

センサーの読み取り値を実数値に。readで用いられる内部関数です。
センサーの読み取り値は24ビットのバイナリ値とするため実際の値の100倍になっています。この関数で24ビットのバイナリ値を連結したのちに100分の1の値で返すようにしています。つまりセンサーの値は小数点2桁となります。
  compose: function(high, mid , low) {
    var val = ((high << 16) + (mid << 8)  + low)/100;
    return val;
  },

データ取得 read

センサーから圧力と温度値を読み出します。
センサーからは温度と圧力値がそれぞれ24bit(3byte)のバイナリデータとしてが出力されるようになっています。それを実数値に変換してアプリ側に返します。
センサーICに対してデータ変換開始(0x44)を書き込んでから変換完了(100ms)を待ちます、その後データ取得(0x10)を書き込んでから全データ(6byte)を一度に読み出し3byteごとに温度、圧力値として実数値変換を行うようになっています。変換された値は2個のデータ配列(pressure,temperature)にまとめてアプリに引き渡します。

  // read  data
  read: function() {
    return new Promise(async (resolve, reject)=>{
      if(this.i2cSlave == null){
        reject("i2cSlave Address does'nt yet open!");
      }else{
        // ADC_CVT
        await this.i2cSlave.writeByte(0x44);
        await this.sleep(100);

        // READ_PT
        await this.i2cSlave.writeByte(0x10);
        this.i2cSlave.readBytes(6).then((v)=>{
            var temperature = this.compose(v[0],v[1],v[2]);
            var pressure = this.compose(v[3],v[4],v[5]);

//          console.log("read ok!");
          resolve([pressure,temperature]);

       },(err)=>{
          reject(err);

       });

      }
    });
  }


3-2.ブラウザアプリ(Javascript: i2c/i2c-HP206C/main.js)

HTML表示の読み込み後に起動するコードです。
I2Cの使用宣言とHP206C(圧力センサー)ドライバの初期化を行った後に、1s周期でデータを読み出してHTMLコンテンツに圧力と温度値を表示させます。
"use strict";

window.addEventListener('load', function (){
  navigator.requestI2CAccess().then((i2cAccess)=>{
    var port = i2cAccess.ports.get(1);
    var hp206c = new HP206C(port,0x76);
    hp206c.init().then(()=>{
      setInterval(()=>{

        hp206c.read().then((values)=>{
          var press = values[0];
          var temp = values[1];

          document.getElementById("pressue").textContent = "Pressue: "+press+"pa";
          document.getElementById("temperature").textContent = "Temperature: "+temp+"deg-C";
        }).catch(function(reason) {
          console.log("READ ERROR:" + reason);
        });

      },1000);
    },(err)=>{
      console.log("HP206C init error");
    });


  },(err)=>{
    console.log("requestI2CAccess error");
  });


}, false);



アプリコード内で重要な部分について解説いたします。

I2C利用宣言

このJavascriptコードでI2Cを使う宣言を行います。
  navigator.requestI2CAccess().then((i2cAccess)=>{
.
.
.
  }).catch(e=> console.error('error', e));

I2Cバスのリソース取得とドライバ初期化

RaspberryPiのI2Cバスは1番目であるため1を設定します。また圧力センサーHP206CはI2Cアドレス0x76であるためドライバにI2Cアドレスを設定し初期化を行います
成功すればHP206Cを使用することができるようになります。
    var port = i2cAccess.ports.get(1);
    var hp206c = new HP206C(port,0x76);
    hp206c.init().then(()=>{
.
.
.
.
    },(err)=>{
      console.log("MCP3425 init error");
    });

電圧値読み出し

HP206Cドライバから温度と圧力値を読み出しHTML画面に値を表示させます。
ドライバからは2個のデータ配列としてセンサー値が返されるためそれぞれを取得して表示するようになっています。
        hp206c.read().then((values)=>{
          var press = values[0];
          var temp = values[1];

          document.getElementById("pressue").textContent = "Pressue: "+press+"pa";
          document.getElementById("temperature").textContent = "Temperature: "+temp+"deg-C";
        }).catch(function(reason) {
          console.log("READ ERROR:" + reason);
        });


3-3.ブラウザアプリ(HTML: i2c/i2c-HP206C/index.html)

お馴染みのHTMLコードです。id="pressue"とid="temperature"の部分に圧力と温度値の文字列がセットされます。
<!doctype html>

<html>
  <head>
    
    
    i2c-GroveBarometer HP206C
    
    
    
    
  </head>
  <body>
    Grove Barometer


    
    
init
init
</body> </html>

4.動作させてみよう

デスクトップにあるgcフォルダを開き i2c/i2c_HP206Cフォルダまで移動します。
index.htmlをダブルクリックするとchromeブラウザが開き圧力と温度値が表示されます。
台風が来たりすると面白いぐらい圧力値が変わっていきます。



まとめ

今回は少し踏み込んでCHIRIMEN RPi3でデバイスを扱う方法を紹介いたしました。 次回はさらに面白味のあるデバイスを使ってみる予定です。

0 件のコメント:

コメントを投稿