通信 nuget パッケージ#
NuGet ギャラリー | System.IO.Ports 8.0.0-preview.3.23174.8
dotnet add package System.IO.Ports --version 8.0.0-preview.3.23174.8
Serial インスタンスの作成#
SerialPort mySerialPort = new SerialPort ("COM17", 9600, Parity.None, 8, StopBits.One) の説明
このコードは、シリアルポートとの通信に使用する SerialPort クラスのインスタンスを作成します。SerialPort クラスのコンストラクタは以下のパラメータを受け取ります:
portName(文字列):シリアルポートの名前、例えば"COM17"。baudRate(整数):ボーレート、例えば9600。parity(Parity列挙型):パリティビット、例えばParity.None。dataBits(整数):データビット数、例えば8。stopBits(StopBits列挙型):ストップビット数、例えばStopBits.One。
上記のコードでは、名前が "COM17" のシリアルポートと通信するための SerialPort オブジェクトを作成しています。ボーレートは 9600、パリティビットは使用せず、データビット数は 8、ストップビット数は 1 と指定しています。
これらのパラメータを自分の環境に合わせて変更することで、開発ボードとの通信を行うことができます。
通信エンコーディング#
通信エンコーディングの変更
UTF-8 エンコーディングを使用する場合
もし、開発ボードが UTF-8 エンコーディングを使用している場合、SerialPort オブジェクトの作成時に Encoding プロパティを System.Text.Encoding.UTF8 に指定することができます。以下に例を示します:
SerialPort mySerialPort = new SerialPort("COM17", 9600, Parity.None, 8, StopBits.One);
mySerialPort.Encoding = System.Text.Encoding.UTF8;
これにより、Godot プログラムはシリアルポートのデータを UTF-8 エンコーディングで読み取るため、文字化けの問題を回避することができます。
????
もしコンソールで一連の疑問符を見た場合、それは文字エンコーディングの問題によるものかもしれません。シリアル通信では、送信側と受信側で同じ文字エンコーディングを使用する必要があります。そうでない場合、受信したデータが文字化けする可能性があります。
開発ボードが使用している文字エンコーディングを確認し、Godot プログラムで同じ文字エンコーディングを使用してデータを読み取るようにしてください。例えば、開発ボードが ASCII エンコーディングを使用している場合、以下のように SerialPort オブジェクトを作成する際に Encoding プロパティを指定することができます:
SerialPort mySerialPort = new SerialPort("COM17", 9600, Parity.None, 8, StopBits.One);
mySerialPort.Encoding = System.Text.Encoding.ASCII;
これらの情報が問題解決の手助けになることを願っています。
もしプログラムがシリアルポートからデータを読み取れない場合、以下の理由が考えられます:
- シリアルポートの名前が正しくありません。
SerialPortクラスのコンストラクタで指定したシリアルポートの名前が、接続されている開発ボードのシリアルポートの名前と一致していることを確認してください。 - ボーレートが正しくありません。
SerialPortクラスのコンストラクタで指定したボーレートが、開発ボードで使用しているボーレートと一致していることを確認してください。 - シリアルポートがオープンされていません。
SerialPort.Openメソッドを呼び出してシリアルポートを開いていることを確認してください。 - 開発ボードがデータを送信していません。開発ボードがシリアルポートを介してデータを送信していることを確認してください。
シリアルポートが開いているかどうかを確認するためには、SerialPort.IsOpen プロパティを使用することができます。このプロパティが true を返す場合、シリアルポートは開いています。それ以外の場合は、シリアルポートは開いていません。
また、問題の特定に役立つデバッグ情報を catch (TimeoutException) ブロックに追加することもできます。例えば、次のようにすることができます:
try
{
string message = mySerialPort.ReadLine();
GD.Print(message);
}
catch (TimeoutException)
{
GD.Print("TimeoutException: Failed to read data from serial port.");
}
これらの情報が問題解決の手助けになることを願っています。
マルチスレッド#
はい、このコードの while (true) ループは、プログラムを手動で終了するまで継続されます。これにより、Godot プロジェクトが起動後にフリーズする可能性があります。
Godot でシリアルポートのデータを読み取りたいが、メインスレッドをブロックしたくない場合、スレッドやタイマーを使用することを検討してください。例えば、System.Threading.Thread クラスを使用して新しいスレッドを作成し、そのスレッドでシリアルポートのデータを読み取り、それをコンソールに出力することができます。以下に簡単なサンプルコードを示します:
using Godot;
using System;
using System.IO.Ports;
using System.Threading;
public partial class io : Node
{
private bool _isRunning = true;
public override void _Ready()
{
// 新しいスレッドを作成して開始する
Thread thread = new Thread(ReadSerialPort);
thread.Start();
}
private void ReadSerialPort()
{
// シリアルポートの名前、ボーレート、タイムアウトを設定する
SerialPort mySerialPort = new SerialPort("COM17", 115200, Parity.None, 8, StopBits.One);
mySerialPort.ReadTimeout = 500;
// シリアルポートをオープンする
mySerialPort.Open();
// データを読み取り、コンソールに出力する
while (_isRunning)
{
try
{
string message = mySerialPort.ReadLine();
GD.Print(message);
}
catch (TimeoutException) { }
}
// シリアルポートをクローズする
mySerialPort.Close();
}
public override void _ExitTree()
{
// スレッドを停止する
_isRunning = false;
}
}
上記のコードでは、新しいスレッドを作成し、そのスレッドでシリアルポートのデータを読み取ります。Godot プロジェクトが終了する際に、_isRunning 変数を false に設定することでスレッドを停止します。これにより、メインスレッドをブロックせずにシリアルポートのデータを読み取ることができます。
シリアルポートへのデータ送信#
もし、シリアルポートを介して開発ボードにデータを送信したい場合、SerialPort クラスの Write メソッドや WriteLine メソッドを使用することができます。例えば、以下のコードは、開発ボードに対して文字列を送信する方法を示しています:
// シリアルポートの名前、ボーレートを設定する
SerialPort mySerialPort = new SerialPort("COM17", 9600, Parity.None, 8, StopBits.One);
// シリアルポートをオープンする
mySerialPort.Open();
// 開発ボードにデータを送信する
string message = "Hello, world!";
mySerialPort.WriteLine(message);
// シリアルポートをクローズする
mySerialPort.Close();
上記のコードでは、WriteLine メソッドを使用して開発ボードに対して文字列を送信しています。Write メソッドを使用してバイト配列や他のデータ型を送信することもできます。
これらの情報が問題解決の手助けになることを願っています。