GP-02-Kit: GPS Desktop Clock
Project IntroductionThe project involves several key steps:
1. Serial connection testing
2. Capturing raw NMEA data
3. Library function calls and format conversion
4. Acquiring GPS satellite - synchronized timing data
5. Displaying data on an OLED screen
Hardware ConnectionsRX connected to GPIO0
TX connected to GPIO1
VCC connected to 3V3
GND connected to GND
OLED to RP2350:
GP4 connected to SDA (OLED_SSD1306)
GP5 connected to SCL (OLED_SSD1306)Project Code Integration
On the basis of acquiring and converting data from the GP-02 module, the project further integrates an OLED display and a battery module to create a desktop GPS - synchronized clock.
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, ADCimport ssd1306from micropyGPS import MicropyGPSimport 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)
After confirming that the code runs without errors, upload the code file to the root directory of the chip.
Engineering DebuggingDebugging includes reading raw data from the GP-02 module via serial connection and parsing NMEA data. This lays the groundwork for subsequent code integration and function calls.
By connecting to the GP-02 module via serial link, raw data can be printed on the terminal.
The micropyGPS library is utilized to parse raw NMEA data from the GP-02 module, enabling rapid development and application of the module.
Code:
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,Pinfrom micropyGPS import MicropyGPSimport 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)
Once the code is executed, the terminal will display GPS - related information, including date, time, latitude, longitude, and speed.
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, UARTimport 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)
Engineering DebuggingDebugging includes reading raw data from the GP-02 module via serial connection and parsing NMEA data. This lays the groundwork for subsequent code integration and function calls.
Raw Data ReadingBy connecting to the GP-02 module via serial link, raw data can be printed on the terminal.
Effect DemonstrationWhen powered by a lithium - ion battery, the device displays GPS data, including date, time, latitude, longitude, speed, and battery level.
Dynamic Effect: The display refreshes once per second.
Terminal Output: The terminal simultaneously prints GPS data and battery level information.
Outdoor Testing: In outdoor environments or near windows, the device acquires location information in about 30 seconds.
Geolocation: Input the acquired latitude and longitude coordinates into a network mapping tool to obtain the corresponding geographical location. For example, entering the coordinates (121, 31) into the latitude - longitude mapper, the result is relatively close to the actual position (121.45, 31.03).
Comments