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

问题描述:

我们需要称量一堆产品,并将它们的重量存储在数据库中。
我们有一个可以通过串口插入的刻度,然后我们想用条形码扫描仪扫描产品的条形码。从c中的串口设备读取数据#

我需要编写一个程序来读取比例数据。我已经阅读并遵循了一堆关于如何去做的文章,但我似乎无法使它工作。

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对象未定义)。

+0

你可以连接类似超级终端的东西,并确定天平是否给你发送任何东西?它是否连续发送数据?或者你必须发送一个命令来请求数据?或者把它变成连续模式? – 2014-10-10 15:49:17

+0

我已经安装了超级终端,但我不知道如何使用它。从规格中,我收集到我必须发送“w”或“s”(“没有随后的CR LF”)并发送重量。超级终端没有任何帮助,但是我不知道我是否正确使用它。 – thomasb 2014-10-10 15:51:15

+0

如果你可以使用超级终端获得一些数据,那么它可能是设备,电缆或端口(可能是我猜测的USB /串行适配器)的问题。或者,也许连接参数是错误的(手册中的错误并非闻所未闻)。 – 2014-10-10 15:57:19

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

您的连接设置看起来与文档相匹配,但是您的代码有很多异味(这对您没有任何意义,.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的SerialPort的顶部为我公司,并已运行到同一类问题(加一百万以上),你。如果您想进一步澄清,请随时询问。

+0

谢谢!你的代码确实有效(并且更简单),尽管这不是问题。 – thomasb 2014-10-14 14:50:17