经过很长一段时间我需要再次编程。 我需要经常通过串口从汽车ecu(?数据)发送命令。
然后我需要接收我将要处理的数据以显示在显示器上(思考赛车显示器具有汽车参数,如温度等)。 我需要经常这样做
我想知道在我开始之前最好的方法吗?
1个用于不断询问和接收数据的线程 用于在屏幕中显示数据的主线程。 (将数据存储在缓冲区中并保存一分钟左右)
任何人都有任何提示指南或如何开始这个。 我测试了使用终端接收数据,我收回了数据,因此配置正在运行。
发送? data =>我得到了数据。答案 0 :(得分:1)
您可以使用SerialPort类并配置BaudRate,DataBits等。然后等待DataReceived事件触发:
public class SerialPortReader
{
public SerialPortReader(string yourPortName)
{
var serialPort = new SerialPort() {
PortName = yourPortName,
BaudRate = 57600; //This will control the rate at what you receive the data
}
serialPort.DataReceived += new SerialDataReceivedEventHandler(OnDataReceived);
serialPort.Open();
}
}
public void OnDataReceived(object sender, SerialDataReceivedEventArgs e)
{
var serialPort = (SerialPort)sender;
// Process your data reading the stream with Read, ReadLine etc...
}
答案 1 :(得分:0)
我们在SerialPort
处理程序中使用的方法是,只要有来自端口的答案,就会有AutoResetEvent
通知。
SerialPort
类在集成的DataReceived
事件中存在一些问题。当没有完整的包可用时(如果您定义了答案长度),有时会触发它。所以你应该检查你期望的答案长度。
我们非常简化的实施:
public class Serialport
{
private SerialPort _serialPort;
private List<byte> _buffer;
private AutoResetEvent _autoResetEvent;
private const int WriteTimeOut = 5;
private event EventHandler ReceivedDataChanged;
public Serialport()
{
_serialPort = new SerialPort();
// set PortName, BaudRate etc
_serialPort.Open();
_serialPort.DiscardInBuffer();
_serialPort.DiscardOutBuffer();
_serialPort.DataReceived += ReceiveData;
}
private void ReceiveData(object sender, SerialDataReceivedEventArgs e)
{
var bytes = _serialPort.BytesToRead;
byte[] buffer = new byte[bytes];
if (_serialPort.IsOpen)
{
_serialPort.BaseStream.Read(buffer, 0, bytes);
_buffer.AddRange(buffer);
}
ReceivedDataChanged?.Invoke(this, new ReceivedBytesEventArgs(_buffer.ToArray()));
_buffer.Clear();
}
private void SendData(byte[] message, int answerLength)
{
_serialPort.ReceivedBytesThreshold = answerLength;
_serialPort.WriteTimeout = WriteTimeOut;
_serialPort.Write(message, 0, message.Length);
}
public string SendDataCommand()
{
if (_serialPort.IsOpen)
{
ReceivedDataChanged += InterpretAnswer;
SendData(message, length);
if (_autoResetEvent.WaitOne(100))
{
ReceivedDataChanged -= InterpretAnswer;
//Data Received and interpreted and send to the caller
return _requestAnswer;
}
ReceivedDataChanged -= InterpretAnswer;
}
return "Connection not open";
}
private void InterpretAnswer(object sender, EventArgs e)
{
// handle all interpretation
// Set the event
_autoResetEvent.Set();
}
}
初始化并打开serialPort。之后,我们连接所有需要的事件并调用SendDataCommand()
方法。此方法是从某个任务调用的公共可见方法。这会调用方法SendData
。一旦有答案,就会触发事件并开始解释。如果解释是在指定的时间内完成的(_autoResetEvent.WaitOne(msToWait)
),则结果将返回给调用方法。
这应该在一个单独的任务中完成,所以在你等待答案时ui不会阻塞
如上所述,这是一个非常简单的例子。您应该在收到的SerialPort处理程序中进行更多检查,因为事件存在一些问题。使用这种方法,您可以对业务逻辑进行更多抽象。
希望这有帮助。