Adafruit_Learning_System_Gu.../HalloWing_Tour_Guide/code.py
2018-11-12 11:52:13 -05:00

156 lines
4.5 KiB
Python

"""
HalloWing GPS Tour Guide
Adafruit invests time and resources providing this open source code.
Please support Adafruit and open source hardware by purchasing
products from Adafruit!
Written by Dave Astels for Adafruit Industries
Copyright (c) 2018 Adafruit Industries
Licensed under the MIT license.
All text above must be included in any redistribution.
"""
import time
from math import sin, cos, radians, atan2, sqrt
import board
from digitalio import DigitalInOut, Direction, Pull
import displayio
import audioio
from busio import UART
import adafruit_gps
uart = UART(board.TX, board.RX, baudrate=9600, timeout=3000)
gps = adafruit_gps.GPS(uart)
# Initialize the GPS module by changing what data it sends and at what rate.
# Turn on the basic GGA and RMC info (what you typically want)
gps.send_command(b'PMTK314,0,1,0,1,0,0,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(b'PMTK220,1000')
switch = DigitalInOut(board.SENSE)
switch.direction = Direction.INPUT
switch.pull = Pull.UP
audio = audioio.AudioOut(board.A0)
backlight = DigitalInOut(board.TFT_BACKLIGHT)
backlight.direction = Direction.OUTPUT
backlight.value = False
splash = displayio.Group()
board.DISPLAY.show(splash)
def play_wave(filename):
try:
wave_file = open(filename, "rb")
wave = audioio.WaveFile(wave_file)
audio.play(wave)
while audio.playing:
pass
wave_file.close()
except OSError:
pass
def show_image(filename):
image_file = None
try:
image_file = open(filename, "rb")
except OSError:
image_file = open("missing.bmp", "rb")
odb = displayio.OnDiskBitmap(image_file)
face = displayio.Sprite(odb, pixel_shader=displayio.ColorConverter(), position=(0, 0))
backlight.value = False
splash.append(face)
board.DISPLAY.wait_for_frame()
backlight.value = True
def distance_between(location_1, location_2):
"""Find the distance betweeto a lat/long"""
R = 3959 # radius of Earth in miles
lat1 = location_1[0]
lat2 = location_2[0]
lon1 = location_1[1]
lon2 = location_2[1]
delta_lat = lat2 - lat1
delta_lon = lon2 - lon1
a = sin(delta_lat / 2) * sin(delta_lat / 2) + \
cos(lat1) * cos(lat2) * \
sin(delta_lon / 2) * sin(delta_lon / 2)
c = 2 * atan2(sqrt(a), sqrt(1 - a))
return R * c
previous_num = 0
previous_distance_code = 0
num = 0
image = None
name = None
detail = None
show_image("welcome.bmp")
# File with place data
# lat,long,image-file,spoken-name-file,detail-file
while True:
gps.update()
if gps.has_fix:
# find the closest listed location
here = (radians(gps.latitude), radians(gps.longitude))
distance = 10000
with open("locations.txt", "r") as f:
for line in f:
f_num, f_lat, f_lon, f_image, f_name, f_detail = line.split(',')
f_dist = distance_between((radians(float(f_lat)), radians(float(f_lon))), here)
if f_dist < distance:
num, distance, image, name, detail = f_num, f_dist, f_image, f_name, f_detail
# categorize the distance
if distance < 0.1:
distance_code = 1
elif distance < 0.5:
distance_code = 2
elif distance < 1.0:
distance_code = 3
else:
distance_code = 4
# play the name when asked
if not switch.value:
play_wave(name)
if previous_distance_code == 1 and distance_code == 1 and previous_num == num:
play_wave(detail)
# update the display if the location or distance category has changed
# if it's relly close, show the image and play the details
if num != previous_num or distance_code != previous_distance_code:
play_wave("computerbeep.wav")
previous_num = num
previous_distance_code = distance_code
if distance_code == 1:
splash.pop()
show_image(image)
play_wave(name)
play_wave(detail)
elif distance_code == 2:
splash.pop()
show_image("green_circle.bmp")
elif distance_code == 3:
splash.pop()
show_image("yellow_circle.bmp")
else:
splash.pop()
show_image("red_circle.bmp")
else:
splash.pop()
show_image("acquiring_fix.bmp")
time.sleep(0.25)