【micro:bit 2021（2つ目）】 PC と micro:bit で送受の両方を行う通信： Node.js・MakeCode でのシンプルなシリアル通信2（USBケーブル接続）

この記事は、[2021年の micro:bit のアドベントカレンダー](https://qiita.com/advent-calendar/2021/microbit) の 9日目の記事です。

以下の記事で、「micro:bit から送信する、または micro:bit で受信する」という送受のどちらか片方を使ったプログラムの話を書いていました。

●【micro:bit 2021】 PC と micro:bit を通信させる方法： Node.js・MakeCode でのシンプルなシリアル通信（USBケーブル接続） - Qiita
　https://qiita.com/youtoy/items/889f8ee3a3bd884f5df8

今回は、「micro:bit　からの送信 ⇒ PC でちょっとした処理をして応答するような処理 ⇒ micro:bit での受信」という流れをの処理をするプログラムを作ってみます。

## 環境の準備
必要なものや、Node.js　のプログラムで必要なライブラリは、[前回の記事](https://qiita.com/youtoy/items/889f8ee3a3bd884f5df8)と同じです。
詳細は、[そちら](https://qiita.com/youtoy/items/889f8ee3a3bd884f5df8)をご覧ください。

## 作ったプログラム
### micro:bit側
前回の記事の内容をもとに、以下のようなプログラムを作ってみました。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">micro:bit のシリアル通信の続き。<br><br>送受信を両方使ったパターン（また、通信先は Node.js のプログラムです）。 <a href="https://t.co/WnZGhwwo4X">pic.twitter.com/WnZGhwwo4X</a></p>&mdash; you (@youtoy) <a href="https://twitter.com/youtoy/status/1467094566688157696?ref_src=twsrc%5Etfw">December 4, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

基本的な動作は、以下のとおりです。

1. micro:bit で Aボタン/Bボタンの押下を待つ
2. ボタンが押されたらシリアル通信を実行し（押されたボタンの文字を送る）、ボタン押下後の処理を無効化する
3. （Node.js側の処理、一定時間後に A か B の文字列が返ってくる）
4. 常にシリアル通信の読み取りをしていて、文字列を受信したら、受信した文字に応じた表示を行って、ボタン押下後の処理を有効化する

この後に出てくる PC側のプログラムは、この micro:bit からの通信を待ち受けて、応答を返すような仕組みになっています。
PC側が能動的に通信をすると、意図しない状況になるのだけど...（きちんとブロックするような処理を入れずに作ってしまってる）

### Node.js のプログラム
以下の Node.js のプログラムは、前回試した内容をもとに組み立てています。
基本的な動作は、「シリアル通信で文字を受信 ⇒ 3秒まつ ⇒ 受信した文字と同じ文字をシリアル通信で送信」という流れです。

```javascript
const microbitPort = "/dev/【自分の環境に合わせて変更】";

const SerialPort = require("serialport");
const Readline = require("@serialport/parser-readline");
const port = new SerialPort(microbitPort, {
  baudRate: 115200,
});

const parser = port.pipe(new Readline());
parser.on("data", (data) => {
  const stringReceived = data.trim();
  console.log(stringReceived);

  setTimeout(() => {
    writeString(stringReceived);
    console.log("end");
  }, 3000);
});

function writeString(inputString) {
  port.write(inputString, function (err) {
    if (err) {
      return console.log("Error on write: ", err.message);
    }
    console.log("message written");
  });
}

port.on("error", function (err) {
  console.log("Error: ", err.message);
});
```

[前回の記事](https://qiita.com/youtoy/items/889f8ee3a3bd884f5df8)では、送信と受信をばらばらのプログラムで試していましたが、今回は PC から micro:bit への送信は、PC から micro:bit からの文字受信を行った後に実行するような組み方になっています。
その際、3秒の時間をあけて行うような流れになっています。

この部分は、今後は、PC で何か処理をして（PC内で、とか、Web の API をたたいて何か情報取得して、とか）、その結果によって micro:bit へ返答する部分を変える、というような何かが入ると良いな、と思っている部分です。

### 実際の動作
動作をさせた時の様子は、以下のとおりです。
micro:bit のボタン押下後、押したボタンによって3秒後に LED の点灯パターンが異なる、という様子が確認できます。

<blockquote class="twitter-tweet" data-conversation="none"><p lang="ja" dir="ltr">送受信の両方を使う仕組みの動作確認。<br>うまく動いた！ <a href="https://t.co/FAIgbCyFFt">pic.twitter.com/FAIgbCyFFt</a></p>&mdash; you (@youtoy) <a href="https://twitter.com/youtoy/status/1467101195521036288?ref_src=twsrc%5Etfw">December 4, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## おわりに
前回に引き続き、シリアル通信の話を記事にしました。

次は、シリアル通信以外の micro:bit と PC の間の通信を実現する何かを試せればと思ってます。