J'ai lu beaucoup de questions ici sur la façon de lire des données de ports série à l'aide de la classe .NET SerialPort, mais aucune des approches recommandées ne s'est révélée totalement efficace pour moi.
Voici le code que j'utilise pour l'instant:
SerialPort port = new SerialPort("COM1");
port.DataReceived += new SerialDataReceivedEventHandler(MyDataReceivedHandler);
Et le gestionnaire d'événements:
void MyDataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
int count = port.BytesToRead;
byte[] ByteArray = new byte[count];
port.Read(ByteArray, 0, count);
}
Mais il me manque encore parfois des données. J'ai essayé différentes manières de lire les données dans le gestionnaire d'événements, mais sans succès.
Comme .NET 4.5 offre de nouvelles possibilités d'effectuer certaines tâches asynchrones, comme avec la méthode ReadAsync qui semble être utilisable sur un flux SerialPort, je suis curieux de voir quelle serait l'approche recommandée pour gérer ces cas.
Pourriez-vous essayer quelque chose comme ceci, par exemple, je pense que ce que vous voulez utiliser est la méthode port.ReadExisting ()
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());
}
}
Ou si vous voulez le faire en fonction de ce que vous essayiez de faire, vous pouvez essayer ceci
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();
}
}
J'ai utilisé un code similaire à @MethodMan mais je devais garder une trace des données envoyées par le port série et rechercher un caractère de fin pour savoir quand le port série était terminé.
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());
}
}
}
}