メインコンテンツまでスキップ

シリアル デバイスと 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)。