Introduction: Gps Thing

gps thingy that points to coords

Supplies

gps neo6m

16 px neopixel ring

ssd1306 128x64 oled

2 buttons

1 raspberry pi pico

wire

Step 1: Wire It Up

connect the things to the microcontroller

Step 2: Program It

put circiutpython on your microcontroller and put this code into code.py, also install adafruit_framebuff, gps, pixelbuf, neopixel and ssd1306 libs



import time
import board
import neopixel
import random
import ssd1306
import busio
import digitalio
import adafruit_gps

pixel_pin = board.GP0
num_pixels = 16

pixels = neopixel.NeoPixel(pixel_pin, num_pixels, brightness=0.1, auto_write=False)

COLORS_COMPASS = [[255, 0, 0], [130, 160, 0], [70, 200, 0], [0, 255, 0]]

i2c = busio.I2C(board.GP13, board.GP12, frequency=200000)
oled = ssd1306.SSD1306_I2C(128, 64, i2c)

uart = busio.UART(board.GP4, board.GP5, baudrate=9600, timeout=10)
gps = adafruit_gps.GPS(uart, debug=False)
gps.send_command(b"PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0")
gps.send_command(b"PMTK220, 100")
last_print = time.monotonic()


def LED_X(num, color):
  pixels[num] = (color[0], color[1], color[2])
   
def COMPASS(num_pixels, pos, color):
  for i in range(num_pixels-1):
    if i != pos or i != pos-1 or i != pos-2 or i != pos+1 or i != pos+2:
      LED_X(i, color[0])
         
    LED_X(pos-1, color[2])
    LED_X(pos, color[3])
    LED_X(pos+1, color[2])
       
   
  LED_X(pos, color[3])
  LED_X(15, [random.randint(0, 255), random.randint(0, 50),random.randint(0, 50)])
  pixels.show()
     
t_num = 7
prev_t_num = t_num

btn1 = digitalio.DigitalInOut(board.GP16)
btn1.direction = digitalio.Direction.INPUT
btn1.pull = digitalio.Pull.DOWN

btn2 = digitalio.DigitalInOut(board.GP17)
btn2.direction = digitalio.Direction.INPUT
btn2.pull = digitalio.Pull.DOWN

btn1_def = btn1.value
btn2_def = btn2.value

tick = 0

button_r = [10, 15, 20, 25, 30, 35, 40]
update_r = [4, 8, 16, 24, 28, 32, 36]

oled.fill(0)
oled.text(f'Starting...', 4, 6, 1)
oled.show()

time.sleep(1)
oled.fill(0)
oled.text(f"WARNING !", 4, 4, 1)
oled.text(f"This is just a fun\nproject! Do not rely\non it in real\nlife applications\nno precision\npromised!   :)", 4, 16, 1)

oled.show()
time.sleep(3)

oled.fill(0)
oled.text(f"X", 4, 4, 1)
oled.show()

gps.update()

waypoint = ["lat", "lon", False]

while 1:  
  tick += 1
   
  gps.update()
   
  if gps.has_fix:
    COMPASS(num_pixels, t_num, COLORS_COMPASS)
  else:
    pixels.fill((255, 0, 0))
    LED_X(15, [random.randint(0, 255), random.randint(0, 50),random.randint(0, 50)])
    pixels.show()
   
  current = time.monotonic()
   
  if btn1.value != btn1_def and tick in button_r == [10, 15, 20, 25, 30, 35, 40]:
    waypoint[0] = [gps.latitude_degrees, gps.latitude_minutes]
    waypoint[1] = [gps.longitude_degrees, gps.longitude_minutes]
    waypoint[2] = True
  if btn2.value != btn2_def and tick in button_r == [10, 15, 20, 25, 30, 35, 40]:
    waypoint[0] = "lat"
    waypoint[1] = "lon"
    waypoint[2] = False
  if btn1.value != btn1_def and btn2.value != btn2_def and tick in button_r == [10, 15, 20, 25, 30, 35, 40]:
    pass
    #future space for manual checkpoint input/recieve mode
   
  if current - last_print >= 1.0 and tick == 39:
    last_print = current
    if not gps.has_fix:

      oled.fill(0)
      oled.text(f'Waiting for fix...', 0, 6, 1)
      oled.text(f'The device is\ntrying to find\nGPS Sattelites\nif this screen wont\ngo away, try to find\na more open area!', 0, 16, 1)
      oled.show()

# "Fix timestamp: {}/{}/{} {:02}:{:02}:{:02}".format(gps.timestamp_utc.tm_mon,gps.timestamp_utc.tm_mday,gps.timestamp_utc.tm_year,gps.timestamp_utc.tm_hour,gps.timestamp_utc.tm_min,gps.timestamp_utc.tm_sec)

#"Precise Latitude: {:2.}{:2.4f} degrees".format(gps.latitude_degrees, gps.latitude_minutes)
#"Precise Longitude: {:2.}{:2.4f} degrees".format(ps.longitude_degrees, gps.longitude_minutes)
#if gps.track_angle_deg is not None:
#  print("Track angle: {} degrees".format(gps.track_angle_deg))
#if gps.horizontal_dilution is not None:
#  print("Horizontal dilution: {}".format(gps.horizontal_dilution))
#if gps.height_geoid is not None:
#  print("Height geoid: {} meters".format(gps.height_geoid))

   
  print(f"{tick} | {btn1.value} | {btn2.value} | {t_num} | {button_r} | {gps.fix_quality}") # debug data print
   
  if waypoint[2] == False and tick in update_r:
    t_num += 1
   
  if tick == 39 and gps.has_fix:
    print("Fix timestamp: {}/{}/{} {:02}:{:02}:{:02}".format(gps.timestamp_utc.tm_mon,gps.timestamp_utc.tm_mday,gps.timestamp_utc.tm_year,gps.timestamp_utc.tm_hour,gps.timestamp_utc.tm_min,gps.timestamp_utc.tm_sec))
    oled.fill(0)
    if gps.fix_quality == 1:
      oled.text("C", 4, 4, 1)
    else:
      oled.text("X", 4, 4, 1)
    if gps.satellites is not None:
      oled.text(f"={gps.satellites}", 10, 4, 1)
    if gps.speed_knots is not None:
      oled.text(f"{round(gps.speed_knots*1.852)} kmh", 40, 4, 1)
    if gps.altitude_m is not None:
      oled.text(f"Height: {gps.altitude_m} m", 4, 16, 1)
     
    oled.text(f"{tick}|{t_num}", 83, 4, 1)
    oled.text(f"Locked: {waypoint[2]}", 4, 46, 1)   
    oled.text(f"LAT: {gps.latitude} m", 4, 26, 1)
    oled.text(f"LON: {gps.longitude} m", 4, 36, 1)
    #print("Latitude: {0:.6f} degrees".format(gps.latitude))
    #print("Longitude: {0:.6f} degrees".format(gps.longitude))
    oled.show()
   
  if t_num > 14:
    t_num = 3
  elif t_num < 3 :
    t_num = 14
   
  if tick >= 40:
    tick = 0
   


Step 3: Power It

power the microcontroller using a usb cable

Step 4: Done

yay, now u can use the thingy