web-dev-qa-db-ja.com

.NETフレームワークを使用してシリアルポートを読み取る正しい方法は何ですか?

ここでは、.NET SerialPortクラスを使用してシリアルポートからデータを読み取る方法について多くの質問を読みましたが、推奨されるアプローチはどれも完全に効率的ではありませんでした。

ここで私が今使用しているコードは次のとおりです。

SerialPort port = new SerialPort("COM1");
port.DataReceived += new SerialDataReceivedEventHandler(MyDataReceivedHandler);

そして、イベントハンドラー:

void MyDataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
    int count = port.BytesToRead;
    byte[] ByteArray = new byte[count];
    port.Read(ByteArray, 0, count);
}

しかし、まだいくつかのデータが欠落していることがあります。イベントハンドラーでデータを読み取る別の方法を試しましたが、運はありません。

.NET 4.5は、SerialPortストリームで使用できると思われる ReadAsync メソッドのように、いくつかの非同期タスクを実行する新しい可能性をもたらすため、推奨される処理方法を知りたいと思います。それらの場合。

30

たとえば、このようなものを試してみてください。あなたが利用したいのはport.ReadExisting() Method

 using System;
 using System.IO.Ports;

 class SerialPortProgram 
 { 
  // Create the serial port with basic settings 
    private SerialPort port = new   SerialPort("COM1",
      9600, Parity.None, 8, StopBits.One); 
    [STAThread] 
    static void Main(string[] args) 
    { 
      // Instatiate this 
      SerialPortProgram(); 
    } 

    private static void SerialPortProgram() 
    { 
        Console.WriteLine("Incoming Data:");
         // Attach a method to be called when there
         // is data waiting in the port's buffer 
        port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived); 
        // Begin communications 
        port.Open(); 
        // Enter an application loop to keep this thread alive 
        Console.ReadLine();
     } 

    private void port_DataReceived(object sender, SerialDataReceivedEventArgs e) 
    { 
       // Show all the incoming data in the port's buffer
       Console.WriteLine(port.ReadExisting()); 
    } 
}

または、あなたがやろうとしていたことに基づいてそれをやりたいですか、あなたはこれを試すことができます

public class MySerialReader : IDisposable
{
  private SerialPort serialPort;
  private Queue<byte> recievedData = new Queue<byte>();

  public MySerialReader()
  {
    serialPort = new SerialPort();
    serialPort.Open();
    serialPort.DataReceived += serialPort_DataReceived;
  }

  void serialPort_DataReceived(object s, SerialDataReceivedEventArgs e)
  {
    byte[] data = new byte[serialPort.BytesToRead];
    serialPort.Read(data, 0, data.Length);
    data.ToList().ForEach(b => recievedData.Enqueue(b));
    processData();
  }

  void processData()
  {
    // Determine if we have a "packet" in the queue
    if (recievedData.Count > 50)
    {
        var packet = Enumerable.Range(0, 50).Select(i => recievedData.Dequeue());
    }
  }

  public void Dispose()
  {
        if (serialPort != null)
        {
            serialPort.Dispose();
        }
  }
22
MethodMan

@MethodManと同様のコードを使用しましたが、シリアルポートが送信しているデータを追跡し、シリアルポートがデータの送信を完了したことを知るために終端文字を探す必要がありました。

private string buffer { get; set; }
private SerialPort _port { get; set; }

public Port() 
{
    _port = new SerialPort();
    _port.DataReceived += new SerialDataReceivedEventHandler(dataReceived);
    buffer = string.Empty;
}

private void dataReceived(object sender, SerialDataReceivedEventArgs e)
{    
    buffer += _port.ReadExisting();

    //test for termination character in buffer
    if (buffer.Contains("\r\n"))
    {
        //run code on data received from serial port
    }
}
4
user1184321
    using System;
    using System.IO.Ports;
    using System.Threading;

    namespace SerialReadTest
    {
        class SerialRead
        {
            static void Main(string[] args)
            {
        Console.WriteLine("Serial read init");
        SerialPort port = new SerialPort("COM6", 115200, Parity.None, 8, StopBits.One);
        port.Open();
        while(true){
          Console.WriteLine(port.ReadLine());
        }

    }
}
}
1
Vimukthi Sineth