-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
136 lines (97 loc) · 3.83 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
"""
Read data from GPS sensor
CSV format:
timestamp, latitude, longitude, altitude
"""
import time
import utils
import smbus2
# Define the I2C bus and address for the SAM-M8Q module
I2C_BUS = utils.get_bus("gps")
GPS_ADDRESS = 0x42
# Initialize logger
logger = utils.init_logger("gps")
# Create an I2C bus instance
bus = smbus2.SMBus(I2C_BUS)
def convert_to_degrees(raw_value):
"""Convert NMEA raw latitude/longitude format to decimal degrees."""
degrees = int(raw_value[:2])
minutes = float(raw_value[2:])
return degrees + minutes / 60
def read_gps_data():
try:
# Read 32 bytes of data from the GPS module
data = bus.read_i2c_block_data(GPS_ADDRESS, 0xFF, 32) # 0xFF is the register address to read data
# Filter out initialization bytes (255)
filtered_data = [byte for byte in data if byte != 255]
return filtered_data
except Exception as e:
logger.warning(f"Error reading GPS data: {e}")
return None
def parse_nmea_sentence(data):
try:
# Convert data to ASCII characters
nmea_sentence = ''.join(chr(byte) for byte in data)
return nmea_sentence
except Exception as e:
logger.warning(f"Error parsing NMEA sentence: {e}")
return None
def extract_lat_lon_alt(nmea_sentence):
latitude = None
longitude = None
altitude = None
try:
if nmea_sentence.startswith("$GNRMC") or nmea_sentence.startswith("$GPRMC"):
parts = nmea_sentence.split(',')
if len(parts) > 6 and parts[3] and parts[5]:
# Extract latitude and longitude
latitude = convert_to_degrees(parts[3])
if parts[4] == 'S':
latitude = -latitude
longitude = convert_to_degrees(parts[5])
if parts[6] == 'W':
longitude = -longitude
elif nmea_sentence.startswith("$GNGGA") or nmea_sentence.startswith("$GPGGA"):
parts = nmea_sentence.split(',')
if len(parts) > 9 and parts[2] and parts[4] and parts[9]:
# Extract latitude and longitude
latitude = convert_to_degrees(parts[2])
if parts[3] == 'S':
latitude = -latitude
longitude = convert_to_degrees(parts[4])
if parts[5] == 'W':
longitude = -longitude
# Extract altitude
altitude = float(parts[9])
# Adjusting longitude by a certain amount
if longitude is not None:
longitude -= 6.0 # Adjust longitude by -6.0 degrees
except Exception as e:
logger.warning(f"Error extracting latitude, longitude, and altitude: {e}")
return latitude, longitude, altitude
def main():
buffer = ""
while True:
# Sleep 80 ms to avoid high CPU usage
time.sleep(0.08)
# Read GPS data
raw_data = read_gps_data()
if not raw_data:
continue
# Append new data to buffer
nmea_sentence_part = parse_nmea_sentence(raw_data)
if not nmea_sentence_part:
continue
buffer += nmea_sentence_part
# Split buffer into complete sentences
sentences = buffer.split('\n')
buffer = sentences[-1] # Keep incomplete sentence in buffer
for sentence in sentences[:-1]:
# Extract and print latitude, longitude, and altitude
lat, lon, alt = extract_lat_lon_alt(sentence)
if lat is not None and lon is not None and alt is not None:
logger.info(f"Latitude: {lat:.7f}, Longitude: {lon:.7f}, Altitude: {alt:.3f}m")
utils.write_csv("gps", [lat, lon, alt])
utils.send_data("gps", {"latitude": lat, "longitude": lon, "altitude": alt}, logger)
if __name__ == "__main__":
main()