0

我最近从 Datalogic 购买了 3 个条形码阅读器(2 个 Magellan 3300HSi 和 1 个 Gryphon 4400)。制造商提供了一个我已安装的 USB 到 COM 驱动程序,并允许我使用 SerialPort 类与扫描仪通信。一旦我插入扫描仪(通过 USB),就会在设备管理器中添加一个 COM 端口,允许我在其上调用 Open() 方法。

我正在构建的应用程序的一部分是测试与扫描仪的通信是否正常。这是通过执行测试扫描来完成的。此扫描中使用的方法是:

1.打开扫描仪

public static SerialPort OpenPort(string comPortName)
{
    bool error;
    this.comport = new SerialPort();
    this.comport.BaudRate = 9600;
    this.comport.DataBits = 8;
    this.comport.StopBits = (StopBits)Enum.Parse(typeof(StopBits), "One");
    this.comport.Parity = (Parity)Enum.Parse(typeof(Parity), "None");
    this.comport.PortName = comPortName;

    try{
        this.comport.Open();
    }
    catch (UnauthorizedAccessException) { error = true; }
    catch (IOException) { error = true; }
    catch (ArgumentException) { error = true; }

    if (error)
    {
            return null;
    }

    return comport;

}

2.数据处理监听器

    public void PortDataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        SerialPort comport = sender as SerialPort;

        if (!comport.IsOpen) return;

        string data = comport.ReadExisting();

        MessageBox.Show("Data received " + data);
    }

3.附加数据处理程序

    this.comPort.DataReceived += new SerialDataReceivedEventHandler(PortDataReceived);

4. 编写关闭/分离方法

    public void CloseScanner()
    {
        if (this.comport.IsOpen)
        {
            this.comport.Close();
            this.comPort.DataReceived -= new SerialDataReceivedEventHandler(PortDataReceived);
        }

为了进行测试扫描,我单击一个按钮,调用 OpenPort,返回一个 SerialPort 对象。我附上数据处理程序。我执行扫描。显示扫描的数据。我关闭扫描仪。

这是问题所在:

如果我只做一次,这就像一种魅力。如果关闭串口后,我想用同一个端口进行另一次测试,端口成功打开,但没有接收到数据。扫描仪(设备)在第二次关闭时发出错误提示音。

奇怪的是,这只发生在我的 Magellan 扫描仪上。Gryphon 在随后的重新开放操作中就像一个魅力。

更奇怪的是,我使用 Putty 的串行模式连接到端口。当关闭 Putty 并再次打开它以进行新会话时,Magellan 扫描仪工作正常。

我的猜测是,这与串行端口在 .NET 中的关闭方式有关。也许资源没有被释放或其他东西。最初我认为这一定是扫描仪问题,需要我遵循某种协议来关闭连接。但是,Putty 似乎可以很好地使用它。(我猜 Putty 正在使用不同的类与扫描仪进行通信,甚至可能是 WIN32 API)。

如果有人知道这可能是什么原因,请告知。这可能是一些线程问题吗?我正在认真考虑查看 Putty 的源代码,看看他们如何解决这个问题或使用 WIN32 API(不过这对我来说会使事情变得过于复杂)。

TLTR: 关闭并重新打开 SerialPort,使我无法从条形码扫描仪接收数据。它仅在第一次打开端口时起作用。我正在使用制造商的 USB 到 COM 驱动程序。我究竟做错了什么?(上面的代码片段)

4

2 回答 2

1

如果您正在开发针对特定设备品牌的条形码阅读器应用程序,最好使用他们的 sdk/objects 而不是使用 .Net 通用 SerialPort 类。.Net 框架在那个领域并没有变得更好。它仍然有点缓慢和错误。

您可以查看 Jan Axelson 的网站,其中包含大量 .Net 和 Win32 中的示例。

于 2012-11-10T05:19:42.050 回答
1

这有点旧,但我认为其他人可以使用一些帮助。我目前正在处理 60 台计算机中的 1 台上的 Magellan 800i 问题并进行一些研究。您的代码有点模糊,使用“this”。在一个不会编译的静态函数中。我猜测您重新创建了额外的 SerialPort 对象并且从不释放原始对象并且您的 open 函数实际上并没有打开端口。您需要发布更多的项目。

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

namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    SerialPort comport = new SerialPort();

    public MainWindow()
    {
        InitializeComponent();
    }


    /// <summary>
    /// Buttonn on form that opens the assigned serial port
    /// Each barcode scanned will display a messagebox until you close the port.  
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void btnOpenScanner_Click(object sender, RoutedEventArgs e)
    {
        if (this.comport.IsOpen == false)
        {
            if (OpenPort("COM4"))
            {
                this.comport.DataReceived += new SerialDataReceivedEventHandler(PortDataReceived);
            }
        }
        else
        {
            MessageBox.Show("This comport is already assigned.  Quit clicking the open button you silly user.");
        }            
    }        

    /// <summary>
    /// Button on Form that closes the serial port
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void btnCloseScanner_Click(object sender, RoutedEventArgs e)
    {
        CloseScanner();
    }


    /// <summary>
    /// Opens the serial port
    /// </summary>
    /// <param name="comPortName"></param>
    public bool OpenPort(string comPortName)
    {
            this.comport = new SerialPort();
            this.comport.BaudRate = 9600;
            this.comport.DataBits = 8;
            this.comport.StopBits = StopBits.One;
            this.comport.Parity = Parity.None;
            this.comport.PortName = comPortName;            

            try
            {
                this.comport.Open();
                return true;
            }
            catch (Exception ex) {
                MessageBox.Show(ex.Message);
                return false;
            }               
    }

    /// <summary>
    ///  Event Handler to receive scanned data
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    public void PortDataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        SerialPort sendingport = (SerialPort)sender;

        if (!sendingport.IsOpen) return;

        string data = sendingport.ReadExisting();

        MessageBox.Show("Data received " + data);

    }

    /// <summary>
    /// Closes the serial port.
    /// </summary>
    public void CloseScanner()
    {
        if (this.comport.IsOpen)
        {
            this.comport.Close();
            this.comport.DataReceived -= new SerialDataReceivedEventHandler(PortDataReceived);                                
        }
    }       
}

}
于 2020-01-06T23:56:53.870 回答