android串口通信—— 自動輪尋可以通信的串口

廢話不多說,開擼代碼。

用的是谷歌開源serialPort api ,下載鏈接

下載后全部導(dǎo)入項目中,什么也不用修改

寫一個工具類SerialPortUtils,設(shè)置好波特率

記錄開始發(fā)送時間和最后一次接收時間,用超時時間來判斷串口是否能正常收發(fā)數(shù)據(jù)

如何連續(xù)三次超時就自動更換串口號,知道接收到數(shù)據(jù)為止

下面是具體的類,僅供參考

public class SerialPortUtils {

? ? private final String TAG = "SerialPortUtils";

? ? private final int baudrate = 38400;//波特率

? ? private boolean serialPortStatus = false; //是否打開串口標(biāo)志

? ? private boolean threadStatus = false; //線程狀態(tài),為了安全終止線程

? ? private SerialPort serialPort = null;//串口

? ? private InputStream inputStream = null;

? ? private OutputStream outputStream = null;

? ? private int size; //讀取數(shù)據(jù)的大小

? ? private Integer i = 0;

? ? private int j = 0;

? ? private long lastReceiveTime ;

? ? private long lastSendTime;

? ? private final long TIME_OUT = 10 * 1000;

? ? private static SerialPortUtils INSTANCE;

? ? private List<String> list=null;

? ? private SerialPortUtils() {

? ? ? ? // 記錄創(chuàng)建對象時的時間

? ? ? ? lastReceiveTime = System.currentTimeMillis();

? ? ? ? lastSendTime = System.currentTimeMillis();

? ? ? ? openSerialPort();

? ? }

? ? public static synchronized SerialPortUtils getInstance() {

? ? ? ? if (INSTANCE == null) {

? ? ? ? ? ? INSTANCE = new SerialPortUtils();

? ? ? ? }

? ? ? ? return INSTANCE;

? ? }

? ? /**

? ? * 打開串口

? ? *

? ? * @return serialPort串口對象

? ? */

? ? private void openSerialPort() {

? ? ? //? i=0;

? ? ? ? try {

? ? ? ? ? ? if (serialPort == null) {

? ? ? ? ? ? ? ? serialPort = new SerialPort(new File(ApiAddress.path), baudrate, 0);

? ? ? ? ? ? ? ? serialPortStatus = true;

? ? ? ? ? ? ? ? threadStatus = false; //線程狀態(tài)

? ? ? ? ? ? ? ? //獲取打開的串口中的輸入輸出流,以便于串口數(shù)據(jù)的收發(fā)

? ? ? ? ? ? ? ? inputStream = serialPort.getInputStream();

? ? ? ? ? ? ? ? outputStream = serialPort.getOutputStream();

? ? ? ? ? ? ? ? //開始線程監(jiān)控是否有數(shù)據(jù)要接收

? ? ? ? ? ? ? ? new ReadThread().start();

? ? ? ? ? ? ? ? Tray.putString(MyApp.myApp,"chuankou",ApiAddress.path);

? ? ? ? ? ? }

? ? ? ? } catch (IOException e) {

? ? ? ? ? ? MainUtil.printLogger(TAG, "openSerialPort: 打開串口異常:" + e.toString());

? ? ? ? }

? ? }

? ? /**

? ? * 關(guān)閉串口

? ? */

? ? public void closeSerialPort() {

? ? ? ? try {

? ? ? ? ? ? inputStream.close();

? ? ? ? ? ? outputStream.close();

? ? ? ? ? ? serialPortStatus = false;

? ? ? ? ? ? threadStatus = true; //線程狀態(tài)

? ? ? ? ? ? serialPort.close();

? ? ? ? ? ? serialPort = null;

? ? ? ? } catch (IOException e) {

? ? ? ? ? ? MainUtil.printLogger(TAG, "closeSerialPort: 關(guān)閉串口異常:" + e.toString());

? ? ? ? }

? ? ? ? MainUtil.printLogger(TAG, "closeSerialPort: 關(guān)閉串口成功");

? ? }

? ? /**

? ? * 發(fā)送串口指令(字符串)

? ? *

? ? * @param sendData String數(shù)據(jù)指令

? ? */

? ? public synchronized void sendSerialPort(byte[] sendData) {

? ? ? ? try {

? ? ? ? ? ? if (sendData.length > 0) {

? ? ? ? ? ? ? ? if (null != outputStream) {

? ? ? ? ? ? ? ? ? ? outputStream.write(sendData);

? ? ? ? ? ? ? ? ? ? outputStream.flush();

? ? ? ? ? ? ? ? ? ? MainUtil.printLogger(TAG, "串口發(fā)送" + ByteHEXUtils.bytesTo_HexString(sendData));

? ? ? ? ? ? ? ? ? ? lastSendTime = System.currentTimeMillis();

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? long miss = lastSendTime - lastReceiveTime;

? ? ? ? ? ? ? ? if (miss > TIME_OUT) {

? ? ? ? ? ? ? ? ? ? //超時

? ? ? ? ? ? ? ? ? ? i++;

? ? ? ? ? ? ? ? ? ? if (i > 3) {

? ? ? ? ? ? ? ? ? ? ? ? if (onChuankouListener != null) {

? ? ? ? ? ? ? ? ? ? ? ? ? ? onChuankouListener.OnChuankouChange(2);

? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? ? ? list=getDevices();

? ? ? ? ? ? ? ? ? ? ? ? if(null!=list){

? ? ? ? ? ? ? ? ? ? ? ? ? ? Tray.putString(MyApp.myApp,"chuankou",list.get(j));

? ? ? ? ? ? ? ? ? ? ? ? ? serialPort = null;

? ? ? ? ? ? ? ? ? ? ? ? ? openSerialPort();

? ? ? ? ? ? ? ? ? ? ? ? ? ? j++;

? ? ? ? ? ? ? ? ? ? ? ? }else {

? ? ? ? ? ? ? ? ? ? ? ? ? ? if("/dev/ttyS1".equals(Tray.getString(MyApp.myApp, "chuankou", "/dev/ttyS2"))){

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Tray.putString(MyApp.myApp,"chuankou","/dev/ttyS2");

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? serialPort = null;

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? openSerialPort();

? ? ? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? ? ? ? ? if("/dev/ttyS2".equals(Tray.getString(MyApp.myApp, "chuankou", "/dev/ttyS2"))){

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Tray.putString(MyApp.myApp,"chuankou","/dev/ttyS1");

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? serialPort = null;

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? openSerialPort();

? ? ? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? } catch (IOException e) {

? ? ? ? ? ? MainUtil.printLogger(TAG, "sendSerialPort: 串口數(shù)據(jù)發(fā)送失?。? + e.toString());

? ? ? ? }

? ? }

? ? private final StringBuffer sb = new StringBuffer();

? ? /**

? ? * 單開一線程,來讀數(shù)據(jù)

? ? */

? ? private class ReadThread extends Thread {

? ? ? ? @Override

? ? ? ? public void run() {

? ? ? ? ? ? super.run();

? ? ? ? ? ? while (!threadStatus) {

? ? ? ? ? ? ? ? try {

? ? ? ? ? ? ? ? ? ? Thread.sleep(100);

? ? ? ? ? ? ? ? } catch (InterruptedException e) {

? ? ? ? ? ? ? ? ? ? e.printStackTrace();

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? final byte[] buffer = new byte[256];

? ? ? ? ? ? ? ? // do something

? ? ? ? ? ? ? ? try {

? ? ? ? ? ? ? ? ? ? size = inputStream.read(buffer);

? ? ? ? ? ? ? ? ? ? String message = new String(ByteHEXUtils.bytesTo_HexString(buffer).getBytes(), 0, size * 2);

? ? ? ? ? ? ? ? ? ? if (message.startsWith("FFFF") && message.endsWith("0D0A")) {

? ? ? ? ? ? ? ? ? ? ? ? if (ByteHEXUtils.count(message, "FFFF") > 1) {

? ? ? ? ? ? ? ? ? ? ? ? ? ? message = message.substring(message.lastIndexOf("FFFF"));

? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? ? ? if (message.substring(message.length() - 6, message.length() - 4).equals(ByteHEXUtils.makeChecksum(message.substring(0, message.length() - 6))) && onDataReceiveListener != null) {

? ? ? ? ? ? ? ? ? ? ? ? ? ? if (onChuankouListener != null) {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? i = 0;

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? onChuankouListener.OnChuankouChange(1);

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? lastReceiveTime = System.currentTimeMillis();

? ? ? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? ? ? ? ? MainUtil.printLogger(TAG, "串口回調(diào)" + message);

? ? ? ? ? ? ? ? ? ? ? ? ? ? onDataReceiveListener.onDataReceive(message, size);

? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? ? ? sb.setLength(0);

? ? ? ? ? ? ? ? ? ? } else {

? ? ? ? ? ? ? ? ? ? ? ? sb.append(message);

? ? ? ? ? ? ? ? ? ? ? ? if (ByteHEXUtils.count(sb.toString(), "FFFF") > 1) {

? ? ? ? ? ? ? ? ? ? ? ? ? ? String str = sb.toString();

? ? ? ? ? ? ? ? ? ? ? ? ? ? sb.setLength(0);

? ? ? ? ? ? ? ? ? ? ? ? ? ? sb.append(str.substring(str.lastIndexOf("FFFF")));

? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? ? ? if (sb.toString().startsWith("FFFF") && sb.toString().endsWith("0D0A")) {

? ? ? ? ? ? ? ? ? ? ? ? ? ? if (sb.substring(sb.length() - 6, sb.length() - 4).equals(ByteHEXUtils.makeChecksum(sb.substring(0, sb.length() - 6))) && onDataReceiveListener != null) {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? lastReceiveTime = System.currentTimeMillis();

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (onChuankouListener != null) {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? i = 0;

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? onChuankouListener.OnChuankouChange(1);

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? MainUtil.printLogger(TAG, "串口回調(diào)" + sb.toString());

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? onDataReceiveListener.onDataReceive(sb.toString(), size);

? ? ? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? ? ? ? ? sb.setLength(0);

? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? } catch (IOException e) {

? ? ? ? ? ? ? ? ? ? e.printStackTrace();

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? }

? ? }

? ? private OnDataReceiveListener onDataReceiveListener = null;

? ? private OnChuankouChangeListener onChuankouListener = null;

? ? public interface OnDataReceiveListener {

? ? ? ? void onDataReceive(String buffer, int size);

? ? }

? ? public void setOnDataReceiveListener(OnDataReceiveListener dataReceiveListener) {

? ? ? ? onDataReceiveListener = dataReceiveListener;

? ? }

? ? // 自定義接口

? ? public interface OnChuankouChangeListener {

? ? ? ? void OnChuankouChange(int status);

? ? }

? ? public void setOnChuankouListener(OnChuankouChangeListener chuankouListener) {

? ? ? ? onChuankouListener = chuankouListener;

? ? }

? ? public List<String>getDevices() {

? ? ? ? if (null == list) {

? ? ? ? ? ? list = new ArrayList<>();

? ? ? ? ? ? File dev = new File("/dev");

? ? ? ? ? ? File[] files = dev.listFiles();

? ? ? ? ? ? int i;

? ? ? ? ? ? for (i = 0; i < files.length; i++) {

? ? ? ? ? ? ? ? if (files[i].getAbsolutePath().startsWith("/dev/ttyS")) {

? ? ? ? ? ? ? ? ? ? MainUtil.printLogger(TAG, "Found new device: " + files[i]);

? ? ? ? ? ? ? ? ? ? list.add(files[i].toString());

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? return list;

? ? }

}

本工具類中有自動替換串口,知道可以通信為止的方法

由于android端接收串口數(shù)據(jù)并不是一次性就可以全部接收到,有可能分兩段,也有可能丟失,所有在接收消息的時候,我做了拼接校驗,比如和板子開發(fā)人員確定好頭部和尾部以及校驗位,本工具類中頭部是FFFF開頭0D0A結(jié)尾的,對不符合的數(shù)據(jù)進(jìn)行了舍棄,并及時清空緩沖區(qū)

本工具類中Tray類似于共享參數(shù),保存了串口路徑,可以用SharedPreferences或者file代替

如有不對請指正。

我的csdn地址:?https://blog.csdn.net/u011847849/article/details/105999406

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容