首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >RS-232不稳定的行为

RS-232不稳定的行为
EN

Stack Overflow用户
提问于 2020-02-24 05:30:55
回答 1查看 58关注 0票数 0

Windows 10-64。去年秋天,我编写了一个小型VB应用程序,用于从RS-232端口驱动"PR-705“串行设备。它运行得天衣无缝。现在,每当我启动该代码时,PR-705的响应都不是很好?我最初使用的是基于FTDI的USB转RS232适配器(Thunderlinx1000),它工作得很好。我想,问题可能和“司机”有关?因此,我添加了一个PCI-Express串行端口卡从StarTech到我的PC。结果:没有改进-同样的反复无常的行为?出于好奇,今天早上,我启动了我值得信赖的Windows HyperTerminal,它工作得天衣无缝(从PCI-e端口出来)!所以我知道问题不是来自设备本身(叹气!)而是在通信链中的某处。

我遇到的问题如下(希望你能检测到一个“模式”):

a)打开串行端口b)以ASCII字符串(例如,"M1") <-设备返回数据以从设备获取所有数据,但是,我必须发送额外的命令: c) "D2“d) "D3”e) "D4“f) "D5”

当我从HyperTerminal运行这些命令时,我得到了出色的行为。

然而,在我的应用程序中,额外的命令("D2“、"D3”、"D4“和"D5")不知何故无法到达设备?例如,当我发送"D2“时,我得到的是"XYZ”数据,这是正常的。但是当我继续使用"D3“时,我仍然得到相同的"XYZ”数据吗?这就好像新命令("D3")从未到达设备?

我的(丑陋的)解决方法是重新发送相同的命令,然后我得到新的数据(大多数时候)。

下面是我的一些代码:

代码语言:javascript
复制
Dim myPort As New IO.Ports.SerialPort("COM2") With {
            .BaudRate = 9600,
            .DataBits = 8,
            .StopBits = IO.Ports.StopBits.One,
            .Parity = IO.Ports.Parity.None,
            .Handshake = IO.Ports.Handshake.RequestToSend,
            .RtsEnable = True,
            .DtrEnable = True,
            .ReadTimeout = 1000000,
            .WriteTimeout = 10000
            }


myPort.Open()
myPort.WriteLine("M1")
myPort.WriteLine("D2")
Incoming = myPort.ReadLine() 

myPort.WriteLine("D2")
Incoming = myPort.ReadLine()

myPort.WriteLine("D3")
Incoming = myPort.ReadLine() 

myPort.WriteLine("D4")
Incoming = myPort.ReadLine() 

myPort.WriteLine("D5")
Incoming = myPort.ReadLine()

我知道TimeOut的值是“极端的”,但设备可能需要15分钟才能回复,这取决于具体情况。我不能在设备响应之前关闭端口,否则我会收到一个错误,这与CTS有关,然后设备会自动重新启动--这不是很理想。我不是RS-232专家,但我用我的一点知识尽我所能做到最好。

EN

回答 1

Stack Overflow用户

发布于 2020-02-25 22:57:52

我找到了我的串口问题的部分答案,但这个解决方案并非没有它自己的问题。我发现了一些我改编的c#代码,其中串行端口“接收”被分成了自己的“事件”。这个很好用。正如您将在下面的代码中看到的,它可以完成这项工作。但现在我面临的问题是,如何“连续”轮询端口以获取仪器返回的所有数据?

下面是c#代码:

代码语言:javascript
复制
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using System.Threading;

namespace WindowsApplication14
{  
    public partial class Form1 : Form
    {
        string Operation, MesureM1, MesureD2, MesureD3, MesureD4;
        SerialPort _serialPort;

        // delegate is used to write to a UI control from a non-UI thread
        private delegate void SetTextDeleg(string text);

        public Form1()
        {
            InitializeComponent();
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            try
            {
                if (!_serialPort.IsOpen)
                    _serialPort.Open();

                _serialPort.Write("PR705\r\n");
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error opening serial port :: " + ex.Message, "Error!");
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            _serialPort = new SerialPort("COM2", 9600, Parity.None, 8, StopBits.One);
            _serialPort.Handshake = Handshake.RequestToSend;
            _serialPort.RtsEnable = true;
            _serialPort.DtrEnable = true;
            _serialPort.DataReceived += new SerialDataReceivedEventHandler(sp_DataReceived);
            _serialPort.ReadTimeout = 500;
            _serialPort.WriteTimeout = 500;
            _serialPort.Open();

            _serialPort.Write("PR705\r\n");

        }

        private void btnM1_Click(object sender, EventArgs e)
        {
            Operation = "M1";
            _serialPort.Write("M1\r\n");    // 0000,111,3.896e+002,0.3371,0.3563
            Thread.Sleep(500);
        }

        private void btnD2_Click(object sender, EventArgs e)
        {
            Operation = "D2";
            _serialPort.Write("D2\r\n");   
            Thread.Sleep(500);
        }

        private void btnD3_Click(object sender, EventArgs e)
        {
            Operation = "D3";
            _serialPort.Write("D3\r\n");   
            Thread.Sleep(500);
        }

        private void btnD4_Click(object sender, EventArgs e)
        {
            Operation = "D4";
            _serialPort.Write("D4\r\n");
            Thread.Sleep(500);
        }

        void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            Thread.Sleep(500);
            string data = _serialPort.ReadLine();
            this.BeginInvoke(new SetTextDeleg(si_DataReceived), new object[] { data });
        }

        private void si_DataReceived(string data)
        {
            String Result = data.Trim();
            textBox1.Text = Result; 

            switch (Operation)
            {
                case "M1":
                    MesureM1= Result; // MesureBase = "0000,111,3.884e+002,0.3377,0.3570"
                    break;
                case "D2":
                    MesureD2 = Result;  // MesureD2 = "0000,111,3.674e+002,3.884e+002,3.322e+002"
                    break;
                case "D3":
                    MesureD3 = Result;  // MesureD3 = "0000,111,3.884e+002,0.2044,0.4862"
                    break;
                case "D4":
                    MesureD4 = Result;  //
                    break;
                default:                
                    break;
            }          
        }  
    }
}

在我的主窗体中,我有四个按钮和一个文本框。M1按钮用于进行测量(向仪器发送"M1“命令)。按钮D2、D3和D4用于从仪器中检索数据。

在我以前的VB应用程序中,我使用如下代码从仪器中连续检索数据:

代码语言:javascript
复制
myPort.WriteLine("M1")

myPort.WriteLine("D2")
Incoming = myPort.ReadLine()

myPort.WriteLine("D3")
Incoming = myPort.ReadLine()    

myPort.WriteLine("D4")
Incoming = myPort.ReadLine()

但是我不知道如何在c#中使用“分离”的方法来完成同样的事情?我尝试将读取操作集中在与M1按钮相同的"event“子按钮中,如下所示:

代码语言:javascript
复制
private void btnM1_Click(object sender, EventArgs e)
{
    Operation = "M1";
    _serialPort.Write("M1\r\n");    // 0000,111,3.896e+002,0.3371,0.3563
    Thread.Sleep(500);

    Operation = "D2";
    _serialPort.Write("D2\r\n");
    Thread.Sleep(500);

    Operation = "D3";
    _serialPort.Write("D3\r\n");
    Thread.Sleep(500);

    Operation = "D4";
    _serialPort.Write("D4\r\n");
    Thread.Sleep(500);
}

但它不工作,我只得到最后一个串口读取,D4。代码不会经过D2和D3。

你觉得我该怎么做呢?我还没有向你展示D5,…D5操作是最复杂的,因为我必须进行“两次读取”,一次是针对一段数据,然后是201次连续读取,以检索波长数据,如下所示:

代码语言:javascript
复制
myPort.WriteLine("D5")
Incoming = myPort.ReadLine() 

Temp = Split(Incoming, ",")
PeakWL = Convert.ToDouble(Temp(2))

For i = 1 To 201
   Incoming = myPort.ReadLine()  
   Temp = Split(Incoming, ",")
   nmValue(i) = CDbl(Temp(0))
   SpectralValue(i) = CDbl(Temp(1))
Next

我会试着自己解决我的问题,但我希望得到一些建议。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60367045

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档