Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 正在尝试将密集的传入串行数据打印到richtextbox中_C#_Arduino_Serial Port_Richtextbox - Fatal编程技术网

C# 正在尝试将密集的传入串行数据打印到richtextbox中

C# 正在尝试将密集的传入串行数据打印到richtextbox中,c#,arduino,serial-port,richtextbox,C#,Arduino,Serial Port,Richtextbox,我正在开发一个基于arduino串行监视器的串行监视器项目,但是有更多的功能 有两个基本功能-读取串行数据和将其可视化到richtextbox,写入串行数据,以及将其可视化到richtextbox。当通信非常密集(arduino尽可能快地发送一条线路)并且用户输入将一些接收到的线路切成两半时,就会出现问题。我做了一个算法,通过设置发送/接收标志将richtextbox中的输入字符串与输出字符串分开。然而,这让这个节目显得很奇怪。有时,发送给arduino的命令在richtextbox中不会显示,

我正在开发一个基于arduino串行监视器的串行监视器项目,但是有更多的功能

有两个基本功能-读取串行数据和将其可视化到richtextbox写入串行数据,以及将其可视化到richtextbox。当通信非常密集(arduino尽可能快地发送一条线路)并且用户输入将一些接收到的线路切成两半时,就会出现问题。我做了一个算法,通过设置发送/接收标志将richtextbox中的输入字符串与输出字符串分开。然而,这让这个节目显得很奇怪。有时,发送给arduino的命令在richtextbox中不会显示,但来自arduino的数据显示良好。我尝试在用户输入可视化方法上设置断点,但很少被激活。更重要的是,我还在读取数据方法的可视化上设置断点,它们也很少被激活。然而,表单没有延迟或冻结,命令在richtextbox中飞行,这与观察到的断点行为相反。打印算法很繁重,因为我实现了多色打印

我的尝试:

    void printToConsole(string print, Color txtColor, string part, Color partColor, bool isMsg, bool endNL)
    {
        while (print.Contains('\r'))
            print = print.Replace("\r", "");

        for (int i = 0; i < print.Length; i++)
        {
            if (newString)
            {
                newString = false;
                printTimeAndPart(part, partColor);
            }
            else if (i == 0 && !prevStrHadNL && isMsg != prevWasMsg)
            {
                printNLTimeAndPart(part, partColor);
            }
            else if (i == 0 && prevStrHadNL)
            {
                printNLTimeAndPart(part, partColor);
            }
            else if (i == print.Length - 1)
            {
                if (print[i] == '\n')
                {
                    if (endNL && isMsg != prevWasMsg)
                        AppendText("\n");
                    prevStrHadNL = true;
                    break;
                }
                else
                {
                    if (endNL)
                        AppendText("\n");
                    prevStrHadNL = false;
                }
            }

            if (print[i] == '\n')
            {
                printNLTimeAndPart(part, partColor);
            }
            else
                AppendText(print[i].ToString(), txtColor);
        }
        prevWasMsg = isMsg;
    }

    private void printNLTimeAndPart(string part, Color partColor)
    {
        AppendText("\n");
        printTimeAndPart(part, partColor);
    }

    private void printTimeAndPart(string part, Color partColor)
    {
        if (timestamp == 1)
            AppendText(DateTime.Now.ToString("HH:mm:ss.fff"), timeColor);
        AppendText(part, partColor);
    }

    private void AppendText(string txt, Color clr)
    {
        if (serialControl.ReadAllowed)
        {
            if (rtArea.InvokeRequired)
            {
                MethodInvoker mi = delegate ()
                { rtArea.AppendText(txt, clr); };
                Invoke(mi);
            }
            else
                rtArea.AppendText(txt, clr);
        }
    }

    private void AppendText(string txt)
    {
        if (serialControl.ReadAllowed)
        {
            if (rtArea.InvokeRequired)
            {
                MethodInvoker mi = delegate ()
                { rtArea.AppendText(txt); };
                Invoke(mi);
            }
            else
                rtArea.AppendText(txt);
        }
    }
-尝试了blockingcollection方法。只需将打印操作放入队列中,并使用主线程的2个附加线程逐个执行操作。(Task.Factory.StartNew)。问题是队列在一分钟内就被3000多个动作填满,整个过程落后了15秒左右

-我尝试启动一个新的Task.Factory for every receive/send方法用于每次打印新命令,并锁定线程,直到命令打印到richtextbox中。这也太慢了

最后我想到了只设置标志并允许或不允许打印事件的想法。使用这种方法,用户输入几乎从不打印在richtextbox中:(

打印算法:

    void printToConsole(string print, Color txtColor, string part, Color partColor, bool isMsg, bool endNL)
    {
        while (print.Contains('\r'))
            print = print.Replace("\r", "");

        for (int i = 0; i < print.Length; i++)
        {
            if (newString)
            {
                newString = false;
                printTimeAndPart(part, partColor);
            }
            else if (i == 0 && !prevStrHadNL && isMsg != prevWasMsg)
            {
                printNLTimeAndPart(part, partColor);
            }
            else if (i == 0 && prevStrHadNL)
            {
                printNLTimeAndPart(part, partColor);
            }
            else if (i == print.Length - 1)
            {
                if (print[i] == '\n')
                {
                    if (endNL && isMsg != prevWasMsg)
                        AppendText("\n");
                    prevStrHadNL = true;
                    break;
                }
                else
                {
                    if (endNL)
                        AppendText("\n");
                    prevStrHadNL = false;
                }
            }

            if (print[i] == '\n')
            {
                printNLTimeAndPart(part, partColor);
            }
            else
                AppendText(print[i].ToString(), txtColor);
        }
        prevWasMsg = isMsg;
    }

    private void printNLTimeAndPart(string part, Color partColor)
    {
        AppendText("\n");
        printTimeAndPart(part, partColor);
    }

    private void printTimeAndPart(string part, Color partColor)
    {
        if (timestamp == 1)
            AppendText(DateTime.Now.ToString("HH:mm:ss.fff"), timeColor);
        AppendText(part, partColor);
    }

    private void AppendText(string txt, Color clr)
    {
        if (serialControl.ReadAllowed)
        {
            if (rtArea.InvokeRequired)
            {
                MethodInvoker mi = delegate ()
                { rtArea.AppendText(txt, clr); };
                Invoke(mi);
            }
            else
                rtArea.AppendText(txt, clr);
        }
    }

    private void AppendText(string txt)
    {
        if (serialControl.ReadAllowed)
        {
            if (rtArea.InvokeRequired)
            {
                MethodInvoker mi = delegate ()
                { rtArea.AppendText(txt); };
                Invoke(mi);
            }
            else
                rtArea.AppendText(txt);
        }
    }
这是我的串行控制器类中的dataReceived方法: 我尝试了几种读取串行数据的方法,未注释的方法是我尝试过的最稳定的方法

    private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
    /*    byte[] buffer = new byte[blockLimit];
          Action kickoffRead = null;
          kickoffRead = delegate
          {
              port.BaseStream.BeginRead(buffer, 0, buffer.Length, delegate (IAsyncResult ar)
              {
                  try
                  {
                      int actualLength = port.BaseStream.EndRead(ar);
                      byte[] received = new byte[actualLength];
                      Buffer.BlockCopy(buffer, 0, received, 0, actualLength);
                      string rcv = Encoding.Default.GetString(received);
                      dataRecieved(rcv);
                  }
                  catch (IOException exc)
                  {
                      //handleAppSerialError(exc);
                  }
                  kickoffRead();
              }, null);
          };
          kickoffRead(); 
        */
        if (ReadAllowed)
        {
            string a = port.ReadExisting();
            //port.DiscardInBuffer();
            dataRecieved(a); //Raise event and pass the string to Form1 serial_dataReceived
        }
    }
因此,我需要一些关于如何准确打印多色消息的建议,而不相互切割,每次打印速度快,cpu负载低(现在i5-4310m上的满负载率为35%(arduino密集型传输)。如果您也能提供一些示例,我将非常高兴