SerialPort

[C#] SerialPortクラスでのデータ書き込み方法

C#のSerialPortクラスを使用してデータを書き込むには、まずSerialPortオブジェクトを作成し、必要なプロパティ(ポート名、ボーレート、パリティ、データビット、ストップビットなど)を設定します。

次に、Openメソッドを呼び出してシリアルポートを開きます。

データを書き込むには、Writeメソッドを使用します。

このメソッドは、文字列やバイト配列を送信することができます。

データの送信が完了したら、Closeメソッドを呼び出してポートを閉じることを忘れないでください。

エラー処理や例外処理も適切に行うことが推奨されます。

データ書き込みの基本手順

SerialPortオブジェクトの作成

C#でシリアルポートを使用するためには、まずSerialPortクラスのインスタンスを作成します。

以下のコードでは、COMポートの設定を行っています。

using System;
using System.IO.Ports;
class Program
{
    static void Main()
    {
        // SerialPortオブジェクトの作成
        SerialPort serialPort = new SerialPort("COM3", 9600);
        
        // ここでポートの設定を行うことができます
    }
}

ポートのオープン

次に、作成したSerialPortオブジェクトをオープンします。

ポートが正常にオープンできたかどうかを確認するために、例外処理を行うことが重要です。

using System;
using System.IO.Ports;
class Program
{
    static void Main()
    {
        SerialPort serialPort = new SerialPort("COM3", 9600);
        
        try
        {
            // ポートをオープン
            serialPort.Open();
            Console.WriteLine("ポートがオープンしました。");
        }
        catch (Exception ex)
        {
            // エラーメッセージを表示
            Console.WriteLine("ポートをオープンできませんでした: " + ex.Message);
        }
    }
}

Writeメソッドによるデータ送信

ポートがオープンしたら、Writeメソッドを使用してデータを送信します。

以下の例では、文字列データを送信しています。

using System;
using System.IO.Ports;
class Program
{
    static void Main()
    {
        SerialPort serialPort = new SerialPort("COM3", 9600);
        
        try
        {
            serialPort.Open();
            Console.WriteLine("ポートがオープンしました。");
            
            // データを送信
            string dataToSend = "こんにちは、シリアルポート!";
            serialPort.Write(dataToSend);
            Console.WriteLine("データを送信しました: " + dataToSend);
        }
        catch (Exception ex)
        {
            Console.WriteLine("エラー: " + ex.Message);
        }
        finally
        {
            // ポートをクローズ
            serialPort.Close();
            Console.WriteLine("ポートがクローズしました。");
        }
    }
}
ポートがオープンしました。
データを送信しました: こんにちは、シリアルポート!
ポートがクローズしました。

ポートのクローズ

データ送信が完了したら、必ずポートをクローズします。

これにより、リソースが解放され、他のアプリケーションがポートを使用できるようになります。

上記のコードでは、finallyブロック内でポートをクローズしています。

エラー処理と例外管理

例外の種類と対処法

C#のSerialPortクラスを使用する際には、いくつかの例外が発生する可能性があります。

以下は、一般的な例外の種類とその対処法です。

例外の種類説明対処法
UnauthorizedAccessExceptionポートにアクセスする権限がない場合に発生アプリケーションを管理者として実行する
IOException入出力エラーが発生した場合に発生ポートの設定を確認し、再試行する
ArgumentException無効な引数が指定された場合に発生引数の値を確認し、正しい値を指定する

データ送信時のエラーハンドリング

データ送信時には、送信先のデバイスが応答しない場合や、ポートが閉じられている場合など、さまざまなエラーが発生する可能性があります。

以下のコードは、データ送信時のエラーハンドリングの例です。

using System;
using System.IO.Ports;
class Program
{
    static void Main()
    {
        SerialPort serialPort = new SerialPort("COM3", 9600);
        
        try
        {
            serialPort.Open();
            Console.WriteLine("ポートがオープンしました。");
            
            string dataToSend = "こんにちは、シリアルポート!";
            
            // データ送信
            try
            {
                serialPort.Write(dataToSend);
                Console.WriteLine("データを送信しました: " + dataToSend);
            }
            catch (TimeoutException)
            {
                Console.WriteLine("データ送信中にタイムアウトが発生しました。");
            }
            catch (IOException ex)
            {
                Console.WriteLine("入出力エラー: " + ex.Message);
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("エラー: " + ex.Message);
        }
        finally
        {
            // ポートをクローズ
            if (serialPort.IsOpen)
            {
                serialPort.Close();
                Console.WriteLine("ポートがクローズしました。");
            }
        }
    }
}

ポートクローズ時の注意点

ポートをクローズする際には、いくつかの注意点があります。

以下のポイントを考慮することが重要です。

  • ポートがオープンしているか確認: ポートがオープンしていない状態でクローズしようとすると、例外が発生します。

IsOpenプロパティを使用して確認します。

  • リソースの解放: ポートをクローズすることで、他のアプリケーションがそのポートを使用できるようになります。

必ずクローズ処理を行うことが重要です。

  • 例外処理: クローズ処理中にエラーが発生する可能性があるため、例外処理を行うことが推奨されます。

以下は、ポートクローズ時の注意点を考慮したコードの例です。

using System;
using System.IO.Ports;
class Program
{
    static void Main()
    {
        SerialPort serialPort = new SerialPort("COM3", 9600);
        
        try
        {
            serialPort.Open();
            Console.WriteLine("ポートがオープンしました。");
        }
        catch (Exception ex)
        {
            Console.WriteLine("ポートをオープンできませんでした: " + ex.Message);
        }
        finally
        {
            // ポートをクローズ
            if (serialPort.IsOpen)
            {
                try
                {
                    serialPort.Close();
                    Console.WriteLine("ポートがクローズしました。");
                }
                catch (Exception ex)
                {
                    Console.WriteLine("ポートクローズ中にエラーが発生しました: " + ex.Message);
                }
            }
        }
    }
}

応用例

バイト配列の送信

シリアルポートを使用してバイト配列を送信することも可能です。

バイト配列は、特にバイナリデータを扱う際に便利です。

以下のコードでは、バイト配列を送信する方法を示しています。

using System;
using System.IO.Ports;
class Program
{
    static void Main()
    {
        SerialPort serialPort = new SerialPort("COM3", 9600);
        
        try
        {
            serialPort.Open();
            Console.WriteLine("ポートがオープンしました。");
            
            // バイト配列の作成
            byte[] dataToSend = { 0x01, 0x02, 0x03, 0x04, 0x05 };
            
            // バイト配列を送信
            serialPort.Write(dataToSend, 0, dataToSend.Length);
            Console.WriteLine("バイト配列を送信しました。");
        }
        catch (Exception ex)
        {
            Console.WriteLine("エラー: " + ex.Message);
        }
        finally
        {
            if (serialPort.IsOpen)
            {
                serialPort.Close();
                Console.WriteLine("ポートがクローズしました。");
            }
        }
    }
}
ポートがオープンしました。
バイト配列を送信しました。
ポートがクローズしました。

非同期でのデータ書き込み

非同期でデータを送信することで、アプリケーションの応答性を向上させることができます。

以下のコードでは、WriteAsyncメソッドを使用して非同期にデータを送信しています。

using System;
using System.IO.Ports;
using System.Threading.Tasks;
class Program
{
    static async Task Main()
    {
        SerialPort serialPort = new SerialPort("COM3", 9600);
        
        try
        {
            serialPort.Open();
            Console.WriteLine("ポートがオープンしました。");
            
            string dataToSend = "非同期データ送信!";
            
            // 非同期でデータを送信
            await serialPort.BaseStream.WriteAsync(System.Text.Encoding.UTF8.GetBytes(dataToSend), 0, dataToSend.Length);
            Console.WriteLine("非同期でデータを送信しました: " + dataToSend);
        }
        catch (Exception ex)
        {
            Console.WriteLine("エラー: " + ex.Message);
        }
        finally
        {
            if (serialPort.IsOpen)
            {
                serialPort.Close();
                Console.WriteLine("ポートがクローズしました。");
            }
        }
    }
}
ポートがオープンしました。
非同期でデータを送信しました: 非同期データ送信!
ポートがクローズしました。

データ送信の進捗管理

データ送信の進捗を管理するためには、送信するデータのサイズを把握し、送信完了までの進捗を表示することが重要です。

以下のコードでは、送信するバイト数をカウントし、進捗を表示しています。

using System;
using System.IO.Ports;
using System.Threading.Tasks;
class Program
{
    static async Task Main()
    {
        SerialPort serialPort = new SerialPort("COM3", 9600);
        
        try
        {
            serialPort.Open();
            Console.WriteLine("ポートがオープンしました。");
            
            byte[] dataToSend = new byte[100]; // 100バイトのデータ
            for (int i = 0; i < dataToSend.Length; i++)
            {
                dataToSend[i] = (byte)i; // データを初期化
            }
            
            int totalBytes = dataToSend.Length;
            int bytesSent = 0;
            
            // データを送信しながら進捗を表示
            while (bytesSent < totalBytes)
            {
                int bytesToSend = Math.Min(10, totalBytes - bytesSent); // 一度に送信するバイト数
                await serialPort.BaseStream.WriteAsync(dataToSend, bytesSent, bytesToSend);
                bytesSent += bytesToSend;
                Console.WriteLine($"進捗: {bytesSent}/{totalBytes} バイト送信完了。");
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("エラー: " + ex.Message);
        }
        finally
        {
            if (serialPort.IsOpen)
            {
                serialPort.Close();
                Console.WriteLine("ポートがクローズしました。");
            }
        }
    }
}
ポートがオープンしました。
進捗: 10/100 バイト送信完了。
進捗: 20/100 バイト送信完了。
進捗: 30/100 バイト送信完了。
進捗: 40/100 バイト送信完了。
進捗: 50/100 バイト送信完了。
進捗: 60/100 バイト送信完了。
進捗: 70/100 バイト送信完了。
進捗: 80/100 バイト送信完了。
進捗: 90/100 バイト送信完了。
進捗: 100/100 バイト送信完了。
ポートがクローズしました。

まとめ

この記事では、C#のSerialPortクラスを使用したデータ書き込みの基本手順やエラー処理、応用例について詳しく解説しました。

シリアルポートを利用することで、さまざまなデバイスとの通信が可能になり、特にバイナリデータや非同期処理の実装が重要であることがわかりました。

これを機に、実際のプロジェクトでシリアル通信を活用し、より高度なアプリケーションを開発してみてください。

関連記事

Back to top button
目次へ