Raspberry Pi 2 向け A/D 変換 : Node.js で土壌湿度センサーを制御してみた

2016.02.18

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

000

車輪開発大好きおたいがです。こんにちは。( 挨拶 )

最近、自席の近くに置いてあるジョロキア ( 通称 : こむろさん ) を自分が世話することになったのですが、ついでに習作のネタになってもらいました。手元にある Raspberry Pi 2 ( 以下 Raspberry Pi ) と土壌湿度センサーを接続して、ジョロキアの土壌水分状況を調べる装置を作ったので、手順をまとめておきます。

用意したもの

昼食ついでに、部品はすべて秋月電子通商で購入。

土壌湿度センサーが出力する値はアナログデータですが、Raspberry Pi には A/D 変換機能が内臓されていないため、外部のコンバータを使用してデジタルデータに変換した値を読み取る必要があります。

図面

001

はじめての Fritzing でお絵かき…便利ですね。これ。

GPIO の詳細についてはこちらにまとまっています。
http://pi.gadgetoid.com/pinout

MCP3208 の詳細についてはこちら
http://ww1.microchip.com/downloads/en/DeviceDoc/21298b.pdf

Node.js 環境構築およびコーディング

"Raspberry Pi" と "A/D 変換" でググると、Python で書かれているサンプルコードが多い印象を受けたのですが、自分は ECMAScript 畑の人間なので Node.js で GPIO を制御することにしました。

Node.js のインストール

$ wget https://nodejs.org/dist/v4.2.6/node-v4.2.6-linux-armv7l.tar.gz
$ tar -xvf node-v4.2.6-linux-armv7l.tar.gz
$ cd node-v4.2.6-linux-armv7l
$ sudo cp -R * /usr/local/

npm モジュールのインストール

使用するモジュールは以下の 2 種類

$ npm install raspi -S
$ npm install raspi-gpio -S

実装コード

002

上記 MCP3208-CI/P の説明書と、調べ先で見かけた Python のサンプルコードを元にアレンジしてみました。

index.js

/**
 * Raspberry Pi 2 (Model B) read SPI data from MCP3208 chip, 8 possible adc's.
 */

var raspi    = require('raspi');
var gpio     = require('raspi-gpio');

const HIGH   = gpio.HIGH;
const LOW    = gpio.LOW;
const Input  = gpio.DigitalInput;
const Output = gpio.DigitalOutput;

var initHandler = function() {

    var d_in  = new Output('GPIO10'); //SPI_MOSI
    var d_out = new Input('GPIO9');   //SPI_MISO
    var clk   = new Output('GPIO11'); //SPI_CSLK
    var cs    = new Output({ 'pin' : 'GPIO8', 'pullResistor' : gpio.PULL_UP });  //SPI_CE0

    var clock = function(count) {
        for(var i = 0; i < count; i++) {
            clk.write(HIGH);
            clk.write(LOW);
        }
    };

    var readValue = function() {
        cs.write(LOW); //start

        var i;
        var ch  = 0; // 0 ch. (0~7)
        var cmd = ( ch | 0x18 ) << 3;
        for(i = 0; i < 5; i++) {
            d_in.write( ( cmd & 0x80 ) ? HIGH : LOW );
            cmd <<= 1;
            clock(1);
        }

        var result = 0;
        for(i = 0; i < 13; i++) { // one null bit and 12 ADC bits.
            result <<= 1;
            clock(1);
            if(d_out.read()) { // === 1
                result |= 0x1;
            }
        }

        cs.write(HIGH); //end

        //TODO:結果出力
        console.log('result : ', result);
    };

    setInterval(readValue, 500);

};

raspi.init(initHandler);

実行

$ sudo node index.js

出力結果

result : 0     //センサーの先端同士がつながっていない
result : 0
result : 1519  //指でセンサーの先端同士をつなぐ
result : 1879
result : 1660
result : 2332
result : 2285
result : 1515
…
result : 1515
…
result : 4095  //水や金属でセンサーの先端同士をつなぐ
result : 4095
result : 4095

MCP3208-CI/P の分解能 ( ぶんかいのう ) は 12bit なので、4096 階調 (0~4095) の数値でセンサーの出力値を表現することができます。

実際にセンサーをジョロキアにぶっ挿した結果

こんな感じで設置しました。( 撮影の都合上、電源は抜いています )

003

名札には「ハバネロの…」と書かれていますがジョロキアです。

result : 4095
result : 4095
result : 4095
result : 4095
result : 4095
result : 4095
result : 4095
result : 3966
result : 3931
result : 3920
result : 3912
result : 3901
result : 3872
result : 3884
result : 3851
result : 3863
…

冬越し中なので水やりは控えていたのですが思った以上に湿っていました。
もうしばらく水は控えて放置することにします。

参考