Skip to content

Instantly share code, notes, and snippets.

@tjpeden
Created April 2, 2019 05:53
Show Gist options
  • Save tjpeden/597770ab422d8531016ea2f6fe25febe to your computer and use it in GitHub Desktop.
Save tjpeden/597770ab422d8531016ea2f6fe25febe to your computer and use it in GitHub Desktop.
Tinkering with CircuitPython and displayio
import time
from rtc import set_time_source
from board import SPI, RX, TX, D9, D10
from busio import UART
from displayio import FourWire, Group, release_displays
from adafruit_gps import GPS
from adafruit_ili9341 import ILI9341
from adafruit_display_text.label import Label
from font_loader import FontLoader
from window import Window
from watcher import Watcher
spi = SPI()
tft_cs = D9
tft_dc = D10
release_displays()
bus = FourWire(spi, command=tft_dc, chip_select=tft_cs)
display = ILI9341(bus, width=240, height=320, rotation=270)
UI = Group(max_size=1)
window = Window(UI, title='GPS', width=240, height=320)
datetime = Label(FontLoader().small_font, max_glyphs=16, color=0xFFFFFF, x=2)
latitude = Label(FontLoader().small_font, max_glyphs=20, color=0xFFFFFF, x=2, y=12, text='Waiting for fix...')
longitude = Label(FontLoader().small_font, max_glyphs=20, color=0xFFFFFF, x=2, y=32)
satellites = Label(FontLoader().small_font, max_glyphs=15, color=0xFFFFFF, x=2, y=52)
content = window.get_content_pane(4)
content.append(datetime)
content.append(latitude)
content.append(longitude)
content.append(satellites)
datetime.y = content.height - 12
display.show(UI)
display.refresh_soon()
display.wait_for_frame()
uart = UART(TX, RX, baudrate=9600, timeout=3)
gps = GPS(uart, debug=False)
set_time_source(gps)
def update(action):
def update_action():
if not gps.has_fix:
return
action()
display.refresh_soon()
display.wait_for_frame()
return update_action
def update_latitude():
latitude.text = 'Latitude: {:.4f}'.format(gps.latitude)
def update_longitude():
longitude.text = 'Longitude: {:.4f}'.format(gps.longitude)
def update_satellites():
satellites.text = 'Satellites: {}'.format(gps.satellites)
def update_datetime():
datetime.text = '{:02}/{:02}/{:04} {: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
)
datetime.x = (content.width - datetime.bounding_box[2]) // 2
latitude_watcher = Watcher(lambda: gps.latitude, action=update(update_latitude))
longitude_watcher = Watcher(lambda: gps.longitude, action=update(update_longitude))
satellites_watcher = Watcher(lambda: gps.satellites, action=update(update_satellites))
datetime_watcher = Watcher(lambda: gps.timestamp_utc.tm_min, action=update(update_datetime))
gps.send_command(b'PMTK220,5000')
gps.send_command(b'PMTK300,1000,0,0,0,0')
gps.send_command(b'PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0')
while True:
gps.update()
latitude_watcher.update()
longitude_watcher.update()
satellites_watcher.update()
datetime_watcher.update()
from adafruit_bitmap_font import bitmap_font
cwd = ("/"+__file__).rsplit('/', 1)[0]
small_font = cwd + "/fonts/Arial-16.bdf"
class FontLoader:
class __FontLoader:
def __init__(self):
self.small_font = bitmap_font.load_font(small_font)
glyphs = b'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-,.: '
self.small_font.load_glyphs(glyphs)
__instance = None
def __init__(self):
if not FontLoader.__instance:
FontLoader.__instance = FontLoader.__FontLoader()
def __getattr__(self, name):
return getattr(FontLoader.__instance, name)
class Watcher:
def __init__(self, current, *, action=None):
self.last = None
self.current = current
self.action = action
def update(self):
try:
value = self.current()
if value != self.last:
self.last = value
self.action()
except:
print("Unexpected error")
from displayio import Group
from adafruit_display_text.label import Label
from adafruit_display_shapes.roundrect import RoundRect
from font import Font
class Window(Group):
def __init__(self, parent, *, title=None, width=None, height=None):
super().__init__(max_size=3)
if not width or not height:
raise RuntimeError("Please provide a width and height")
self.width = width
self.height = height
parent.append(self)
self._content = None
self._main = Group(max_size=1)
self.append(self._main)
self._main.append(
RoundRect(0, 0, self.width, self.height, 3, fill=0x330033, outline=0xFF00FF)
)
if title:
self._titlebar = Group(max_size=2)
self.append(self._titlebar)
self._titlebar.append(
RoundRect(0, 0, self.width, 30, 3, fill=0x550055, outline=0xFF00FF)
)
self._titlebar.append(
Label(Font().small_font, text=title, color=0xFFFF00, x=8, y=14)
)
else:
self._titlebar = None
def get_content_pane(self, max_size=1):
if not self._content:
y = 32 if self._titlebar else 2
width = self.width - 4
height = self.height - (34 if self._titlebar else 4)
self._content = Content(self, max_size=max_size, x=2, y=y, width=width, height=height)
return self._content
class Content(Group):
def __init__(self, parent, *, width=None, height=None, **kwargs):
super().__init__(**kwargs)
if not width or not height:
raise RuntimeError("Please provide a width and height")
self.width = width
self.height = height
parent.append(self)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment