tinygo monitor で快適なシリアルモニター生活を

この記事は TinyGo Advent Calendar 2024 初日の記事です。
TinyGo を使った組み込み開発に欠かせないシリアル通信ツールの一つとして、 `tinygo monitor` の使い方を紹介します。

https://qiita.com/advent-calendar/2024/tinygo

----

組込開発時、マイコンとのシリアル通信のやり取りには以下のようなソフトがよく使用されます。

* コマンドライン
    * GNU screen
    * minicom
    * picocom
* GUI
    * PuTTY
    * Tera Term
    * Arduino IDE 付属のシリアルモニター

ここでは TinyGo のサブコマンドである `tinygo monitor` を紹介します。
詳細な使い方やオプションについては、公式ドキュメントを参考にしてください。

https://tinygo.org/docs/tutorials/serialmonitor/

## TinyGo とは

組み込みマイコンの開発ができたり Wasm 開発が出来たりする Go コンパイラーです。
詳しくは拙著の 「基礎から学ぶ TinyGoの組込み開発」 を参照してください。

https://www.amazon.co.jp/dp/4863544006

## TinyGo のシリアルモニター機能

TinyGo で以下のようなバイナリをマイコンに書き込んだ場合、シリアルモニターを使うと `hello world!` という出力を確認することができます。

```go
// $TINYGOROOT/src/examples/serial
package main

import "time"

func main() {
	for {
		println("hello world!")
		time.Sleep(time.Second)
	}
}
```

書き込みから確認までは以下の通り。

```shell
$ tinygo flash --target wioterminal --size short examples/serial
   code    data     bss |   flash     ram
   7052     108    6688 |    7160    6796

$ tinygo monitor
Connected to COM18. Press Ctrl-C to exit.
hello world!
hello world!
hello world!
```

シリアル通信可能な複数の候補が存在する場合などは以下のようなエラーになります。

```shell
$ tinygo monitor
multiple serial ports available - use -port flag, available ports are COM18, COM81
```

その場合は `--target` を指定するか `--port` を指定してください。
`--port` に設定する値は `tinygo ports` で調べることができます。`--target` を指定するときも、複数の同じターゲットボード (以下だと `wioterminal`) があると失敗するので、その場合は `--port` を使用してください。

```shell
// --target を指定する場合
$ tinygo monitor --target wioterminal
Connected to COM18. Press Ctrl-C to exit.
hello world!
hello world!
hello world!
```

```shell
// --port を使用する場合
$ tinygo ports
Port                 ID        Boards
COM18                2886:802D wioterminal
COM81                2E8A:0003 waveshare-rp2040-zero

$ tinygo monitor --port COM18
Connected to COM18. Press Ctrl-C to exit.
hello world!
hello world!
hello world!
```

## 書込みとシリアルモニターの同時実行

環境によりますが、 `tinygo flash -monitor` を使う事で `tinygo flash` で書き込むと同時に `tinygo monitor` することもできます。
うまく動作しない場合は、個別にコマンドを実行してください。

```shell
$ tinygo flash --target wioterminal --size short --monitor examples/serial
   code    data     bss |   flash     ram
   7052     108    6688 |    7160    6796
Connected to COM18. Press Ctrl-C to exit.
hello world!
hello world!
hello world!
```

## シリアル通信での値の送受信

以下はシリアルに書き込まれた値をオウム返しする例です。
`tinygo monitor` で `Enter / Return` キーを押しても反応しません。

これは、 Go の `fmt.Scanf` や `bufio.Scanner` が `LF` を受け取らないと読み取り完了しないため、です。
`Enter / Return` キーを押しても `tinygo monitor` では `CR` しか送信されません。
`LF` を送るには `C-j` (`Ctrl` を押しながら `j` キー) を押す必要があります。

```go
// $TINYGOROOT/src/examples/echo2
package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	fmt.Printf("Echo console enabled. Type something then press enter:\r\n")

	scanner := bufio.NewScanner(os.Stdin)

	for {
		msg := ""
		fmt.Scanf("%s\n", &msg)
		fmt.Printf("You typed (scanf) : %s\r\n", msg)

		if scanner.Scan() {
			fmt.Printf("You typed (scanner) : %s\r\n", scanner.Text())
		}
	}
}
```

うまく実行できれば以下のように表示されます。

```
$ tinygo flash --target wioterminal --size short --monitor examples/echo2
   code    data     bss |   flash     ram
  76440    1740    6672 |   78180    8412
Connected to COM18. Press Ctrl-C to exit.
You typed (scanf) : hello
You typed (scanner) : world
```

## ボーレート設定方法

ボーレートの設定が必要な場合がありますが、その場合は `--baudrate 9600` 等を指定してください。
TinyGo 環境では 115200bps がデフォルトですが、 AVR マイコンなどの場合は指定が必要です。

```shell
$ tinygo monitor -baudrate=9600
```

`tinygo flash` からも使用できます。

```shell
$ tinygo flash -target arduino-nano -monitor -baudrate 9600
```

## まとめ

TinyGo がインストールされていたら使用可能な `tinygo monitor` を紹介しました。
必ずしも相手のマイコン等は TinyGo で作られている必要はないので、適宜ご使用ください。


## おまけ

`tinygo monitor` は `arudino-cli monitor` をイメージ移植したものです。
ちなみに `arduino-cli` も Go で書かれています。

https://arduino.github.io/arduino-cli/1.1/commands/arduino-cli_monitor/

Linux および macOS 環境は minicom で、 Windows 環境で Tera Term で、というような説明が煩雑であったため `tinygo monitor` が作られました。
なお、書籍 「基礎から学ぶ TinyGoの組込み開発」 の現行にはぎりぎり間に合ったぐらいのタイミングだったので minicom / Tera Term も紹介されているし `tinygo monitor` も少し紹介されている、という感じです。

https://github.com/tinygo-org/tinygo/pull/3156