Pico + GY-NEO6MV2 GPS Clock - 1U Mini Rack
We calculate the final price from your selected file. You review and accept it before payment.
Saved on this device.
Model information
- Source
- Printables
- Category
- Electronics
- License
- Creative Commons — Attribution — Noncommercial
Pico + GY-NEO6MV2 GPS Clock - 1U Mini Rack Faceplate
Inspired by Jeff Geerling’s video on the Pico GPS Clock, I decided to build my own version tailored for the "1U Mini Rack" system. This faceplate allows you to mount a GPS clock directly into your desktop rack setup.
While Jeff’s original project focused on the Waveshare L76K GNSS Module, I’ve adapted this build to use a standard GY-NEO6MV2 GPS module and a common 16x2 LCD screen (with I2C module) for a clean, readable display.
Support me by using my referral code on Prusa Website: @maxcou_485438
Hardware Required
To build this, you will need:
Raspberry Pi Pico (or Pico W)
GY-NEO6MV2 GPS Module (with external antenna)
16x2 LCD Display (with I2C Backpack/Interface)
1U Mini Rack system (This faceplate is designed to fit the standard 1U mini rack mounting holes)
x12 M2 Screws for mounting internal electronics
x4 M3 Screws for securing the case
Print Settings
Material: PLA or PETG (I used PETG)
Infill: 15-20%
Supports: No support needed, already integrated into the model Front_1U_TimeGPS for Raspberry Pi Pico support (Need to be removed so that the micro-USB connector of the Pico can fit)
Layer Height: 0.2mm
Setup & Code
I used the micropyGPS, RPI-PICO-I2C-LCD to handle the GPS NMEA data and the I2C display.
Note: Make sure your GPS antenna has a clear view of the sky or is placed near a window to get a satellite lock!
from machine import UART, Pin, I2C
from micropyGPS import MicropyGPS
from pico_i2c_lcd import I2cLcd
import time--- 1. SETUP LCD (I2C1 for Pins 26/27) ---
i2c = I2C(1, sda=Pin(26), scl=Pin(27), freq=400000)
lcd = I2cLcd(i2c, 0x27, 2, 16)
--- 2. SETUP GPS ---
gps_uart = UART(0, baudrate=9600, tx=Pin(0), rx=Pin(1))
my_gps = MicropyGPS(location_formatting='dd')
--- 3. CONFIGURATION ---
TIMEZONE_OFFSET = -5
had_fix = False
display_cycle = 0 # Which value to show (0-3)
loop_counter = 0 # Tracks how many 0.5s loops have passed
HOLD_TIME = 20 # 20 loops * 0.1s = 2 seconds per value
def get_local_datetime(gps_obj, offset):
d = gps_obj.date
t = gps_obj.timestamp
try:
utc_tuple = (2000 + d[2], d[1], d[0], int(t[0]), int(t[1]), int(t[2]), 0, 0)
utc_seconds = time.mktime(utc_tuple)
local_seconds = utc_seconds + (offset * 3600)
return time.localtime(local_seconds)
except:
return None
print("System Starting... Searching for Satellites (NEO-6M)")
lcd.clear()
lcd.putstr("GPS Searching...")
while True:
if gps_uart.any():
raw_data = gps_uart.read()
for b in raw_data:
try:
my_gps.update(chr(b))
except:
continue
if my_gps.fix_type < 3 and had_fix:
print("\n[!] 3D Fix Lost.")
lcd.clear()
lcd.putstr("Fix Lost")
had_fix = False
elif my_gps.fix_type == 3 and not had_fix:
print("\n[OK] 3D Fix Acquired!")
lcd.clear()
had_fix = True
if my_gps.fix_type == 3:
local = get_local_datetime(my_gps, TIMEZONE_OFFSET)
if local:
# Prepare Terminal Timestamp
timestamp = "{:04}-{:02}-{:02} {:02}:{:02}:{:02}".format(
local[0], local[1], local[2], local[3], local[4], local[5]
)
# --- LCD ROW 1: Constant Time ---
lcd.move_to(0, 0)
lcd.putstr("{:02}:{:02}:{:02} ".format(local[3], local[4], local[5]))
# --- LCD ROW 2: Managed Rotation ---
# We only update the content of Row 2 if the HOLD_TIME is met
if loop_counter == 0:
lcd.move_to(0, 1)
lcd.putstr(" ") # Clear row
lcd.move_to(0, 1)
if display_cycle == 0:
lcd.putstr(f"Satellites: {my_gps.satellites_in_use}")
elif display_cycle == 1:
lcd.putstr(f"HDOP: {my_gps.hdop}")
elif display_cycle == 2:
lcd.putstr(f"VDOP: {my_gps.vdop}")
elif display_cycle == 3:
lcd.putstr(f"PDOP: {my_gps.pdop}")
# Increment loop counter
loop_counter += 1
# If we reached the hold time, reset loop counter and move to next value
if loop_counter >= HOLD_TIME:
loop_counter = 0
display_cycle = (display_cycle + 1) % 4
# --- TERMINAL LOG (Updates every 0.5s) ---
print(f"\rLocal Time: {timestamp} | Sats: {my_gps.satellites_in_use} | PDOP: {my_gps.pdop} | HDOP: {my_gps.hdop} | VDOP: {my_gps.vdop} ", end='')
else:
print(".", end='')
lcd.move_to(0, 1)
lcd.putstr(f"Sats Found: {my_gps.satellites_in_use} ")
time.sleep(0.1)</code></pre><p><strong>Support me by using my referral code on Prusa Website:</strong> <em>@maxcou_485438</em></p>