Python异步串口读取和LCD显示写入

2024-10-04 01:34:13 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个带gps模块的树莓PI。GPS模块报告4Hz的位置。我想在i2c LCD屏幕上显示这些数据,但是更新屏幕需要很长的时间,所以我不能在串行循环中完成。 我想每秒更新一次LCD,同时继续不间断地接收GPS数据。 我目前的代码(对此表示歉意)如下:

import time
import serial
import string
import pynmea2
import lcd
import geopy.distance
import asyncio
import threading

ser = serial.Serial()
ser.port = "/dev/ttyACM0"
ser.baudrate = 9600
ser.timeout = 1
ser.open()
ser.write(b'\xB5\x62\x06\x08\x06\x00\xFA\x00\x01\x00\x01\x00\x10\x96') #tell GPS module to report at 4 Hz


reader = pynmea2.NMEAStreamReader(open(ser.port))
lcd.lcd_init()

qual = 0
kmph = 0
alt = "?"
sats = "0"
timeStart = 1
timeDiff = 1
prevLat = 0
prevLon = 0
totalDist = 0
PDOP = 0


async def readGPS():
    global qual
    global kmph
    global alt
    global sats
    global timeStart
    global timeDiff
    global prevLat
    global prevLon
    global totalDist
    global PDOP
    while True:
        try:
            for msg in reader.next():
                if type(msg) == pynmea2.types.talker.GGA:
                    timeDiff = time.time() - timeStart
                    timeStart = time.time() #reset time to now
                    qual = msg.gps_qual
                    if msg.altitude == None:
                        alt = "?"
                    else:
                        alt = round(msg.altitude)
                    if str(msg.num_sats).startswith("0"):
                        sats = str(msg.num_sats)[1]
                    else:
                        sats = str(msg.num_sats)
                    if prevLat != 0 and kmph >= 2 and PDOP < 2.5:
                        try:
                            prevLatLon = (prevLat, prevLon)
                            curLatLon = (float(msg.latitude), float(msg.longitude))
                            incr = geopy.distance.distance(prevLatLon, curLatLon).m
                            totalDist += incr
                            print(totalDist)
                        except Exception as e:
                            print(e)
                            
                    if int(msg.latitude) != 0:
                            prevLat = float(msg.latitude)
                            prevLon = float(msg.longitude)
                    
                if type(msg) == pynmea2.types.talker.VTG:
                    try:
                        kmph = round(int(msg.spd_over_grnd_kmph))
                    except:
                        kmph = 0
                if type(msg) == pynmea2.types.talker.GSA:
                    try:
                        PDOP = float(msg.pdop)
                    except:
                        continue

                print(str(kmph) + ' ' + str(alt) + 'm   ' + sats + ' sats, q' + str(qual) + ' Hz = ' + str(round(1/timeDiff, 1)), end='\r')

        except UnicodeDecodeError:
            continue
        except KeyboardInterrupt:
            lcd.lcd_byte(0x01, lcd.LCD_CMD)
            exit()
            
async def updateLCD(): #Write info to LCD
    print("LCD")
    lcd.lcd_string(str(kmph) + '       ' + sats + ' sats', lcd.LCD_LINE_1)
    lcd.lcd_string(str(alt) + 'm     q' + str(qual) + '  ' + str(round(1/timeDiff, 1)) + 'Hz', lcd.LCD_LINE_2)
    await asyncio.sleep(1)

async def main():
    while True:
        await readGPS()
        await updateLCD()

loop = asyncio.get_event_loop()
loop.create_task(main())
loop.run_forever()

这将运行readGPS()循环,但似乎从未启动updateLCD()循环


Tags: importiflcdtimemsgaltglobalser