SoFunction
Updated on 2025-03-10

Android serial communication programming and serial protocol analysis

Android serial communication programming: Embedded programming, wearable devices and smart devices will use serial ports. Here I will analyze it.

1. Android serial communication

Serial port communication adopts a third-party open source project to realize serial port data transmission and reception.

1. Serialport api and jni of the project using /p/android-serialport-api/;
2. Supports 4 serial ports to send and receive simultaneously, with a regular automatic transmission function, and the Txt or Hex mode can be selected for the sending and receiving mode;
3. n,8,1, no choice;
4. To alleviate the interface lag, the refresh of the receiving area uses a separate thread for regular refresh;
5. The data in the sending area and some settings will be automatically saved when the program is closed and will be automatically loaded when it is opened;
6. jni recompiled it with the latest NDKr8b

Simple writing steps:

1. Create a new project and name it yourself
2. Directly copy the serialport API and jni folders to the newly created project. If you don’t want to compile jni by yourself, even copy the libs folder together.
3. Go to the official Android website to download NDK, unzip, go to the jni directory in CMD, and execute the absolute path\ndk-build
4. Encapsulate a tool class yourself or use the SerialPort class directly. Take a direct use example:
Directly plagiarize the original project and make some changes to this point
mSerialPort = ();
It can be changed here
new SerialPort(new File("/dev/s3c2410_serial0"), 9600, 0);//COM0, baud rate 9600
5. There is nothing to say about the use of SerialPortFinder. After instantiation, you can get all devices by using .getAllDevicesPath().
For other data conversion, please refer to the source code

You can refer to Google android-serialport-api example for the source code

/p/android-serialport-api/source/checkout
svn checkout /svn/trunk

2. Analysis of serial communication protocol

1. Basic communication format

Field Description Length (bytes)
Starting symbol 0F, hexadecimal code 1
Information type: One byte, hexadecimal code (0F, F0, FF, etc. reserved codes are not used) 1
The information length is the length of the information content. The ASCII code represents (0~9, A~F, the maximum length is 256) (for example, the length is 11, and the hexadecimal is 0B, then two bytes are written 0x30 0x42).
Note: Because the maximum length 256 cannot meet the requirements of some instructions, the length has been expanded. The following is the extension description:
If the highest bit of the first byte is 1, it indicates the extended length. In the extended length state, the other 15 bytes save the length through hexadecimal big-endian mode. For example: 0x80 0x12 means length is 0x001 2, 0x81 0x12 means length is 0x0112. 2
Information content A set of hexadecimal codes N
Verification One byte, hexadecimal code, is the exclusive OR of all codes from the information type to the object number. 1
End symbol F0, one byte, hexadecimal code (To ensure reliability, the end symbol issued by the car machine is F0 FF) 1

2. Protocol analysis


/**
    * Read terminal device data
    * @author Administrator
    */ 
  private class ReadThread extends Thread { 
 
    @Override 
    public void run() { 
      (); 
 
      // Define the maximum length of a package      int maxLength = 2048; 
      byte[] buffer = new byte[maxLength]; 
      // The actual length is received each time      int available = 0; 
      // Total length of the packets currently received      int currentLength = 0; 
      // Protocol header length is 4 bytes (start character 1, type 1, length 2)      int headerLength = 4; 
 
      while (!isInterrupted()) { 
        try { 
          available = (); 
          if (available > 0) { 
            // Prevent overflow from exceeding the maximum length of the array            if (available > maxLength - currentLength) { 
              available = maxLength - currentLength; 
            } 
            (buffer, currentLength, available); 
            currentLength += available; 
          } 
           
        } 
        catch (Exception e) { 
          (); 
        } 
 
        int cursor = 0; 
        // If the currently received packet is greater than the length of the header, parse the current packet        while (currentLength >= headerLength) { 
          // Get the first byte at the head          if (buffer[cursor] != 0x0F) { 
            --currentLength; 
            ++cursor; 
            continue; 
          } 
           
          int contentLenght = parseLen(buffer, cursor, headerLength); 
          // If the length of the content package is greater than the maximum content length or is less than or equal to 0, it means that there is a problem with the package and discard it          if (contentLenght <= 0 || contentLenght > maxLength - 5) { 
            currentLength = 0; 
            break; 
          } 
          // If the current length is obtained is less than the length of the entire packet, a loop will be released and wait for data to continue receiving          int factPackLen = contentLenght + 5; 
          if (currentLength < contentLenght + 5) { 
            break; 
          } 
 
          // A complete package is generated          // proceOnePacket(buffer,i,factPackLen); 
          onDataReceived(buffer, cursor, factPackLen); 
          currentLength -= factPackLen; 
          cursor += factPackLen;  
        } 
        // The residual bytes are moved to the first buffer        if (currentLength > 0 && cursor > 0) { 
          (buffer, cursor, buffer, 0, currentLength); 
        } 
      } 
    } 
  } 
 
  /**
    * Get the length of the protocol content
    * @param header
    * @return
    */ 
  public int parseLen(byte buffer[], int index, int headerLength) { 
 
//   if ( - index < headerLength) { return 0; } 
    byte a = buffer[index + 2]; 
    byte b = buffer[index + 3]; 
    int rlt = 0; 
    if (((a >> 7) & 0x1) == 0x1) { 
      rlt = (((a & 0x7f) << 8) | b); 
    } 
    else { 
      char[] tmp = new char[2]; 
      tmp[0] = (char) a; 
      tmp[1] = (char) b; 
      String s = new String(tmp, 0, 2); 
      rlt = (s, 16); 
    } 
 
    return rlt; 
  } 
 
protected void onDataReceived(final byte[] buffer, final int index, final int packlen) { 
    ("Message Received"); 
    byte[] buf = new byte[packlen]; 
    (buffer, index, buf, 0, packlen); 
    (myHandler).analyze(buf);  
  } 

Thank you for reading, I hope it can help you. Thank you for your support for this site!