0
0

More than 1 year has passed since last update.

CHIRIMENをNode.jsで使用してみる⑵ ー GPIO編 ー

Last updated at Posted at 2021-10-26

はじめに

本記事では、複数回に分けて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

配線

以下の図のように配線してください。
schematic.png

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

配線

以下の図のように配線してください。
schematic.png

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

配線

以下の図のように配線してください。
schematic.png

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

配線

以下の図のように配線してください。
schematic.png

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パーツの使用方法についての記事になる予定です。

0
0
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
0
0