一、前言
最近公司开了一个新项目,新项目有新设备也就意味着新的协议的对接,本来一切顺顺利利的进行,不过这次的设备数据传输出现了点问题,一段并不长的数据被分割成了两段传给我这边。
其实数据量并不大,可以一次性传过来的,可惜设备都已经订好了没法变动底层的代码了,也很无奈,于是将之前封装的串口读写库加了一个可选的拼包功能。
二、原理和流程图
image跟之前的区别主要还是SerialThread读取流的方式的区别
由原本的等待流反馈数据的被动等待,改为了不断轮询判断流中数据大小,如果有数据则拼接至已有的readBytes数组
直到流中没有数据后,便将数据回调给接口
三、功能的实现
(一)轮询读取函数的实现
在SerialPortReadThread中写了个死循环,不断判断inputStream中的数据大小
/**
* 轮询读取,判断inputStream中是否还有数据,还有就拼接
* */
private void splicingRead(){
while (!isInterrupted()) {
if (null == mInputStream) {
return;
}
Log.i(TAG, "run: ");
int size = 0;
try {
/** 获取流中数据的量*/
int i = mInputStream.available();
if (i == 0) {
size = 0;
} else {
/** 流中有数据,则添加到临时数组中*/
size = mInputStream.read(mReadBuffer);
}
} catch (IOException e) {
e.printStackTrace();
}
if (size > 0) {
/** 发现有信息后就追加到临时变量*/
Log.i("SerialPortReadThread", size + "");
readBytes = DataUtil.arrayAppend(readBytes, mReadBuffer, size);
Log.i("SerialPortReadThread", DataUtil.bytesToHexString(readBytes, readBytes.length));
} else {
/** 没有需要追加的数据了,回调*/
if (readBytes != null) {
onDataReceived(readBytes);
}
/** 清空,等待下个信息单元*/
readBytes = null;
}
SystemClock.sleep(50);
}
}
(二)如何在项目中使用
现在gradle中添加依赖
maven { url "https://jitpack.io" }
implementation 'com.github.Giftedcat:AndroidSerialPortManager:v1.0.2'
在项目中使用时,和之前的区别就是多了一个readType的参数
可以传递
SerialPortManager.NORMAL
serialPortManager = new SerialPortManager(new File("/dev/ttyS4"), 9600)
.setOnSerialPortDataListener(new OnSerialPortDataListener() {
@Override
public void onDataReceived(final byte[] bytes) {
/** 接收到串口数据*/
}
});
或者
SerialPortManager.SPLICING
serialPortManager = new SerialPortManager(new File("/dev/ttyS4"), 9600, SerialPortManager.SPLICING)
.setOnSerialPortDataListener(new OnSerialPortDataListener() {
@Override
public void onDataReceived(final byte[] bytes) {
/** 接收到串口数据*/
}
});
一种是常规的读取方式,另一种就是这次的拼包的读取方式
具体使用哪一种可以根据实际情况选择
四、结语
有问题和建议都可以在评论区给我留言
网友评论