Skip to content

Commit 44eb33e

Browse files
authored
Merge pull request #28 from makermelissa/master
Added GPS FeatherWing
2 parents dfa20cc + a52990b commit 44eb33e

File tree

7 files changed

+253
-2
lines changed

7 files changed

+253
-2
lines changed
+183
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
# The MIT License (MIT)
2+
#
3+
# Copyright (c) 2019 Melissa LeBlanc-Williams for Adafruit Industries LLC
4+
#
5+
# Permission is hereby granted, free of charge, to any person obtaining a copy
6+
# of this software and associated documentation files (the "Software"), to deal
7+
# in the Software without restriction, including without limitation the rights
8+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
# copies of the Software, and to permit persons to whom the Software is
10+
# furnished to do so, subject to the following conditions:
11+
#
12+
# The above copyright notice and this permission notice shall be included in
13+
# all copies or substantial portions of the Software.
14+
#
15+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
# THE SOFTWARE.
22+
"""
23+
`adafruit_featherwing.gps_featherwing`
24+
====================================================
25+
26+
Helper for using the `Ultimate GPS FeatherWing <https://www.adafruit.com/product/3133>`_.
27+
28+
* Author(s): Melissa LeBlanc-Williams
29+
"""
30+
31+
__version__ = "0.0.0-auto.0"
32+
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_FeatherWing.git"
33+
34+
import busio
35+
import adafruit_gps
36+
from adafruit_featherwing import shared
37+
38+
class GPSFeatherWing:
39+
"""Class representing an `Ultimate GPS FeatherWing
40+
<https://www.adafruit.com/product/3133>`_.
41+
42+
Automatically uses the feather's I2C bus."""
43+
def __init__(self, update_period=1000, baudrate=9600):
44+
"""
45+
:param int update_period: (Optional) The amount of time in milliseconds between
46+
updates (default=1000)
47+
:param int baudrate: (Optional) The Serial Connection speed to the GPS (default=9600)
48+
"""
49+
if not isinstance(update_period, int):
50+
raise ValueError("Update Frequency should be an integer in milliseconds")
51+
if update_period < 250:
52+
raise ValueError("Update Frequency be at least 250 milliseconds")
53+
timeout = update_period // 1000 + 2
54+
if timeout < 3:
55+
timeout = 3
56+
57+
self._uart = busio.UART(shared.TX, shared.RX, baudrate=baudrate, timeout=timeout)
58+
self._gps = adafruit_gps.GPS(self._uart, debug=False)
59+
# Turn on the basic GGA and RMC info
60+
self._gps.send_command(b'PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0')
61+
self._gps.send_command(b'PMTK220,{}'.format(update_period))
62+
63+
def update(self):
64+
"""
65+
Make sure to call ``gps.update()`` every loop iteration and at least twice
66+
as fast as data comes from the GPS unit (usually every second).
67+
68+
:return: Whether it has parsed new data
69+
:rtype: bool
70+
"""
71+
return self._gps.update()
72+
73+
def read(self, size):
74+
"""
75+
Read the UART for any information that may be on it
76+
77+
:param int size: The size in bytes of the data to retrieve
78+
:return: Any data that is on the UART
79+
:rtype: bytearray
80+
"""
81+
if isinstance(size, int) and size > 0:
82+
return self._uart.read(size)
83+
return None
84+
85+
def send_command(self, command):
86+
"""
87+
Send a bytearray command to the GPS module
88+
89+
:param bytearray command: The command to send
90+
"""
91+
if isinstance(command, bytearray):
92+
self._gps.send_command(command)
93+
94+
@property
95+
def latitude(self):
96+
"""
97+
Return the Current Latitude from the GPS
98+
"""
99+
return self._gps.latitude
100+
101+
@property
102+
def longitude(self):
103+
"""
104+
Return the Current Longitude from the GPS
105+
"""
106+
return self._gps.longitude
107+
108+
@property
109+
def fix_quality(self):
110+
"""
111+
Return the Fix Quality from the GPS
112+
"""
113+
return self._gps.fix_quality
114+
115+
@property
116+
def has_fix(self):
117+
"""
118+
Return whether the GPS has a Fix on some satellites
119+
"""
120+
return self._gps.has_fix
121+
122+
@property
123+
def timestamp(self):
124+
"""
125+
Return the Fix Timestamp as a struct_time
126+
"""
127+
return self._gps.timestamp_utc
128+
129+
@property
130+
def satellites(self):
131+
"""
132+
Return the Number of Satellites we have a fix on
133+
"""
134+
return self._gps.satellites
135+
136+
@property
137+
def altitude(self):
138+
"""
139+
Return the Altitude in meters
140+
"""
141+
return self._gps.altitude_m
142+
143+
@property
144+
def speed_knots(self):
145+
"""
146+
Return the GPS calculated speed in knots
147+
"""
148+
return self._gps.speed_knots
149+
150+
@property
151+
def speed_mph(self):
152+
"""
153+
Return the GPS calculated speed in Miles per Hour
154+
"""
155+
return self._gps.speed_knots * 6076 / 5280
156+
157+
@property
158+
def speed_kph(self):
159+
"""
160+
Return the GPS calculated speed in Kilometers per Hour
161+
"""
162+
return self._gps.speed_knots * 1.852
163+
164+
@property
165+
def track_angle(self):
166+
"""
167+
Return the Tracking angle in degrees
168+
"""
169+
return self._gps.track_angle_deg
170+
171+
@property
172+
def horizontal_dilution(self):
173+
"""
174+
Return the Horizontal Dilution
175+
"""
176+
return self._gps.horizontal_dilution
177+
178+
@property
179+
def height_geoid(self):
180+
"""
181+
Return the Height GeoID in meters
182+
"""
183+
return self._gps.height_geoid

adafruit_featherwing/shared.py

+3
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,6 @@
3333
import busio
3434

3535
I2C_BUS = busio.I2C(board.SCL, board.SDA)
36+
37+
RX = board.RX
38+
TX = board.TX

docs/api.rst

+4-1
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,7 @@
1717
:members:
1818

1919
.. automodule:: adafruit_featherwing.rtc_featherwing
20-
:members:
20+
:members:
21+
22+
.. automodule:: adafruit_featherwing.gps_featherwing
23+
:members:

docs/examples.rst

+4
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ Ensure your device works with this simple test.
3131
:caption: examples/featherwing_rtc_simpletest.py
3232
:linenos:
3333

34+
.. literalinclude:: ../examples/featherwing_gps_simpletest.py
35+
:caption: examples/featherwing_gps_simpletest.py
36+
:linenos:
37+
3438
Other Tests
3539
------------
3640

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
"""
2+
This example will connect to the GPS at the default 9600 baudrate and
3+
update once per second. Initialization is automatically handled and there
4+
are some additional features such as MPH and KPH calculations.
5+
"""
6+
import time
7+
from adafruit_featherwing import gps_featherwing
8+
9+
# Create a GPS featherwing instance.
10+
gps = gps_featherwing.GPSFeatherWing()
11+
12+
# Main loop runs forever printing the location, etc. every second.
13+
last_print = time.monotonic()
14+
while True:
15+
# Make sure to call gps.update() every loop iteration and at least twice
16+
# as fast as data comes from the GPS unit (usually every second).
17+
# This returns a bool that's true if it parsed new data (you can ignore it
18+
# though if you don't care and instead look at the has_fix property).
19+
gps.update()
20+
# Every second print out current location details if there's a fix.
21+
current = time.monotonic()
22+
if current - last_print >= 1.0:
23+
last_print = current
24+
if not gps.has_fix:
25+
# Try again if we don't have a fix yet.
26+
print('Waiting for fix...')
27+
continue
28+
# Print out details about the fix like location, date, etc.
29+
print('=' * 40) # Print a separator line.
30+
print('Fix timestamp: {}/{}/{} {:02}:{:02}:{:02}'.format(
31+
gps.timestamp.tm_mon, # Grab parts of the time from the
32+
gps.timestamp.tm_mday, # struct_time object that holds
33+
gps.timestamp.tm_year, # the fix time. Note you might
34+
gps.timestamp.tm_hour, # not get all data like year, day,
35+
gps.timestamp.tm_min, # month!
36+
gps.timestamp.tm_sec))
37+
print('Latitude: {0:.6f} degrees'.format(gps.latitude))
38+
print('Longitude: {0:.6f} degrees'.format(gps.longitude))
39+
print('Fix quality: {}'.format(gps.fix_quality))
40+
# Some attributes beyond latitude, longitude and timestamp are optional
41+
# and might not be present. Check if they're None before trying to use!
42+
if gps.satellites is not None:
43+
print('# satellites: {}'.format(gps.satellites))
44+
if gps.altitude is not None:
45+
print('Altitude: {} meters'.format(gps.altitude))
46+
if gps.speed_knots is not None:
47+
print('Speed (Knots): {} knots'.format(gps.speed_knots))
48+
if gps.speed_mph is not None:
49+
print('Speed (Miles Per Hour): {} MPH'.format(gps.speed_mph))
50+
if gps.speed_kph is not None:
51+
print('Speed (KM Per Hour): {} KPH'.format(gps.speed_kph))
52+
if gps.track_angle is not None:
53+
print('Track angle: {} degrees'.format(gps.track_angle))
54+
if gps.horizontal_dilution is not None:
55+
print('Horizontal dilution: {}'.format(gps.horizontal_dilution))
56+
if gps.height_geoid is not None:
57+
print('Height geo ID: {} meters'.format(gps.height_geoid))

requirements.txt

+1
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ adafruit-circuitpython-ht16k33
77
adafruit-circuitpython-dotstar
88
adafruit-circuitpython-neopixel
99
adafruit-circuitpython-ds3231
10+
adafruit-circuitpython-gps

setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
'adafruit-circuitpython-register', 'adafruit-circuitpython-ina219',
4040
'adafruit-circuitpython-seesaw', 'adafruit-circuitpython-ht16k33',
4141
'adafruit-circuitpython-dotstar', 'adafruit-circuitpython-neopixel',
42-
'adafruit-circuitpython-ds3231'],
42+
'adafruit-circuitpython-ds3231', 'adafruit-circuitpython-gps'],
4343

4444
# Choose your license
4545
license='MIT',

0 commit comments

Comments
 (0)