论文部分内容阅读
[摘要]介绍在Java application中基于JACOB利用dll实现托利多8142电子秤与计算机数据通信的技术。
[关键词]dll 8142电子称 串口通信 Java
中图分类号: TP3文献标识码:A 文章编号:1671-7597(2008)0720014-01
在基于JAVA SWING 技术开发的过磅管理系统中,需要与串口通信,读取电子称的数据。Microsoft 的Mscomm是一个功能强大的串口通信控件,在VB中用它来开发串口通信程序是一个不错的选择。JAVA 的jni类库用于访问c/c++代码是比较方便的,但是用来访问VB开发的串口通信程序却很麻烦[1]。JACOB(JAVA-COM Bridge)是一个开源的基于jni技术开发的类库,用于JAVA代码与COM组件之间的通信。本文利用JACOB在JAVA SWING 中调用VB下开发的dll串口通信程序,实现对地磅数据的自动读取。
一、8142 系列电子秤串口数据格式与Mscomm通信控件
绿华糖厂使用的托利多电子秤型号是8142或是8142pro,这两种电子秤的串口发送数据方式都是设置为连续发送,而且数据格式都是一样的,如表1所示:
其中,状态字A、B、C分别表示小数点位置、分度倍乘、是否超载等信息,具体见电子称所附说明书。限于篇幅,不再一一给出。综上可知一帧数据共有18个字节,但实际传输中只用了17个字节,最后一个字节检查校验和,一般不使用。
计算机与串口通信程序的开发利用MSComm ActiveX控件是比较方便的[2]。它具有如下重要属性:CommPort属性:设置与返回通讯端口数;Settings属性:设置与返回波特率,奇偶校验位,字符串的停止位和数据位;PortOpen属性:设置与返回通讯端口的状态,并可开放、关闭端口;Input属性:返回和删除接收缓冲区的字符;Output属性:写字符串到发送缓冲区。
(一)数据包的提取
数据包的提取是利用OnComm事件来完成的。设置MSComm的Rthreshold属性为18,这样当接收缓冲区收到18个字节时,就会发生Mscomm事件。由于电子称工作于连续发送方式,即使收到18个字节仍不能保证是一个完整的数据帧。因此就必须对这18个字节做进一步的分析,以确认是否为有效数据。由表1的数据格式可知,正确的数据包的第一个字节为02H,第17个字节为0DH。这样,在Mscomm事件中就可以检测这两个位置的字节以判断是否为正确的数据帧。
(二)超载检测和负值检测
如果接受的数据超载(即接受的重量超过电子秤的量程范围)或者为负值,接受数据就没有意义了,所以必须对它进行检测。超载检测主要是判断数据包中的状态字B的‘2’位数据是否为‘1’,若为‘1’,则为超载;若为‘0’,则为正常,可以通过超载检测。负值检测主要是判断状态字B中的‘1’位数据是否为‘1’,若为‘1’,则为负值;若为‘0’,则为正常,可以通过检测。
(三)重量数据的析取
在托利多电子秤上所显示的重量数据在数据包中处于5 到10 位,有6 个字节,每个字节对应于电子秤所显示的一位数值。将每个字节转换为字符并连接为字符串,就可以作为重量数据返回给上层调用程序了。
二、电子称数据采集DLL控件的开发
通信程序的开发是在VB6.0环境下完成的。点击“文件”->“新建工程”,在弹出的新建工程对话框中选择ActiveX DLL控件选项,新建一个工程,取名为tuledo8142。并为该工程添加一个MSComm控件。源码主要包括两个函数与一个OnComm事件处理。其中getCheng函数供swing调用以设置通信格式并打开COM口[3]。其代码如下:
Public Function getCheng()
MSComm1.CommPort = 1
MSComm1.Settings = "9600,e,7,1"
MSComm1.RThreshold = 18
MSComm1.InputLen = 18
MSComm1.InBufferCount = 0
MSComm1.PortOpen = True
End Function
在OnComm事件中判斷数据帧是否有效,并负责析取重量数据,主要代码如下:
Private Sub MSComm1_OnComm()
Dim inbytes() As Byte
inbytes = MSComm1.Input
If inbytes(0) = 2 And inbytes(16) = 13 Then
value = Chr(inbytes(4)) & Chr(inbytes(5)) & Chr(inbytes(6)) & Chr(inbytes(7)) & Chr(inbytes(8)) & Chr(inbytes(9))
MSComm1.InBufferCount = 0
MSComm1.PortOpen = False
Exit Sub
End Sub
getValue函数仅供swing读出重量值:
Public Function getValue() As String
getValue = value
End Function
接着就需要将该通信程序封装为OCX控件。具体步骤为,点击“文件”->“生成tuledo8142.dll…” 。这样会生成tuledo8142.dll文件,可以供swing使用了。
三、在swing中使用数据采集dll控件
(一)JACOB的安装
在Eclipse3.2中,右键点击工程,打开configuration对话框,将jacob.jar文件加入到CLASSPATH中。
(二)在swing中的JAVA读磅值函数
public String readCheng(){
String result= "noData";
int count = 0;
//使用JACOB启动读称:
DispatchchengReader = new Dispatch("youjvcheng.Class1");
Dispatch.call(chengReader, "beginReadCheng");
//等待结果:
while(result.equals("noData") ){
result = Dispatch.call(chengReader, "getResult").toString();
if(count++ >10000)break;
}
Return result;
}
(三)使用多线程实时显示磅值
在实时显示数据的同时,为了不影响正常操作的进行,必须用多线称实现数据的显示[4]。以下是显示数据的线称类:
class dispChengThread implements Runnable
{
public void run()
{
Dispatch chengReader = new Dispatch("cheng4Thread.Class1");
while(isChengThreadRunned){
try{
Thread.sleep(400);
}catch(InterruptedException e)
{
System.out.println(" 读磅秤线程出现异常:\n");
e.printStackTrace();
}
String result= "noData";
int count = 0;
//启动读称:
Dispatch.call(chengReader, "beginReadCheng");
//等待结果:
while(result.equals("noData") ){
//每隔50ms读一次数据:
try{
Thread.sleep(50);
}catch(InterruptedException e)
{
System.out.println(" 讀磅秤线程出现异常:\n");
e.printStackTrace();
}
result = Dispatch.call(chengReader, "getResult").toString();
if(count++ >10)break;
}//end while
ValueChengLabel.setText( ( "第"+v++ +"次读磅:"+result));
valueCheng = result;
}//end while
//线程结束:
valueChengLabel.setText("");
chengReader = null;
}//end run()
}// end dispChengThread
四、应用情况
本文提出swing电子称数据采集方案已在籽棉收购系统中得到应用。数据读取快速准确,运行稳定,取的了满意的效果。
参考文献:
[1]雍俊海.Java 程序设计教程[M]. 清华大学出版社,2007.
[2]贺海辉,石林祥,魏淑桃. 基于MSComm和Windsock的智能管理系统的研究与设计[J] .微计算机信息,2006,22,(7):230-232.
[3]Jeffrey Richter. Windows 核心编程[M].机械工业出版社,2000.
[4]Karl Avedal,Danny Ayers. JAVA编程指南[M].电子工业出版社,2001.
[关键词]dll 8142电子称 串口通信 Java
中图分类号: TP3文献标识码:A 文章编号:1671-7597(2008)0720014-01
在基于JAVA SWING 技术开发的过磅管理系统中,需要与串口通信,读取电子称的数据。Microsoft 的Mscomm是一个功能强大的串口通信控件,在VB中用它来开发串口通信程序是一个不错的选择。JAVA 的jni类库用于访问c/c++代码是比较方便的,但是用来访问VB开发的串口通信程序却很麻烦[1]。JACOB(JAVA-COM Bridge)是一个开源的基于jni技术开发的类库,用于JAVA代码与COM组件之间的通信。本文利用JACOB在JAVA SWING 中调用VB下开发的dll串口通信程序,实现对地磅数据的自动读取。
一、8142 系列电子秤串口数据格式与Mscomm通信控件
绿华糖厂使用的托利多电子秤型号是8142或是8142pro,这两种电子秤的串口发送数据方式都是设置为连续发送,而且数据格式都是一样的,如表1所示:
其中,状态字A、B、C分别表示小数点位置、分度倍乘、是否超载等信息,具体见电子称所附说明书。限于篇幅,不再一一给出。综上可知一帧数据共有18个字节,但实际传输中只用了17个字节,最后一个字节检查校验和,一般不使用。
计算机与串口通信程序的开发利用MSComm ActiveX控件是比较方便的[2]。它具有如下重要属性:CommPort属性:设置与返回通讯端口数;Settings属性:设置与返回波特率,奇偶校验位,字符串的停止位和数据位;PortOpen属性:设置与返回通讯端口的状态,并可开放、关闭端口;Input属性:返回和删除接收缓冲区的字符;Output属性:写字符串到发送缓冲区。
(一)数据包的提取
数据包的提取是利用OnComm事件来完成的。设置MSComm的Rthreshold属性为18,这样当接收缓冲区收到18个字节时,就会发生Mscomm事件。由于电子称工作于连续发送方式,即使收到18个字节仍不能保证是一个完整的数据帧。因此就必须对这18个字节做进一步的分析,以确认是否为有效数据。由表1的数据格式可知,正确的数据包的第一个字节为02H,第17个字节为0DH。这样,在Mscomm事件中就可以检测这两个位置的字节以判断是否为正确的数据帧。
(二)超载检测和负值检测
如果接受的数据超载(即接受的重量超过电子秤的量程范围)或者为负值,接受数据就没有意义了,所以必须对它进行检测。超载检测主要是判断数据包中的状态字B的‘2’位数据是否为‘1’,若为‘1’,则为超载;若为‘0’,则为正常,可以通过超载检测。负值检测主要是判断状态字B中的‘1’位数据是否为‘1’,若为‘1’,则为负值;若为‘0’,则为正常,可以通过检测。
(三)重量数据的析取
在托利多电子秤上所显示的重量数据在数据包中处于5 到10 位,有6 个字节,每个字节对应于电子秤所显示的一位数值。将每个字节转换为字符并连接为字符串,就可以作为重量数据返回给上层调用程序了。
二、电子称数据采集DLL控件的开发
通信程序的开发是在VB6.0环境下完成的。点击“文件”->“新建工程”,在弹出的新建工程对话框中选择ActiveX DLL控件选项,新建一个工程,取名为tuledo8142。并为该工程添加一个MSComm控件。源码主要包括两个函数与一个OnComm事件处理。其中getCheng函数供swing调用以设置通信格式并打开COM口[3]。其代码如下:
Public Function getCheng()
MSComm1.CommPort = 1
MSComm1.Settings = "9600,e,7,1"
MSComm1.RThreshold = 18
MSComm1.InputLen = 18
MSComm1.InBufferCount = 0
MSComm1.PortOpen = True
End Function
在OnComm事件中判斷数据帧是否有效,并负责析取重量数据,主要代码如下:
Private Sub MSComm1_OnComm()
Dim inbytes() As Byte
inbytes = MSComm1.Input
If inbytes(0) = 2 And inbytes(16) = 13 Then
value = Chr(inbytes(4)) & Chr(inbytes(5)) & Chr(inbytes(6)) & Chr(inbytes(7)) & Chr(inbytes(8)) & Chr(inbytes(9))
MSComm1.InBufferCount = 0
MSComm1.PortOpen = False
Exit Sub
End Sub
getValue函数仅供swing读出重量值:
Public Function getValue() As String
getValue = value
End Function
接着就需要将该通信程序封装为OCX控件。具体步骤为,点击“文件”->“生成tuledo8142.dll…” 。这样会生成tuledo8142.dll文件,可以供swing使用了。
三、在swing中使用数据采集dll控件
(一)JACOB的安装
在Eclipse3.2中,右键点击工程,打开configuration对话框,将jacob.jar文件加入到CLASSPATH中。
(二)在swing中的JAVA读磅值函数
public String readCheng(){
String result= "noData";
int count = 0;
//使用JACOB启动读称:
DispatchchengReader = new Dispatch("youjvcheng.Class1");
Dispatch.call(chengReader, "beginReadCheng");
//等待结果:
while(result.equals("noData") ){
result = Dispatch.call(chengReader, "getResult").toString();
if(count++ >10000)break;
}
Return result;
}
(三)使用多线程实时显示磅值
在实时显示数据的同时,为了不影响正常操作的进行,必须用多线称实现数据的显示[4]。以下是显示数据的线称类:
class dispChengThread implements Runnable
{
public void run()
{
Dispatch chengReader = new Dispatch("cheng4Thread.Class1");
while(isChengThreadRunned){
try{
Thread.sleep(400);
}catch(InterruptedException e)
{
System.out.println(" 读磅秤线程出现异常:\n");
e.printStackTrace();
}
String result= "noData";
int count = 0;
//启动读称:
Dispatch.call(chengReader, "beginReadCheng");
//等待结果:
while(result.equals("noData") ){
//每隔50ms读一次数据:
try{
Thread.sleep(50);
}catch(InterruptedException e)
{
System.out.println(" 讀磅秤线程出现异常:\n");
e.printStackTrace();
}
result = Dispatch.call(chengReader, "getResult").toString();
if(count++ >10)break;
}//end while
ValueChengLabel.setText( ( "第"+v++ +"次读磅:"+result));
valueCheng = result;
}//end while
//线程结束:
valueChengLabel.setText("");
chengReader = null;
}//end run()
}// end dispChengThread
四、应用情况
本文提出swing电子称数据采集方案已在籽棉收购系统中得到应用。数据读取快速准确,运行稳定,取的了满意的效果。
参考文献:
[1]雍俊海.Java 程序设计教程[M]. 清华大学出版社,2007.
[2]贺海辉,石林祥,魏淑桃. 基于MSComm和Windsock的智能管理系统的研究与设计[J] .微计算机信息,2006,22,(7):230-232.
[3]Jeffrey Richter. Windows 核心编程[M].机械工业出版社,2000.
[4]Karl Avedal,Danny Ayers. JAVA编程指南[M].电子工业出版社,2001.