android串口通信接受自定义协议数据并解析问题

1.一般自定义的串口协议

 串口传输接口底层是按位(bit)发送的,上层是按byte发送和接收的,但协议为了方便描述,每个byte用十六进制数(0x00~0xFF)表示,范相当于十进制的0~255,而byte为八位且是有符号类型,相当于十进制的-128~127,明显0x8F~0xFF(128~255)是不能准确转换为byte的,咋办?

byte b = 0xFF;

编译器会提示出错,因为0xFF被当作255整数处理,255超过了byte(-128~127)的范围,不能直接赋值,那咋办?强转啊!

 byte b = (byte) 0xFF;

这样就没问题了,但此时你会不会觉得这样写就和协议想发送0xFF的想法不匹配了呢,我明明想发个255来着,那我告诉你,你一个一个字节的发,每个字节就只能是-128~127,不能在其他范围,所以强转的目的是你可以发送这个0xFF的前提,发送的值肯定不是255,具体是啥:

public class Main {

    public static void main(String[] args) {
        byte c1 = (byte) 0xFF;
        int c2 = c1 & 0xFF;
        System.out.println(""+c1);
        System.out.println(""+c2);
    }
}
-1
255

Process finished with exit code 0

可见,实际上是一个-1,但接受端为了表达这是个发送端发送给我的是0xFF(255)而不是-1,你可以通过取到该字节值后 “ 该值 & 0xFF”转为无符号值即255.

通常自定义协议的格式:

一.接收到数据是不固定的长度,协议是起始是AA AA    结束是DE D0
接收到的数据有可能是AA AA 08 56 82 44 DE DO

二.接受到数据是不固定的长度,协议的起始A0 55  第三个字节为协议长度,结束字节是发送数据的异或校验值,

列如:A0 55 04 51 00 00    55 A0 55 04 53 00 01 56

结束字节是前面各个字节异或后的值:

 /**
     * 异或校验和
     * @param data
     * @return
     */
    public static byte getXor(byte[] data){
        byte temp=data[0];
        for (int i = 1; i 

2.分段接收数据不好解析

在读取串口数据时,通常在线程中读取输入流中的数据,这时接受的字节数是不固定的,一条指令被分成若干段,接受到的散乱字节不好处理,看到网上有做延时接受处理,也就是输入流可用的时候就延时一会儿,等接受完了再一次性读出来,效果不错:

/**
     * 4.接收串口数据的线程
     */
    private class ReceiveThread extends Thread {
        @Override
        public void run() {
            //条件判断,只要条件为true,则一直执行这个线程
            while (isStart) {
                if (inputStream == null) {
                    return;
                }
                byte[] readData = new byte[1024*4];
                try {
                    String receiveCmd = "";
                    String HEAD = "A055";
                    StringBuilder sb = new StringBuilder();
                    // 为了一次性读完,做了延迟读取
                    if (inputStream.available() > 0 ) {
                        SystemClock.sleep(200);
                        int size = inputStream.read(readData);
                        if (size > 0) {
                            String readString = DataUtils.ByteArrToHex(readData, 0, size);
                            LogUtils.d(readString);
                            if(!TextUtils.isEmpty(readString)){
                                String[] split = readString.split(HEAD);
                                for (int i = 1; i < split.length; i++) {
                                    receiveCmd = HEAD+split[i];
                                    sb.append(receiveCmd+"\n");
                                    LogUtils.e(receiveCmd);
                                }
                            }
                            EventBus.getDefault().post(sb.toString());
                            sb.setLength(0);
                        }
                    }

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }
    }

 

 

你可能感兴趣的:(android串口通信接受自定义协议数据并解析问题)