如何从串口获取多行结果 [英] How to get multi line result from serial port

查看:71
本文介绍了如何从串口获取多行结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 winform 项目并尝试向串行端口发送命令并从中接收数据.我期待多行响应,但使用以下代码我只得到响应的第一行.我不想使用 ReadExisting.

<代码>{SerialPort mySerialPort = new SerialPort("COM5");mySerialPort.BaudRate = 115200;mySerialPort.Parity = Parity.None;mySerialPort.StopBits = StopBits.One;mySerialPort.DataBits = 8;mySerialPort.Handshake = Handshake.None;mySerialPort.DtrEnable = true;mySerialPort.RtsEnable = true;mySerialPort.Open();var command = Command.Authentication.GetStringValue();mySerialPort.WriteLine(命令);mySerialPort.DataReceived += new SerialDataReceivedEventHandler(_serialPort_DataReceived);字符串 _response = mySerialPort.ReadLine();mySerialPort.Close();}

<小时>

void _serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e){SerialPort sp = (SerialPort)sender;sp.ReadLine();}

我的回复看起来像:

<块引用>

请求:成功请求:MAC_ADDR:000D6F111C5DB14C请求:FWINFO:构建 01要求:HWINFO:Gen3 R0c

我试过了:

<代码>{_serialPort = 新的 SerialPort(_currentSerialSettings.PortName = Home.PortName,_currentSerialSettings.BaudRate,_currentSerialSettings.Parity,_currentSerialSettings.DataBits,_currentSerialSettings.StopBits);_serialPort.Open();//发送命令_serialPort.WriteLine(Command.Get_Device_List.GetStringValue());线程 t = 新线程(读取线程);t.Start(_serialPort);}私有无效读取线程(对象上下文){SerialPort serialPort = 上下文为 SerialPort;而 (serialPort.IsOpen){string inData = serialPort.ReadLine();Debug.WriteLine(inData);}}

这里有两个问题:

  1. 我想在上层方法中获取数据,而不是在 ReadThread 中.

  2. 它没有给出最后的数据.

我错过了什么吗?

旁注:如果我多次使用 mySerialPort.ReadLine(); ,那么我能够捕获整个响应,但响应可能因命令而异.目前它在 ReadLine 上崩溃,而数据不存在

解决方案

试试下面的代码.使用异步读取并在处理命令之前等待行尾返回:

使用系统;使用 System.Collections.Generic;使用 System.ComponentModel;使用 System.Data;使用 System.Drawing;使用 System.Linq;使用 System.Text;使用 System.Windows.Forms;使用 System.IO.Ports;命名空间 WindowsFormsApplication1{公共部分类 Form1 :表单{公共 Form1(){初始化组件();}private void button1_Click(object sender, EventArgs e){SerialPort _serialPort = new SerialPort("COM5");_serialPort.BaudRate = 115200;_serialPort.Parity = Parity.None;_serialPort.StopBits = StopBits.One;_serialPort.DataBits = 8;_serialPort.Handshake = Handshake.None;_serialPort.DtrEnable = true;_serialPort.RtsEnable = true;_serialPort.DataReceived += (AsyncRead);_serialPort.Open();}字符串输入数据 = "";private void AsyncRead(对象发送者,SerialDataReceivedEventArgs e){SerialPort serialPort = 发送方为 SerialPort;string inData = serialPort.ReadExisting();输入数据 += 输入数据;int returnIndex = inputData.IndexOf('\n');如果(返回索引 >= 0){字符串命令 = inputData.Substring(0, returnIndex);//从输入数据中删除命令inputData = inputData.Substring(returnIndex + 1);//测试命令是否只是一个返回if (command.Length > 0){进程命令(命令);}}}private void ProcessCommand(string inputLine){}}}

<小时>

带有队列和计时器的代码

使用系统;使用 System.Collections.Generic;使用 System.ComponentModel;使用 System.Data;使用 System.Drawing;使用 System.Linq;使用 System.Text;使用 System.Windows.Forms;使用 System.IO.Ports;命名空间 WindowsFormsApplication8{公共部分类 Form1 :表单{静态列表<字符串>queue = new List();公共 Form1(){初始化组件();定时器 timer1 = new Timer();timer1.Tick += new EventHandler(timer1_Tick);timer1.Interval = 500;timer1.Start();}private void button1_Click(object sender, EventArgs e){SerialPort _serialPort = new SerialPort("COM5");_serialPort.BaudRate = 115200;_serialPort.Parity = Parity.None;_serialPort.StopBits = StopBits.One;_serialPort.DataBits = 8;_serialPort.Handshake = Handshake.None;_serialPort.DtrEnable = true;_serialPort.RtsEnable = true;_serialPort.DataReceived += (AsyncRead);_serialPort.Open();}字符串输入数据 = "";private void AsyncRead(对象发送者,SerialDataReceivedEventArgs e){SerialPort serialPort = 发送方为 SerialPort;string inData = serialPort.ReadExisting();输入数据 += 输入数据;int returnIndex = inputData.IndexOf('\n');如果(返回索引 >= 0){字符串命令 = inputData.Substring(0, returnIndex);//从输入数据中删除命令inputData = inputData.Substring(returnIndex + 1);//测试命令是否只是一个返回if (command.Length > 0){队列.添加(命令);}}}private void timer1_Tick(对象发送者,EventArgs e){if (queue.Count > 0){字符串命令=队列[0];queue.RemoveAt(0);}}}}

I'm working with winform project and trying to send a command to the serial port and receive data from it. I'm expecting a multi-line response, but using the following code I'm getting only the first line of the response. I don't want to use ReadExisting.

{
    SerialPort mySerialPort = new SerialPort("COM5");

    mySerialPort.BaudRate = 115200;
    mySerialPort.Parity = Parity.None;
    mySerialPort.StopBits = StopBits.One;
    mySerialPort.DataBits = 8;
    mySerialPort.Handshake = Handshake.None;
    mySerialPort.DtrEnable = true;
    mySerialPort.RtsEnable = true;

    mySerialPort.Open();

    var command = Command.Authentication.GetStringValue();
    mySerialPort.WriteLine(command);               

    mySerialPort.DataReceived += new SerialDataReceivedEventHandler(_serialPort_DataReceived);

    string _response = mySerialPort.ReadLine();

    mySerialPort.Close();
}       


void _serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    SerialPort sp = (SerialPort)sender;
    sp.ReadLine();
}

My response looks like:

REQ: SUCCESS
REQ: MAC_ADDR:000D6F111C5DB14C
REQ: FWINFO: Build 01
REQ: HWINFO: Gen3 R0c

I've tried:

{
    _serialPort = new SerialPort(
        _currentSerialSettings.PortName = Home.PortName,
        _currentSerialSettings.BaudRate,
        _currentSerialSettings.Parity,
        _currentSerialSettings.DataBits,
        _currentSerialSettings.StopBits);

    _serialPort.Open();

    //send command
    _serialPort.WriteLine(Command.Get_Device_List.GetStringValue());

    Thread t = new Thread(ReadThread);            
    t.Start(_serialPort);
}

private void ReadThread(object context)
{
    SerialPort serialPort = context as SerialPort;

    while (serialPort.IsOpen)
    {
        string inData = serialPort.ReadLine();
        Debug.WriteLine(inData);                
    }
}

Here are the two issues:

  1. I want to get data in upper method, not in ReadThread.

  2. It’s not giving the last data.

Am I missing something?

Side Note: If I use mySerialPort.ReadLine(); multiple times then i'm able to catch the whole response, but response may vary by command. And currently it's crashing on ReadLine while data is not present

解决方案

Try code below. Uses Asynchronous Read and waits for the return at end of line before processing a command :

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            SerialPort _serialPort = new SerialPort("COM5");

            _serialPort.BaudRate = 115200;
            _serialPort.Parity = Parity.None;
            _serialPort.StopBits = StopBits.One;
            _serialPort.DataBits = 8;
            _serialPort.Handshake = Handshake.None;
            _serialPort.DtrEnable = true;
            _serialPort.RtsEnable = true;

            _serialPort.DataReceived += (AsyncRead);
            _serialPort.Open();


        }
        string inputData = "";
        private void AsyncRead(object sender, SerialDataReceivedEventArgs e)
        {
            SerialPort serialPort = sender as SerialPort;
            string inData = serialPort.ReadExisting();
            inputData += inData;

            int returnIndex = inputData.IndexOf('\n');
            if(returnIndex >= 0)
            {
                string command = inputData.Substring(0, returnIndex);
                //remove command from inputData
                inputData = inputData.Substring(returnIndex + 1);

                //test if command is just a return
                if (command.Length > 0)
                {
                    ProcessCommand(command);
                }
            }
        }
        private void ProcessCommand(string inputLine)
        {
        }

    }
}


Code with queue and timer

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;

namespace WindowsFormsApplication8
{
    public partial class Form1 : Form
    {
        static List<string> queue = new List<string>();
        public Form1()
        {
            InitializeComponent();
            Timer timer1 = new Timer();
            timer1.Tick += new EventHandler(timer1_Tick);
            timer1.Interval = 500;
            timer1.Start();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            SerialPort _serialPort = new SerialPort("COM5");

            _serialPort.BaudRate = 115200;
            _serialPort.Parity = Parity.None;
            _serialPort.StopBits = StopBits.One;
            _serialPort.DataBits = 8;
            _serialPort.Handshake = Handshake.None;
            _serialPort.DtrEnable = true;
            _serialPort.RtsEnable = true;

            _serialPort.DataReceived += (AsyncRead);
            _serialPort.Open();


        }
        string inputData = "";
        private void AsyncRead(object sender, SerialDataReceivedEventArgs e)
        {
            SerialPort serialPort = sender as SerialPort;
            string inData = serialPort.ReadExisting();
            inputData += inData;

            int returnIndex = inputData.IndexOf('\n');
            if (returnIndex >= 0)
            {
                string command = inputData.Substring(0, returnIndex);
                //remove command from inputData
                inputData = inputData.Substring(returnIndex + 1);

                //test if command is just a return
                if (command.Length > 0)
                {
                    queue.Add(command);
                }
            }
        }
        private void timer1_Tick(object sender, EventArgs e)
        {

            if (queue.Count > 0)
            {
                string command = queue[0];
                queue.RemoveAt(0);
            }
        }

    }
}

这篇关于如何从串口获取多行结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆