SoFunction
Updated on 2025-04-10

Android's operation guide for reading serial port data

Reading serial port data on Android systems is a common requirement, especially when we need to communicate with hardware devices. Through open source projectsCrazy-MT/SerialAssistant, we can quickly learn how to implement this feature on Android. The following are detailed steps and code examples to help you better understand and implement serial communication.

1. Determine the serial number and baud rate

1. Find device files

In Linux systems (Android is based on Linux), serial devices are usually represented as /dev/ttySx or /dev/ttyUSBx, where x is a number. For example, /dev/ttyS0 represents the first serial port, and /dev/ttyUSB0 represents the first USB serial port adapter.

2. View available serial ports through the file system

You can use the ls /dev/tty* command in the terminal of your Android device to view available serial device files. Use ADB (Android Debug Bridge) to connect and access device terminals:

adb shell
ls /dev/tty*

2. Determine the baud rate

The baud rate is the rate of serial communication, and the unit is baud. Common baud rates are 9600, 19200, 38400, 57600, 115200, etc. The choice of baud rate is usually determined by the specifications or protocols of the serial port device. You need to consult the equipment manual or confirm with the equipment supplier.

3. Read serial port data

After selecting the correct serial port number and baud rate, the serial port data can be read through the input stream. Here is a sample code for reading a thread:

private class ReadThread extends Thread {
    @Override
    public void run() {
        ();
        while(!isInterrupted()) {
            try
            {
                if (mInputStream == null) return;
                int size = (tempBuff);
                if (size > 0){
                    onDataReceived((tempBuff, 0, size));
                }
                try
                {
                    (10);//Delay 10ms                } catch (InterruptedException e)
                {
                    ();
                }
            } catch (Throwable e)
            {
                ();
                return;
            }
        }
    }
}

4. Data packet processing

Taking a certain brand of electronic scales as an example, its data protocol is as follows:

Take the weight

1、initiative/The data format of the passive mode is the same。
2、Advance computer command(HEX): 1b 01 02
3、Data format:(Total 24 byte)

01 02  000.000kg 000.000kg sta  X   03 04
Data header  net weight       Tare weight      state check Data tail

SHead1        SOH(01H)   1 byte,Title Begins
SHead2        STX(02H)   1 byte,Start the text
Weight 1          7 byte,net weight。
Weight Units  U1U0       2 byte,Units of weight。like“kg”
Weight2           7 byte,Tare weight。
Weight Units  U1U0       2 byte,Units of weight。like“kg”
Status        STA        1 byte,state
Check Sum     BCC        1 byte,use BCC algorithm,remove SOH STX ETX EOT 及本byte外所有字符的 BCC check。
Tail1         ETX(03H)   1 byte,End of title
Tail2         EOT(04H)   1 byte,Transmission ends

Weight format(net weight/Tare weight),例like:
123.456kg
23.456kg
12.3456kg
0.012kg
-12.345kg
-1.234kg
-0.0001kg
(If there is no data in front, fill it with spaces。like果小数点后面有四位,That is accurate 0.1g)

state:
bit7:1 Weight overflow;0 Normal weight
bit6:1 Not reset to zero after booting(There are heavy objects on the weighing plate when the machine is turned on);0 Reset to zero after booting
bit5:1 Currently in peeling mode;0 Not currently    Peeling mode
bit4:1 The current weight is 0;0 The current weight is not 0 
bit3:1 Stable weight;0 Unstable weight 
bit2~bit0  0

In serial communication, processing data packets and ensuring data integrity is an important task. In this blog, we will explore how to use Java to read data through the serial port and make sure that each read data is complete. We will explain how to design a system to process packets, including the logic of packet parsing and verification.

5. Packet parsing class

Define an abstract packet class Packet:

public abstract class Packet {
    protected byte[] data;

    public Packet(byte[] data) {
         = data;
    }

    public byte[] getData() {
        return data;
    }

    public abstract String getNetWeight();
    public abstract String getTareWeight();
    public abstract byte getStatus();
}

Implement specific data analysis class DefaultPacket:

public class DefaultPacket extends Packet {

    public DefaultPacket(byte[] data) {
        super(data);
    }

    @Override
    public String getNetWeight() {
        return new String(data, 2, 7);
    }

    @Override
    public String getTareWeight() {
        return new String(data, 11, 7);
    }

    @Override
    public byte getStatus() {
        return data[20];
    }

    public static String parseStatus(byte status) {
        StringBuilder sb = new StringBuilder();
        ("Weight Overflow: ").append((status & 0x80) != 0).append("\n");
        ("Not Zeroed on Power-up: ").append((status & 0x40) != 0).append("\n");
        ("Tare Mode: ").append((status & 0x20) != 0).append("\n");
        ("Weight is Zero: ").append((status & 0x10) != 0).append("\n");
        ("Weight Stable: ").append((status & 0x08) != 0).append("\n");
        return ();
    }
}

6. Packet parsing interface and implementation class

Define the packet resolution interface PacketParser:

public interface PacketParser {
    int getDataLength();
    boolean isValid(byte[] data);
    boolean checkChecksum(byte[] data);
    Packet parse(byte[] data);
}

Specific data packet analysis class

DefaultPacketParser implements specific packet parsing and verification logic:

public class DefaultPacketParser implements PacketParser {
    @Override
    public int getDataLength() {
        return 24;
    }

    @Override
    public boolean isValid(byte[] data) {
        return data[0] == 0x01 && data[1] == 0x02 && data[22] == 0x03 && data[23] == 0x04;
    }

    @Override
    public boolean checkChecksum(byte[] data) {
        byte checksum = 0;
        for (int i = 2; i < 21; i++) {
            checksum ^= data[i];
        }
        return checksum == data[21];
    }

    @Override
    public Packet parse(byte[] data) {
        return new DefaultPacket(data);
    }
}

7. Packet input stream class

The PacketInputStream class uses PacketParser to process the parsing and verification of data packets and accumulates invalid data:

import ;
import ;
import ;
import ;
import ;

public class PacketInputStream extends FilterInputStream {
    private PacketParser parser;
    private byte[] buffer;
    private int bufferPos = 0;
    private ByteArrayOutputStream byteArrayBuffer = new ByteArrayOutputStream();

    public PacketInputStream(InputStream in, PacketParser parser) {
        super(in);
         = parser;
         = new byte[()];
    }

    public Packet readPacket() throws IOException {
        // Write the remaining invalid data to the buffer        if (() &gt; 0) {
            byte[] invalidData = ();
            (invalidData, 0, buffer, 0, );
            bufferPos = ;
            ();
        }

        while (bufferPos &lt; ()) {
            int read = (buffer, bufferPos, () - bufferPos);
            if (read == -1) {
                return null; // EOF reached
            }
            bufferPos += read;
        }

        int start = findPacketStart(buffer);
        while (start == -1 &amp;&amp; bufferPos &gt;= 2) {
            (buffer, 1, buffer, 0, bufferPos - 1);
            bufferPos--;
            int read = (buffer, bufferPos, 1);
            if (read == -1) {
                return null; // EOF reached
            }
            bufferPos += read;
            start = findPacketStart(buffer);
        }

        if (start != 0) {
            byte[] remainingData = (buffer, start, bufferPos);
            (remainingData, 0, buffer, 0, );
            bufferPos = ;
            return null;
        }

        if (!(buffer)) {
            (buffer, 0, bufferPos);
            bufferPos = 0;
            return null; // Return null means invalid packet        }

        if (!(buffer)) {
            (buffer, 0, bufferPos);
            bufferPos = 0;
            return null; // Return null to indicate verification failure        }

        Packet packet = ((buffer, ()));
        bufferPos = 0;
        return packet;
    }

    private int findPacketStart(byte[] data) {
        for (int i = 0; i &lt;  - 1; i++) {
            if (data[i] == 0x01 &amp;&amp; data[i + 1] == 0x02) {
                return i;
            }
        }
        return -1;
    }
}

8. Read thread class

ReadThread uses PacketInputStream and PacketParser to read and process packets:

import ;

private class ReadThread extends Thread {
    private PacketInputStream packetInputStream;

    public ReadThread(InputStream inputStream, PacketParser parser) {
         = new PacketInputStream(inputStream, parser);
    }

    @Override
    public void run() {
        ();
        while (!isInterrupted()) {
            try {
                Packet packet = ();
                if (packet != null) {
                    if (packet instanceof DefaultPacket) {
                        onDataReceived((DefaultPacket) packet);
                    }
                }
            } catch (IOException e) {
                ();
                return;
            }
        }
    }

    private void onDataReceived(DefaultPacket packet) {
        ("Net Weight: " + ());
        ("Tare Weight: " + ());
        ("Status: " + (()));
    }
}

Summarize

Through abstract packet analysis logic, we can better handle the integrity of serial packets. We define the packet classes Packet and DefaultPacket, and use the PacketParser interface to implement the parsing and verification of packets. The PacketInputStream class is responsible for handling the read and accumulation of invalid data of data, while ReadThread is responsible for reading and processing valid data packets. This design makes the code more modular, easy to maintain and scale, and can easily adapt to packets in different formats.

The above is the detailed content of the Android operation guide for reading serial port data. For more information about reading serial port data from Android, please pay attention to my other related articles!