シリアルデータの読み取りのためのJavaWebの窓

シリアル・データ読み出しクラス、シリアルデータは窓を読むため。

シーン羊の実行を模倣するために呼ばれる羊、観察オオカミ、オオカミたとえばオブザーバ1.、ブログを参照してください。

https://blog.csdn.net/dada360778512/article/details/6977758

2.データのアナログシリアル伝送は2つのツール、仮想シリアルポートドライバ、シリアルデバッグアシスタントを必要と;を参照することができます。

https://jingyan.baidu.com/article/046a7b3eae7028f9c27fa9f7.html

3. RXTX(シリアルおよびパラレル通信を提供する)、シリアル動作のためのオープンソースライブラリに基づい。特定の構成、以下を参照してください。

https://blog.csdn.net/liu4071325/article/details/53392218

必要なプラグイン/キット:
参照1.プロジェクト:RXTXcomm.jar

2.windowsサーバーは、次の3つのファイルが必要です:
       \ JDK \ JRE \ libに\ EXTのディレクトリ---> RXTXcomm.jar
      \ JDK \ビン---> rxtxParallel.dllとrxtxSerial.dllのディレクトリ

2.Linuxサーバは、次の3つのファイルを配置する必要があります

       \ JDKのディレクトリ\ JRE \ libに\ EXT ---> RXTXcomm.jar
      \ JDKディレクトリ\ binに---> librxtxParallel.soとlibrxtxSerial.so

共有をありがとう!

コード:

1.観察SerialReader.javaを作成します。 

import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.NoSuchPortException;
import gnu.io.PortInUseException;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import gnu.io.UnsupportedCommOperationException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Observable;
import java.util.TooManyListenersException;

/**
 * <p>串口数据读取类,用于windows的串口数据读取</p>
 * 
 * 声明被观察者SerialReader,继承Observable<br/>
 * 观察者,继承Observer<br/>
 * 
 * Observer模式  主要是观察者与被观察者之间的关系。<br/>
 * 
 */
public class SerialReader extends Observable implements Runnable, SerialPortEventListener {
	static CommPortIdentifier portId;
	int delayRead = 200;
	int numBytes; // buffer中的实际数据字节数
	private static byte[] readBuffer = new byte[4096]; // 4k的buffer空间,缓存串口读入的数据
	static Enumeration portList;
	InputStream inputStream;
	SerialPort serialPort;
	//声明观察者时,被指定的参数信息
	HashMap serialParams;
	// 端口读入数据事件触发后,等待n毫秒后再读取,以便让数据一次性读完
	public static final String PARAMS_DELAY = "delay read"; // 延时等待端口数据准备的时间
	public static final String PARAMS_TIMEOUT = "timeout"; // 超时时间
	public static final String PARAMS_PORT = "port name"; // 端口名称
	public static final String PARAMS_DATABITS = "data bits"; // 数据位
	public static final String PARAMS_STOPBITS = "stop bits"; // 停止位
	public static final String PARAMS_PARITY = "parity"; // 奇偶校验
	public static final String PARAMS_RATE = "rate"; // 波特率

	public SerialReader() {
	}

	/**
	 * 初始化端口操作的参数.
	 * 
	 * @see
	 */
	public SerialReader(HashMap params) {
		serialParams = params;
		init();
	}

	private void init() {
		try {
			// 参数初始化
			int timeout = Integer.parseInt(serialParams.get(PARAMS_TIMEOUT).toString());
			int rate = Integer.parseInt(serialParams.get(PARAMS_RATE).toString());
			int dataBits = Integer.parseInt(serialParams.get(PARAMS_DATABITS).toString());
			int stopBits = Integer.parseInt(serialParams.get(PARAMS_STOPBITS).toString());
			int parity = Integer.parseInt(serialParams.get(PARAMS_PARITY).toString());
			delayRead = Integer.parseInt(serialParams.get(PARAMS_DELAY).toString());
			String port = serialParams.get(PARAMS_PORT).toString();
			// 打开端口
			portId = CommPortIdentifier.getPortIdentifier(port);
			EWeightConstant.IS_OPEN_PORT = true;
			serialPort = (SerialPort) portId.open("SerialReader", timeout);
			inputStream = serialPort.getInputStream();
			serialPort.addEventListener(this);// 注册串口监听
			serialPort.notifyOnDataAvailable(true);// 数据可用
			serialPort.setSerialPortParams(rate, dataBits, stopBits, parity);// 设置参数
		} catch (PortInUseException e) {
			// System.out.println("串口已经被占用!");
			e.printStackTrace();
		} catch (TooManyListenersException e) {
			// System.out.println("串口监听者过多!");
			e.printStackTrace();
		} catch (UnsupportedCommOperationException e) {
			// System.out.println("串口操作命令不支持!");
			e.printStackTrace();
		} catch (NoSuchPortException e) {
			// System.out.println("串口不存在!");
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		Thread readThread = new Thread(this);
		readThread.start();
	}

	public void run() {
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	public void serialEvent(SerialPortEvent event) {
		try {
			// 等待1秒钟让串口把数据全部接收后在处理
			Thread.sleep(delayRead);
			// System.out.print("serialEvent[" + event.getEventType() + "] ");
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		switch (event.getEventType()) {
		case SerialPortEvent.BI: // 10
		case SerialPortEvent.OE: // 7
		case SerialPortEvent.FE: // 9
		case SerialPortEvent.PE: // 8
		case SerialPortEvent.CD: // 6
		case SerialPortEvent.CTS: // 3
		case SerialPortEvent.DSR: // 4
		case SerialPortEvent.RI: // 5
		case SerialPortEvent.OUTPUT_BUFFER_EMPTY: // 2
			break;
		case SerialPortEvent.DATA_AVAILABLE: // 1
			try {
				// 多次读取,将所有数据读入
				while (inputStream.available() > 0) {
					numBytes = inputStream.read(readBuffer);
				}
				// numBytes = inputStream.read(readBuffer);
				changeMessage(readBuffer, numBytes);
			} catch (IOException e) {
				e.printStackTrace();
			}
			break;
		}
	}

	// 通过observer pattern将收到的数据发送给observer
	// 将buffer中的空字节删除后再发送更新消息,通知观察者
	private String temp1 = "";

	public void changeMessage(byte[] message, int length) {
		setChanged();
		byte[] temp = new byte[length];
		System.arraycopy(message, 0, temp, 0, length);
		// 判断数据是否稳定,稳定则只监听不执行更新数据
		if (!"".equals(temp1)) {
			if (!temp1.equals(new String(temp).trim())) {
				temp1 = new String(temp).trim();
				notifyObservers(temp);
				// System.out.println("msg[" + numBytes + "]: [" + new
				// String(temp).trim() +"]");
			}
		} else {
			temp1 = new String(temp).trim();
			notifyObservers(temp);
		}
	}
	/**
	 * 调试用,获取所有的串口
	 */
	static void listPorts() {
		Enumeration portEnum = CommPortIdentifier.getPortIdentifiers();
		while (portEnum.hasMoreElements()) {
			CommPortIdentifier portIdentifier = (CommPortIdentifier) portEnum.nextElement();
			System.out.println("串口名称:"+portIdentifier.getName() + " - " +"串口类型:"+getPortTypeName(portIdentifier.getPortType()));
		}
	}

	/**
	 * 读取所有串口名字
	 */
	public static String getPortName() {
		CommPortIdentifier portId;
		Enumeration en = CommPortIdentifier.getPortIdentifiers();
		while (en.hasMoreElements()) {
			portId = (CommPortIdentifier) en.nextElement();
			if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
				return portId.getName();
			}
		}
		return "";
	}

	/**
	 * 读取所有串口名字
	 */
	public static void closePort() {
		CommPortIdentifier portId;
		Enumeration en = CommPortIdentifier.getPortIdentifiers();
		while (en.hasMoreElements()) {
			portId = (CommPortIdentifier) en.nextElement();
			if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {

			}
		}
	}

	static String getPortTypeName(int portType) {
		switch (portType) {
		case CommPortIdentifier.PORT_I2C:
			return "I2C";
		case CommPortIdentifier.PORT_PARALLEL:
			return "Parallel";
		case CommPortIdentifier.PORT_RAW:
			return "Raw";
		case CommPortIdentifier.PORT_RS485:
			return "RS485";
		case CommPortIdentifier.PORT_SERIAL:
			return "Serial";
		default:
			return "unknown type";
		}
	}

	public static HashSet<CommPortIdentifier> getAvailableSerialPorts() {
		HashSet<CommPortIdentifier> h = new HashSet<CommPortIdentifier>();
		Enumeration thePorts = CommPortIdentifier.getPortIdentifiers();
		while (thePorts.hasMoreElements()) {
			CommPortIdentifier com = (CommPortIdentifier) thePorts.nextElement();
			switch (com.getPortType()) {
			case CommPortIdentifier.PORT_SERIAL:
				try {
					CommPort thePort = com.open("CommUtil", 50);
					thePort.close();
					h.add(com);
				} catch (PortInUseException e) {
					// System.out.println("Port, " + com.getName()+ ", is in
					// use.");
				} catch (Exception e) {
					// System.out.println("Failed to open port " +
					// com.getName()+ e);
				}
			}
		}
		return h;
	}
}

2.オブザーバを作成CommDataObserver.java


import java.util.Observable;
import java.util.Observer;
/**
 * 观察类,继承Observer<br/>
 * 创建一个观察类,该观察类有自己的name名称
 *
 */
public class CommDataObserver implements Observer {
	private String name;
	
	public CommDataObserver() {
	}

	public CommDataObserver(String name) {
		this.name = name;
	}
	/**
	 * 监控串口,获取串口数据
	 */
	public void update(Observable o, Object arg) {
		//获取串口返回数据
		String weight = new String((byte[]) arg).trim();
		//将获取到的数据,赋值到全局变量里,以便可以调用该数据
		EWeightConstant.GOOD_WEIGHT = weight;
				
		//testing  start 根据串口类型不同,返回的数据格式也不尽相同,此处调试打印而已 {{
		System.out.println("weight="+weight);
		StringBuilder sb = new StringBuilder(weight);// 0.000或者00.000
		sb.insert(weight.length() - 3, ".");
		System.out.println(sb.toString() + "kg");
		//testing  end }}
		
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

}

3.ポートの初期化データと観察者との観測を作成し、GetWeightUtil.javaを観察追加


import java.util.HashMap;

import gnu.io.SerialPort;
/**
 * 获取串口工具类
 * 此处声明观察者和被观察者
 */
public class GetWeightUtil {
	
	/**
	 * 串口设置, 初始化端口数据
	 * @param com 端口
	 */
	public static void comConfig(String com) {
		//存储端口数据
		HashMap<String, Comparable> params = new HashMap<String, Comparable>();
		// 端口名称
		params.put(SerialReader.PARAMS_PORT, com);
		// 波特率
		params.put(SerialReader.PARAMS_RATE, 9600);
		// 设备超时时间 1秒
		params.put(SerialReader.PARAMS_TIMEOUT, 1000); 
		// 端口数据准备时间 1秒
		params.put(SerialReader.PARAMS_DELAY, 200); 
		// 数据位
		params.put(SerialReader.PARAMS_DATABITS, SerialPort.DATABITS_8); 
		// 停止位
		params.put(SerialReader.PARAMS_STOPBITS, SerialPort.STOPBITS_1); 
		// 无奇偶校验
		params.put(SerialReader.PARAMS_PARITY, SerialPort.PARITY_NONE); 
		//创建被观察者
		SerialReader serialReader = new SerialReader(params);
		//创建观察者
		CommDataObserver obServer = new CommDataObserver("电子秤");
		//添加一个观察者,加入观察
		serialReader.addObserver(obServer);
		
		//TODO 调试用,输出到控制台 显示所有串口号
		SerialReader.listPorts();
	}
	
	public static void main(String[] args) throws Exception{
		comConfig("COM1");
		while(true){
			Thread.sleep(1000);
			System.out.println(EWeightConstant.GOOD_WEIGHT);	
		}
		
	}
}

4.EWeightConstant.java

/**
 * 记录串口的基础信息 全局变量
 *
 */
public class EWeightConstant {
	/**
	 * 串口数据
	 */
	public static String GOOD_WEIGHT = "0";
	/**
	 * 串口是否打开
	 */
	public static Boolean IS_OPEN_PORT = false;
}

5.Controllerメソッドの呼び出しは、シリアルデータを取得し、事業の発展に作用します

/**
	 * 前端 调用该方法,用于获取串口返回数据
	 * 如果想一直调用该串口返回数据,JS前端可做轮询
	 * @param request
	 * @return
	 */
    @RequestMapping(value = "/getWeight", method = RequestMethod.GET)
    @ResponseBody
    public String getWeight(HttpServletRequest request) {
    	// 获取数据的串口
    	final String E_WEIGHT_COM = "COM1";
    	try{
    		if(!EWeightConstant.IS_OPEN_PORT){
        		GetWeightUtil.comConfig(E_WEIGHT_COM);	
        	}
    	}catch(Exception e){
    		e.printStackTrace();
    	}
    	//全局变量,记录串口数据
    	String weight = EWeightConstant.GOOD_WEIGHT;
    	//输出串口数据,查看串口数据格式
    	System.out.println("获取串口原始数据格式  = " + weight);
    	if(StringUtils.equals(weight, "0")){
    		return weight;
    	}
    	//截取字符串,获取要取得数据部分
    	weight = weight.substring(weight.indexOf("+")+1, weight.indexOf("  "));
    	System.out.println("最终数据,返回截取后的数据="+weight);
    	return weight;
    }

 

おすすめ

転載: blog.csdn.net/lanqibaoer/article/details/82500987