C# 读取richtextbox中的命令响应

C# 读取richtextbox中的命令响应,c#,serial-port,at-command,C#,Serial Port,At Command,我正在尝试向USB加密狗发送一串AT命令。我已经成功地写入了串口。但我没有成功地回过头来阅读。基本上,我想做的是将Let say AT发送到加密狗,然后在richtextbox中接收OK。接下来将从另一台设备向加密狗发送信息,并在richtextbox中读取 下面是我正在使用的代码: namespace WindowsFormsApplication5 { public partial class Form1 : Form { SerialPort sp = nu

我正在尝试向USB加密狗发送一串AT命令。我已经成功地写入了串口。但我没有成功地回过头来阅读。基本上,我想做的是将Let say AT发送到加密狗,然后在richtextbox中接收OK。接下来将从另一台设备向加密狗发送信息,并在richtextbox中读取

下面是我正在使用的代码:

namespace WindowsFormsApplication5
{
    public partial class Form1 : Form
    {
        SerialPort sp = null; //<---- serial port at form level

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

            // initialise port in form loadmyport.PortName = "COM3";
            sp = new SerialPort();
            sp.PortName = "COM8";
            sp.BaudRate = 115200;
            sp.Parity = Parity.None;
            sp.DataBits = 8;
            sp.StopBits = StopBits.One;
            sp.NewLine = System.Environment.NewLine;
            sp.ReadTimeout = 2000;
            sp.WriteTimeout = 2000;
            sp.DtrEnable = false;
            sp.RtsEnable = false;
            sp.WriteBufferSize = 4096;
            sp.ReadBufferSize = 4096;
            sp.Handshake = Handshake.None;
            sp.Encoding = System.Text.Encoding.ASCII;

            // also set up baud rate etc here.
            // attach event handler to capture data received 
            sp.DataReceived += new SerialDataReceivedEventHandler(sp_DataReceived);
        }

        private void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
        SerialPort sp = (SerialPort)sender;
        string indata = sp.ReadExisting();
        Console.WriteLine("Data Received:");
        Console.Write(indata);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            connect.Enabled = false;
            try
            {
                // open port if not already open
                // Note: exception occurs if Open when already open.
                if (!sp.IsOpen)
                {
                    sp.Open();
                }
                // send data to port
                sp.Write("ATXXX,XXXXXXX\r\n");
                disconnect.Enabled = true;
            }
            catch (Exception)
            {

               // report exception to user
                Console.WriteLine(e.ToString());
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            connect.Enabled = true;

            try
            {
                // open port if not already open
                // Note: exception occurs if Open when already open.
                if (!sp.IsOpen)
                {
                    sp.Open();
                }
                // send data to port
                sp.Write("atXX,0\r\n");
            }
            catch (Exception)
            {

                Console.WriteLine(e.ToString());
            }
            finally
            {
                disconnect.Enabled = false;
            }
        }


        public void OnApplicationExit(object sender, EventArgs e)
        {
            sp.Close();
        }
    }
}
命名空间窗口窗体应用程序5
{
公共部分类Form1:Form
{

SerialPort sp=null;//不要在主代码中直接从串行端口读取数据。您为接收到的数据事件准备了一个事件处理程序,它当前将响应写入调试控制台。您只需更改事件处理程序,改为将文本写入富文本框。(您用于读取数据并在文本框中显示数据的代码将永远不会显示任何内容,因为(a)port_DataReceived看起来从未订阅过任何事件,因此不会调用它,以及(b)您的sp_DataReceived事件处理程序正在读取数据并将其记录到调试输出,因此尝试读取端口的任何其他代码都会发现该端口为“空”)

请注意,sp_DataReceived事件将在另一个线程上引发,而不是在您的UI线程上引发,因此您需要调用或开始调用以将控件传递回UI线程,以便将文本添加到文本框中


还请注意,您可能不会以单个“数据包”的形式获得响应数据。它可能被分成几个部分,因此您需要将每个传入消息添加到文本框中文本的末尾,以便将收到的所有部分的整个响应缝合在一起。

不要在主代码中直接从串行端口读取数据。您已经为接收到的数据事件准备了一个事件处理程序,它当前会将响应写入调试控制台。您只需更改事件处理程序,将文本写入富文本框即可。(您用于读取数据并在文本框中显示数据的代码将永远不会显示任何内容,因为(a)port_DataReceived看起来从未订阅过任何事件,因此不会调用它,(b)您的sp_DataReceived事件处理程序正在读取数据并将其记录到调试输出,因此尝试读取端口的任何其他代码都会发现它为“空”)

请注意,sp_DataReceived事件将在另一个线程上引发,而不是在您的UI线程上引发,因此您需要调用或开始调用以将控件传递回UI线程,以便将文本添加到文本框中


还请注意,您可能无法将响应作为单个“数据包”获得。它可能被分割为多个部分,因此您需要将每个传入消息添加到文本框中的文本末尾,以便将您收到的所有部分的整个响应缝合在一起。

您有一个datareceived处理程序(sp_datareceived),为什么不使用它?让我更新我的帖子。我将它添加到数据接收处理程序私有void sp_DataReceived(object sender,SerialDataReceivedEventArgs e){SerialPort sp=(SerialPort)sender;string indata=sp.ReadExisting();Console.WriteLine(“数据接收:”);Console.Write(indata);仍然看不到任何内容。@HansPassant的可能副本感谢线程的帮助。您有一个datareceived处理程序(sp_datareceived),为什么不使用它?让我更新我的帖子。我将此添加到data received处理程序private void sp_datareceived中(对象发送方,SerialDataReceivedEventArgs e){SerialPort sp=(SerialPort)发送方;字符串indata=sp.ReadExisting();Console.WriteLine(“收到的数据:”);Console.Write(indata);仍然看不到任何内容。@HansPassant的可能副本感谢该线程非常有用。感谢jason。不幸的是,我是C#的新手。我可以给出如何执行调用和开始调用的要点。因为我认为接收到的数据事件没有被触发。查看示例-它非常接近您需要的内容。如果事件不是f如果你根本没有接收到数据-请参阅-你正在禁用DtrEnable和RtsEnable,这可能会停止设备对你的响应。在创建串行端口时,你应该只设置端口名、波特率、奇偶校验、数据位、停止位,并且通常将所有其他值保留为默认值,除非你知道需要更改它们。谢谢@jasonWilliams。在我将DtrEnable和RtsEnable设置为真并添加了一个委托方法之后,它就起作用了。我的第二个问题是,当我发送数据包时,它们以一些奇怪的字符形式出现在richtextbox中。我是否必须将其转换为字节或其他什么?您将收到二进制数据。如果它表示ASCII文本,则需要使用Encoding.ASCII Encoding.GetString()将字节数组正确转换为文本。如果它是非文本数据,则需要将其转换为十六进制转储或其他基于文本的格式,以使其在文本框中可读。Hi@jasonWilliams。感谢您之前的响应。请您向我展示一个我可以使用的十六进制转储示例的链接。我将接收十六进制的值。“如果是非文本数据,则需要将其转换为十六进制转储或其他基于文本的格式,以使其在文本框中可读"谢谢jason。不幸的是,我是C#的新手。我可以给出如何执行调用和开始调用的要点。因为我认为接收到的数据事件没有被触发。请查看示例-它非常接近您所需要的。如果事件根本没有触发,那么您就没有接收到数据-请参阅-您正在禁用DtrEnable和RtsEnable,这两个选项可能会停止设备回复您。创建串行端口时,您应该只设置端口名、波特率、奇偶校验、数据位、停止位,并且通常将所有其他值保留为默认值,除非您知道需要更改它们。谢谢@jasonWilliams。在我将DtrEnable和RtsEnable设置为true和