`
liuxi1024
  • 浏览: 391010 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

java串口编程-读取称重仪表中净重

 
阅读更多

一、需求说明

        将仪表和计算机串口相连,计算机通过软件向仪表发送指令,然后仪表返回结果,在计算机软件界面上显示。

 

二、实现过程

1、查看仪表说明书

        仪表型号为XK3190-A9,主要是查看相关参数(波特率、数据位、停止位、奇偶校验),通讯方式及指令规则。

 

2、使用串口通讯工具、串口监听工具进行调试

        网上可以下到很多相关软件,主要是方便测试。串口通讯工具、串口监听工具(AccessPort)

 

3、将仪表“通讯方式”改成“指令模式”

        根据说明书,在仪表上输入:打印设置--->98--->输入--->....

 

4、java编码(重点)

(1)使用comm在java程序中管理本地端口,目前,常见的Java串口包有SUN在1998年发布的串口通信API:comm2.0.jar(Windows下)、comm3.0.jar(Linux/Solaris);IBM的串口通信API以及一个开源的实现。鉴于在Windows下SUN的API比较常用以及IBM的实现和SUN的在API层面都是一样的,那个开源的实现又不像两家大厂的产品那样让人放心,这里就只介绍SUN的串口通信API在Windows平台下的使用。

(2)附件中“javacomm20-win32.zip”



 

(3)解压该压缩包,从commapi\Readme.html开始读起

(4)Copy win32com.dll to your <JDK>\bin directory.
(5)Copy comm.jar、javax.comm.properties to your <APP>\lib directory.

(6)研究java.comm包中的相关类及功能



----javax.comm.CommPortIdentifier 这个类主要用于对串口进行管理和设置,是对串口进行访问控制的核心类。

 

----javax.comm.SerialPort 这个类用于描述一个RS-232串行通信端口的底层接口,它定义了串口通信所需的最小功能集。通过它,用户可以直接对串口进行读、写及设置工作。 

 

 

(7)开始编写自己的代码

 

##### 串口参数配置(配置到spring容器里) #####

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">

<beans>
	<bean class="self.phoenix.application.SerialParameters">
		<!-- 端口名称 -->
		<property name="portName"><value>COM1</value></property>
		<!-- 波特率 -->
		<property name="baudRate"><value>4800</value></property>
		<!-- 输入流控制 -->
		<property name="flowControlIn"><value>0</value></property>
		<!-- 输出流控制 -->
		<property name="flowControlOut"><value>0</value></property>
		<!-- 数据位 -->
		<property name="databits"><value>8</value></property>
		<!-- 停止位 -->
		<property name="stopbits"><value>1</value></property>
		<!-- 奇偶校验 -->
		<property name="parity"><value>0</value></property>
	</bean>
</beans>

 

#####用于处理注册驱动、打开端口、发送指令、关闭端口及释放资源#####

 

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.comm.CommDriver;
import javax.comm.CommPortIdentifier;
import javax.comm.NoSuchPortException;
import javax.comm.PortInUseException;
import javax.comm.SerialPort;
import javax.comm.UnsupportedCommOperationException;

import self.phoenix.application.SerialConnectionException;
import self.phoenix.application.SerialParameters;

public class SerialConnUtils {
	
	private OutputStream os= null;
    private InputStream is = null;
    private CommPortIdentifier portId = null;
	private SerialPort sPort = null;
	private SerialParameters parameters = null;
	private CommDriver commDriver = null;
	
	public SerialConnUtils(SerialParameters parameters) {
		this.parameters = parameters;
		if(commDriver == null){
			try {
				commDriver = (CommDriver) Class.forName("com.sun.comm.Win32Driver").newInstance();
				commDriver.initialize();
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}
		}
	}
	
	public void openConnection() throws SerialConnectionException {
		// Obtain a CommPortIdentifier object for the port you want to open.
		try {
		    portId = CommPortIdentifier.getPortIdentifier(parameters.getPortName());
		} catch (NoSuchPortException e) {
		    throw new SerialConnectionException(e.getMessage());
		}
		
		// Open the port represented by the CommPortIdentifier object. Give
		// the open call a relatively long timeout of 30 seconds to allow
		// a different application to reliquish the port if the user 
		// wants to.
		try {
		    sPort = (SerialPort)portId.open("SerialDemo", 30000);
		} catch (PortInUseException e) {
		    throw new SerialConnectionException(e.getMessage());
		}
		
		try {
		    setConnectionParameters();
		} catch (SerialConnectionException e) {	
		    sPort.close();
		    throw e;
		}
		
		// Set receive timeout to allow breaking out of polling loop during
		// input handling.
		/*try {
		    sPort.enableReceiveTimeout(30);
		} catch (UnsupportedCommOperationException e) {
		}*/
	}
	
	public void setConnectionParameters() throws SerialConnectionException {

		// Save state of parameters before trying a set.
		int oldBaudRate = sPort.getBaudRate();
		int oldDatabits = sPort.getDataBits();
		int oldStopbits = sPort.getStopBits();
		int oldParity = sPort.getParity();
		int oldFlowControl = sPort.getFlowControlMode();

		// Set connection parameters, if set fails return parameters object
		// to original state.
		try {
			sPort.setSerialPortParams(parameters.getBaudRate(),
					parameters.getDatabits(), parameters.getStopbits(),
					parameters.getParity());
		} catch (UnsupportedCommOperationException e) {
			parameters.setBaudRate(oldBaudRate);
			parameters.setDatabits(oldDatabits);
			parameters.setStopbits(oldStopbits);
			parameters.setParity(oldParity);
			throw new SerialConnectionException("Unsupported parameter");
		}

		// Set flow control.
		try {
			sPort.setFlowControlMode(parameters.getFlowControlIn()
					| parameters.getFlowControlOut());
		} catch (UnsupportedCommOperationException e) {
			throw new SerialConnectionException("Unsupported flow control");
		}
	}
	
	/**
	 * 向端口发送十六进制指令 02 41 44 30 35 03
	 * 返回:02 41 44 2B 30 30 30 35 36 36 31 31 41 03
	 * @return 净重
	 * @throws SerialConnectionException
	 */
	public double sendSerialCommand() throws SerialConnectionException {

		//十六进制指令
		byte[] baKeyword = new byte[6];
		baKeyword[0] = 0x02;
		baKeyword[1] = 0x41;
		baKeyword[2] = 0x44;
		baKeyword[3] = 0x30;
		baKeyword[4] = 0x35;
		baKeyword[5] = 0x03;
		
		//净重
		Double netWeight = 0.0;

		try {
			//向串口发送指令
			os = sPort.getOutputStream();
			os.write(baKeyword, 0, baKeyword.length);
			
			//用于从串口读数据,返回14字节的信息
    		byte[] readBuffer = new byte[14]; 
    		int numBytes = 0; 
    		is = sPort.getInputStream();
    		
    		numBytes = is.read(readBuffer);
    		
    		System.out.println(new String(readBuffer));
    		
    		//4~12为数据内容
    		String value = Hex2StringUtils.byte2HexStrByi(readBuffer,4,12);
			if (value != null && !value.trim().equals(""))
				netWeight = Double.valueOf(value) / 1000;
    		
		} catch (IOException e) {
			e.printStackTrace();
		}
		return netWeight;
	}

	public void closeConnection() {
		// Check to make sure sPort has reference to avoid a NPE.
		if (sPort != null) {
			try {
				// close the i/o streams.
				os.close();
				is.close();
			} catch (IOException e) {
				System.err.println(e);
			}

			// Close the port.
			sPort.close();
			
			//Release resources
			portId = null;
		}
	}
}

 

 ###### ACSII与16进制转换的Utils类 #####

import java.io.ByteArrayOutputStream;
import java.io.IOException;

public class Hex2StringUtils {

	public static void main(String[] args) throws IOException {

	}

	/*
	 * 16进制数字字符集
	 */
	private static String hexString = "0123456789ABCDEF";

	/*
	 * 将字符串编码成16进制数字,适用于所有字符(包括中文)
	 */
	public static String encode(String str) {
		// 根据默认编码获取字节数组
		byte[] bytes = str.getBytes();
		StringBuilder sb = new StringBuilder(bytes.length * 2);
		// 将字节数组中每个字节拆解成2位16进制整数
		for (int i = 0; i < bytes.length; i++) {
			sb.append(hexString.charAt((bytes[i] & 0xf0) >> 4));
			sb.append(hexString.charAt((bytes[i] & 0x0f) >> 0));
		}
		return sb.toString();
	}

	/*
	 * 将16进制数字解码成字符串,适用于所有字符(包括中文)
	 */
	public static String decode(String bytes) {
		ByteArrayOutputStream baos = new ByteArrayOutputStream(
				bytes.length() / 2);
		// 将每2位16进制整数组装成一个字节
		for (int i = 0; i < bytes.length(); i += 2)
			baos.write((hexString.indexOf(bytes.charAt(i)) << 4 | hexString
					.indexOf(bytes.charAt(i + 1))));
		return new String(baos.toByteArray());
	}

	public static String byte2HexStr(byte[] b) {
		String hs = "";
		String stmp = "";
		for (int n = 0; n < b.length; n++) {
			stmp = (Integer.toHexString(b[n] & 0XFF));
			if (stmp.length() == 1)
				hs = hs + "0" + stmp;
			else
				hs = hs + stmp;
			// if (n<b.length-1) hs=hs+":";
		}
		return hs.toUpperCase();
	}

	public static String byteHexStr(byte b) {
		String hs = "";
		String stmp = "";
		// /for (int n = 0; n < b.length; n++) {
		stmp = (Integer.toHexString(b & 0XFF));
		if (stmp.length() == 1)
			hs = "0" + stmp;
		else
			hs = stmp;
		// if (n<b.length-1) hs=hs+":";
		// }
		return hs.toUpperCase();
	}

	public static String byte2HexStrByi(byte[] b, int start, int end) {
		String hs = "";
		String stmp = "";
		for (int n = start; n < end; n++) {
			stmp = (Integer.toHexString(b[n] & 0XFF));
			if (stmp.length() == 1)
				hs = hs + decode("0" + stmp);
			else
				hs = hs + decode(stmp);
			// if (n<b.length-1) hs=hs+":";
		}
		return hs.toUpperCase();
	}
}

 

##### 调用函数,取得净重值 #####

public double getSerialPortNetWeight() {
		double netWeight = 0;
		SerialConnUtils serialConnUtils = null;
		try {
			//调用串口通讯工具类
			serialConnUtils = new SerialConnUtils(parameters);
			//打开连接
			serialConnUtils.openConnection();
			//发送指令,并取得返回值
			netWeight = serialConnUtils.sendSerialCommand();
		} catch (Exception ex) {
			ex.printStackTrace();
		} finally {
			//释放资源
			serialConnUtils.closeConnection();
		}
		return netWeight;
	}

 

 

5、在串口监听工具配合下进行软件调试

 

129     [00000000]  IRP_MJ_CREATE                   Port Opened - javaw.exe
130     [00000000]  IOCTL_SERIAL_SET_BAUD_RATE      Baud Rate: 4800
131     [00000000]  IOCTL_SERIAL_SET_LINE_CONTROL   StopBits: 1, Parity: No, DataBits: 8
132     [00000000]  IOCTL_SERIAL_SET_BAUD_RATE      Baud Rate: 9600
133     [00000000]  IOCTL_SERIAL_SET_LINE_CONTROL   StopBits: 1, Parity: No, DataBits: 8
134     [00000000]  IOCTL_SERIAL_SET_BAUD_RATE      Baud Rate: 9600
135     [00000000]  IOCTL_SERIAL_SET_LINE_CONTROL   StopBits: 1, Parity: No, DataBits: 8
136     [00000000]  IOCTL_SERIAL_SET_BAUD_RATE      Baud Rate: 4800
137     [00000000]  IOCTL_SERIAL_SET_LINE_CONTROL   StopBits: 1, Parity: No, DataBits: 8
138     [00000000]  IOCTL_SERIAL_SET_BAUD_RATE      Baud Rate: 4800
139     [00000000]  IOCTL_SERIAL_SET_LINE_CONTROL   StopBits: 1, Parity: No, DataBits: 8
140     [00000000]  IOCTL_SERIAL_SET_BAUD_RATE      Baud Rate: 4800
141     [00000000]  IOCTL_SERIAL_SET_LINE_CONTROL   StopBits: 1, Parity: No, DataBits: 8
142     [00000000]  IRP_MJ_WRITE                    Length: 0006, Data: 02 41 44 30 35 03 
143     [00000013]  IRP_MJ_READ                     Length: 0014, Data: 02 41 44 2B 30 30 30 35 36 36 31 31 41 03 
144     [00001356]  IRP_MJ_CLOSE                    Port Closed
145     [00000000]  IRP_MJ_CREATE                   Port Opened - javaw.exe
146     [00000000]  IOCTL_SERIAL_SET_BAUD_RATE      Baud Rate: 4800
147     [00000000]  IOCTL_SERIAL_SET_LINE_CONTROL   StopBits: 1, Parity: No, DataBits: 8
148     [00000000]  IOCTL_SERIAL_SET_BAUD_RATE      Baud Rate: 9600
149     [00000000]  IOCTL_SERIAL_SET_LINE_CONTROL   StopBits: 1, Parity: No, DataBits: 8
150     [00000000]  IOCTL_SERIAL_SET_BAUD_RATE      Baud Rate: 9600
151     [00000000]  IOCTL_SERIAL_SET_LINE_CONTROL   StopBits: 1, Parity: No, DataBits: 8
152     [00000000]  IOCTL_SERIAL_SET_BAUD_RATE      Baud Rate: 4800
153     [00000000]  IOCTL_SERIAL_SET_LINE_CONTROL   StopBits: 1, Parity: No, DataBits: 8
154     [00000000]  IOCTL_SERIAL_SET_BAUD_RATE      Baud Rate: 4800
155     [00000000]  IOCTL_SERIAL_SET_LINE_CONTROL   StopBits: 1, Parity: No, DataBits: 8
156     [00000000]  IOCTL_SERIAL_SET_BAUD_RATE      Baud Rate: 4800
157     [00000000]  IOCTL_SERIAL_SET_LINE_CONTROL   StopBits: 1, Parity: No, DataBits: 8
158     [00000000]  IRP_MJ_WRITE                    Length: 0006, Data: 02 41 44 30 35 03 
159     [00000013]  IRP_MJ_READ                     Length: 0014, Data: 02 41 44 2B 30 30 30 36 39 36 31 31 36 03 
160     [00000349]  IRP_MJ_CLOSE                    Port Closed

 

Length:0006,      Data:02 41 44 30 35 03    为发送的十六进制指令

Length:0014,      Data:02 41 44 2B 30 30 30 36 39 36 31 31 36 03 为返回的十六进制内容

 

三、总结:调试过程中,串口监听工具起着很重要的作用。

  • 大小: 33.8 KB
  • 大小: 13 KB
分享到:
评论
2 楼 谷熙亚 2013-04-10  
//十六进制指令 
        byte[] baKeyword = new byte[6]; 
        baKeyword[0] = 0x02; 
        baKeyword[1] = 0x41; 
        baKeyword[2] = 0x44; 
        baKeyword[3] = 0x30; 
        baKeyword[4] = 0x35; 
        baKeyword[5] = 0x03; 


为什么要向串口发这个流啊?
不是只从称重显示器读取它传过来的流就行了吗?刚开始学请指教啊!
1 楼 谷熙亚 2013-04-02  
求大神的项目源码,,,,727668704@qq.com

相关推荐

    S7-1200称重仪表数据读取

    总结来说,S7-1200 PLC通过Modbus RTU与XMT808-I智能显示控制仪进行通讯,实现称重仪表数据的读取,涵盖了PLC硬件配置、Modbus通信参数设定、编程逻辑及数据处理等多个环节。在实施过程中,需要充分理解各组件的功能...

    Android串口编程--开关灯Demo

    在串口编程中,我们通常会设置波特率、数据位、停止位和校验位。这些参数需要根据硬件设备的要求来设定,例如,常见的波特率有9600、115200等。在USB串口通信中,这些配置可能需要通过控制传输(Control Transfer)...

    s7-200 称重程序

    标题 "s7-200 称重程序" 指的是使用西门子S7-200系列PLC(可编程逻辑控制器)进行称重应用的编程实例。S7-200是西门子推出的一款小型、功能强大的PLC,常用于自动化设备和生产线控制系统中。在工业领域,称重程序是...

    java-串口-rxtx-2.2.zip

    总之,RXTX是Java编程中不可或缺的工具,特别是当涉及到硬件设备交互或者需要进行串口、并口通信时。这个"java-串口-rxtx-2.2.zip"压缩包为Windows 64位环境提供了必要的库文件,帮助开发者快速实现串行和并行通信...

    Java串口通信编程

    在 Java 串口通信编程中,需要部署 RXTX 类库。RXTX 的部署配置包括 Win7 64 系统、WinXP 系统和 Linux 系统等。例如,在 Win7 64 系统中,需要将 RXTXcomm.jar、rxtxSerial.dll 和 rxtxParallel.dll 文件添加到 ...

    java 读取串口数据(绝对可使用)

    Java 读取串口数据是Java编程中一个重要的部分,特别是在物联网(IoT)设备通信、嵌入式系统以及工业自动化等领域。RXTX库是一个流行的开源Java库,用于实现与串行端口(COM口)和并行端口的交互。在本教程中,我们将...

    Java串口编程 Java手机串口短信发送

    在Java中,我们可以使用javax.comm库来实现串口通信。这个库提供了SerialPort类,它包含了打开、配置和读写串口所需的方法。然而,需要注意的是,javax.comm库在Java 1.6后不再被官方维护,因此在较新的Java版本中...

    Java串口操作_java串口编程_

    在Java中实现串口通信,通常需要借助第三方库,如RXTX或JSSC(Java Simple Serial Connector)。本文将详细介绍Java如何进行串口操作,并探讨相关知识点。 一、Java串口编程基础 1. 串行通信:串行通信是一种数据...

    上海耀华称重3190-c8称重显示器 控制仪表技术手册

    ### 上海耀华称重3190-C8称重显示器 控制仪表技术手册解析 #### 第一章 概述 XK3190-C8称重指示器是一款高性能的数字称重显示器,适用于各种工业称重环境,如生产加工、仓储物流等领域。该设备集成了现代化的微...

    java串口编程起步

    本文将详细介绍一个简单的Java串口编程框架——`SerialBean`类,它提供了基本的串口操作功能,包括串口的初始化、读取、写入以及关闭等。 #### 二、SerialBean类介绍 `SerialBean`类是整个串口编程框架的核心,用于...

    FX1N与梅物勒-托利多称重仪表(XK3123)通信.rar

    通过理解并掌握以上知识点,你可以成功地实现FX1N PLC与梅特勒-托利多XK3123称重仪表的通信,从而在自动化系统中实时获取和利用重量数据。这个示例提供了学习和实践工业通信的一个实际应用场景,对于提升工业自动化...

    mac上的java串口编程包

    Java串口编程在Mac OS平台上是一项重要的技术,它允许开发者通过Java程序与硬件设备进行通信,比如Arduino控制器、传感器或其他支持串行接口的设备。在Mac上进行Java串口编程时,开发者通常会借助第三方库或者Java的...

    VB读取地磅称重仪表

    在VB(Visual Basic)编程环境中,读取地磅称重仪表的数据是一项常见的任务,尤其在自动化控制和数据记录系统中。地磅称重仪表通常通过串行通信接口(如RS-232)与计算机进行连接,以传输实时的重量信息。本教程将...

    cors-filter-1.7.jar 和 java-property-utils-1.9.jar

    而`java-property-utils-1.9.jar` 提供了一些用于处理Java属性文件的工具类,这些工具在配置CORS过滤器时可能会用到,例如读取配置文件中的CORS策略。 在配置CORS过滤器时,首先需要将这两个库添加到项目的类路径中...

    串口编程,java串口编程,Shell源码.zip

    在Java中,`javax.comm`库提供了串口编程的支持。然而,这个库已经不再维护,因此现代的Java开发者通常使用第三方库如RXTX或jSerialComm。这些库提供了方便的API来打开、配置和读写串口。 - **RXTX库**:RXTX是...

    java读取电子称重量数据完整版rxtx包

    在Java编程环境中,读取电子称重量数据通常涉及到串行通信技术,这在工业自动化、物流管理、零售业等领域有着广泛应用。"java读取电子称重量数据完整版rxtx包"是一个专为此目的设计的解决方案,它使用了RXTX库,这是...

    java串口编程串口驱动

    在Java中,我们通常使用第三方库如RXTX或JSSC来处理串口操作,因为Java标准库并不直接支持串口通信。 1. **Java串口API**:Java并没有内置的串口API,因此开发者通常依赖于第三方库。RXTX和JSSC是两个流行的库,...

    Java解决UTF-8的BOM问题

    首先,`UnicodeInputStream`和`UnicodeReader`是Java中用于处理Unicode编码流的类。它们是`java.io`包的一部分,提供了对带有BOM的文件进行读取的功能。`UnicodeInputStream`是一个过滤输入流,它的主要任务是检测并...

    地磅称重管理的软件(vb源代码),有仪表通信串口和地磅连接读取重量的示例

    这款基于VB(Visual Basic)编写的地磅称重管理软件提供了一个直观的用户界面,结合了仪表通信串口技术,能够有效地与地磅设备进行数据交互,从而实现对重量的实时读取和管理。 VB是一种面向对象的编程语言,由微软...

Global site tag (gtag.js) - Google Analytics