首页 > 解决方案 > C# 虚拟串口问题!错误命令后不恢复

问题描述

我是一名初学者程序员,目前正在开发一个带有虚拟串行端口的项目。这是我第一次和他们一起工作,我还在学习。现在,我只是想基本上创建我自己的腻子版本——我可以自信地从端口读取和写入的东西。

我正在尝试从称重传感器获取力数据。他们响应我给定的命令集(例如“w”返回权重),如果该命令未被识别,则以“E”响应。

很多时候我的代码都能正常工作——只要我不给它一个它无法识别的命令,它就会做出应有的响应。但是,一旦我发送了一个错误的命令,它只会从那里响应“E”,即使是正确的命令也是如此。在我的代码中关闭并重新打开端口并没有帮助——它仍然只响应“E”。

我能够“重置”情况的唯一方法是在 Putty 中打开和关闭会话。然后我可以再次从我的程序中获得好的数据。称重传感器在 Putty 100% 的时间内做出应有的响应,并且能够在执行错误命令后恢复。

Putty 可以做些什么来“重置”我的代码中还没有做的情况?我正在关闭港口...救命!!!

    static SerialPort firstSerialPort;
    static bool myContinue;

    static void Main(string[] args)
    {
        string message;
        Thread readThread = new Thread(Read);

        //Initializing a SerialPort object
        firstSerialPort = new SerialPort("COM3", 9600, Parity.None,8,StopBits.One);

        //Checking if serial ports are initially open
        Console.WriteLine("First serial port is open: {0}", firstSerialPort.IsOpen);

        //Selecting the properties
        firstSerialPort.Handshake = Handshake.XOnXOff;
        firstSerialPort.DtrEnable = false;
        firstSerialPort.RtsEnable = false;

        //Opening the ports
        Console.WriteLine("Attempting to open the ports!");
        firstSerialPort.Open();

        //Clearing the buffers
        firstSerialPort.DiscardOutBuffer();
        firstSerialPort.DiscardInBuffer();
        firstSerialPort.BaseStream.Flush();

        myContinue = true;
        readThread.Start();
        Console.WriteLine("First serial port is open: {0}", firstSerialPort.IsOpen);

        Console.WriteLine("Type QUIT to exit"+"\n");

        while (myContinue) {
            message = Console.ReadLine();
            if (message == "QUIT")
            {
                myContinue= false;
            }
            else
            {
                firstSerialPort.WriteLine(message + "\r");
            }
        }

        Console.WriteLine("\n"+ "Attempting to close the ports!");
        firstSerialPort.Close();

        Console.WriteLine("First serialPort is open: {0}", firstSerialPort.IsOpen);

        //Holding console open
        Console.WriteLine("Press any key to continue.");
        Console.ReadKey();
    }

    public static void Read()
    {
        while (myContinue) 
        {
            while (firstSerialPort.IsOpen)
            {
                Thread.Sleep(100); //This adds a delay. Commands will not work without this

                try
                {
                    //Reading back data 
                    string firstMessage = firstSerialPort.ReadLine();

                    Console.WriteLine("firstMessage: {0}", firstMessage);

                    Console.WriteLine();

                }
                catch (System.IO.IOException error)
                {
                    return;
                }
                catch (System.InvalidOperationException error)
                {
                    return;
                }
            }
        }
    }

标签: c#serial-portputtyvirtual-serial-port

解决方案


我编写了一些终端程序,类似于 putty 和超级终端。为了详细说明我的评论,这里有一些代码可以提供帮助:

我的论坛有一个 Keypress 事件,在该事件中,我将按下任何键并将其写入串行端口。请注意,这只是一个简单的示例,但应该让您朝着正确的方向前进:

public const int WM_VSCROLL = 0x0115;
public const int SB_BOTTOM = 7;

[DllImportAttribute("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);

private void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
    try
    {
        //scroll terminal to latest char
        richTextBoxConsole.SelectionStart = richTextBoxConsole.Text.Length;
        SendMessage(richTextBoxConsole.Handle, WM_VSCROLL, SB_BOTTOM, 0);

        //Send character to port
        serialPort1.Write(e.KeyChar.ToString());
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

这是我收到的数据事件:

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

    //DataReceived event is on it's own thread, need to invoke to update the UI
    this.Invoke((MethodInvoker)delegate
    {
        foreach (char c in data)
        {
            richTextBoxConsole.AppendText(c + "");

            if (c == '\b')
            {
                //backspace, erase a char
                richTextBoxConsole.Text = richTextBoxConsole.Text.Substring(0, richTextBoxConsole.Text.Length - 2);
            }
        }

        richTextBoxConsole.SelectionStart = richTextBoxConsole.Text.Length;
        SendMessage(richTextBoxConsole.Handle, WM_VSCROLL, SB_BOTTOM, 0);
    });
}

推荐阅读