串口数据异常,数据段获取到两段或者三段

<pre name="code" class="java">串口数据初始化了两次,出现了本来是一段数据的,却获取到几段被分割的数据>原因
</span>设置串口参数依次为(波特率,数据位,停止位,奇偶检验) 
//第二次初始化串口,所以问题出现了获取到了两段,三段,更多的数据段的问题

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Timestamp;
import java.util.Enumeration;
import java.util.TooManyListenersException;

import javax.comm.CommPortIdentifier;
import javax.comm.PortInUseException;
import javax.comm.SerialPort;
import javax.comm.SerialPortEvent;
import javax.comm.SerialPortEventListener;
import javax.comm.UnsupportedCommOperationException;

import Service.InsertService;

import vo.zuobiao;

public class DSerialPort implements Runnable, SerialPortEventListener {

	private String appName = "串口通讯测试[富士康比赛2016]";
	private int timeout = 2000;//open 端口时的等待时间
	private int threadTime = 0;
	
	private CommPortIdentifier commPort;
	private SerialPort serialPort;
	private InputStream inputStream;
	private OutputStream outputStream;
	private Integer ZId;
	private Integer ZX;
	private Integer ZY;
	InsertService I =new InsertService();


	public Integer getZId() {
		return ZId;
	}


	public void setZId(Integer zId) {
		ZId = zId;
	}


	public Integer getZX() {
		return ZX;
	}


	public void setZX(Integer zX) {
		ZX = zX;
	}


	public Integer getZY() {
		return ZY;
	}


	public void setZY(Integer zY) {
		ZY = zY;
	}


	/**
	 * @方法名称 :listPort
	 * @功能描述 :列出所有可用的串口
	 * @返回值类型 :void
	 */
	@SuppressWarnings("rawtypes")
	public void listPort(){
		CommPortIdentifier cpid;
		Enumeration en = CommPortIdentifier.getPortIdentifiers();
		
		System.out.println("now to list all Port of this PC:" +en);
		
		while(en.hasMoreElements()){
			cpid = (CommPortIdentifier)en.nextElement();
			if(cpid.getPortType() == CommPortIdentifier.PORT_SERIAL){
				System.out.println(cpid.getName() + ", " + cpid.getCurrentOwner());
			}
		}
	}
	
	
	/**
	 * @方法名称 :selectPort
	 * @功能描述 :选择一个端口,比如:COM1
	 * @返回值类型 :void
	 *	@param portName
	 */
	@SuppressWarnings("rawtypes")
	public void selectPort(String portName){
		
		this.commPort = null;
		CommPortIdentifier cpid;
		Enumeration en = CommPortIdentifier.getPortIdentifiers();
		
		while(en.hasMoreElements()){
			cpid = (CommPortIdentifier)en.nextElement();
			if(cpid.getPortType() == CommPortIdentifier.PORT_SERIAL
					&& cpid.getName().equals(portName)){
				this.commPort = cpid;
				break;
			}
		}
		
		openPort();
	}
	
	/**
	 * @方法名称 :openPort
	 * @功能描述 :打开SerialPort
	 * @返回值类型 :void
	 */
	private void openPort(){
		if(commPort == null)
			log(String.format("无法找到名字为'%1$s'的串口!", commPort.getName()));
		else{
			log("端口选择成功,当前端口:"+commPort.getName()+",现在实例化 SerialPort:");
			
			try{
				serialPort = (SerialPort)commPort.open(appName, timeout);
				serialPort.setSerialPortParams(9600,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);//  1这里我初始化的一次串口
				log("实例 SerialPort 成功!");
			}catch(PortInUseException e){
				throw new RuntimeException(String.format("端口'%1$s'正在使用中!", 
						commPort.getName()));
			} catch (UnsupportedCommOperationException e) {																								//			2
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * @方法名称 :checkPort
	 * @功能描述 :检查端口是否正确连接
	 * @返回值类型 :void
	 */
	private void checkPort(){
		if(commPort == null)
			throw new RuntimeException("没有选择端口,请使用 " +
					"selectPort(String portName) 方法选择端口");
		
		if(serialPort == null){
			throw new RuntimeException("SerialPort 对象无效!");
		}
	}
	
	/**
	 * @方法名称 :write
	 * @功能描述 :向端口发送数据,请在调用此方法前 先选择端口,并确定SerialPort正常打开!
	 * @返回值类型 :void
	 *	@param message
	 */
	public void write(String message) {
		checkPort();
		
		try{
			outputStream = new BufferedOutputStream(serialPort.getOutputStream());
		}catch(IOException e){
			throw new RuntimeException("获取端口的OutputStream出错:"+e.getMessage());
		}
		
		try{
			outputStream.write(message.getBytes());
			log("信息发送成功!");
		}catch(IOException e){
			throw new RuntimeException("向端口发送信息时出错:"+e.getMessage());
		}finally{
			try{
				outputStream.close();
			}catch(Exception e){
			}
		}
	}
	
	/**
	 * @方法名称 :startRead
	 * @功能描述 :开始监听从端口中接收的数据
	 * @返回值类型 :void
	 *	@param time  监听程序的存活时间,单位为秒,0 则是一直监听
	 * @throws UnsupportedCommOperationException 
	 */
	public void startRead(int time) throws UnsupportedCommOperationException{
		checkPort();
		
		try{
			inputStream = new BufferedInputStream(serialPort.getInputStream());
		}catch(IOException e){
			throw new RuntimeException("获取端口的InputStream出错:"+e.getMessage());
		}
		
		try{
//			//设置串口参数依次为(波特率,数据位,停止位,奇偶检验) 
//			serialPort.setSerialPortParams(9600,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);//第二次初始化串口,所以问题出现了获取到了两段,三段,更多的数据段的问题
			serialPort.addEventListener(this); 
		}catch(TooManyListenersException e){
			throw new RuntimeException(e.getMessage());
		}
		
		serialPort.notifyOnDataAvailable(true);
		
		log(String.format("开始监听来自'%1$s'的数据--------------", commPort.getName()));
		if(time > 0){
			this.threadTime = time*1000;
			Thread t = new Thread(this);
			t.start();
			log(String.format("监听程序将在%1$d秒后关闭。。。。", threadTime));
		}
	}
	
	
	/**
	 * @方法名称 :close
	 * @功能描述 :关闭 SerialPort
	 * @返回值类型 :void
	 */
	public void close(){
		serialPort.close();
		serialPort = null;
		commPort = null;
	}
	
	
	public void log(String msg){
		System.out.println(appName+" --> "+msg);
	}


	/**
	 * 数据接收的监听处理函数
	 */
	@Override
	public void serialEvent(SerialPortEvent arg0) {
		switch(arg0.getEventType()){
		case SerialPortEvent.BI:/*Break interrupt,通讯中断*/ 
        case SerialPortEvent.OE:/*Overrun error,溢位错误*/ 
        case SerialPortEvent.FE:/*Framing error,传帧错误*/
        case SerialPortEvent.PE:/*Parity error,校验错误*/
        case SerialPortEvent.CD:/*Carrier detect,载波检测*/
        case SerialPortEvent.CTS:/*Clear to send,清除发送*/ 
        case SerialPortEvent.DSR:/*Data set ready,数据设备就绪*/ 
        case SerialPortEvent.RI:/*Ring indicator,响铃指示*/
        case SerialPortEvent.OUTPUT_BUFFER_EMPTY:/*Output buffer is empty,输出缓冲区清空*/ 
            break;
        case SerialPortEvent.DATA_AVAILABLE:/*Data available at the serial port,端口有可用数据。读到缓冲数组,输出到终端*/
        	byte[] readBuffer = new byte[100];
            String ss = "";
            try {
            	
            		while (inputStream.available() > 0) {
                    inputStream.read(readBuffer);
                }
                
            	ss = new String(readBuffer).trim(); 									///起床开搞         	
            	
	            log("接收到端口返回数据(长度为-------------------------"+ss.length()+"):"+ss);
	            if(ss.length()==14)
	            {
	            	if(check(ss))
		            {
		            
			            zuobiao zz=new zuobiao();
			            zz.setZX(Integer.parseInt(ss.substring(4, 9))/10);
			            zz.setZY(Integer.parseInt(ss.substring(9, 14))/10);
			            
			            zz.setZLeft(Integer.parseInt(ss.substring(4, 9))/10);
			            zz.setZRight(you-Integer.parseInt(ss.substring(4, 9))/10);
			            zz.setZFront(qian-Integer.parseInt(ss.substring(9, 14))/10);
			            zz.setZBehind(Integer.parseInt(ss.substring(9, 14))/10);
			            Timestamp d = new Timestamp(System.currentTimeMillis()); 
			            zz.setZTime(d);
			            I.insert(zz);
		            }
	            }
            } catch (IOException e) {
            }
		}
	}
	
	private final static String mChars = "EEEF";  //检查是否为EFEE字符串 
	private final static String mChars1 = "EF00";  //检查是否为EFEE字符串 
	static int qian=700;
	static int you=600;
	public boolean check(String a)
	{
		 a=a.substring(0,4) ;													//:取从beginIndex位置开始到endIndex位置的子字符串。
		 System.out.println("+++++++++++++++___________________"+a);
		 if(a.equals(mChars1))
		 {
			 qian=Integer.parseInt(a.substring(4, 9))/10;					//初始化前方距离
			 you  =Integer.parseInt(a.substring(9, 14))/10;					//初始化右方距离
			 return false;
		 }
		 if(a.equals(mChars))
		 return true;
		 else
		return false;

	}  

	@Override
	public void run() {
		try{
		}catch(Exception e){
			e.printStackTrace();
		}
	}
}

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值