RDK X3与ESP32串口通讯 - 非阻塞式互传字符串
本文实现了RDK X3和ESP32通过UART串口双向通讯,实现字母+数字的复合通讯需求。并且,所有的通讯部分均使用非阻塞式的函数,未来使用时,只需要在程序主循环中按照一定的频率调用这个非阻塞式的函数来检查串口收发即可。
代码托管在GitHub:https://github.com/WuChao-2024/UART_X3_ESP32
使用示例
硬件连接图
RDK X3在40PIN上默认使能 UART3,物理管脚号 8 和 10,IO电压 3.3V,支持波特率:9600,19200,38400,57600,115200,921600.
我使用的ESP32开发板为ESP32-DevKitC-V1,基本上淘宝20元出头的都是这个板子,IO电压3.3V,有三个硬串口,分别为UART0,1,2,其中0用于固件下载和Debug串口输出。在这里我用的是UART2与RDK X3进行串口通讯。
如果您使用的是Arduino-UNO或者ESP8266,并且使用唯一的硬件串口与RDK X3进行通讯,烧录Arduino固件时需要断开与RDK X3的串口连接。
RDK X3 的代码(Python)
# 实现非阻塞式输入功能,实际应用中可以删除此部分代码
# Non-blocking input implementation, can be removed in practical applications
from time import sleep
from select import select
from sys import stdin
# 引入RDK X3的串口库
# Import the serial library for RDK X3
from serial import Serial
def main():
# 初始化并打开RDK X3的串口,波特率为115200
# Initialize and open the serial port for RDK X3 with a baud rate of 115200
try:
x3_serial = Serial("/dev/ttyS3", 115200, timeout=1)
except Exception as e:
print("Open Serial /dev/ttyS3 failed!\n")
exit()
print("Open serial Successfully\n")
# 程序主循环
# Main program loop
while True:
# 检查Serial2是否有数据可读,若有直到接收到换行符\n时接收数据
# Check if there is any data to read from Serial2, and receive data until encountering newline '\n'
if x3_serial.in_waiting:
data_receive_from_uart = x3_serial.read_until(b"\n").decode('UTF-8')
print("\033[31m" + "--> RDK X3 Received Message From ESP32: \n%s"%data_receive_from_uart + "\033[0m")
# 检查系统标准输入(键盘)是否有回车输入,如果有,则捕获并发送到串口
# Check if there's an enter key input from system standard input (keyboard), capture and send it to the serial port if so
r, w, e = select([stdin], [], [], 0.0)
if r:
data_receive_from_shell = stdin.readline()
print()
# 在应用中,你可以随时发送
# you can send message anytime
x3_serial.write(data_receive_from_shell.encode('UTF-8'))
# 等待1秒,假设你要做其他的事情,例如视频帧的处理
# Delay for 0.001 seconds to allow time for other operations such as video frame processing
sleep(0.001)
if __name__ == "__main__":
main()
ESP32 的代码(Arduino)
void setup() {
// 启动ESP32的调试串口Serial-0
// Start ESP32 Debug Serial-0
Serial.begin(115200);
while (!Serial);
Serial.println("Serial 0 init successfully.");
// 启动用于X3的Serial-2
// Start Serial-2 for X3
Serial2.begin(115200);
while (!Serial2);
Serial.println("Serial 2 init successfully.");
int cnt = 1;
// 程序主循环
while (true) {
// 以下程序将检查ESP32 Debug串口的输入,如果你有回车输入动作,则会捕获输入并发送
// 在应用中,你可以直接使用Serial2.println函数,将字符串发送到串口
if (Serial.available()) {
String data_receive_from_DebugSerial = Serial.readStringUntil('\n');
Serial2.println(data_receive_from_DebugSerial);
}
// 从Serial2接收数据,一直接收到\n
// Receive data from Serial2 until \n
if (Serial2.available()) {
String data_receive_from_uart = Serial2.readStringUntil('\n');
Serial.print("--> ESP32 Received Message From RDK X3: \n" + data_receive_from_uart);
Serial.println();
}
//等待0.01秒,假设你要做其他的事情,例如小车的PID巡线控制或处理传感器数据
// Delay for 0.01 seconds to allow time for other operations such as PID line-following control of a car or sensor data processing
delay(10);
}
}
void loop() {
}
RDK X3 的 UART回环测试
在2.0.0及以上版本的系统,参考手册:使用串口 | RDK X3用户手册 (horizon.cc)
短接RDK X3的40pin的RX和TX,也就是8和10号脚,运行测试程序。
python3 /app/40pin_samples/test_serial.py
出现以下内容说明RDK X3的串口正常
请输出需要测试的串口设备名:/dev/ttyS3
请输入波特率(9600,19200,38400,57600,115200,921600):115200
Serial<id=0x7fbe32fc40, open=True>(port='/dev/ttyS3', baudrate=115200, bytesize=8, parity='N', stopbits=1, timeout=1, xonxoff=False, rtscts=False, dsrdtr=False)
Starting demo now! Press CTRL+C to exit
Send: AA55
Recv: AA55
Send: AA55
Recv: AA55
Send: AA55
Recv: AA55
ESP32 的 UART回环测试
以下程序用于测试ESP32的UART2,使用Arduino-IDE将以下程序烧录进ESP32,短接TX2和RX2脚。
void setup() {
// 启动ESP32的调试串口Serial0
// Start ESP32 Debug Serial0
Serial.begin(115200);
while (!Serial);
Serial.println("Serial 0 init successfully.");
// 启动用于X3的Serial2
// Start Serial2 for X3
Serial2.begin(115200);
while (!Serial2);
Serial.println("Serial 2 init successfully.");
int cnt = 1;
# 程序主循环
while (true) {
// 调试信息
// Debug Message
Serial.print("loop: "); Serial.println(cnt);
cnt ++;
String data = "AA55";
Serial.println("Data Send:" + data);
Serial.print("Data Receive:");
// 向Serial2发送数据
// Send data to Serial2
Serial2.println(data);
delay(10);
// 从Serial2接收数据,直到缓冲区为空
// Receive data from Serial2 until its buffer is empty
while (Serial2.available()) {
char data_rx = Serial2.read();
Serial.print(data_rx);
}
Serial.println();
delay(1000);
}
}
void loop() {
}
串口调试器出现以下信息,说明ESP32的串口的回环测试通过:
loop: 1
Data Send:AA55
Data Receive:AA55
loop: 2
Data Send:AA55
Data Receive:AA55
loop: 3
Data Send:AA55
Data Receive:AA55
loop: 4
Data Send:AA55
Data Receive:AA55
...