#!/usr/bin/python # -*- coding:utf-8 -*- import RPi.GPIO as GPIO import serial import time import os import csv from datetime import datetime import pynmea2 # GPIO configuration GPIO.setmode(GPIO.BCM) GPIO.setwarnings(False) ser = serial.Serial('/dev/ttyUSB3', 115200) ser.flushInput() myhost = os.uname()[1] # CSV file settings csv_filename = f"gps_data_{myhost}.csv" csv_headers = ["Timestamp", "Latitude", "Longitude"] def parse_gps_data(gps_string): try: msg = pynmea2.parse(gps_string) if isinstance(msg, pynmea2.GGA): if msg.latitude and msg.longitude: return f"{msg.latitude:.6f}", f"{msg.longitude:.6f}" except pynmea2.ParseError as e: print(f"Parse error: {e}") return None, None def write_to_csv(lat, lon): timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") with open(csv_filename, mode='a', newline='') as file: writer = csv.writer(file) writer.writerow([timestamp, lat, lon]) time.sleep(12) def send_at(command, back, timeout): ser.write((command + '\r\n').encode()) time.sleep(timeout) if ser.inWaiting(): time.sleep(0.01) rec_buff = ser.read(ser.inWaiting()).decode() if back not in rec_buff: print(command + ' ERROR') print(command + ' back:\t' + rec_buff) return 0 else: print("Raw GPS data:", rec_buff) gps_sentences = rec_buff.split('\r\n') for sentence in gps_sentences: if sentence.startswith('$'): lat, lon = parse_gps_data(sentence) if lat and lon: print(f"Parsed GPS data: {lat}, {lon}") write_to_csv(lat, lon) return 1 print('No valid GPS data found') return 0 else: print('GPS is not ready') return 0 def get_gps_position(): print('Starting GPS') send_at('AT+CGPS=1,1', 'OK', 1) time.sleep(2) while True: answer = send_at('AT+CGPSINFO', '+CGPSINFO: ', 1) if answer == 1: break else: print('Waiting for GPS fix...') time.sleep(2) # Create CSV file with headers if it doesn't exist if not os.path.exists(csv_filename): with open(csv_filename, mode='w', newline='') as file: writer = csv.writer(file) writer.writerow(csv_headers) try: get_gps_position() except Exception as e: print(f"Error: {e}") finally: if ser: ser.close() GPIO.cleanup()