由于公司新展开一个业务,需要用到扫描仪,买来的是个USB口的,可是我们应用程序界面上是没有光标的,需要USB转 COM口后,再用程序来读串口的数据,买的这个扫描枪型号是Metrologic的 M S5415,随附的扫描仪设置手册里有个条码是:设置扫描仪USB模拟串口输出(需装驱动),扫一下就可以将扫描仪的USB 转换成COM口.用扫描仪扫一下这个条目后,我的电脑设备管理器出现一个其它设备,黄色的,然后更新驱动程序,找到官方网站下载的驱动后,确定,一会驱动安装完成,扫描仪出现一声响,此时在我的电脑,设备管理器的端口下的列表里出现了个COM3.这个COM3就是现在的扫描仪了。此时再通过程序监视COM3的数据。
通过.NET的SerialPort类可以实现该功能, 以下是我测试用的一个DEMO程序,根据《C# 与VB.NET 网络通信开发实战》完成的一个DEMO,该书的第二章有详细串口通信解释.
View Code
using
System;
using
System.Collections.Generic;
using
System.ComponentModel;
using
System.Data;
using
System.Drawing;
using
System.Linq;
using
System.Text;
using
System.Windows.Forms;
using
System.IO.Ports;
namespace
MetrologicClient
{
public
partial
class
Form2 : Form
{
private
System.IO.Ports.SerialPort serialPort
=
new
System.IO.Ports.SerialPort();
public
Form2()
{
InitializeComponent();
}
private
void
Form2_Load(
object
sender, EventArgs e)
{
serialPort.DataReceived
+=
new
System.IO.Ports.SerialDataReceivedEventHandler(DataReceived);
//
.SerialDataReceivedEventHandler(DataReceived);
string
[] portNames
=
System.IO.Ports.SerialPort.GetPortNames();
for
(
int
i
=
0
; i
<=
portNames.Length
-
1
; i
++
)
{
cbbCOMPorts.Items.Add(portNames[i]);
}
btnDisconnect.Enabled
=
false
;
}
private
void
btnConnect_Click(
object
sender, EventArgs e)
{
if
(serialPort.IsOpen)
{
serialPort.Close();
}
try
{
serialPort.PortName
=
cbbCOMPorts.Text;
serialPort.BaudRate
=
9600
;
serialPort.Parity
=
System.IO.Ports.Parity.None;
serialPort.DataBits
=
8
;
serialPort.StopBits
=
System.IO.Ports.StopBits.One;
serialPort.Open();
lblMessage.Text
=
cbbCOMPorts.Text
+
"
connected.
"
;
btnConnect.Enabled
=
false
;
btnDisconnect.Enabled
=
true
;
}
catch
(Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
private
void
btnDisconnect_Click(
object
sender, EventArgs e)
{
try
{
serialPort.Close();
lblMessage.Text
=
serialPort.PortName
+
"
disconnected.
"
;
btnConnect.Enabled
=
true
;
btnDisconnect.Enabled
=
false
;
}
catch
(Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
private
void
btnSend_Click(
object
sender, EventArgs e)
{
try
{
serialPort.Write(txtDataToSend.Text
+
Environment.NewLine);
txtDataReceived.AppendText(
"
>
"
+
txtDataToSend.Text
+
Environment.NewLine );
txtDataReceived.ScrollToCaret();
txtDataToSend.Text
=
string
.Empty;
}
catch
(Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
private
void
DataReceived(
object
sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
txtDataReceived.BeginInvoke(
new
myDelegate(updateTextBox));
}
public
delegate
void
myDelegate();
public
void
updateTextBox()
{
txtDataReceived.AppendText(serialPort.ReadExisting()
+
"
test
"
);
txtDataReceived.ScrollToCaret();
}
}
}
以上程序在扫描不足8位的条形码是没有问题,在像水、电的催款单上面条形码都要30多位数字,可是扫出来的条形码还是只有8位,后来在程序中停了一下线程就可以了。
如以下程序
View Code
public
delegate
void
myDelegate();
public
void
updateTextBox()
{
System.Threading.Thread.Sleep(
1000
);
txtDataReceived.AppendText(serialPort.ReadExisting()
+
"
test
"
);
txtDataReceived.ScrollToCaret();
}
以上只是解决扫描枪USB模拟COM口的技术问题,在放到实际应用中,问题不止这点,
我需要在WIN FORM程序中完成串口程序,接收到串口的数据以后,传到WIN FORM程序中的Browser控件里的网页程序,其中网页程序中有Javascript来接收,JS程序如下
View Code
function toNextPage(obj) {
var now_iframe
=
window.document.getElementById(
'
iframe1
'
);
now_iframe.contentWindow.location
=
"
Payment_gas.aspx?barcode=
"
+
obj;
//
return;
}
WIN FORM 中调用WEB程序中Javascript的程序如下
View Code
code4
mshtml.IHTMLDocument2 currentDoc
=
(mshtml.IHTMLDocument2) CurrendWB.Document.DomDocument;
mshtml.IHTMLWindow2 win
=
(mshtml.IHTMLWindow2) currentDoc.parentWindow;
win.execScript(
"
toNextPage(\"
"
+
unstring
+
"
\")
"
,
"
javascript
"
);
问题出在下面这一句
win.execScript("toNextPage(\""+ unstring +"\")", "javascript");
变量 unstring是扫描仪扫出来的值,默认情况,扫出来的字符是带回车符的 ,假如unstring是“20110224回车符”这样传进去,到执行Javascript的时候,Javascript程序就会变成如下这样的形式
function toNextPage(“
20110224
”)
这样是不符合Javascript语法的,会出现HRESULT:0x80020101 的语法错误.
如果把这一句话改成
win.execScript("toNextPage("+ unstring +")", "javascript");
在调用的时候,不是把扫描值当成字符,javascript在接收到全是数字的扫描结果就会直接把它当成科学计数法,如果unstring = 8801124811022218270060101700060007,javascript接收到以后直接变成int型的8.801124811022218e 33,失去了原有意义。这个问题的解决要感谢一下同事WuWei.
以下是开发过程中的一些参考资料
http://msdn.microsoft.com/zh-cn/library/system.io.ports.serialport(v=vs.80).aspx
http://book.51cto.com/art/200807/81872.htm
http://hi.baidu.com/qq305965235/blog/item/955116cd49f7531c01e928ad.html
其它参资料
串口:略
SerialPort类
DataReceived
事件
:从
SerialPort
对象接收数据时,将在辅助线程上引发
DataReceived
事件。由于此事件在辅助线程而非主线程上引发,因此尝试修改主线程中的一些元素(如
UI
元素)时会引发线程异常。如果有必要修改主
Form
或
Control
中的元素,请使用
Invoke
回发更改请求,这将在正确的线程上执行。