GPS桌面时钟
本文介绍了 RP2350 通过 MicroPython 编程实现桌面 GPS 卫星授时时钟的项目设计。
项目介绍
包括串口连接测试、原始 NMEA 数据捕获、库函数调用与格式转换、获取 GPS 卫星授时数据、OLED 显示等流程。
硬件连接
示意图

GP-02
GP-02 | RP2350 |
---|---|
RX | GPIO0 |
TX | GPIO1 |
VCC | 3V3 |
GND | GND |
OLED
GP4 ---- SDA (OLED_SSD1306)
GP5 ---- SCL (OLED_SSD1306)
工程调试
包括串口读取 GP-02 模组原始数据、NVEA 数据解析,为之后的代码合并和调用作铺垫。
原始数据
串口连接 GP-02 模组,终端打印原始串口数据
代码
'''
Name: GPS module
Version: v1.0
Date: 2025.05
Author: ljl
Other: Acquiring origin GPS data and print them in Shell
'''
from machine import Pin, UART
import time
# initialize UART
gps_uart = UART(0, baudrate=9600, tx=Pin(0), rx=Pin(1))
def read_gps_data():
""" Read GPS data and print """
if gps_uart.any():
line = gps_uart.readline().decode('utf-8').strip()
print(f"{line}")
while True:
read_gps_data()
time.sleep(0.05)
连接芯片,配置解释器,运行代码。
效果
终端打印原始 NMEA 数据

分别给出几种不同卫星定位系统的数据

解析数据
使用 micropyGPS 库实现 GPS 原始 NMEA 数据解析,实现 GP-02 模组的快速开发和应用。
代码
'''
Name: GPS data translation
Version: v1.0
Date: 2025.05
Author: ljl
Other: Translate origin GPS data by micropyGPS library and print them in Shell
'''
from machine import UART,Pin
from micropyGPS import MicropyGPS
import time
# initialize UART configuration
gps_uart = UART(0, baudrate=9600, tx=Pin(0), rx=Pin(1))
# initialize GPS translator
my_gps = MicropyGPS(8) # east eight time zone
def update_gps():
""" Read GPS module """
while gps_uart.any():
char = gps_uart.read(1)
if char:
my_gps.update(chr(char[0]))
def print_gps_data():
""" print GPS data """
if my_gps.date and my_gps.timestamp:
date_str = f"{my_gps.date[2]}-{my_gps.date[1]:02d}-{my_gps.date[0]:02d}"
time_str = f"{my_gps.timestamp[0]:02d}:{my_gps.timestamp[1]:02d}:{int(my_gps.timestamp[2]):02d}"
latitude_str = f"{my_gps.latitude[0]:.6f} {my_gps.latitude[1]}"
longitude_str = f"{my_gps.longitude[0]:.6f} {my_gps.longitude[1]}"
speed_str = f"{my_gps.speed[2]:.2f} km/h"
print(f"Date: {date_str}")
print(f"Time: {time_str}")
print(f"Latitude: {latitude_str}")
print(f"Longitude: {longitude_str}")
print(f"Speed: {speed_str}")
else:
print("Waiting for GPS data...")
while True:
update_gps()
print_gps_data()
time.sleep(1)
效果
终端打印日期、时间、经纬度、速度信息

流程图

工程代码
在前面获取 GP-02 模组数据并实现转换的基础上,进一步结合 OLED 和电池模块,实现桌面 GPS 授时时钟的设计。
'''
Name: GPS clock
Version: v1.0
Date: 2025.05
Author: ljl
Other: Acquiring GPS data and showing on OLED screen
include data, time, latitude, longtitude and speed.
The micropyGPS.py is necessary, see details to https://github.com/inmcm/micropyGPS/
'''
from machine import Pin, I2C, UART, ADC
import ssd1306
from micropyGPS import MicropyGPS
import time
# initialize I2C and OLED
sda = Pin(4)
scl = Pin(5)
i2c = I2C(0, sda=sda, scl=scl, freq=400000)
oled = ssd1306.SSD1306_I2C(128, 64, i2c)
# initialize UART
gps_uart = UART(0, baudrate=9600, tx=Pin(0), rx=Pin(1))
# initialize GPS
my_gps = MicropyGPS(8) # east eight time zone
# initialize ADC pin
adc = ADC(Pin(29))
def update_gps():
""" Read data from GPS module """
while gps_uart.any():
char = gps_uart.read(1)
if char:
my_gps.update(chr(char[0]))
def display_data():
""" Display Date on OLED """
oled.fill(0)
if my_gps.date and my_gps.timestamp:
date_str = f"{my_gps.date[2]}-{my_gps.date[1]:02d}-{my_gps.date[0]:02d}"
time_str = f"{my_gps.timestamp[0]:02d}:{my_gps.timestamp[1]:02d}:{int(my_gps.timestamp[2]):02d}"
latitude_str = f"{my_gps.latitude[0]:.3f} {my_gps.latitude[1]}"
longitude_str = f"{my_gps.longitude[0]:.3f} {my_gps.longitude[1]}"
speed_str = f"{my_gps.speed[2]:.1f} km/h"
oled.text('Date: '+date_str, 0, 0)
oled.text('Time: '+time_str, 0, 10)
oled.text('LAT: '+latitude_str, 0, 20)
oled.text('LON: '+longitude_str, 0, 30)
oled.text('Speed: '+speed_str, 0, 40)
else:
oled.text("Waiting for GPS...", 0, 0)
oled.rotate(0)
oled.show()
def print_gps_data():
"""print GPS data"""
if my_gps.date and my_gps.timestamp:
date_str = f"{my_gps.date[2]}-{my_gps.date[1]:02d}-{my_gps.date[0]:02d}"
time_str = f"{my_gps.timestamp[0]:02d}:{my_gps.timestamp[1]:02d}:{int(my_gps.timestamp[2]):02d}"
print(f"Date: {date_str}, Time: {time_str}")
print(f"Latitude: {my_gps.latitude[0]:.6f} {my_gps.latitude[1]}")
print(f"Longitude: {my_gps.longitude[0]:.6f} {my_gps.longitude[1]}")
print(f"Altitude: {my_gps.altitude} m")
print(f"Speed: {my_gps.speed[2]} km/h")
print(f"Course: {my_gps.course} degrees")
print(f"Satellites in view: {my_gps.satellites_in_view}")
print(f"Satellites in use: {my_gps.satellites_in_use}")
print(f"HDOP: {my_gps.hdop}")
print(f"VDOP: {my_gps.vdop}")
print(f"PDOP: {my_gps.pdop}")
else:
print("Waiting for GPS data...")
# parameters of voltage divide resistor
R1, R2 = 1000000, 1000000 # 1M
Vref_BAT = 3.9 # battery voltage in full charged state
def get_battery_level():
''' measure battery voltage by ADC '''
adc_value = adc.read_u16()
voltage = (adc_value / 65535) * 3.3
DIV_RATIO = (R1 + R2) / R1
actual_voltage = voltage * DIV_RATIO # voltage division compensation
percent = min(max((actual_voltage - 3.3) / (Vref_BAT - 3.3) * 100, 0), 100)
return percent, actual_voltage
def BAT_display(percent,x,y,width,height):
''' battery percent, icon position and size (x,y,width,height) '''
oled.fill_rect(x,y,width+2,height+16,0) # part clear
oled.text('{:.0f}%'.format(percent), width+6+x, y)
# draw battery icon
oled.rect(0+x, 0+y, width, height, 1) # frame (x,y,width,height)
oled.rect(width-1+x, int(height/3)+y, 3, int(height/3), 1) # anode
oled.fill_rect(2+x, 2+y, int((width-4) * percent / 100), height-4, 1) # electric percent column
oled.rotate(0)
oled.show()
while True:
update_gps()
display_data()
print_gps_data()
percent, voltage = get_battery_level()
BAT_display(percent,0,52,30,9)
print('Battery Voltage: {:.2f} V, Battery Level: {:.1f}%'.format(voltage,percent))
time.sleep(1)
运行代码,确认执行无误后,将代码文件上传至芯片根目录。
效果演示
连接锂电池供电,显示 GPS 数据,包括日期、时间、经纬度、速度、电池电量信息。


动态效果(每秒刷新一次)

同时终端打印 GPS 数据与电池电量信息

室外测试
室外环境或窗边,等待 30 秒左右,可获取到位置信息

读取经纬坐标信息,输入网络地图,可得到相应的地理位置

将上述采集得到的经纬坐标 (121,31) 输入网址 经纬度定位 ,点击 查询 按钮,可获得对应的地理位置

定位结果与实际位置 (121.45,31.03) 较为接近

总结
本文介绍了 Beetle RP2350 通过 MicroPython 编程实现桌面 GPS 卫星授时时钟的项目设计,为 RP2350 的快速开发和应用提供了参考。
评论