Quantcast
Channel: Node.jsタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9134

【micro:bit 2021】 PC と micro:bit を通信させる方法: Node.js・MakeCode でのシンプルなシリアル通信(USBケーブル接続)

$
0
0
この記事は、2021年の micro:bit のアドベントカレンダー の 6日目の記事です。 micro:bit を PC と USBケーブルでつないだ状態で、PC との間でやりとりをする方法の 1つである「シリアル通信」を扱います。 その中でも Node.js を用いたものについて、軽いお試しをしていく形です。 過去に micro:bit と PC との間の通信について書いた記事 過去にも、micro:bit と PC との間で何らか通信させる話を、以下のように複数書いています。 Bluetooth関連 Web Bluetooth API を使い micro:bit とブラウザの間で BLE通信 あらためて noble でガジェットを扱う話に着手する: toio と micro:bit を複数混在させてスキャン、toio の複数制御(6台分) - Qiita Web Bluetooth API で BLE(Chrome と micro:bit をつなぐ) micro:bit と #obniz で BLE + UART を試そうとした話と Mac用ツール micro:bit で BLE + UART による文字列の送受信 #obniz と micro:bit で obniz-noble を使った BLE通信 シリアル通信関連 Web Serial API を使って micro:bit からセンサーの値(XYZ)を読み取る&リアルタイムなグラフ化 Web Serial API を使って micro:bit からセンサーの値を読み取る(途中段階まで) Web Serial API を使った micro:bit への値の書き込み Web Serial API を最短の手順で試したくてやったこと(micro:bit を利用) #toio を Alexa や micro:bit から操作する 〜概要編〜(JavaScriptライブラリを使ってみた) その中で、使ったという話は書いたけれど、ソースコードを公開したり等とはしていなかったと思われる  「Node.js でのシリアル通信を使う」 という形での PC連携について記事を書いていきます。 シリアル通信のためのライブラリ・ブロック Node.js でシリアル通信 Node.js でシリアル通信を扱おうとした場合、使われる仕組みとして有名どころはこちらかと思います。 ●Hello from Node Serialport | Node Serialport  https://serialport.io/ micro:bit以外のデバイスと組み合わせた話は、ちょっとしたコードを掲載したものは書いて出していました。 ●GR-ROSE と Node.js のプログラムの間でシリアル通信(一方向) - Qiita  https://qiita.com/youtoy/items/460a9458309b0b4a7dbd この時は、「シリアル通信で受信した内容を、1行ごとに読んでログに出すだけ」という感じでした。 const SerialPort = require('serialport') const Readline = require('@serialport/parser-readline') const port = new SerialPort('/dev/【自分の環境に合わせて変更】') const parser = port.pipe(new Readline({ delimiter: '\r\n' })) parser.on('data', console.log) ソースコードも、かなりシンプル。 今回はもう少し、仕組みを足したものを作っていきます。 micro:bit でシリアル通信 過去の記事でも登場していますが、MakeCode for micro:bit で開発した場合に、シリアル通信を扱うブロックは以下になります。 (「高度なブロック」の中の「シリアル通信」の部分) 諸事情により、micro:bit でのシリアル通信(MakeCode for micro:bit を使うパターン)について、ちょっと見直してる。 pic.twitter.com/rfVq85G1bK— you (@youtoy) December 4, 2021 このブロックを使うことで、読み書きを行うことができます。 簡単なシリアル通信を試す まずは、簡単なシリアル通信を試します。 以下のシンプルなものを、動かしてみます。 micro:bit のセンサーの値を、PC で受けとってログに出力(通信の向きは、micro:bit から PC) PC で Node.js のプログラムを実行したら、micro:bit側の LED が特定の表示になる(通信の向きは、PC から micro:bit) ここで、PC と micro:bit は USBケーブルでつなぎ、その USBケーブルによるシリアル通信を行う形にします。 micro:bit のセンサーの値を PC でログに出力 micro:bit側のブロック micro:bit側は、以下のような内容にしました。 加速度の X・Y・Z のそれぞれの値を、単純にカンマ区切りで書き出すだけのものです(出力間隔は 0.5秒)。 この時点で、プログラムを書き込んだ後に、「コンソールを表示 デバイス」という部分を押すと、シリアル通信で送られている値を見ることができます(また、グラフも表示されます)。 micro:bit側の準備は、これで完了です。 Node.js のプログラム 上記で micro:bit からシリアル通信で書き出すようにしたセンサーの値を、Node.js で受け取りログとして出力してみます。 なお、以下の内容は Mac で試しています(シリアルポートの指定の部分が、Mac用になってます)。 まず、USBケーブルで micro:bit を接続した状態で、以下のコマンドを実行します。 $ ls -l /dev/tty.* 実行結果で何行かの出力が得られたのですが、その中で自分の場合は /dev/tty.usbmodem●●●●●●● というような名称のものが、micro:bit のシリアルポートでした(●の部分は数字が入ります)。 上記の確認が終わったら、Node Serialport を使えるように npm i serialport を実行します。 その後、公式ドキュメントの以下や過去に使ったプログラムを元に、プログラムを作成します。 ●SerialPort Usage | Node Serialport  https://serialport.io/docs/guide-usage ●What are Parsers? | Node Serialport  https://serialport.io/docs/api-parsers-overview 動作させるものは、以下になります。 const SerialPort = require("serialport"); const Readline = require("@serialport/parser-readline"); const port = new SerialPort("/dev/【自分の環境に合わせて変更】", { baudRate: 115200, }); const parser = port.pipe(new Readline()); parser.on("data", console.log); 上記を実行して、以下のような出力を得ることができました。 Node.js のプログラムで、それを受信して、ログに書き出し。↓こちらを使って。●Hello from Node Serialport | Node Serialport https://t.co/Kh7OHF51nK pic.twitter.com/qp1zRqmJCq— you (@youtoy) December 4, 2021 Node.js のプログラムで「split」を使う 3つのデータがカンマ区切りで出てきたので、それを 1つずつ取り出そうと、プログラムの最後の行を以下のように変更してみました。 parser.on("data", (data) => console.log(data.split(","))); 以下の処理を使っています。  ●String.prototype.split() - JavaScript | MDN   https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/split そうすると、以下のツイートの画像の、上半分のほうの出力が得られました。 split() を使って分けようとしたら、こうなってた...下半分は、「delimiter: "\r\n"」を指定した後の出力。●String.prototype.split() - JavaScript | MDN https://t.co/09fsyjoaTf pic.twitter.com/8boaq27gVG— you (@youtoy) December 4, 2021 どうも、先ほどのログ出力をしていた時、出力の後ろには空白がたくさんついていたようでした。それと \r も付いていたり... とりあえず \r を除いてしまおうかと、先ほどのプログラムの中で、 delimiter: "\r\n" を指定しました。最後から 2行目の内容を、以下のように書きかえてます。 const parser = port.pipe(new Readline({ delimiter: "\r\n" })); その結果が、上のツイートの画像の、下半分のほうです。 「さて、空白を除去するのは何だっけ?」と思って、ググろうとしたところ、Twitter でタイムリーにコメントをいただけました。 trim() してから split() してみるとよいのではないでしょうか— ぺんた (@plageoj) December 4, 2021 以下を見ると、改行文字も除去してくれるらしく、 \r を除く部分もやってくれそうです。 ●String.prototype.trim() - JavaScript | MDN  https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/trim 最終的に以下の内容にすることで、無事に x・y・z のそれぞれの値を、余計な文字が含まれない状態で得られました。 const SerialPort = require("serialport"); const Readline = require("@serialport/parser-readline"); const port = new SerialPort("/dev/【自分の環境に合わせて変更】", { baudRate: 115200, }); const parser = port.pipe(new Readline()); parser.on("data", (data) => console.log(data.trim().split(","))); そして、無事に良い感じの結果を得られました。 改行文字も除去と書いてあったので、delimiter の指定はなくして、以下のきれいな結果を得られました。ありがとうございます。 pic.twitter.com/WnUPIks9yD— you (@youtoy) December 4, 2021 PC で Node.js のプログラムを実行したら micro:bit側の LED が特定の表示になる micro:bit側のブロック micro:bit側は、以下のような内容にしました。 micro:bit のシリアル通信で文字を受信する。 pic.twitter.com/I3RscMSWDL— you (@youtoy) December 4, 2021 Node.js のプログラム Node.js で作ったプログラムは以下のとおりです。 const SerialPort = require("serialport"); const port = new SerialPort("/dev/【自分の環境に合わせて変更】", { baudRate: 115200, }); const stringSent = "abc"; port.write(stringSent, function (err) { if (err) { return console.log("Error on write: ", err.message); } console.log("message written"); setTimeout(() => console.log("end"), 3000); }); port.on("error", function (err) { console.log("Error: ", err.message); }); setTimeout(() => console.log("end"), 3000); という処理を入れて、シリアル通信での PC からの書き込みを行った後、すぐにプログラムが終了しないようにしています。 これを入れている理由は、Node.js のプログラムがすぐに終了すると、それに連動して micro:bit 側のプログラムも終了させられるためです。今回の内容は、これを入れてないと LED が特定パターンで光る前に、micro:bit側のプログラムが終了させられて、LED の表示が出ないまま初期状態に戻る動作となりました。 なお、 const stringSent = "abc"; の部分を const stringSent = "123"; に変えて実行すると、micro:bit上の LED の点灯パターンが変わります。 おわりに 今回、PC と micro:bit との間で有線のシリアル通信を行いました。 そして、両方とも無事に想定通りの動作をさせることができました。 今回は軽いお試しのみでしたが、PC と連携をさせた部分を活用し、micro:bit単体では実現できない仕組みを、PC の力を借りて実行するようなものを試せればと思います。 余談 最後に書いていた件の 1つの方向性として、以下のように Groveモジュールを使えば実現できる IoT の仕組みを、PC の力を借りて実行するようなものは、試せればと思っています。 ●【IoTLT 2020】 micro:bit を使った IoT(Grove - UART Wifi V2 との組み合わせ、IFTTT利用) - Qiita  https://qiita.com/youtoy/items/459289951134544e73eb

Viewing all articles
Browse latest Browse all 9134

Trending Articles