はじめに
本記事では、複数回に分けてCHIRIMENコミュニティが提供しているnpmパッケージnode-web-gpioとnode-web-i2cを使用してNode.jsからGPIOとI2Cを制御するために私が実施した方法とそのサンプルコードを記載した備忘録になっています。
今回は前回の記事に引き続きExamplesにあるGPIO ExamplesのコードをNode.jsから実行可能にする方法について説明していきます。
コードの主な違い
Webブラウザ版とNode.js 版でのコードの主な違いについて説明します。
- navigator()関数がNode.jsでは使用不可、記述する必要がないため削除する。
- sleep()関数がNode.js には存在しないため、使用する場合は適宜実装する必要がある。
- その他、HTML下では動作するがNode.js下では動作しない記法を変更する必要がある。
ex)下記GPIO-Buttonなどの"ledPort.write(val === 0 ? 1 : 0);"という表記はNode.js では使用できない。
GPIO-Blink
CHIRIMENからLEDを点滅させるGPIO-Blinkについて説明します。
使用パーツ
- LED x 1
- 抵抗(100Ω〜470Ω) x 1 (220Ωのカラーコード:赤赤茶金)
- ジャンパー線(オス・メス) x 2
- ブレッドボード x 1
配線
Webブラウザ版のJavaScript
// プログラムの本体となる関数です。await で扱えるよう全体を async 関数で宣言します。
async function main() {
// 非同期関数は await を付けて呼び出します。
const gpioAccess = await navigator.requestGPIOAccess(); // GPIO を操作する
const port = gpioAccess.ports.get(26); // 26 番ポートを操作する
await port.export("out"); // ポートを出力モードに設定
// 無限ループ
while (true) {
// 1秒間隔で LED が点滅します。
await port.write(1); // LED を点灯
await sleep(1000); // 1000 ms (1秒) 待機
await port.write(0); // LED を消灯
await sleep(1000); // 1000 ms (1秒) 待機
}
}
// await sleep(ms) と呼ぶと、指定 ms (ミリ秒) 待機
// 同じものが polyfill.js でも定義されているため省略可能
function sleep(ms) {
return new Promise(function (resolve) {
setTimeout(resolve, ms);
});
}
// 宣言した関数を実行します。このプログラムのエントリーポイントです。
main();
Node.js版のJavaScript
"gpio-ledblink.js"というファイル名で下記のコードを保存してください。
このNode.jsでは、LEDが5回点滅すると処理が終了します。
// node-web-gpioを呼び出すおまじない
const { requestGPIOAccess } = require("node-web-gpio");
// sleep関数の実装
const sleep = require("util").promisify(setTimeout);
async function blink() {
const gpioAccess = await requestGPIOAccess();
// LEDの接続されているポートの指定
const port = gpioAccess.ports.get(26);
await port.export("out");
// 点滅した回数を指定する引数 i
var i = 0;
while (i < 5) {
await port.write(1);
await sleep(1000);
await port.write(0);
await sleep(1000);
i = i + 1;
}
}
blink();
実行してみよう
下記のようにコマンドラインから実行し、LEDが5回点滅すれば成功です。
% node gpio-ledblink.js
GPIO-Button
CHIRIMENからタクトスイッチの入力を読み込み、タクトスイッチを押すとLEDが点灯、離すと消灯します。なお、GPIOポートの読み込みにはonchange関数を使用しています。
使用パーツ
- タクトスイッチ x 1
- LED x 1
- 抵抗(100Ω〜470Ω) x 1 (220Ωのカラーコード:赤赤茶金)
- ジャンパー線(オス・メス) x 4
- ブレッドボード x 1
配線
Webブラウザ版のJavaScript
main();
async function main() {
var gpioAccess = await navigator.requestGPIOAccess();
var ledPort = gpioAccess.ports.get(26); // LEDの付いているポート
await ledPort.export("out");
var switchPort = gpioAccess.ports.get(5); // タクトスイッチの付いているポート
await switchPort.export("in");
switchPort.onchange = function(val) {
// スイッチはPullupで離すと1なので反転させる
ledPort.write(val === 0 ? 1 : 0);
};
}
Node.js版のJavaScript
"gpio-button.js"というファイル名で下記のコードを保存してください。
このNode.jsでは、タクトスイッチを押すとLEDが点灯し、離すと消灯します。5回繰り返すと終了します。
// タクトスイッチでLEDの点灯を行うチュートリアル
const { requestGPIOAccess } = require("node-web-gpio");
async function button() {
const gpioAccess = await requestGPIOAccess();
// LEDの接続されているポートの指定
const ledPort = gpioAccess.ports.get(26);
await ledPort.export("out");
// タクトスイッチの接続されているポートの指定
const switchPort = gpioAccess.ports.get(5);
await switchPort.export("in");
// 点灯回数をカウントする引数cnt
var cnt = 0;
switchPort.onchange = function(val) {
// ボタンを押すと点灯、離すと消灯する
if (cnt > 9 && val.value == 0){
console.log("Light : OFF");
process.exit(1);
}
if(val.value == 1){
ledPort.write(0);
console.log("Light : OFF");
cnt = cnt + 1;
} else if(val.value == 0){
ledPort.write(1);
console.log("Light : ON");
cnt = cnt + 1;
}
};
}
button();
実行してみよう
下記のようにコマンドラインから実行し、タクトスイッチを押すとLEDが点灯し、離すと消灯すれば成功です。
% node gpio-button.js
Light : OFF
Light : ON
Light : OFF
Light : ON
Light : OFF
GPIO-readGpioValue
CHRIMENからタクトスイッチの状態(押されているか、押されていないか)をコンソールへ出力します。なお今回は、GPIO-Buttonとは異なり、GPIOポートの読み込みにread関数を使用したポーリング処理によって読み込みを実現しています。
使用パーツ
- タクトスイッチ x 1
- ジャンパ線(オス・メス)x 2
- ブレッドボード x 1
配線
Webブラウザ版のJavaScript
main();
async function main() {
var gpioAccess = await navigator.requestGPIOAccess();
console.log("GPIO ready!");
var port = gpioAccess.ports.get(5);
await port.export("in");
while (true) {
var value = await port.read();
console.log("unixtime:" + new Date().getTime() + " gpio(5)= " + value);
await sleep(500);
}
}
Node.js版のJavaScript
"gpio-readgpiovalue.js"というファイル名で下記のコードを保存してください。
タクトスイッチを押すとON、離すとOFFのように入力状況が出力します。合計で10回シュッツ力されると終了します。
// タクトスイッチの入力状態を確認するチュートリアル
const { requestGPIOAccess } = require("node-web-gpio");
// sleep関数の実装
const sleep = require("util").promisify(setTimeout);
async function button() {
const gpioAccess = await requestGPIOAccess();
console.log("GPIO ready!");
const switchPort = gpioAccess.ports.get(5);
await switchPort.export("in");
// タクトスイッチの入力回数をカウントする引数cnt
var cnt = 0;
// タクトスイッチの入力状況を把握する引数flag
var flag = 0;
while(cnt != 10) {
const value = await switchPort.read();
if (flag == 1 && value == 1){
console.log("Button : OFF");
flag = 0;
cnt = cnt + 1;
} else if (flag == 0 && value == 0) {
console.log("Button : ON");
flag = 1;
cnt = cnt + 1;
}
}
process.exit(1);
}
button();
実行してみよう
下記のようにコマンドラインから実行し、タクトスイッチを押すとON、離すとOFFのように入力状況が出力されると成功です。
% node gpio-readgpiovalue.js
GPIO ready!
Button : ON
Button : OFF
Button : ON
Button : OFF
Button : ON
Button : OFF
GPIO-pirSensor
使用パーツ
- 人感センサー (KP-IR412) x 1 (※ジェネリック部品(HC-SR501)でも可)
- ジャンパー線(オス・メス)x 6
- ブレッドボード x 1
配線
Webブラウザ版のJavaScript
main();
async function main() {
var gpioAccess = await navigator.requestGPIOAccess();
var sensor = document.getElementById("sensor");
var dPort = gpioAccess.ports.get(12);
await dPort.export("in");
dPort.onchange = function(v) {
if (v === 1) {
sensor.innerHTML = "ON";
} else {
sensor.innerHTML = "OFF";
}
};
}
Node.js版ブラウザ版のJavaScript
"gpio-kp-ir412.js"というファイル名で下記のコードを保存してください。
人感センサーによる感知のON/OFFを3回行います。
// KP-IR412で人体赤外線感知を行うチュートリアル
const { requestGPIOAccess } = require("node-web-gpio");
async function ir412() {
const gpioAccess = await requestGPIOAccess();
// KP-IR412の接続されているポートの指定
const port = gpioAccess.ports.get(12);
await port.export("in");
// センサーの検知回数をカウントする引数cnt
var cnt = 0;
// センサーで感知した結果を出力する
// ただしセンサーの仕様上、ONからOFFにリセットされるまでに4〜6秒かかる
port.onchange = function(v) {
if (cnt > 3 && v.value == 0){
console.log("Sensor : OFF");
process.exit(1);
}
if (v.value == 1) {
console.log("Sensor : ON");
cnt = cnt + 1;
} else {
console.log("Sensor : OFF");
cnt = cnt + 1;
}
};
}
ir412();
実行してみよう
下記のようにコマンドラインから実行し、人感センサーによる感知のON/OFFが3回行われると終了します。
% node gpio-kp-ir412.js
Sensor : ON
Sensor : OFF
Sensor : ON
Sensor : OFF
Sensor : ON
Sensor : OFF
さいごに
今回は以上になります。今回はnode-web-gpioでのGPIOの使用方法についての記事でした。次回はnode-web-i2cで使用可能なI2Cパーツの使用方法についての記事になる予定です。