BME280は1チップのセンサICで温度と湿度、気圧の3つの値を取得できます。
通信方法はI2CとSPIが選択できるが、ここではI2C接続とします。
スイッチサイエンスや秋月電子などから購入できます。
ここでは秋月電子から購入しました。I2C接続するために予めJ3はジャンパします。
johnny-fiveはNode.js上のフレームワーク(モジュール)です。
Firmataプロトコルを使って、ホスト(Windows,Mac,linux、ラズパイなど)からArduinoなどのマイコンを
制御することができます。
ExamplesにはBME280に参考例が見当たらないが、
公式サイトjohnny-five.io にはv0.9.45からBME280に対応しているようである。
今回はNiftyクラウドに保存します。
###検証
以下の接続する。
BME280 Arduino
VCC <-> VCC(3.3V)
SCK <-> A5
SDI <-> A4
GND <-> GND
Arduino Nano(互換)にfirmataを書き込み済みとする。
ホストはwindows7で試す
コマンドプロンプト(PwerShell)で作業用ディレクトリを開く。
「node -v 」 で node.jsがインストール済みなのを確認する
「npm i johnny-five 」 でjohnny-fiveモジュールをインストールする。
以下 検証コード
var five = require("johnny-five");
var board = new five.Board("COM8"); //ポート名指定はWindowsで必要なため、
board.on('ready', function () {
var bme280 = new five.IMU({
controller: "BME280",
address: 0x76, // optional
});
bme280.on("data", function(e,data) {
if( this.barometer.pressure >90 ){ //気圧の初回値が変なので、異常値は読み飛ばす
console.log(" celsius(摂氏) : ", this.temperature.celsius);
console.log(" fahrenheit(華氏) : ", this.temperature.fahrenheit);
console.log(" pressure(hPa) : ", this.barometer.pressure *10);
console.log(" relative humidity(相対湿度) : ", this.hygrometer.relativeHumidity);
console.log("--------------------------------------");
process.exit(); //終了
}
});
})
※this.barometer.pressureを10倍しているのはKpaで返されるため。
###実行結果
PS C:\Users\XX\Documents\nodebots\mysolution>node .\BME280.js
1467475451763 SerialPort COM8
1467475451771 Connected COM8
1467475456184 Repl Initialized
celsius(摂氏) : 27.7
fahrenheit(華氏) : 81.86
pressure(hPa) : 1006.3599999999999
relative humidity(相対湿度) : 58.094
正常に取得できるようであるが、初回だけ気圧の値がおかしいので読み飛ばすようにした。
### ラズパイをホストにする。
Raspberry PiとArduinoをUSBケーブルで接続します。
node -v でnode.jsのバージョンを確認します。
もし、0.x系なら、ラズパイのnode.jsが古いので、入れ換えます。
手順は
http://make.kosakalab.com/make/electronic-work/nodejs_raspi/
を参考にしました。
詳細な手順は省略しますが、現時点での最新版のv6.2.2にします、
johnny-fiveパッケージのインストール
$ npm install johnny-five
前出の検証コードを実行してみます。
pi@raspberrypi:~/work$ node bme280.js
1467490740052 Device(s) /dev/ttyUSB0
1467490740181 Connected /dev/ttyUSB0
1467490744655 Repl Initialized
celsius(摂氏) : 28.66
fahrenheit(華氏) : 83.59
pressure(hPa) : 1005.8499999999999
relative humidity(相対湿度) : 64.082
--------------------------------------
nifty cloud に保存するためNifty SDKインストールする。
npm install ncmb --save
以下のファイルを作成
>var ncmb = new NCMB("アプリケーションキー","クライアントキー");
アプリ毎に付与されたアプリケーションキー,クライアントキーです。詳しくはnifty クラウドを参照
/**
BME280 Arduino
*/
var NCMB = require("ncmb");
var ncmb = new NCMB("アプリケーションキー","クライアントキー");
var five = require("johnny-five");
var board = new five.Board();
board.on('ready', function () {
var bme280 = new five.IMU({
controller: "BME280",
address: 0x76, // optional
freq:1000 * 60 // optional
});
var TempLog = ncmb.DataStore("Temperature2") ;
bme280.on("data", function(e,data) {
if( this.barometer.pressure >90 ){ //気圧の初回値が変なので、異常値は読み飛ばす
console.log(" celsius(摂氏) : ", this.temperature.celsius);
console.log(" fahrenheit(華氏) : ", this.temperature.fahrenheit);
console.log(" pressure(hPa) : ", this.barometer.pressure *10);
console.log(" relative humidity(相対湿度) : ", this.hygrometer.relativeHumidity);
console.log("--------------------------------------");
var tempLog = new TempLog() ;
tempLog
.set("date",(new Date()))
.set("celsius",this.temperature.celsius)
.set("pressure",this.barometer.pressure *10)
.set("humidity",this.hygrometer.relativeHumidity)
.save()
.then(function(tempLog){
console.log("message is saved.");
return tempLog.update();
})
.then(function(tempLog){
});
}
});
})
board.on("error", function(err) {
console.log("There was an error" + err);
});
** node temp2.js ** として実行します。
ニフティの管理画面でデータを確認します。
ブラウザで表示してみる。
http://mb.cloud.nifty.com/doc/current/index.html
からncmb.min.jsをダウンロードする。
下記のようなテストのhtmlを作成する
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<script src="ncmb.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.2/Chart.min.js"></script>
<style>
canvas{
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
<script>
var data1 = {
labels: [],
datasets: [
{
label: "Prime and Fibonacci1",
fillColor: "rgba(251,180,120,0.6)",
strokeColor: "rgba(254,230,170,1)",
pointColor: "rgba(254,230,124,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(220,220,220,0.5)",
data: []
}
]
};
var data2 = {
labels: [],
datasets: [
{
label: "Prime and Fibonacci2",
fillColor: "rgba(251,120,196,0.6)",
strokeColor: "rgba(120,230,170,1)",
pointColor: "rgba(254,230,170,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(220,220,220,0.5)",
data: []
}
]
};
var data3 = {
labels: [],
datasets: [
{
label: "Prime and Fibonacci3",
fillColor: "rgba(80,240,196,0.6)",
strokeColor: "rgba(254,230,170,1)",
pointColor: "rgba(254,120,170,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(220,220,220,0.5)",
data: []
}
]
};
function displayLineChart() {
var ncmb = new NCMB("アプリケーションキー","クライアントキー");
var Temperature = ncmb.DataStore("Temperature2");
Temperature.order("date", true)
.limit(120)
.fetchAll()
.then(function(results){
console.log("Successfully retrieved " + results.length );
for (var i = 0; i < results.length; i++) {
var object = results[i];
console.log(object.date.iso);
data1.labels[i] = i;
data2.labels[i] = i;
data3.labels[i] = i;
data1.datasets[0].data[i] = object.celsius;
data2.datasets[0].data[i] = object.pressure;
data3.datasets[0].data[i] = object.humidity;
}
var ctx = document.getElementById("lineChart1").getContext("2d");
var options = { };
var lineChart = new Chart(ctx).Line(data1, {
scaleShowVerticalLines: false,
scaleShowHorizontalLines: false,
scaleOverride : true,
scaleSteps : 25,
scaleStepWidth : 0.5,
scaleStartValue : 20,
});
var ctx = document.getElementById("lineChart2").getContext("2d");
var options = { };
var lineChart = new Chart(ctx).Line(data2, {
scaleShowVerticalLines: false,
scaleShowHorizontalLines: false,
scaleOverride : true,
scaleSteps : 25,
scaleStepWidth : 1.0,
scaleStartValue : 995,
});
var ctx = document.getElementById("lineChart3").getContext("2d");
var options = { };
var lineChart = new Chart(ctx).Line(data3, {
scaleShowVerticalLines: false,
scaleShowHorizontalLines: false,
scaleOverride : true,
scaleSteps : 90,
scaleStepWidth : 1,
scaleStartValue : 10,
});
})
.catch(function(err){
console.log(err);
});
}
</script>
</head>
<body onload="displayLineChart();">
<div class="box">
<p><canvas id="lineChart1" height="250" width="720"></canvas></p>
<p><canvas id="lineChart2" height="250" width="720"></canvas></p>
<p><canvas id="lineChart3" height="250" width="720"></canvas></p>
</div>
</body>
ローカル、またはサーバーにアップして、グラフ表示されればok。
小数点桁数を揃えてないなど、雑な表示であるがデータ確認が目的なのでとりあえず、よしとする。
以上