The serial port communication module (@ohos.busManager.serial) provides object-oriented serial port management capabilities. It supports functions such as obtaining the list of available serial ports, enabling or disabling serial ports, reading and writing data, controlling hardware signals, and configuring flow control. This module is applicable to scenarios where data needs to be exchanged through serial ports, such as industrial automation, Internet of Things (IoT) device interconnection, embedded device debugging, and GPS module communication.
When developing serial port communication, you need to understand the following basic concepts:
Serial port
It is an expansion interface that uses serial communication, where data is transmitted sequentially one bit at a time. The serial port features simple communication lines. Only one pair of transmission lines is required to implement a two-way communication in a long distance.
Baud rate
It indicates the number of bits transmitted per second and is a metric for measuring the serial port communication rate. Common baud rates include 9600, 19200, 38400, 57600, and 115200. Both communication parties must use the same baud rate to correctly send and receive data.
Data bits
It indicates the number of actual data bits in communication and can be set to 5, 6, 7, or 8 bits. The most commonly used data bit length is 8 bits.
Parity
It is used to check the correctness of data transmission. The following modes are supported: none (NONE), odd (ODD), even (EVEN), mark (MARK), and space (SPACE).
Stop bits
It is used to identify the end of a data packet and can be set to 1 or 2 bits. The most commonly used stop bit length is 1 bit.
Flow control
It is used to control the data transmission rate and prevent data loss. Common flow control modes include hardware flow control (RTS/CTS) and software flow control (XON/XOFF).
The core process of the serial port communication service is as follows:
Figure 1 Data flow of serial port communication
Data written by the application layer → Sent by the serial port driver → Physical serial cable → Peer serial port device
↓
Data read by the application layer ← Buffered by the serial port driver ← Physical serial cable ← Peer serial port device Development tool and configuration:
As a development tool, DevEco Studio is one of the prerequisites for serial port communication development. Developers can use DevEco Studio to perform development, debugging, and packaging. Download and install DevEco Studio and verify basic operations to ensure that it can function properly. For details, see Creating a Project in DevEco Studio User Guide.
SDK version configuration:
The ArkTS APIs provided by this module require SDK API version 26.0.0 or later.
The following table describes the main APIs for serial port communication.
| API | Description |
|---|---|
| SerialPort.getSerialPortList(): Promise<SerialPort[]> | Queries the serial port device list. The SerialPort object array is returned. This API uses a promise to return the result. |
| SerialPort.open(config?: SerialConfigs): Promise<void> | Opens a serial port device. When a serial port device is opened for the first time, the system displays a dialog box asking the user to authorize access to the target serial port. If the user rejects the request, error code 35700007 is thrown. The authorization expires upon removal of the USB virtual serial port, system user switching, or restart of the device. Re-authorization is required in this case. This API uses a promise to return the result. |
| SerialPort.close(): Promise<void> | Closes a serial port device. This API uses a promise to return the result. |
| SerialPort.write(data: Uint8Array, timeout?: number): Promise<number> | Sends data to a serial port device. The length range of the data sent each time is (0, 4096]. This API uses a promise to return the result. |
| SerialPort.onDataRead(callback: Callback<Uint8Array>): void | Listens for data receiving events on the serial port. This API uses an asynchronous callback to return the received data. After close is called, all callbacks are cleared. |
| SerialPort.offDataRead(callback?: Callback<Uint8Array>): void | Cancels listening for data receiving events on the serial port. This API uses an asynchronous callback to return the result. |
| SerialPort.flush(): Promise<void> | Flushes the serial port buffer, including the read buffer and write buffer. Data in the buffer will be directly discarded and will not be sent or read. This API uses a promise to return the result. |
| SerialPort.drain(): Promise<void> | Waits until all write requests are complete. This API uses a promise to return the result. |
| SerialPort.setRts(enable: boolean): Promise<void> | Sets the status of the request to send (RTS) signal. This API uses a promise to return the result. |
| SerialPort.getCts(): Promise<boolean> | Obtains the status of the clear to send (CTS) signal. This API uses a promise to return the result. |
| SerialPort.sendBrk(): Promise<void> | Sends a BRK signal. This API uses a promise to return the result. |
SerialConfigs parameter description:
| Name | Type | Mandatory | Default Value | Description |
|---|---|---|---|---|
| baudRate | number | No | 115200 | Baud rate. |
| dataBits | DataBits | No | DataBits.EIGHT | Data bits. |
| stopBits | StopBits | No | StopBits.ONE | Stop bits. |
| parity | Parity | No | Parity.NONE | Parity bit. |
| rtscts | boolean | No | false | Check whether RTS/CTS hardware automatic flow control is enabled. true to enable; false otherwise. |
| xon | boolean | No | false | Check whether XON software flow control is enabled. true to enable; false otherwise. |
| xoff | boolean | No | false | Check whether XOFF software flow control is enabled. true to enable; false otherwise. |
| xany | boolean | No | false | Check whether the software flow control restart for any character is enabled. true to enable; false otherwise. |
The following sample code is only a necessary process for serial port communication and needs to be executed in a specific method.
Import the module.
import { serial, BusinessError } from '@kit.BasicServicesKit'; Obtain the serial port device list.
try {
const portList = await serial.getSerialPortList();
console.info(`${TAG} getSerialPortList success, count: ${portList.length}`);
portList.forEach((port: serial.SerialPort, index: number) => {
console.info(`${TAG} [${index}] portName=${port.portInfo.portName}, vendorId=${port.portInfo.vendorId}, productId=${port.portInfo.productId}`);
});
if (portList.length > 0) {
this.port = portList[0];
}
} catch (err) {
const e = err as BusinessError;
console.error(`${TAG} getSerialPortList failed, code: ${e.code}, message: ${e.message}`);
} Open the serial port device.
try {
if (!this.port) {
console.error(`${TAG} No serial port found, please call getSerialPortList first`);
return;
}
const config: serial.SerialConfigs = {
baudRate: 115200,
dataBits: serial.DataBits.EIGHT,
stopBits: serial.StopBits.ONE,
parity: serial.Parity.NONE
};
await this.port.open(config);
console.info(`${TAG} open success`);
} catch (err) {
const e = err as BusinessError;
console.error(`${TAG} open failed, code: ${e.code}, message: ${e.message}`);
} Register a callback to receive data and listen for serial port data.
try {
if (!this.port) {
console.error(`${TAG} No serial port found, please call getSerialPortList first`);
return;
}
this.dataCallback = (data: Uint8Array) => {
console.info(`${TAG} onDataRead: ${Array.from(data).join(', ')}`);
};
this.port.onDataRead(this.dataCallback);
console.info(`${TAG} onDataRead registered`);
} catch (err) {
const e = err as BusinessError;
console.error(`${TAG} onDataRead failed, code: ${e.code}, message: ${e.message}`);
} Write data through the serial port.
try {
if (!this.port) {
console.error(`${TAG} No serial port found, please call getSerialPortList first`);
return;
}
const data = new Uint8Array([0x48, 0x65, 0x6C, 0x6C, 0x6F]);
const writeLen = await this.port.write(data);
console.info(`${TAG} write success, length: ${writeLen}`);
} catch (err) {
const e = err as BusinessError;
console.error(`${TAG} write failed, code: ${e.code}, message: ${e.message}`);
} Refresh the buffer and wait until the sending is complete.
try {
if (!this.port) {
console.error(`${TAG} No serial port found, please call getSerialPortList first`);
return;
}
await this.port.flush();
console.info(`${TAG} flush success`);
} catch (err) {
const e = err as BusinessError;
console.error(`${TAG} flush failed, code: ${e.code}, message: ${e.message}`);
} Hardware signal control.
Set the RTS signal to high level.
try {
if (!this.port) {
console.error(`${TAG} No serial port found, please call getSerialPortList first`);
return;
}
await this.port.setRts(true);
console.info(`${TAG} setRts(true) success`);
} catch (err) {
const e = err as BusinessError;
console.error(`${TAG} setRts failed, code: ${e.code}, message: ${e.message}`);
} Obtain the CTS signal status.
try {
if (!this.port) {
console.error(`${TAG} No serial port found, please call getSerialPortList first`);
return;
}
const ctsStatus = await this.port.getCts();
console.info(`${TAG} getCts success, CTS: ${ctsStatus}`);
} catch (err) {
const e = err as BusinessError;
console.error(`${TAG} getCts failed, code: ${e.code}, message: ${e.message}`);
} Send the break signal.
try {
if (!this.port) {
console.error(`${TAG} No serial port found, please call getSerialPortList first`);
return;
}
await this.port.sendBrk();
console.info(`${TAG} sendBrk success`);
} catch (err) {
const e = err as BusinessError;
console.error(`${TAG} sendBrk failed, code: ${e.code}, message: ${e.message}`);
} Deregister the callback for receiving data and close the serial port device.
try {
if (!this.port) {
console.error(`${TAG} No serial port found, please call getSerialPortList first`);
return;
}
await this.port.close();
console.info(`${TAG} close success`);
this.port = null;
} catch (err) {
const e = err as BusinessError;
console.error(`${TAG} close failed, code: ${e.code}, message: ${e.message}`);
}