简体   繁体   English

串口Port.Datareceived无法触发(.net 4.5)

[英]Serial Port.Datareceived is not firing (.net 4.5)

I am using .net 4.5 and since i got aware about some internet discussion about .net having wrong code implementation to rad serial data, i went with the code below. 我使用的是.net 4.5,由于我知道有关.net的一些互联网讨论,它们对rad串行数据的代码实现错误,因此我使用了以下代码。

The problems is however even despite i can see i create a COM port connection (to the right com port number), its never firing on data received. 问题是,即使我可以看到我创建了一个COM端口连接(到正确的COM端口号),也从未触发接收到的数据。 The data receiving is based upon a simple Arduino app, (Arduino monitor does show data gets send over serial), but .net never seams to fire upon serial events. 数据接收基于一个简单的Arduino应用程序(Arduino监视器确实显示数据已通过串行发送),但是.net绝不会在发生串行事件时触发。

I've put breakpoints on eventread, it never gets hit 我在eventread上设置了断点,但它从未被击中

i've looked at other discussions here like .NET SerialPort DataReceived event not firing but so far they don't resolve the issue i have. 我在这里查看了其他讨论,例如.NET SerialPort DataReceived事件未触发,但到目前为止,它们仍无法解决我遇到的问题。 I tried various combination of serial line setups, and believe the below ones are correct. 我尝试了各种串行线设置的组合,并认为以下设置是正确的。 as for Arduino part the line is setup as: 至于Arduino部分,该行设置为:

Serial.begin(9600);

I call my class like : `InfraredSensor mySens = new InfraredSensor("COM4",9600);' 我这样称呼我的班级:'InfraredSensor mySens = new InfraredSensor(“ COM4”,9600);'

class InfraredSensor
{
    private string Eventlogapp = "IRlogging"; 
    private SerialPort Port;
    public InfraredSensor(string COMport, int baudrate) //constructor
    {
        if (applicationlog != "") this.EventlogSapec = applicationlog;
        WriteEventLog(EventlogSapec, EventSource, "Initializing-IR:" + COMport, info, EventIRStarted);

        // I found that the .net standard implementation for com port reading is not OK (.net doesnt follow win32 api).
        // There are numerous readings about it, but a good way to read seams to be to use Serial BaseStream.ReadAsync
        // code below is based upon : http://www.c-sharpcorner.com/code/2880/serial-port-with-efficient-data-reading-in-c-sharp.aspx

        this.comport = COMport;
        SerialPort Port = new SerialPort(comport);

        Port.BaudRate = baudrate;
        Port.DataBits = 8;
        Port.Parity = Parity.None;
        Port.StopBits = StopBits.One;
        Port.Handshake = Handshake.None;

        Port.NewLine = Environment.NewLine;
        Port.ReceivedBytesThreshold = 2; // + linefeed 
        Port.DataReceived += ReadEvent;
        Port.Open();
        Port.DtrEnable = true;
       // i've tested from here i do have an open connection
       // its just dat ReadEvent never fires...
    }


      private void ReadEvent(object sender, SerialDataReceivedEventArgs e)
    {
        byte[] buffer = new byte[2];//todo i only send "A" or "B", for the debug moment 
        Action kickoffRead = null;

        kickoffRead = (Action)(() => Port.BaseStream.BeginRead(buffer, 0, buffer.Length, delegate (IAsyncResult ar)
        {
            try
            {
                int count = Port.BaseStream.EndRead(ar);
                byte[] dst = new byte[count];
                Buffer.BlockCopy(buffer, 0, dst, 0, count);
                RaiseAppSerialDataEvent(dst);
            }
            catch (Exception ex)
            {
                WriteEventLog(Eventlogapp, "IR", "Failure-IR:" + ex.Message, info, 204);
            }
            kickoffRead();
        }, null)); kickoffRead();
    }

    private void RaiseAppSerialDataEvent(byte[] Data)
    {
    // code never gets to here
        string msg = Encoding.Default.GetString(Data);
    int breakpointhere = 0;

        if (msg.Contains('A')) WriteEventLog(Eventlogapp, "IR", "Sensor A", info, 213);

        if (msg.Contains('B')) WriteEventLog(Eventlogapp, "IR", "Sensor B", info, 214);


    }
}

I ran out of ideas (and hair as its driving me nuts) what could cause this behaviour ? 我没有想法了(头发使我发疯)是什么原因引起的?

finally this took me 2 days ... 终于这花了我2天时间...

in arduino code i now use 在我现在使用的arduino代码中

serial.print("Mytext\n");  // using \n to be sure of escape character

for the serial line config i now use 我现在使用的串行线配置

this.comport = COMport;
this.Port = new SerialPort(comport);
this.Port.BaudRate = baudrate;
this.Port.DataBits = 8;
this.Port.Parity = Parity.None;
this.Port.StopBits = StopBits.One;
this.Port.Handshake = Handshake.None;
this.Port.RtsEnable = true;
      //  Port.NewLine = "\n";
       //   Port.ReceivedBytesThreshold = 2; // + linefeed 
        this.Port.DataReceived += new new SerialDataReceivedEventHandler(ReadEvent);

....
..
SerialDataReceivedEventHandler(ReadEvent);
//code didnt change inside but the method has changed see the +=

The DataReceived event fires when there is data coming through the serial port, but it can fire randomly. 当有数据通过串行端口时,将触发DataReceived事件,但是它可以随机触发。 So you could get part of the message in one event and the other half of the message in another event. 因此,您可以在一个事件中得到消息的一部分,而在另一事件中得到消息的另一半。 You should have some sort of key to know when you have the whole message. 您应该拥有某种钥匙,才能知道完整的消息。 So build your string until you have the whole message then do something based on the message. 因此,构建您的字符串,直到获得完整的消息,然后根据该消息执行一些操作。

For example, my device's message is done when there is a Line Feed. 例如,当有换行时,我的设备的消息已完成。 So my code looks something like: 所以我的代码看起来像:

char ESC = (char)27;
char CR = (char)13;
char LF = (char)10;
StringBuilder sb = new StringBuilder();

private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
    string Data = serialPort1.ReadExisting();

    foreach (char c in Data)
    {
        if (c == LF)
        {
            sb.Append(c);

            //we have our message, do something, maybe like
            if (sb.ToString().Contains("A"))
            {
                //print A
            }
            else
            {
                //print B
            }
        }
        else
        {
            sb.Append(c);
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM