香橙派5 Plus物联网开发实战:GPS与OLED屏的硬件交互指南
最近在折腾一个智能小车项目时,发现香橙派5 Plus作为主控板确实是个不错的选择。它丰富的接口让连接各种传感器变得异常方便,特别是UART和I2C这两个最常用的通信协议。本文将分享如何通过UART连接GPS模块获取定位数据,同时用I2C驱动OLED屏幕显示实时信息,打造一个简易的车载数据仪表盘。
1. 硬件准备与环境配置
在开始之前,我们需要确保手头有以下硬件组件:
- 香橙派5 Plus开发板(运行Ubuntu系统)
- GPS模块(支持UART通信,如NEO-6M)
- 0.96寸OLED显示屏(SSD1306驱动,I2C接口)
- 杜邦线若干
- 5V电源适配器
系统环境检查:
首先登录香橙派,打开终端执行以下命令检查系统信息:
uname -a cat /etc/os-release确认系统版本为Ubuntu,内核版本支持Rockchip RK3588芯片组。如果系统版本不符,建议先更新到最新版本:
sudo apt update && sudo apt upgrade -y2. 启用UART接口连接GPS模块
GPS模块通常使用UART进行数据传输,我们需要先启用香橙派5 Plus上的UART接口。
2.1 确定GPS模块的连接引脚
以NEO-6M GPS模块为例,它通常有四根线:
- VCC(3.3V或5V)
- GND
- TX(发送)
- RX(接收)
香橙派5 Plus的40针GPIO接口上,UART3的引脚定义如下:
| 功能 | 物理引脚号 | GPIO编号 |
|---|---|---|
| TX | 8 | GPIO1_B0 |
| RX | 10 | GPIO1_B1 |
| GND | 6 | - |
注意:连接时GPS模块的TX应接香橙派的RX,RX接TX,不要接反。
2.2 配置系统启用UART3
编辑系统配置文件启用UART3接口:
sudo nano /boot/firmware/ubuntuEnv.txt找到overlays=这一行,添加rk3588-uart3-m1(注意如果已有其他overlay,用空格分隔):
overlays=rk3588-uart3-m1保存后重启系统:
sudo reboot重启后检查UART设备是否成功启用:
ls /dev/ttyS*应该能看到/dev/ttyS3设备文件。
2.3 测试GPS数据接收
安装Python串口库并编写测试脚本:
sudo apt install python3-pip pip3 install pyserial创建gps_test.py文件:
import serial from time import sleep ser = serial.Serial('/dev/ttyS3', baudrate=9600, timeout=1) try: while True: data = ser.readline().decode('ascii', errors='replace').strip() if data.startswith('$GPRMC'): print(f"GPS数据: {data}") sleep(0.1) except KeyboardInterrupt: ser.close() print("程序结束")运行脚本后,将GPS模块放置在开阔区域,应该能看到类似以下的NMEA格式数据:
$GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A3. 配置I2C接口驱动OLED屏幕
OLED显示屏通常使用I2C协议通信,下面介绍如何启用I2C并驱动SSD1306屏幕。
3.1 硬件连接
SSD1306 OLED屏通常有四根线:
- VCC(3.3V)
- GND
- SCL(时钟)
- SDA(数据)
连接到香橙派5 Plus的GPIO:
| OLED引脚 | 香橙派引脚 | 功能 |
|---|---|---|
| VCC | 1 | 3.3V |
| GND | 9 | GND |
| SCL | 5 | GPIO3_A1 (I2C2_SCL) |
| SDA | 3 | GPIO3_A0 (I2C2_SDA) |
3.2 启用I2C接口
编辑配置文件启用I2C2:
sudo nano /boot/firmware/ubuntuEnv.txt修改overlays=行,添加rk3588-i2c2-m0:
overlays=rk3588-uart3-m1 rk3588-i2c2-m0保存后重启:
sudo reboot检查I2C设备:
ls /dev/i2c*应该能看到/dev/i2c-2设备。安装工具检测设备:
sudo apt install i2c-tools sudo i2cdetect -y 2如果OLED连接正确,应该能看到类似以下输出,其中3C是SSD1306的默认地址:
0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- 3c -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --3.3 使用Python驱动OLED
安装必要的库:
pip3 install smbus2 pillow对于SSD1306 OLED,我们可以使用luma.oled库:
pip3 install luma.oled创建oled_test.py文件:
from luma.core.interface.serial import i2c from luma.oled.device import ssd1306 from luma.core.render import canvas from time import sleep # 初始化I2C和OLED设备 serial = i2c(port=2, address=0x3C) device = ssd1306(serial) # 显示测试内容 with canvas(device) as draw: draw.rectangle(device.bounding_box, outline="white", fill="black") draw.text((10, 10), "香橙派5 Plus", fill="white") draw.text((10, 30), "OLED测试", fill="white") sleep(5)运行脚本后,OLED屏幕应该会显示测试文字。
4. 构建智能小车数据仪表盘
现在我们将GPS数据和OLED显示结合起来,创建一个实时显示位置信息的仪表盘。
4.1 解析GPS数据
修改之前的GPS测试脚本,增加NMEA数据解析功能:
import serial from time import time def parse_gprmc(gprmc_str): """解析GPRMC NMEA语句""" parts = gprmc_str.split(',') if len(parts) < 12 or parts[2] != 'A': return None # 解析纬度 lat_deg = float(parts[3][:2]) lat_min = float(parts[3][2:]) latitude = lat_deg + lat_min / 60 if parts[4] == 'S': latitude = -latitude # 解析经度 lon_deg = float(parts[5][:3]) lon_min = float(parts[5][3:]) longitude = lon_deg + lon_min / 60 if parts[6] == 'W': longitude = -longitude # 解析速度(节转换为km/h) speed = float(parts[7]) * 1.852 if parts[7] else 0.0 return { 'time': parts[1], 'latitude': latitude, 'longitude': longitude, 'speed': speed, 'date': parts[9] }4.2 综合显示程序
创建完整的仪表盘程序dashboard.py:
import serial from luma.core.interface.serial import i2c from luma.oled.device import ssd1306 from luma.core.render import canvas from time import sleep, strftime from datetime import datetime # 初始化OLED oled_serial = i2c(port=2, address=0x3C) oled = ssd1306(oled_serial) # 初始化GPS gps = serial.Serial('/dev/ttyS3', baudrate=9600, timeout=1) def format_coord(coord, is_lat): """格式化经纬度显示""" direction = 'N' if is_lat and coord >=0 else 'S' if is_lat else 'E' if coord >=0 else 'W' abs_coord = abs(coord) degrees = int(abs_coord) minutes = (abs_coord - degrees) * 60 return f"{degrees}°{minutes:.2f}'{direction}" last_update = 0 current_data = None try: while True: # 读取GPS数据 line = gps.readline().decode('ascii', errors='ignore').strip() if line.startswith('$GPRMC'): current_data = parse_gprmc(line) last_update = time() # 每0.5秒刷新一次显示 if time() - last_update < 0.5: with canvas(oled) as draw: # 显示标题 draw.text((5, 2), "智能小车仪表盘", fill="white") if current_data: # 显示GPS数据 draw.text((5, 15), f"���间: {current_data['time'][:2]}:{current_data['time'][2:4]}", fill="white") draw.text((5, 25), f"纬度: {format_coord(current_data['latitude'], True)}", fill="white") draw.text((5, 35), f"经度: {format_coord(current_data['longitude'], False)}", fill="white") draw.text((5, 45), f"速度: {current_data['speed']:.1f} km/h", fill="white") else: draw.text((15, 30), "等待GPS信号...", fill="white") # 显示系统时间 draw.text((70, 2), strftime("%H:%M"), fill="white") sleep(0.1) except KeyboardInterrupt: gps.close() print("仪表盘关闭")4.3 常见问题排查
在实际项目中可能会遇到以下问题:
GPS无数据输出:
- 检查接线是否正确(TX/RX不要接反)
- 确保GPS模块有足够开阔的天空视野
- 尝试降低波特率(有些模块默认是4800而不是9600)
OLED不显示:
- 使用
i2cdetect确认设备地址是否正确 - 检查OLED是否需要外部供电(有些模块需要单独5V供电)
- 确认I2C是否已正确启用
- 使用
系统重启后配置丢失:
- 确保修改的是
/boot/firmware/ubuntuEnv.txt而不是临时文件 - 检查文件权限是否正确
- 确保修改的是
# 检查文件权限 ls -l /boot/firmware/ubuntuEnv.txt # 应该显示类似:-rw-r--r-- 1 root root5. 项目扩展与优化建议
基础功能实现后,可以考虑以下增强功能:
5.1 数据记录功能
添加SD卡模块,记录行驶轨迹:
import csv from datetime import datetime def init_log_file(): with open('/mnt/sdcard/gps_log.csv', 'a', newline='') as f: writer = csv.writer(f) writer.writerow(['timestamp', 'latitude', 'longitude', 'speed']) def log_position(data): with open('/mnt/sdcard/gps_log.csv', 'a', newline='') as f: writer = csv.writer(f) writer.writerow([ datetime.now().isoformat(), data['latitude'], data['longitude'], data['speed'] ])5.2 添加更多传感器
通过I2C可以连接更多传感器丰富数据:
- BME280:温湿度气压传感器
- MPU6050:加速度计/陀螺仪
- BH1750:光照传感器
多传感器连接时注意地址冲突,有些模块(如BME280)支持修改I2C地址。
5.3 优化显示效果
使用Pillow库创建更丰富的显示内容:
from PIL import ImageFont # 加载自定义字体 font_small = ImageFont.truetype("DejaVuSans.ttf", 10) font_large = ImageFont.truetype("DejaVuSans.ttf", 14) with canvas(oled) as draw: draw.text((5, 5), "智能小车", font=font_large, fill="white") draw.text((5, 25), f"速度: {speed:.1f} km/h", font=font_small, fill="white") # 绘制简单的速度条 draw.rectangle((5, 40, 5 + int(speed), 45), outline="white", fill="white")5.4 低功耗优化
对于电池供电的小车项目,可以考虑:
- 降低CPU频率
- 关闭不必要的服务
- 使用
vcgencmd工具监控功耗
# 安装vcgencmd工具 sudo apt install libraspberrypi-bin # 查看当前功耗 vcgencmd get_throttled