ラズパイで GPIO の入出力を今まで試してきましたが、
せっかく Node.js を使っているので、Web サーバーと組み合わせてブラウザから
LED の点灯が操作できないかと思って作ってみました。
あぁ、Nodejs+ラズパイ楽しい。
目次
準備編
適当なフォルダを準備して
npm init
を実行
今回は Web サーバーに micro、開発用に micro-dev を使います。
https://github.com/zeit/micro
https://github.com/zeit/micro-dev
npm でパッケージのダウンロードをしていきます。
npm install micro
npm install micro-dev
package.json も micro-dev の README を見ながら少しいじります。
1 2 3 4
| "scripts": { "start": "micro", "dev": "micro-dev" }
|
作成編
index.js という名前で以下を保存します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| const fs = require("fs"); const path = require("path"); const { json } = require("micro");
const pinnum = 21;
const pathstr = "/sys/class/gpio/"; const gpio21 = path.join(pathstr, "gpio" + pinnum);
const htmltext = fs.readFileSync(process.cwd() + "/console.html"); const jquery = fs.readFileSync(process.cwd() + "/jquery-3.3.1.min.js");
fs.writeFileSync(path.join(pathstr, "export"), pinnum); fs.writeFileSync(path.join(gpio21, "direction"), "out");
process.on("exit", () => { fs.writeFileSync(path.join(pathstr, "unexport"), pinnum); console.log("PROCESS EXIT"); });
module.exports = async (req, res) => { const url = req.url;
console.log(`url=${url}`); let ms = "ON"; if (url == "/state") { let state = fs.readFileSync(path.join(gpio21, "value"), "utf8"); res.write(`${state}`); } else if (url == "/sw") { let state = fs.readFileSync(path.join(gpio21, "value"), "utf8"); state = state == 0 ? 1 : 0; fs.writeFileSync(path.join(gpio21, "value"), state); } else if (url == "/jquery-3.3.1.min.js") { res.writeHead(200, { "Content-Type": "text/javascript" }); res.write(jquery); } else { res.writeHead(200, { "Content-Type": "text/html" }); res.write(htmltext); } res.end(); };
|
サーバーに対する URL で、
- LED のステータス送信
- LED の点灯切り替え
- javascript ファイル送信
- html ファイル送信
を処理します。
プロセスの停止は Ctrl+c で行うのですが、
今までだとecho 21 > /sys/class/gpio/unexport;
を実行してからでないと、
アプリケーションを実行できない問題があったけど、
process.on('exit',関数
でecho 21 > /sys/class/gpio/unexport;
を
割り当てると、終了時に GPIO の解放処理を入れることができた。
Node.js で GPIO を触るときの定型パターンかもしれない。
加えて、クライアント側の html を作ります。
console.html として以下を保存します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| <html lang="ja"> <head> <style> main { margin: 10px; } #state { height: 300; width: 300; background-color: #000; margin: 10px; } #ledsw { height: 50; width: 100; margin: 10px; margin-left: 100px; font-size: 20px; } </style> </head> <body> <main> <div> <div id="state"></div> <button id="ledsw">state</button> </div> </main> <script src="./jquery-3.3.1.min.js"></script> <script> let readstate = function () { $.ajax({ url: "./state", type: "POST", data: {}, cache: false, }).done(function (data) { if (data.replace(/\r?\n/g, "") == "0") { $("#ledsw").text("ON"); $("#state").css("background-color", "#000"); } else { $("#ledsw").text("OFF"); $("#state").css("background-color", "#f00"); } }); }; let changestate = function () { $.ajax({ url: "./sw", type: "POST", data: {}, cache: false, }).done(function (data) { readstate(); }); }; $(function () { readstate(); }); $("#ledsw").click(function () { changestate(); }); </script> </body> </html>
|
あと console.html で jquery を使用しているので、jquery-3.3.1.min.js を保存しておきます。
細かいバージョンはこだわらなくていい気がします。
ここまででフォルダ構成は以下のようになります
---console.html
|-index.js
|-jquery-3.3.1.min.js
|-package-lock.json
|-package.json
`-node_modules
実行するときはsudo npm start
実行したら、ブラウザで http://[ラズパイの IP アドレス]:3000 にアクセスしてみましょう。
下の画像の画面が開きます。
LED の点灯状況とブラウザ側での表示が連動します。
LED が付くとブラウザ側でも表示が赤くなります。
もし、LED が付いたままブラウザを更新しても、
ページ取得時に現在の LED の点灯ステータスを取得しているので、
整合性も崩れずに済みます。
これでクライアントサイドの WEB 画面と、LED の点灯を連動させることができました。
今回でラズパイをブラウザからコントロールする渡りが付いたので、
ブラウザからサーボモーターとセンサーを操作してみたいですね。
ではでは