从c#中的串行端口设备读取数据

本文关键字:读取 数据 串行端口 | 更新日期: 2023-09-27 18:26:13

我们需要称量一堆产品,并将它们的重量存储在数据库中
我们有一个可以通过串行端口插入的磅秤,然后我们想用条形码扫描仪扫描产品的条形码。

我需要写一个程序来读取刻度数据。我读了很多关于如何做到这一点的文章,但我似乎无法做到。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
namespace Weighting
{
    public partial class Form1 : Form
    {
        SerialPort port = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
        public Form1()
        {
            this.InitializeComponent();
            this.port.Open();
            this.port.Encoding = Encoding.ASCII;
            this.port.Handshake = Handshake.None;
            this.port.RtsEnable = true;
            this.port.ReceivedBytesThreshold = 1;
            this.port.DataReceived += new SerialDataReceivedEventHandler(this.port_DataReceived);
        }
        ~Form1()
        {
            this.port.Close();
            this.port.Dispose();
        }
        private void button2_Click(object sender, EventArgs e)
        {
            try
            {
                char[] data = new char[] { 's', ' ', ''r', ''n' };
                this.port.Write(data, 0, 1);
                Thread.Sleep(500);
                var InputData = this.port.ReadLine();
                if (!string.IsNullOrEmpty(InputData))
                {
                    MessageBox.Show(InputData);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
        void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            var InputData = this.port.ReadLine();
            this.BeginInvoke(new Action(() =>
                {
                    MessageBox.Show(InputData);
                }));
        }
    }
}

DataReceived处理程序从不被激发,ReadLine()从不返回任何内容。

天平的规格可以在这里找到(第10章):http://www.kern-sohn.com/manuals/files/English/FCB-BA-e-0911.pdf

请注意,很可能是我的串行端口或电缆不工作,或者天平不发送数据,或者其他什么(我使用串行端口设备已经有15年了)。你怎么能测试一切正常?

谢谢!

更新

连接参数取自(并解释)旧Excel宏:

With MSComm1
    .CommPort = 1
    .Handshaking = 0
    .RThreshold = 1
    .RTSEnable = True
    .Settings = "9600,n,8,1"
    .SThreshold = 1
    .PortOpen = True
End With

这个宏应该在几年前就可以工作了,但我自己无法使它工作(MSComm1对象没有定义)。

从c#中的串行端口设备读取数据

您的连接设置看起来与文档相匹配,但您的代码闻起来有点难闻(这对您没有什么不利之处,使用.NET SerialPort简直是噩梦!)。

您没有将SerialPort.NewLine属性设置为Environment.NewLine(CRLF),而是使用默认值'n(LF)。这本身并不能解决问题,因为您只需要在调用ReadLine()的结果末尾返回一个回车。

真正的问题是DataReceived处理程序。很多人建议使用它,但通过我详尽的测试,它大大降低了结果的确定性,尤其是在使用ASCII等友好编码进行通信时。因为您通过发送s字符来启动命令,所以我会诚实地去掉它,只在Write之后立即调用ReadLine()。(您不需要Thread.Sleep,因为ReadLine只会阻塞,直到读入终止的字符串或达到超时为止)。

您的ReceivedBytesThreshold设置为1,它指定了在提升DataReceived之前要填充的缓冲区大小,因此您试图为接收到的每个字节读取一整行(不管怎样,DataReceived都是不可预测的)。

下面是一个如何清理它的示例(除了删除DataReceived处理程序之外)。我不能确定这是否会解决你的问题,但进行这些更正会使调试更容易。作为一个有助于调试的临时更改,您可以重新调用Sleep调用,调用ReadExisting而不是ReadLine,并检查它从缓冲区中提取的内容(如果有的话)。

private void button2_Click(object sender, EventArgs e)
{
    try
    {
        this.port.Write("s");
        var InputData = this.port.ReadLine();
        if (!string.IsNullOrEmpty(InputData))
        {
            MessageBox.Show(InputData);
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.ToString());
    }
} 

我刚刚为我的公司编写了一个位于.NET串行端口顶部的库,遇到了与您相同的问题(加上一百万)。如果您想进一步澄清,请随时询问。

正如@user3894601所指出的,问题是通过使用原始电缆和USB适配器解决的。