ここでは、.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 メソッドのように、いくつかの非同期タスクを実行する新しい可能性をもたらすため、推奨される処理方法を知りたいと思います。それらの場合。
たとえば、このようなものを試してみてください。あなたが利用したいのは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();
}
}
@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
}
}
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());
}
}
}
}