Java实现串口通信的小样例


用Java实现串口通信(windows系统下),须要用到sun提供的串口包 javacomm20-win32.zip。当中要用到三个文件,配置例如以下:

1.comm.jar放置到 JAVA_HOME/jre/lib/ext;
2.win32com.dll放置到 JAVA_HOME/bin;
3.javax.comm.properties 两个地方都要放

    jre/lib(也就是在JAVA目录下的jre)

   JAVA_HOME/jre/lib

 

说一下我应用的环境。电子秤称重时,计算机通过串口给称重控制显示器发送一次命令“R”,控制显示器则发送一次重量数据给串口,计算机再读取将数据显示在网页上。这样就构成了一个实时称重系统。

读写串口的代码例如以下:

package com.chengzhong.tools;

import java.io.*;



import javax.comm.CommPortIdentifier;

import javax.comm.*;



/**

*

* This bean provides some basic functions to implement full duplex

* information exchange through the serial port.

*

*/



public class SerialBean

{



public static String PortName;

public static CommPortIdentifier portId;

public static SerialPort serialPort;

public static OutputStream out;

public static InputStream in;



//保存读数结果

public static String result="";

public static int openSignal=1;



/**

*

* Constructor

*

* @param PortID the ID of the serial to be used. 1 for COM1,

* 2 for COM2, etc.

*

*/



public SerialBean(int PortID)

{

  PortName = "COM" +PortID;



}



/**

*

* This function initialize the serial port for communication. It starts a

* thread which consistently monitors the serial port. Any signal captured

* from the serial port is stored into a buffer area.

*

*/



public int Initialize()

{



	openSignal=1;



	try

	{

		

	portId = CommPortIdentifier.getPortIdentifier(PortName);

	



	try

	{

	serialPort = (SerialPort)

	portId.open("Serial_Communication", 2000);

	

	} catch (PortInUseException e)

	{

		

		if(!SerialBean.portId.getCurrentOwner().equals("Serial_Communication"))

		{

			

			openSignal=2;  //该串口被其他程序占用

		}else if(SerialBean.portId.getCurrentOwner().equals("Serial_Communication")){

			

			openSignal=1;

			return  openSignal;

		}

		

	  return openSignal;

	}



	//Use InputStream in to read from the serial port, and OutputStream

	//out to write to the serial port.



	try

	{

	in = serialPort.getInputStream();

	out = serialPort.getOutputStream();



	} catch (IOException e)

	{

		

		  openSignal=3;   //输入输出流错误

		  return openSignal;



	}



	//Initialize the communication parameters to 9600, 8, 1, none.



	try

	{

	serialPort.setSerialPortParams(9600,

	SerialPort.DATABITS_8,

	SerialPort.STOPBITS_1,

	SerialPort.PARITY_NONE);

	} catch (UnsupportedCommOperationException e)

	{

		

		  openSignal=4;   //參数不对

		  return openSignal;

	}

	} catch (NoSuchPortException e)

	{

		 

		  portId=null;

		  openSignal=5;  //没有该串口

		 

		  return openSignal;

	}



	// when successfully open the serial port, create a new serial buffer,

	// then create a thread that consistently accepts incoming signals from

	// the serial port. Incoming signals are stored in the serial buffer.



	 

// return success information



return openSignal;

}







/**

*

* This function returns a string with a certain length from the incoming

* messages.

*

* @param Length The length of the string to be returned.

*

*/



public static void ReadPort()

{

	SerialBean.result="";

int c;

try {

	if(in!=null){

		while(in.available()>0)

		{

			c = in.read();

			Character d = new Character((char) c);

			SerialBean.result=SerialBean.result.concat(d.toString());

		}

	}

	

} catch (IOException e) {

	// TODO Auto-generated catch block

	e.printStackTrace();

}



}



/**

*

* This function sends a message through the serial port.

*

* @param Msg The string to be sent.

*

*/



public static void WritePort(String Msg)

{



try

{

	if(out!=null){

		for (int i = 0; i < Msg.length(); i++)

		     out.write(Msg.charAt(i));

	}

  

} catch (IOException e) {

	 

	return;

	

}

}



/**

*

* This function closes the serial port in use.

*

*/





public void ClosePort()

{

 

  serialPort.close();

}

}

这样通过 SerialBean.result 就可得到读数结果。

至于把数据放到网页上,就要用到Ajax了,这里用到了一个Ajax框架dwr, dwr类Put.java 例如以下:

package com.chengzhong.dwr;



import java.io.IOException;



import com.chengzhong.tools.Arith;

import com.chengzhong.tools.SerialBean;



public class Put {

	

	//2011.9.17

	public String write(){

		

		

		//发送指令R,仪器发送一次净重数据

		SerialBean.WritePort("R");

		//读取数据

		SerialBean.ReadPort();

		String temp=SerialBean.result.trim();   //我这里temp是形如 wn125.000kg 的数据

		if(!temp.equals("") && temp.length()==11)

		{

			 return (change(temp)).toString();

			

		}else{

			return "";

		}

		

		

	}

	

	//响应開始称重

	public String startWeight(String num){

		

		 int n=Integer.parseInt(num.trim());

		 SerialBean SB = new SerialBean(n);

		 SB.Initialize();

		 return SerialBean.openSignal+"";  //返回初始化信息

		

	}

	

//响应停止称重

	

	public void endWeight(){

		



		

		try {

			//关闭输入、输出流

			SerialBean.in.close();

			SerialBean.out.close();

		} catch (IOException e) {

			// TODO Auto-generated catch block

			e.printStackTrace();

		}

		

		if(SerialBean.serialPort!=null){

			SerialBean.serialPort.close();  //关闭串口

		}

		

		SerialBean.serialPort=null;

		SerialBean.portId=null;

		

		SerialBean.result="";

		

	}

	/**

           * 将形如 wn125.000kg 格式的重量转换为 125.000 (kg)(四舍五入,小数点后保留两位)

	 */

	 public  String change(String source){

		 Double result=0.0;

		 String s1=source.substring(2,9);

		 try{

			 result=Double.parseDouble(s1);

			 result=Arith.round(result,2);

		 }catch(Exception e){

			 e.printStackTrace();

			 return "";

		 }

		 

		 return result.toString();

	 }

	 



	 

}



 

注:Arith.java是一个java 的高精度计算文件。

package com.chengzhong.tools;

import java.math.BigDecimal;



/**

* 因为Java的简单类型不可以精确的对浮点数进行运算,这个工具类提供精

* 确的浮点数运算,包含加减乘除和四舍五入。

*/



public class Arith{

    //默认除法运算精度

    private static final int DEF_DIV_SCALE = 10;

    //这个类不能实例化

    private Arith(){

    }



    /**

     * 提供精确的加法运算。

     * @param v1 被加数

     * @param v2 加数

     * @return 两个參数的和

     */

    public static double add(double v1,double v2){

        BigDecimal b1 = new BigDecimal(Double.toString(v1));

        BigDecimal b2 = new BigDecimal(Double.toString(v2));

        return b1.add(b2).doubleValue();

    }

    /**

     * 提供精确的减法运算。

     * @param v1 被减数

     * @param v2 减数

     * @return 两个參数的差

     */

    public static double sub(double v1,double v2){

        BigDecimal b1 = new BigDecimal(Double.toString(v1));

        BigDecimal b2 = new BigDecimal(Double.toString(v2));

        return b1.subtract(b2).doubleValue();

    }

    /**

     * 提供精确的乘法运算。

     * @param v1 被乘数

     * @param v2 乘数

     * @return 两个參数的积

     */

    public static double mul(double v1,double v2){

        BigDecimal b1 = new BigDecimal(Double.toString(v1));

        BigDecimal b2 = new BigDecimal(Double.toString(v2));

        return b1.multiply(b2).doubleValue();

    }



    /**

     * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到

     * 小数点以后10位,以后的数字四舍五入。

     * @param v1 被除数

     * @param v2 除数

     * @return 两个參数的商

     */

    public static double div(double v1,double v2){

        return div(v1,v2,DEF_DIV_SCALE);

    }



    /**

     * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale參数指

     * 定精度,以后的数字四舍五入。

     * @param v1 被除数

     * @param v2 除数

     * @param scale 表示表示须要精确到小数点以后几位。

     * @return 两个參数的商

     */

    public static double div(double v1,double v2,int scale){

        if(scale<0){

            throw new IllegalArgumentException(

                "The scale must be a positive integer or zero");

        }

        BigDecimal b1 = new BigDecimal(Double.toString(v1));

        BigDecimal b2 = new BigDecimal(Double.toString(v2));

        return b1.divide(b2,scale,BigDecimal.ROUND_HALF_UP).doubleValue();

    }



    /**

     * 提供精确的小数位四舍五入处理。

     * @param v 须要四舍五入的数字

     * @param scale 小数点后保留几位

     * @return 四舍五入后的结果

     */

    public static double round(double v,int scale){



        if(scale<0){

            throw new IllegalArgumentException(

                "The scale must be a positive integer or zero");

        }

        BigDecimal b = new BigDecimal(Double.toString(v));

        BigDecimal one = new BigDecimal("1");

        return b.divide(one,scale,BigDecimal.ROUND_HALF_UP).doubleValue();

    }

}




 

 

网页页面上:

<script type="text/javascript" src="/ChengZhong/dwr/engine.js"></script>

<script type="text/javascript" src="/ChengZhong/dwr/util.js"></script> 

<script type='text/javascript' src='/ChengZhong/dwr/interface/ss.js' ></script>

<script type='text/javascript' >

 var ID;

     function begin(){

       ID=window.setInterval('get()',500); //每隔半秒自己主动调用 get(),取得毛重数据填入文本框中

     }

 function get()

     {       

        ss.write(readIt);    //调用dwr类 Put.java  中的write方法   

     }

     function readIt(Data){

     

       if(Data!=null && Data!="")

       {

           document.getElementById("mzBF").value=Data;

                }

       

     } 

</script>




 



dwr的使用就不说了

你可能感兴趣的:(java实现)