Skip to content

Instantly share code, notes, and snippets.

@waldo323
Last active June 4, 2018 18:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save waldo323/319e30e9e037fcc4f9ef5fe496762932 to your computer and use it in GitHub Desktop.
Save waldo323/319e30e9e037fcc4f9ef5fe496762932 to your computer and use it in GitHub Desktop.
pothole or other points of interest tracker with a feather joywing, gps module, sdcard writer, and an m4 board (work in progress)
import time
import board
import busio
import adafruit_gps
import adafruit_pcf8523
import adafruit_seesaw.seesaw
import digitalio
import adafruit_sdcard
import storage
import neopixel
from micropython import const
led = neopixel.NeoPixel(board.NEOPIXEL, 1)
led.brightness = 0.2
led_color = (0, 0, 0)
led_last_color = (0, 0, 0)
myI2C = busio.I2C(board.SCL, board.SDA)
rtc = adafruit_pcf8523.PCF8523(myI2C)
RX = board.RX
TX = board.TX
# pylint: disable=bad-whitespace
BUTTON_RIGHT = const(6)
BUTTON_DOWN = const(7)
BUTTON_LEFT = const(9)
BUTTON_UP = const(10)
BUTTON_SEL = const(14)
# pylint: enable=bad-whitespace
button_mask = const((1 << BUTTON_RIGHT) |
(1 << BUTTON_DOWN) |
(1 << BUTTON_LEFT) |
(1 << BUTTON_UP) |
(1 << BUTTON_SEL))
days = ("Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday")
spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
# Use board.SD_CS for Feather M0 Adalogger
cs = digitalio.DigitalInOut(board.D10)
# Or use a GPIO pin like 15 for ESP8266 wiring:
# cs = digitalio.DigitalInOut(board.GPIO15)
sdcard = adafruit_sdcard.SDCard(spi, cs)
vfs = storage.VfsFat(sdcard)
storage.mount(vfs, "/sd")
ss = adafruit_seesaw.seesaw.Seesaw(myI2C)
ss.pin_mode_bulk(button_mask, ss.INPUT_PULLUP)
last_x = 0
last_y = 0
with open("/sd/test.txt", "w") as f:
f.write("Hello world!\r\n")
t = rtc.datetime
print(t) # uncomment for debugging
f.write("The date is %s %d/%d/%d" % (days[t.tm_wday],
t.tm_mday,
t.tm_mon,
t.tm_year))
f.write("The time is %d:%02d:%02d" % (t.tm_hour, t.tm_min, t.tm_sec))
time.sleep(1) # wait a second
uart = busio.UART(TX, RX, baudrate=9600, timeout=3000)
# Create a GPS module instance.
gps = adafruit_gps.GPS(uart)
# begin gps example
# Turn on the basic GGA and RMC info (what you typically want)
gps.send_command('PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0')
# Turn on just minimum info (RMC only, location):
#gps.send_command('PMTK314,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0')
# Turn off everything:
#gps.send_command('PMTK314,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0')
# Tuen on everything (not all of it is parsed!)
#gps.send_command('PMTK314,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0')
# Set update rate to once a second (1hz) which is what you typically want.
gps.send_command('PMTK220,1000')
# Or decrease to once every two seconds by doubling the millisecond value.
# Be sure to also increase your UART timeout above!
#gps.send_command('PMTK220,2000')
# You can also speed up the rate, but don't go too fast or else you can lose
# data during parsing. This would be twice a second (2hz, 500ms delay):
#gps.send_command('PMTK220,500')
# Main loop runs forever printing the location, etc. every second.
last_print = time.monotonic()
while True:
x = ss.analog_read(2)
y = ss.analog_read(3)
if (abs(x - last_x) > 3) or (abs(y - last_y) > 3):
print(x, y)
last_x = x
last_y = y
buttons = ss.digital_read_bulk(button_mask)
if not buttons & (1 << BUTTON_RIGHT):
print("Button A pressed")
led[0] = (0, 0, 10)
if not buttons & (1 << BUTTON_DOWN):
print("Button B pressed")
led[0] = (0, 0, 10)
if not buttons & (1 << BUTTON_LEFT):
print("Button Y pressed")
led[0] = (0, 0, 10)
if not buttons & (1 << BUTTON_UP):
print("Button x pressed")
led[0] = (0, 0, 10)
if not buttons & (1 << BUTTON_SEL):
print("Button SEL pressed")
led[0] = (0, 0, 10)
time.sleep(0.01)
# Make sure to call gps.update() every loop iteration and at least twice
# as fast as data comes from the GPS unit (usually every second).
# This returns a bool that's true if it parsed new data (you can ignore it
# though if you don't care and instead look at the has_fix property).
gps.update()
# Every second print out current location details if there's a fix.
current = time.monotonic()
if current - last_print >= 1.0:
last_print = current
if not gps.has_fix:
# Try again if we don't have a fix yet.
print('Waiting for fix...')
led[0] = (10, 0, 0)
continue
else:
led[0] = (0, 10, 0)
with open("/sd/test_gps.txt", "a") as f:
# We have a fix! (gps.has_fix is true)
# Print out details about the fix like location, date, etc.
# f.write('=' * 40) # Print a separator line.
f.write('Fix timestamp: {}/{}/{} {:02}:{:02}:{:02},'.format(
gps.timestamp_utc.tm_mon, # Grab parts of the time from the
gps.timestamp_utc.tm_mday, # struct_time object that holds
gps.timestamp_utc.tm_year, # the fix time. Note you might
gps.timestamp_utc.tm_hour, # not get all data like year, day,
gps.timestamp_utc.tm_min, # month!
gps.timestamp_utc.tm_sec))
f.write('Latitude: {} degrees,'.format(gps.latitude))
f.write('Longitude: {} degrees,'.format(gps.longitude))
f.write('Fix quality: {},'.format(gps.fix_quality))
# Some attributes beyond latitude, longitude and timestamp are optional
# and might not be present. Check if they're None before trying to use!
if gps.satellites is not None:
f.write('# satellites: {},'.format(gps.satellites))
if gps.altitude_m is not None:
f.write('Altitude: {} meters,'.format(gps.altitude_m))
if gps.track_angle_deg is not None:
f.write('Speed: {} knots,'.format(gps.speed_knots))
if gps.track_angle_deg is not None:
f.write('Track angle: {} degrees,'.format(gps.track_angle_deg))
if gps.horizontal_dilution is not None:
f.write('Horizontal dilution: {},'.format(gps.horizontal_dilution))
if gps.height_geoid is not None:
f.write('Height geo ID: {} meters,'.format(gps.height_geoid))
# end gps example
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment