发帖
5 0 0

【Ai-GP-02-Kit】GPS 桌面时钟

无垠的广袤
论坛元老

32

主题

37

回帖

3609

积分

论坛元老

积分
3609
QQ
GP系列 34 5 8 小时前
[i=s] 本帖最后由 无垠的广袤 于 2025-5-28 01:03 编辑 [/i]

【Ai-GP-02-Kit】GPS 桌面时钟

本文介绍了 安信可 GPS 模组 与 RP2350 主控通过 MicroPython 编程实现桌面 GPS 卫星授时时钟的项目设计。

项目介绍

包括串口连接测试、原始 NMEA 数据捕获、库函数调用与格式转换、获取 GPS 卫星授时数据、OLED 显示等流程。

硬件连接

示意图

connect_gp02.jpg

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)

连接芯片,配置解释器,运行代码。

效果

终端打印原始 NVEA 数据

gps_print.gif

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

gps_print.jpg

解析数据

使用 micropyGPS 库实现 GPS 原始 NVEA 数据解析,实现 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)

效果

终端打印日期、时间、经纬度、速度信息

gps_translate_print.gif

流程图

flowchart_gps.jpg

工程代码

在前面获取 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_clock_battery.jpg

gps_clock_GP02.jpg

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

gps_clock.gif

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

gps_clock_print.gif

室外测试

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

gps_module_night.jpg

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

gps_clock_test_night.jpg

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

gps_local.jpg

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

gps_module_night.gif

总结

本文介绍了 安信可 GPS 模组 与 RP2350 通过 MicroPython 编程实现桌面 GPS 卫星授时时钟的项目设计,为 GP-02 模组的快速开发和应用提供了参考。

──── 0人觉得很赞 ────

使用道具 举报

优秀~
GP-02 我也有一个还不知道做什么,在屋子里面也能拿到日期时间么,是不得里窗户近点。
学习了
学习了
WT_0213 发表于 2025-5-28 08:36
GP-02 我也有一个还不知道做什么,在屋子里面也能拿到日期时间么,是不得里窗户近点。 ...

室内可以获取时钟信息,但是收不到经纬度坐标
您需要登录后才可以回帖 立即登录
高级模式
返回
统计信息
  • 会员数: 28835 个
  • 话题数: 41268 篇