LoginSignup
1
2

More than 5 years have passed since last update.

Raspberry PiからMeshbluにDS18B20のセンシングデータを送信する

Posted at

Firmata互換のIOを使い、同じセンサーモジュールからRaspberry PiでもArduinoでもセンシングデータ取得コードの抽象化を試しています。取得したデータはMeshbluに送信してMongoDBにストアします。特に1-WireのDS18B20の場合はArduinoでもAdd arduino library to Firmata or Johnny-Five #285によるとConfigurable Firmataが必要になります。GPIOのアナログとデジタルの違いもあってJohnny-Fiveを使った抽象化は難しそうです。

Raspi-ioの1-Wireは未実装

最初はJohnny-FiveのRaspi-ioを試しました。Temperature (DS18B20)のサンプルのPIN番号をRaspberry PiにあわせてGPIO4に変更します。

~/node_apps/raspi-io-led/app.js
var five = require("johnny-five");

five.Board().on("ready", function() {
  // This requires OneWire support using the ConfigurableFirmata
  var temperature = new five.Temperature({
    controller: "DS18B20",
    //pin: 2
    pin: "GPIO4"
  });

  temperature.on("data", function(err, data) {
    console.log(data.celsius + "°C", data.fahrenheit + "°F");
  });
});

残念ながら実行するとエラーになりました。

$ sudo npm start

> raspi-io-led@0.0.1 start /home/pi/node_apps/raspi-io-led
> node app.js

1428295981604 Device(s) undefined
1428295981745 Connected RaspberryPi-IO
1428295981825 Repl Initialized
>>
/home/pi/node_apps/raspi-io-led/node_modules/raspi-io/lib/index.js:720
        throw "sendOneWireConfig is not yet implemented";
        ^
sendOneWireConfig is not yet implemented

Raspi-ioのindex.js見ると1-Wireは未実装のようです。

js index.js
sendOneWireConfig() {
throw 'sendOneWireConfig is not yet implemented';
}

Node.jsでw1_slaveファイルを読む

前回はデバイスのw1_slaveファイルを読んでDS18B20から温度を読むことに成功しました。Node.jsでも直接w1_slaveファイルを読むことにします。Publishing Temperature Reading From a DS18B20 1-Wire Digital Temperature Sensor Using a Raspberry Pi and node.jsを参考にします。

Rasbperry Piにログインしてプロジェクトを作成します。

$ mkdir -p ~/node_apps/meshblu-ds18B20
$ cd !$

package.jsonにmeshblu-npmのパッケージを追加します。

~/node_apps/meshblu-ds18B20/package.json
{
    "name": "meshblu-ds18b20",
    "version": "0.0.1",
    "private": true,
    "dependencies": {
        "meshblu": "1.19.1"
    },
    "scripts": {"start": "node app.js"}
}

環境変数に定義したMeshbluへの接続情報を確認します。Raspberry Piに用意してあったmqtt-pubデバイスを認証に使います。

~/.bashrc
export MESHBLU_BROKER=xxx.xxx.xxx.x
export MESHBLU_URL=https://$MESHBLU_BROKER
export MQTT_PUB_UUID=mqtt-pub
export MQTT_PUB_TOKEN=123456

メインプログラムを書きます。DS18B20のデバイスIDはハードコードしました。Meshbluの認証が成功した後w1_slaveファイルを1分間隔で読みます。正規表現を使い温度の数字部分を抜き出します。摂氏にした温度はJSON形式にしてMeshbluへWebSocketで送信します。

~/node_apps/meshblu-ds18B20/app.js
var meshblu = require('meshblu'),
      fs = require('fs');

var interval = 60*1000;
var w1Slave = '/sys/bus/w1/devices/28-0314626a2cff/w1_slave';

var conn = meshblu.createConnection({
    "uuid": process.env.MQTT_PUB_UUID,
    "token": process.env.MQTT_PUB_TOKEN,
    "protocol": "websocket",
    "server": process.env.MESHBLU_URL
});

conn.on('notReady', function(data){
    console.log('UUID FAILED AUTHENTICATION!');
    console.log(data);
});

conn.on('ready', function(data){
    console.log('UUID AUTHENTICATED!');
    console.log(data);

    var readSensor = function(){    
        fs.readFile(w1Slave, 'utf8', function(err, data) {
            if (err) throw err;
            var matches = data.match(/t=(\d+)/);
            var celsius = parseInt(matches[1]) / 1000;
            var output = {"temperature": celsius};
            console.log(output);
            conn.data({
                "temperature": celsius
            });
        });
    };

    setInterval(readSensor, interval);    
});

プログラムを実行します。1間隔で取得した温度が標準出力されます。

$ npm start

> meshblu-ds18b20@0.0.1 start /home/pi/node_apps/meshblu-ds18B20
> node app.js

UUID AUTHENTICATED!
{ api: 'connect',
  status: 201,
  socketid: 'Q2mR6Ctg5UOpJJrRAAAD',
  uuid: 'mqtt-pub',
  token: '889346' }
...
{ temperature: 27.375 }
{ temperature: 27.5 }
{ temperature: 27.625 }
{ temperature: 27.5 }
{ temperature: 27.625 }

MeshbluコンテナのMongoDBの確認

Meshbluコンテナのシェルを起動します。

$ docker exec -it  meshblu bash

MongoDBシェルを使いRaspberry Piから送信されたセンシングデータを確認します。

$ mongo skynet
MongoDB shell version: 2.4.13
connecting to: skynet

直近の3件を表示します。1分間隔でセンシングデータが保存されています。

> db.data.find().sort({ $natural: -1 }).limit(3)
{ "timestamp" : "2015-04-06T08:52:37.899Z", "temperature" : "27.625", "_id" : ObjectId("55224955a545260b00c971b3") }
{ "timestamp" : "2015-04-06T08:51:37.863Z", "temperature" : "27.5", "_id" : ObjectId("55224919a545260b00c971b2") }
{ "timestamp" : "2015-04-06T08:50:37.851Z", "temperature" : "27.625", "_id" : ObjectId("552248dda545260b00c971b1") }
1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2