java连接串口
java se 没有连串口的组件,通过mina
mina的简介:
https://www.oschina.net/p/mina?hmsr=aladdin1e1
核心库:
public final class SerialConnector extends AbstractIoConnector
public interface IoHandler
public class SerialAddress extends SocketAddress
大概流程如下:
SerialConnector把IoHandler设置为自己的处理Handler,并且连接指定的SerialAddress。连接完成后,IoHandler中可以通过sessionOpened得到串口连接的sesseion,可以通过session发送数据。
main代码如下:
//创建串口连接
SerialConnector connector = new SerialConnector();
//绑定处理handler
COMHandler comHandler=new COMHandler();//COMHandler是实现IoHandler的子类
connector.setHandler(comHandler);
try{
//配置串口连接,参数自己用实际的字符串代替
SerialAddress address = new SerialAddress((String) hs.get("COMM.PortName"),
Integer.parseInt((String) hs.get("COMM.BaudRate")), DataBits.DATABITS_8, StopBits.BITS_1, Parity.NONE,
FlowControl.NONE);
connector.connect(address);
} catch (Throwable e) {
throw new RuntimeException("打开串口失败", e);
}
comHandler().getSession().write("abcd");//写数据
COMHandler 代码如下:
public class COMHandler implements IoHandler
{
IoSession session=null;
@Override
public void sessionCreated(IoSession session) throws Exception {
// TODO Auto-generated method stub
}
@Override
public void sessionOpened(IoSession session) throws Exception {
// TODO Auto-generated method stub
this.session=session;
}
@Override //读数据
public void messageReceived(IoSession session, Object message) throws Exception {
// TODO Auto-generated method stub
}
//......
}
-------------------------------------------------------------------
完整的类:
-------------------------------------------------------------------
pom.xml
<!-- https://mvnrepository.com/artifact/org.rxtx/rxtx -->
<dependency>
<groupId>org.rxtx</groupId>
<artifactId>rxtx</artifactId>
<version>2.1.7</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.mina/mina-core -->
<dependency>
<groupId>org.apache.mina</groupId>
<artifactId>mina-core</artifactId>
<version>2.0.2</version>
</dependency>
<dependency>
<groupId>org.apache.mina</groupId>
<artifactId>mina-integration-beans</artifactId>
<version>2.0.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.mina/mina-transport-serial -->
<dependency>
<groupId>org.apache.mina</groupId>
<artifactId>mina-transport-serial</artifactId>
<version>2.0.2</version>
</dependency>
public class COM
{
private Logger logger = Logger.getLogger(COM.class);
private COMHandler comHandler;
private SerialConnector connector;//一个串口只有一个连接
public COM() {
// TODO Auto-generated constructor stub
comHandler=new COMHandler();
}
public HashMap loadConfig_ini() throws IOException
{
HashMap map = new HashMap<>();
InputStream is=COM.class.getResourceAsStream("/config.ini");
BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
String line;
String section = "";
while((line = reader.readLine())!=null){
line = line.trim();
if(line.isEmpty() || line.startsWith("#"))
continue;
if(line.endsWith("]")){
section = line.substring(line.indexOf('[')+1, line.length()-1);
logger.debug("section:"+section+","+line.indexOf('['));
continue;
}
int pos = line.indexOf('=');
if(pos<0){
logger.info("xx"+(int)line.charAt(0)+"xx,"+line.startsWith("[")+","+line.endsWith("]"));
continue;
}
String name = line.substring(0, pos).trim();
if(!section.isEmpty())
name = section+"."+name;
String value = line.substring(pos+1).trim();
map.put(name, value);
}
logger.debug("配置:"+map);
return map;
}
public void connect(){
//创建串口连接
connector = new SerialConnector();
//绑定处理handler
connector.setHandler(comHandler);
//设置过滤器
connector.getFilterChain().addLast("logger",new LoggingFilter());
//增加编解码过滤器
//发送时将对象编码为字节数组,接收时将字节解码为对象
connector.getFilterChain().addLast("serial-port-codec",
new ProtocolCodecFilter(new COMEncoder(), new COMDecoder()));
try{
HashMap hs=this.loadConfig_ini();
//配置串口连接
SerialAddress address = new SerialAddress((String) hs.get("COMM.PortName"),
Integer.parseInt((String) hs.get("COMM.BaudRate")), DataBits.DATABITS_8, StopBits.BITS_1, Parity.NONE,
FlowControl.NONE);
connector.connect(address);
logger.info("成功打开串口"+hs.get("COMM.PortName"));
} catch (Throwable e) {
throw new RuntimeException("打开串口失败", e);
}
}
public void disconnect(){
for(IoSession session: connector.getManagedSessions().values()){
session.close(true);
}
connector.dispose();
connector=null;
}
public Logger getLogger() {
return logger;
}
public void setLogger(Logger logger) {
this.logger = logger;
}
public COMHandler getComHandler() {
return comHandler;
}
public void setComHandler(COMHandler comHandler) {
this.comHandler = comHandler;
}
public SerialConnector getConnector() {
return connector;
}
public void setConnector(SerialConnector connector) {
this.connector = connector;
}
}
package luyao;
import org.apache.log4j.Logger;
import org.apache.mina.core.service.IoHandler;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import luyao.data.Frame;
import luyao.data.FrameBB;
/**
* 串口通信处理类
* @author Administrator
*
*/
public class COMHandler implements IoHandler
{
protected Logger logger = Logger.getLogger(this.getClass());
IoSession session=null;
@Override
public void sessionCreated(IoSession session) throws Exception {
// TODO Auto-generated method stub
}
@Override
public void sessionOpened(IoSession session) throws Exception {
// TODO Auto-generated method stub
this.session=session;
}
@Override
public void sessionClosed(IoSession session) throws Exception {
// TODO Auto-generated method stub
}
@Override
public void sessionIdle(IoSession session, IdleStatus status) throws Exception {
// TODO Auto-generated method stub
}
@Override
public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
// TODO Auto-generated method stub
}
@Override
public void messageReceived(IoSession session, Object message) throws Exception {
// TODO Auto-generated method stub
}
@Override
public void messageSent(IoSession session, Object message) throws Exception {
// TODO Auto-generated method stub
}
}
package luyao;
import org.apache.log4j.Logger;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolEncoder;
import org.apache.mina.filter.codec.ProtocolEncoderOutput;
import luyao.common.utils;
import luyao.data.*;
/**
* 串口编码
* @author Administrator
*
*/
public class COMEncoder implements ProtocolEncoder {
static private Logger logger = Logger.getLogger(COMEncoder.class);
@Override
public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception {
// TODO Auto-generated method stub
logger.trace("发送数据:" + message);
if (!(message instanceof Frame)) {
logger.error("不能识别的数据:" + message.getClass().getName());
return;
}
//IoBuffer是MINA内部使用的一个byte buffer,MINA并没有直接使用NIO 的ByteBuffer。不过IoBuffer 是对 ByteBuffer 的一个封装。IoBuffer 中的很多方法都是对 ByteBuffer 的直接继承。只是对 ByteBuffer 添加了一些扩展了更加实用的方法。
IoBuffer buff = IoBuffer.allocate(4096).setAutoExpand(true);
Frame frame = (Frame) message;
buff.putShort(frame.title);
buff.put(frame.func);
buff.put(frame.length);
switch(frame.func & 0xFF){
case 0x04:
encodeFrame04((Frame04)frame, buff);
break;
case 0x11:
encodeFrame11((Frame11)frame, buff);
break;
case 0x55:
encodeFrame55((Frame55)frame, buff);
break;
case 0x66:
encodeFrame66((Frame66)frame, buff);
break;
case 0x88:
encodeFrame88((Frame88)frame, buff);
break;
case 0xBB:
encodeFrameBB((FrameBB)frame, buff);
break;
default:
logger.error("不能发送的数据:"+frame);
return;
}
/*
* flip()方法
flip方法将Buffer从写模式切换到读模式。调用flip()方法会将position设回0,并将limit设置成之前position的值。
换句话说,position现在用于标记读的位置,limit表示之前写进了多少个byte、char等 —— 现在能读取多少个byte、char等。
*/
buff.flip();
byte[] bytes = new byte[buff.remaining()];
buff.get(bytes);//把IoBuffer的值赋给byte[]。若需要再转换为String则new(byte[])
buff.put(utils.sum(bytes, 0, bytes.length));
buff.flip();
out.write(buff);
}
private void encodeFrameBB(FrameBB frame, IoBuffer buff) {
for (int i = 0; i < 6; ++i)
buff.putShort(frame.pos[i]);
}
private void encodeFrame88(Frame88 frame, IoBuffer buff) {
for (int i = 0; i < 10; ++i)
buff.putInt(frame.pv[i]);
}
private void encodeFrame66(Frame66 frame, IoBuffer buff) {
for (int i = 0; i < 5; ++i)
buff.putInt(frame.pv[i]);
}
private void encodeFrame55(Frame55 frame, IoBuffer buff) {
for (int i = 0; i < 5; ++i)
buff.putInt(frame.pv[i]);
}
private void encodeFrame11(Frame11 frame, IoBuffer buff) {
buff.put(frame.id);
buff.putInt(frame.position_ab);
buff.putInt(frame.velocity);
}
private void encodeFrame04(Frame04 frame, IoBuffer buff) {
buff.put(frame.state);
for(int i=0; i<5; ++i){
buff.putInt(frame.pos[i]);
}
}
@Override
public void dispose(IoSession session) throws Exception {
// TODO Auto-generated method stub
}
}
package luyao;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;
/**
* 串口解码
* @author Administrator
*
*/
public class COMDecoder implements ProtocolDecoder {
@Override
public void decode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
// TODO Auto-generated method stub
}
@Override
public void finishDecode(IoSession session, ProtocolDecoderOutput out) throws Exception {
// TODO Auto-generated method stub
}
@Override
public void dispose(IoSession session) throws Exception {
// TODO Auto-generated method stub
}
}
本文地址:https://blog.csdn.net/weixin_41664930/article/details/107160264
上一篇: 拖拽悬挂缩进尺自定义Word段落的编号与首字之间的距离
下一篇: 荐 Mysql主从复制(代码详解)