2014-11-21 104 views
0

我的控制台程序遇到了一些麻烦。我试图从条码扫描器的串行连接中检索数据。串口通讯问题C#

问题是: - 第一次阅读是完美的; - 第二次读取结​​果不正确,除非我等待大约一分钟。

下面是代码:

using System; 
using System.IO.Ports; 

class PortDataReceived 
{ 

    public static void Main() 
    { 
     SerialPort mySerialPort = new SerialPort("COM10"); 

     mySerialPort.BaudRate = 9600; 
     mySerialPort.Parity = Parity.None; 
     mySerialPort.StopBits = StopBits.One; 
     mySerialPort.DataBits = 8; 
     mySerialPort.Handshake = Handshake.RequestToSend; 

     mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler); 

     mySerialPort.Open(); 

     Console.WriteLine("Press any key to continue..."); 
     Console.WriteLine(); 
     Console.ReadKey(); 

     mySerialPort.Close(); 

    } 

    private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e) 
    { 
     SerialPort sp = (SerialPort)sender; 
     string indata = sp.ReadExisting(); 
     Console.WriteLine("Data Received:"); 
     Console.WriteLine(indata);     
    } 
} 

这里是2的结果,而不从第一等待足够的时间来第二次读取同一条码的读取:

Press any key to continue... 
Data Received: 
229000400718 
Data Received: 
2 
Data Received: 
2 
Data Received: 
9 
Data Received: 
0 
Data Received: 
0 
Data Received: 
0 
Data Received: 
4 
Data Received: 
0 
Data Received: 
0 
Data Received: 
7 
Data Received: 
1 
Data Received: 
8 

有什么建议?

提前致谢!

+0

你试过port.DtrEnable = true? – 2014-11-21 14:52:46

+0

看起来像您的条形码扫描器首次发送条形码号码,然后通过字符相同的条形码字符。您是否尝试过使用一些串口监视器来查看扫描仪实际发送的内容? – Reniuz 2014-11-21 14:52:47

+0

我已经试过port.DtrEnable = true,没有任何变化。 我也使用HyperTerminal进行监控,并且没有问题:我正确接收每个字符串。 – 2014-11-21 15:42:21

回答

0

您需要有结束字符才能知道您的消息何时完成。大多数人使用\r\n (13,10)并从串行端口读取到行尾(即\ r \ n)。

您正在为每个角色获得一个事件并快速阅读它。

+0

如何使用'\ r \ n'来读取消息?任何例子? – 2014-11-21 14:49:24

+2

通常该过程将是Serial.ReadLine()而不是Serial.ReadExisting()。然后,需要将条形码编码器配置为发送CRLF(其中大多数是以此方式默认配置的)。 – crushndent 2014-11-21 14:58:59

+0

我使用摩托罗拉DS457,它似乎没有CRLF字符。我试图使用serial.ReadLine(),但没有比较在我的外壳中,因为方法总是在等待。 – 2014-11-21 15:52:46

0

您需要某种计时器来检查正在读取的多个字符是否是单个读取的一部分,或者它们是否是两次不同的扫描。第二次扫描的事件触发之间的时间可能很短,只需在事件触发后设置一个计时器即可启动,如果在下一个事件之前到期,那么它就是条形码的末尾,如果没有将读取附加到前一个事件(使用某种缓冲区)。

0

看来,第二次读取的数据来自于焦炭的焦炭,所以我会使用StringBuilder B和附加输入数据,直到一个有效的条形码接收和(即检查对数据库的有效性)

保存在b

我建议是这样的:

private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e) 
{ 
    SerialPort sp = (SerialPort)sender; 
    StringBuilder b = new StringBuilder(); 

    while(!IsValidBarcode(b.ToString())) 
    { 
     b.Append(sp.ReadExisting()); 
    } 

    Console.WriteLine("Data Received:"); 
    Console.WriteLine(b.ToString()); 
} 

private static Boolean IsValidBarcode(String s) 
{ 
    if (String.IsNullOrEmpty(s)) return false; 

    // (1) Query a database for expected barcodes ... 
    // (2) Check s for Start-Stop-Characters ... 
    // (3) Query the device for completed barcode ... 

    throw new NotImplementedException(); 
} 

或本

private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e) 
{ 
    SerialPort sp = (SerialPort)sender; 
    StringBuilder b = new StringBuilder(); 

    Thread.Sleep(1000);  // 1 second delay for testing purposes 

    b.Append(sp.ReadExisting()); 

    Console.WriteLine("Data Received:"); 
    Console.WriteLine(b.ToString()); 
} 
+0

第二次读取的数据以随机数量进来。有时按char字符排列,有时会分成3-4个字符的块。 条码的长度并不总是相同,并且没有“新行”字符。 – 2014-11-21 15:49:46

+0

必须有一些信息来确定条码的结尾(停止字符,长度,...)否则,我建议参考条形码阅读器驱动程序的文档 – Benj 2014-11-21 16:30:00

+0

对不起,发送垃圾评论。也许第一次读取是完美的,因为这是第一次调用静态EventHandler,并且在从COM10实际读取数据之前存在一个轻微的延迟。你有没有检查过第三次或第四次扫描发生了什么?在实际读取sp.ReadExisting()读取数据之前,您是否尝试过插入Thread.Sleep(100)之类的轻微延迟? – Benj 2014-11-21 16:40:21

0

卢卡Pillin,我刚才已经包括了Thread.Sleep 3秒,它解决了问题

using System; 
using System.Threading; 
using System.IO.Ports; 

class PortDataReceived 
{ 

    public static void Main() 
    { 
     SerialPort mySerialPort = new SerialPort("COM2"); 

     mySerialPort.BaudRate = 9600; 
     mySerialPort.Parity = Parity.None; 
     mySerialPort.StopBits = StopBits.One; 
     mySerialPort.DataBits = 8; 
     mySerialPort.Handshake = Handshake.RequestToSend; 

     mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler); 

     mySerialPort.Open(); 

     Console.WriteLine("Press any key to continue..."); 
     Console.WriteLine(); 
     Console.ReadKey(); 

     mySerialPort.Close(); 

    } 

    private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e) 
    { 
    // 
     string indata = string.Empty; 
     SerialPort sp = (SerialPort)sender; 
     **Thread.Sleep(3000);** 
       indata = sp.ReadExisting(); 


     Console.WriteLine("Data Received:"); 
     Console.WriteLine(indata); 
    } 
}