侧边栏壁纸
博主头像
Z同学博主等级

工作磨平激情前,坚持技术的热忱。 欢迎光临Z同学的技术小站。 分享最新的互联网知识。

  • 累计撰写 274 篇文章
  • 累计创建 55 个标签
  • 累计收到 74 条评论

Android SerialPort 串口通讯调试

Z同学
2020-08-21 / 0 评论 / 0 点赞 / 1,420 阅读 / 2,674 字
温馨提示:
本文最后更新于 2022-01-17,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

前言

Android 如何通过串口通讯,给其他外设设备进行传值。

1.串口通信

首先,串口是一个广泛的称谓。 UART,TTL,RS232,RS485 等遵循类似通讯时序的协议的接口都可以被通称为串口。

通过命令查询,/dev/ 下面,我们可以看到tty 开头的就是我们的全部硬件设备节点了。

设置通信节点的 波特率:9600,115200 等

busybox stty -F /dev/tty* raw speed 9600 

向该串口写入数据

echo -e "\x20\x22" >> /dev/tty*   //发送的字节码

echo -e "这个是字符串" >> /dev/tty* //发送的字符

向该串口节点读取返回值

cat /dev/tty*

在配合XShell 你可以实现从系统层进行的串口信息通讯检查,如果整个流程通讯正常之后,我们就可以使用应用来封装整体的通讯协议内容了。

例如
1.通过数据线,将该串口直接通过USB连接到你的电脑之中,
电脑通过com1 进行随时读取串口值。
2.通过adb命令进入,然后输入上面介绍的指令。往该串口输入值。

正常状态下:你的电脑就能够通过串口得到adb命令输入的参数值。

这个通道顺畅之后。我们就要封装app端代码了。使用app端直接往串口进行传参

2.Android端串口调试

这里我介绍一个https://github.com/AIlll/AndroidSerialPort 已经封装好的库。

使用很简单

implementation 'com.aill:AndroidSerialPort:1.0.8' 
/**
 * @param 1 串口路径
 * @param 2 波特率
 * @param 3 flags 给0就好
 */
SerialPort serialPort = new SerialPort(new File("/dev/ttyS1"), 9600, 0);

//从串口对象中获取输出流
OutputStream outputStream = serialPort.getOutputStream();
//需要写入的数据
byte[] data = new byte[x];
data[0] = ...;
data[1] = ...;
data[x] = ...;
//写入数据
outputStream.write(data);
outputStream.flush();

//读数据,建议采用子线程
  private class ReadThear extends Thread {
        private InputStream inputStream;
        public  boolean     isRunning = true;

        public ReadThear(InputStream inputStream) {
            this.inputStream = inputStream;
        }

        @Override
        public void run() {
            super.run();
            try {
                while (isRunning) {
                    if (inputStream.available() > 0) {
                        //当接收到数据时,sleep 500毫秒(sleep时间自己把握)
                        Thread.sleep(500);
                        //sleep过后,再读取数据,基本上都是完整的数据
                        byte[] buffer = new byte[inputStream.available()];
                        int size = inputStream.read(buffer);
                    }
                }
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

readThear = new ReadThear(serialPort.getInputStream());
readThear.start();

到这里 串口的读写就完毕了。

但是有些情况下我们可能面临的设备su路径不正确

//默认su路径是/system/bin/su,有些设备su路径是/system/xbin/su
//在new SerialPort();之前设置su路径
SerialPort.setSuPath("/system/xbin/su");

3.字节参数的各种转换

其他:
该库还有关于 ByteUtil 用于处理字节转换的工具。

 com.aill.androidserialport.ByteUtil.java
//字符串转字节
public static byte[] hexStringToByteArray(String s)
//字节转字符串
public static String hexBytesToString(byte[] hexBytes)
//16进制字符串转int
public static int hexStringToInt(String hexString)
//16进制字符串转byte数组
public static byte[] hexStringToBytes(String hexString)

其他常用转换方法:

// 可以将float转为16进制int
Float.floatToIntBits(float num) 
//不要将int强转byte因为int8位,byte4位,强转会不准确,
//下面就是将int转为byte[]数组
ByteBuffer.allocate(4).putInt(int num).array();  

//byte[] 数组的复制

System.arraycopy(Object src,  int  srcPos,Object dest, int destPos,int length);
* @param      src      the source array. 源数组
* @param      srcPos   starting position in the source array. 源数组的起始位置
* @param      dest     the destination array. 目标数组
* @param      destPos  starting position in the destination data. 目标数组的起始位置
* @param      length   the number of array elements to be copied. 复制的长度

案例:
例如串口需要发送 10 位字节 参数分别为:

20 ff 11 00 00 00 00 00 00 3a

那么我们的 byte[] 的写法为

 private byte[] data = new byte[]{
            0x20 , (byte) 0xff, 0x11, 0x00,
            0x00, 0x00, 0x00, 0x00,
             0x00, 0x3a
    };
0

评论区