2017-08-24 252 views
0

经过很长时间我需要再次编程。 我需要不断地通过串口从汽车ecu(?data)发送一个命令。c#不断请求和处理来自串口的数据

然后我需要接收那些我将要在显示器上显示的数据(思考赛车显示器和汽车参数如温度等)。 我需要不断地做到这一点

我不知道在我开始之前什么是最好的方式来做到这一点?

1个用于不断询问和接收数据的线程 用于在屏幕上显示数据的主线程。 (将数据存入缓冲区并保存一分钟左右)

任何人有任何提示或指导如何开始。 我测试了接收数据与终端,我得到了数据,所以配置工作。

发送?数据=>我拿回数据。

回答

0

的方法,我们正在使用我们的SerialPort处理程序是,以有一个AutoResetEvent一旦有来自港口的答复就会收到通知。

SerialPort FrameWork的类有几个与集成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(); 
    } 
} 

一个串口被初始化并打开。之后,我们连接所有需要的事件,并致电SendDataCommand()方法。该方法是从某个任务调用的公共可见方法。这称为方法SendData。只要有答案,就会触发事件并开始解释。如果在指定的时间内完成解释(_autoResetEvent.WaitOne(msToWait)),则结果返回给调用方法。 这应该在一个单独的任务中完成,所以当你等待答案时,UI将不会阻止。

如上所述,这是一个非常简明的例子。您应该在收到的SerialPort处理程序中执行更多检查,因为该事件存在一些问题。通过这种方法,您将对业务逻辑有更多的抽象。

希望这会有所帮助。

+0

感谢您的信息 – Ditn

1

你可以只使用SerialPort类和配置波特率,数据位等..然后就等着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... 
}