Quelle est la bonne façon de lire un port série using.NET cadre?
J'ai lu beaucoup de questions ici sur la façon de lire les données des ports série en utilisant la classe. net SerialPort, mais aucune des approches recommandées ne s'est révélée complètement efficace pour moi.
Voici le code que j'utilise pour maintenant:
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 des données parfois. J'ai essayé une manière différente de lire les données dans le gestionnaire d'événements mais sans chance.
Comme le. net 4.5 apporte de nouvelles possibilités pour en faire tâches asynchrones, comme avec la méthode ReadAsync qui semble utilisable sur un flux SerialPort, je suis curieux de voir quelle serait l'approche recommandée pour gérer ces cas.
2 réponses
Pourriez-vous essayer quelque chose comme ceci par exemple, je pense que ce que vous voulez utiliser est le port .Readexisting () Méthode
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
class new SerialPortProgram();
}
private 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
Application.Run();
}
private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
// Show all the incoming data in the port's buffer
Console.WriteLine(port.ReadExisting());
}
}
Ou voulez-vous 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 que le port série envoyait et rechercher un caractère de terminaison pour savoir quand le port série a été envoyé.
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
}
}