欢迎使用串口通讯, 首先说明下我这里使用的是RS485通讯,采用的是半双工通讯, 所以收和发不能同时操作需要发送等待一段时间来接收完数据在发送其他指令了, 这里顺便在说下RS232, 它采用的是全双工通讯, 可以同时收发,但是只能一对一, 不像RS485可以串联同时最大128个收发器。好了,废话不多说,代码整起。
初始化操作
private InputStream inputStream = null;
private OutputStream outputStream = null;
//串口连接状态
private boolean serialState = false;
private String PORT;
private int BANDAGE;
//处理接收串口数据的线程池
private ExecutorService fixedThreadPool;
//接收串口的接口回调
private OnRequireSerialData listen;
//判断是那个串口
private String type = motorType;
public void setOnRequireSerialData(OnRequireSerialData onRequireSerialData) {
this.listen = onRequireSerialData;
}
//0、电机 1、电源
public static String motorType = "motorType";
public static String powerType = "powerType";
//初始化操作
public SerialPortUtils(String PORT, int BANDAGE, String type) {
this.PORT = PORT;
this.BANDAGE = BANDAGE;
this.type = type;
fixedThreadPool = Executors.newFixedThreadPool(4);
}
打开串口
public void openSerialPort(){
new Thread(){
@Override
public void run() {
super.run();
try {
if(!serialState){
SerialPort s = new SerialPort(new File(PORT), BANDAGE);
writeServiceLogsAndShowToast("串口打开成功: " + type);
inputStream = s.getInputStream();
outputStream = s.getOutputStream();
serialState = true;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
关闭串口
public void closeSerialPort(){
try {
if(serialState){
if(inputStream != null) {
inputStream.close();
}
if(outputStream != null){
outputStream.close();
}
serialState = false;
writeServiceLogsAndShowToast("关闭串口: " + type);
}
} catch (IOException e) {
e.printStackTrace();
}
}
发送串口数据(防止发送指令太频繁, 这个有个等待时间)
private long beforeSendDate = 0;
public void sendSerialPort(final byte[] sendData){
try {
if(serialState){
long d = System.currentTimeMillis();
if(d - beforeSendDate > sendSerialInterval){
beforeSendDate = d;
outputStream.write(sendData);
outputStream.flush();
LoggerUtils.showLog(getClass(), getPortTypeString(serialType) + "串口数据发送成功");
fixedThreadPool.execute(receiveRunnable);
}else{
writeServiceLogsAndShowToast("指令发送太频繁了: " + type);
}
}else{
writeServiceLogsAndShowToast("请先打开串口: " + type);
}
} catch (IOException e) {
e.printStackTrace();
writeServiceLogsAndShowToast("串口数据发送失败: " + type);
}
}
读取接收字节
private byte[] readFromPort() {
byte[] b = null;
try {
int buffets = inputStream.available();
while (buffets != 0) {
b = new byte[buffets];
inputStream.read(b);
buffets = inputStream.available();
}
} catch (IOException e) {
e.fillInStackTrace();
}
return b;
}
处理接收数据(这里接收数据有三种情况, 一种是没数据返回, 一种有数据返回但是校验不对, 一种是正确的)(这里接收串口的数据也需要等待一段时间大概在200ms左右, 应为是RS485串口, 所以需要等待一下)
public final static long receiveDataDate = 300;
private Runnable receiveRunnable = new Runnable() {
public void run() {
try {
Thread.sleep(receiveDataDate);
byte[] b = readFromPort();
if(b != null){
MotorData f = getMotorData(b);
if(f != null){
if(listen != null){
listen.getSerialData(f);
}
}else{
if(listen != null){
listen.getSerialError(parsingErrorCode);
}
}
}else{
if(listen != null){
listen.getSerialError(noDataErrorCode);
}
}
} catch (InterruptedException ex) {
ex.fillInStackTrace();
}
}
};
使用串口工具
int carBandage = 19200;
String carPort = "/dev/ttyS7";
carSerialUtl = new SerialPortUtils(carPort, carBandage, motorType);
carSerialUtl.openSerialPort();
carSerialUtl.setOnRequireSerialData(new OnRequireSerialData() {
@Override
public void getSerialData(MotorData motorData) {
LoggerUtils.showLog(getBaseServiceContext(), "motorError: " + code);
}
@Override
public void getSerialError(int code) {
LoggerUtils.showLog(getBaseServiceContext(), "motorError: " + code);
}
});```
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)