シリアル デバイスと Arduino
Serial* 組み込み関数は、COM ポートとして認識されるあらゆるものと通信します: USB で接続した Arduino、ESP32、
Raspberry Pi Pico、USB シリアル変換アダプター、GPS 受信機、シリアル モードのバーコード スキャナー、
レシート プリンターやラベル プリンター、G コードを受け付ける 3D プリンターや CNC コントローラー、計測機器、
自作のボタン ボックス、マクロ パッド、ロータリー ノブ、LED コントローラーなどです。デバイスはテキストの行を送受信し、
スクリプトはその行を Input.Observer で実行できるあらゆる操作に変換します。
活用例:
- ボタン ボックスやマクロ パッド。 Arduino がボタンを読み取り、
B1、B2、... を出力します。シリアル モニターが各行をショートカット、メディア キー、ウィンドウの操作に変換します。 - 音量ノブやスクロール ノブ。 ポテンショメーターやロータリー エンコーダーが位置を出力し、モニターが 音量を設定したりスクロールしたりします。
- ステータス ライト。 ジェスチャやホットキーが LED ストリップを制御するボードに
LED 255 0 0を送信し、 録画中であることやビルドの失敗をライトで示します。 - センサー。 タイマーがボードに温度や明るさを問い合わせ、その値を表示したり、ファイルに記録したり、 画面を暗くしたりします。
- スキャナーとリーダー。 リーダーが送信するバーコードや RFID タグのそれぞれが、入力されたテキスト、 検索、またはファイル内の検索になります。
- 機械。 G コードの行をプリンターやプロッターに送信します。1 つのコマンドにつき 1 回の
SerialWriteTextLineです。
ポートの確認
Windows は各デバイスに COM3 のような名前を付けます。デバイス マネージャーでは ポート (COM と LPT) の下に表示され、
Arduino IDE ではボードのメニューに表示されます。スクリプトで一覧を取得することもできます。
n = SerialEnumeratePorts();
if (n == 0) UtilityPrint("No COM ports. Is the board plugged in?");
for (i = 0; i < n; i = i + 1) {
UtilityPrint(SerialGetEnumeratedPortAt(i));
}
一覧は番号順に並ぶため、COM3 は COM10 より前になります。デバイスを別の USB ポートに差し替えると、
番号が変わることがあります。
通信速度、フレーム構成、行末
- 通信速度 (
baudRate) はデバイスと一致させる必要があります。Arduino のスケッチのSerial.begin(...)に指定した数値で、通常は9600または115200です。 - フレーム構成 はほぼ常に、データ ビット 8、パリティなし、ストップ ビット 1 です:
8、SerialParity.None、SerialStopBits.One。定数で記述してください: ストップ ビットの引数に数値の1をそのまま指定すると、 1.5 ストップ ビットという意味になります。 - 行末。 受信した行は、指定した
terminatorで終わり、terminatorは行から取り除かれます。 空のテキストは CR LF を意味し、これは Arduino のSerial.printlnが送信するものです。LF だけで行が終わるデバイスには"\n"を、CR だけで行が終わるデバイスには"\r"を使用します。SerialWriteTextLineは、送信する内容の末尾に 同じ terminator を付けます。呼び出し自体がポートを開く場合は CR LF を付けます。CR LF の場合、Serial.readStringUntil('\n')で読み取る Arduino のスケッチは、末尾に CR が付いた行を受け取るため、trim()で取り除きます。"\n"の場合は、取り除く CR はありません。 - 信号。 ポートを開くと、Arduino IDE と同じように DTR と RTS の信号がオンになります。これにより、 Arduino Uno や Nano の多くのボード、および同じリセット回路を持つ他のボードが再起動します。
デバイスと通信する 3 つの方法
-
1 回の問い合わせに 1 回の応答。 開いていないポートに対する
SerialWriteTextLineとSerialGetTextLineは、 その 1 回の呼び出しのために、呼び出しのbaudRate、8-N-1 でポートを開きます。ポートが既に開いている場合、baudRate引数は無視されます。ポートを開いたときに再起動しないデバイスに適しています。 シリアル デバイスに問い合わせるを参照してください。 -
開いたままにするポート。
SerialOpenPortは、SerialClosePortを呼び出すまで指定した設定でポートを開き、 デバイスが送信するすべての行をSerialGetTextLineで読み取れるように蓄積します。Arduino Uno や Nano の多くのボードは ポートが開かれるたびに再起動するため、ポートは Load グローバル イベントで一度だけ開き、 ジェスチャやホットキーからはそのポートに書き込むようにします。SerialOpenPortは、ポートが存在しない場合、 取り外されている場合、または別のプログラムで開かれている場合はfalseを返します。Input.Observer が既に開いているポートや、 モニターが使用しているポートの場合は、エラーでアクションを停止します。// Load global event: open the port once, at the sketch's speed. An Uno or Nano// restarts every time its port opens, so a port opened per command would lose// the command while the board boots.if (!SerialOpenPort("COM4", 115200, SerialParity.None, 8, SerialStopBits.One, "")) {UtilityPrint("COM4 isn't available: unplugged, or open in the Arduino IDE's Serial Monitor?");}// Any gesture or hotkey: send a command line and read the board's reply.// (The sketch reads a line with Serial.readStringUntil('\n') and answers OK.)if (SerialWriteTextLine("COM4", "LED 255 0 0", 115200)) {reply = SerialGetTextLine("COM4", 1, 115200);if (reply != "OK") UtilityPrint(StringFormat("Board said: {0}", reply, ""));} -
モニター。
SerialMonitorCreateは、SerialMonitorDeleteを呼び出すまで、デバイスが送信する行ごとに バックグラウンドでスクリプトを実行します。受信した行はContextGetSerialTextLine()です。 シリアル デバイスのボタンをメディア キーに割り当てると次の例を参照してください。// Arduino side: a potentiometer on A0, one reading per line.// void setup() { Serial.begin(115200); }// void loop() { Serial.println(analogRead(A0)); delay(50); }// Empty text as the terminator means CR LF, which Serial.println sends.SerialMonitorCreate("knob", "COM4", 115200, SerialParity.None, 8, SerialStopBits.One, "","line = ContextGetSerialTextLine(); if (StringIsNumber(line, true)) MultimediaSetVolume(AudioEndpoint.Playback, StringToNumber(line, true) / 1023.0);");
モニターについて知っておくべきこと。
- 行は届いた順に 1 つずつ実行されます: 次の行のスクリプトは、前の行のスクリプトが終了してから開始されます。 待機できる行は最大 256 行で、それを超えると古いものから破棄されます。
- すべてのアクションを停止すると、行に対して実行中のスクリプトが停止し、待機中の行は破棄されます。 モニター自体は実行を続けます。すべてのアクションを停止するホットキーはさらに踏み込み、すべてのモニターを削除して そのポートを閉じます。
- モニター自身のスクリプトを含め、どのスクリプトも
SerialWriteTextLineでモニター中のポートに送信できるため、 モニターはデバイスに応答できます。SerialGetTextLineはモニター中のポートを読み取れません: すべての行はモニターに届きます。 - 各モニター名は 1 つのポートに属します。このポートのモニターの名前で
SerialMonitorCreateを呼び出すと、 そのモニターが置き換えられます。その名前が既に別のポートを監視している場合、ポートがSerialOpenPortで開かれている場合、 または別のモニターがポートを使用している場合は、エラーでアクションを停止します。ポートが存在しない場合、取り外されている場合、 または別のプログラムで開かれている場合はfalseになります。 - デバイスを取り外すとモニターは終了し、コンソールの システム タブに 1 行書き込まれます。
デバイスを再接続しても、モニターは自動的には再開されません。
SerialMonitorCreateをもう一度実行してください (ホットキーから、または次回起動時の Load イベントで)。
COM ポートを開けるのは一度に 1 つのプログラムだけです。 Arduino IDE のシリアル モニターまたはシリアル
プロッターが開いている間は Input.Observer はポートを開けず、Input.Observer がポートを開いている間は IDE で
スケッチを書き込めません。書き込む前にポートを閉じてください (SerialClosePort または SerialMonitorDelete)。