Android 读取 485设备数据

187 阅读1分钟

最近在做一个项目,采用 Android 的工控屏通过 485 协议读取硬件数据,经过一顿折腾,终于可以正常的读取到数据了,不过还有点问题,希望大神指点。

首先加载andoird 串口库

dependencies {
    implementation 'io.github.xmaihh:serialport:2.1.1'
}

获取设备数据

import android.util.Log;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import android_serialport_api.SerialPort;

public class SerialComm {
    private SerialPort serialPort;
    private InputStream inputStream;
    private OutputStream outputStream;
    private ReadThread mReadThread;
    private List<Byte> receivedDataBuffer = new ArrayList<>();
    private static final int PACKET_LENGTH = 5; // 假设数据包长度为16字节

    public void open() {
        try {
            serialPort = new SerialPort(new File("/dev/ttyS2"), 9600, 1, 8, 0, 0, 0);
            inputStream = serialPort.getInputStream();
            outputStream = serialPort.getOutputStream();
            mReadThread = new ReadThread();
            mReadThread.start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void close() {
        if (serialPort != null) {
            serialPort.close();
        }
    }

    public void write(byte[] data) {
        try {
            outputStream.write(data);
            outputStream.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void sendHexString(String hexString) throws IOException {
        byte[] bytes = hexStringToByteArray(hexString);
        outputStream.write(bytes);
    }

    private byte[] hexStringToByteArray(String hexString) {
        int len = hexString.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4)
                    + Character.digit(hexString.charAt(i + 1), 16));
        }
        return data;
    }
    //在子线程里面完成获取数据
    private class ReadThread extends Thread {
        @Override
        public void run() {
            while (true) {
                try {
                    if (inputStream == null) return;
                    //这里获取到有效的数据长度,不知道为什么 485 会把一条数据,分多次返回
                    int available = inputStream.available();

                    if (available > 0) {
                        Log.e("有效长度",available + "");
                        byte[] buffer = new byte[available];
                        int bytesRead = inputStream.read(buffer);
                        if (bytesRead > 0) {
                            for (int i = 0; i < bytesRead; i++) {
                                receivedDataBuffer.add(buffer[i]);
                            }
                            processReceivedData();
                        }
                    }
                    Thread.sleep(10);
                } catch (Throwable e) {
                    Log.e("SerialComm", "读取数据异常", e);
                    return;
                }
            }
        }
    }
    /**
    * 将获取到的数据,进行长度比较,如果小于预设长度,存放到 ArrayList 里面
    */
    private void processReceivedData() {
        while (receivedDataBuffer.size() >= PACKET_LENGTH) {
            byte[] completePacket = new byte[PACKET_LENGTH];
            for (int i = 0; i < PACKET_LENGTH; i++) {
                completePacket[i] = receivedDataBuffer.get(i);
            }
            handleCompletePacket(completePacket);
            for (int i = 0; i < PACKET_LENGTH; i++) {
                receivedDataBuffer.remove(0);
            }
        }
    }
    //将完成的数据转换成十六进制的数据
    private void handleCompletePacket(byte[] packet) {
        String hexString = Utils.bytesToHex(packet);
        Log.d("SerialComm", "Received Packet: " + hexString);
        // 在这里添加对完整数据包的处理逻辑
    }
}