从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对象没有定义)。
您的连接设置看起来与文档相匹配,但您的代码闻起来有点难闻(这对您没有什么不利之处,使用.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适配器解决的。