It is a memo dealing with GPS module in Python of Raspberry Pi 3. OS version of Raspberry Pi 3
~~Raspbian GNU/Linux 8.0 (jessie)~~ Raspbian GNU / Linux 9.4 (stretch) (Fixed October 5, 2018)
is.
For the GPS module, I used Akizuki Denshi's "GPS receiver kit 1 compatible with" Michibiki "with PPS output".
This GPS module sends out the received GPS data serially. There are two ways to serially communicate with the Raspberry Pi 3: using the USB port or using the GPIO pin. When using a USB port, a USB serial conversion module is required, so I used GPIO pins this time. Connect the Raspberry Pi 3 and the GPS module as follows.
Raspberry Pi3 | GPS module |
---|---|
04(5v) | 5V |
06(Ground) | GND |
08(TXD0) | RXD |
10(RXD0) | TXD |
I don't use the GPS 1PPS pin, so I don't connect anything.
For serial communication with Raspberry Pi3, enable serial in raspi-config and set not to use serial as a console.
Launch raspi-config and enable serial as follows:
pi$ sudo raspi-config
Select 5 Interfacing Options and then P6 Serial. Select Yes for "Would you like a login shell to be accessible over serial?", Finish, and reboot.
pi$ sudo reboot
A device called / dev / serial0 will be created.
pi$ ls /dev/se*
/dev/serial0 /dev/serial1
Modify /boot/cmdline.txt to set serial0 not to be used as a console.
pi$ cat /boot/cmdline.txt
dwc_otg.lpm_enable=0 console=tty1 console=serial0,115200 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait quiet splash plymouth.ignore-serial-consoles
Delete "console = serial0,115200" in the editor and reboot.
pi$ sudo reboot
Install the Python serial module. (October 5, 2018: Changed from python-serial to pyserial)
pi$ pip install pyserial
If you are not using pyenv, install it with pip3.
Now you can use Python on Raspberry Pi 3 for serial communication. If you connect the GPS module to the Raspberry Pi3, launch Python as follows, and check it, you can see that the GPS data can be read.
pi$ python3
>>> import serial
>>> s = serial.Serial('/dev/serial0', 9600, timeout=10)
>>> print(s.readline())
b'\x00\x00\xc0\x00\xfe\x00pK&&KLN\xcb14,302,,06,08,254,27,30,07,230,29*70\r\n'
>>> print(s.readline())
b'$GPGSV,4,4,14,23,05,150,19,14,04,054,*74\r\n'
>>>
The first readline () is half-finished data, but the second and subsequent readline () seems to be able to read GPS data.
The data sent from the GPS module is a character string in the format NMEA-0183. For the data format of NMEA-0183, the site "NMEA 0183 sentences data analysis" is easy to understand.
The GPS module receives signals from GPS satellites and displays information such as time, latitude, longitude, altitude above sea level, number and ID of satellites used for positioning, and position (azimuth and elevation) of each satellite in NMEA-0183 format. It is sent as a character string of.
There is a Python library that converts this string data into programmatically easy-to-use data. A web search found micropyGPS and pynmea2.
micropyGPS is a GPS data analysis library that runs on Python 3.x and MicroPython. When you enter GPS data, it analyzes it and adds and updates the data to the GPS object. Information such as time, latitude, longitude, number of satellites used for positioning and ID can be obtained as GPS object data. The documentation is also solid.
pynmea2 just seems to parse GPS data line by line, and the documentation looks poor.
So I decided to use micropyGPS as a library. To use it, just download micropyGPS.py from Github and place it in the directory where you start Python.
The Python program that reads GPS data looks like this: Read the data from the GPS module The process of adding and updating data to the GPS object is made into a thread, and the data is output every 3 seconds.
The time zone time difference (+9 hours in Japan) and the latitude / longitude output format are specified as arguments when creating a MicroGPS object. It seems that the following format can be specified as the output format.
'ddm'Decimal degrees, minutes(40° 26.767′ N)
'dms'Decimal degrees, minutes, seconds(40° 26′ 46″ N)
'dd'Decimal degree(40.446° N)
import serial
import micropyGPS
import threading
import time
gps = micropyGPS.MicropyGPS(9, 'dd') #Create a MicroGPS object.
#Arguments are time zone time difference and output format
def rungps(): #Read GPS module and update GPS object
s = serial.Serial('/dev/serial0', 9600, timeout=10)
s.readline() #Discard the first line as it may read half-finished data
while True:
sentence = s.readline().decode('utf-8') #Read GPS data and convert it to a character string
if sentence[0] != '$': #The beginning is'$'If not, throw it away
continue
for x in sentence: #Analyze the read character string and add or update data to the GPS object
gps.update(x)
gpsthread = threading.Thread(target=rungps, args=()) #Create a thread to execute the above function
gpsthread.daemon = True
gpsthread.start() #Start a thread
while True:
if gps.clean_sentences > 20: #Output when proper data is accumulated to some extent
h = gps.timestamp[0] if gps.timestamp[0] < 24 else gps.timestamp[0] - 24
print('%2d:%02d:%04.1f' % (h, gps.timestamp[1], gps.timestamp[2]))
print('longitude latitude: %2.8f, %2.8f' % (gps.latitude[0], gps.longitude[0]))
print('Above sea level: %f' % gps.altitude)
print(gps.satellites_used)
print('Satellite number: (Elevation angle,Azimuth,SN ratio)')
for k, v in gps.satellite_data.items():
print('%d: %s' % (k, v))
print('')
time.sleep(3.0)
When I run the program, the following result is output. Latitude and longitude after the decimal point are hidden.
14:02:19.0
longitude latitude: 35.********, 139.********
Above sea level: 51.900000
Positioning satellite: [17, 28, 6, 3, 193, 1, 22, 8]
Satellite number: (Elevation angle,Azimuth,SN ratio)
193: (59, 173, 40)
3: (71, 124, 24)
6: (13, 259, 27)
1: (49, 42, 16)
8: (15, 115, 21)
42: (48, 170, 34)
11: (40, 69, None)
14: (4, 47, None)
17: (42, 317, 15)
19: (20, 307, None)
22: (56, 66, 21)
23: (10, 145, None)
28: (63, 248, 38)
30: (3, 224, 16)
The next line after "Satellite number" is the satellite number, elevation angle, azimuth angle, and signal-to-noise ratio of the captured satellite. Satellite number 193 is "Quasi-Zenith Satellite No. 1 Michibiki".
Recommended Posts