当前位置: 首页 > 知识库问答 >
问题:

从串行端口GPS读取python

李胤
2023-03-14

我做了一个python程序,从串行端口读取gps数据。GPS冰球流NMEA数据语句连续插入USB时。我的程序打开端口,然后尝试读取数据,解析它,然后将其与从Arduino提取的其他数据一起写入文本文件。

我遇到的问题是,当我第一次运行程序时,有时它无法读取数据。我放入了一些Try/Exception捕获,发现以某种方式无法从GPS串行端口读取数据
如果我点击Cntrl-C几次,这似乎可以解决它遇到的问题,然后它开始正常工作。我倾向于认为这是一个时间问题,即GPS何时进入流媒体,以及程序何时尝试读取串行缓冲区。

显然,我在代码中做了一些不正确的事情。我只是尽我所能把它拍在一起,就我的目的而言,它工作得很好,但需要一点帮助,让它更坚固,这样其他可能使用它的人就不会被它古怪的行为所困扰。

下面是它(一些缩进是错误的,因为从记事本复制粘贴)。任何帮助都会很好。

import serial
import pynmea2
import time
#####Global Variables######################################
#be sure to declare the variable as 'global var' in the functions

ID = 0
arduino = 0
ser2 = 0
fh = ""
rssi_dB = 0
gps = "NaN"

#    User configurable

gps_com_port = 19   # com 19 Shop7 at Hm 8
arduino_com_port = 18  # com 18 Shop7 at Hm 6

#    MCS2000 specific conversion rates
#    DON'T CHANGE!!!
slope1 = 0.0170
slope2 = 0.008
slope3 = 0.020
slope4 = 0.000
cutoff1 = 700
cutoff2 = 430
cutoff3 = 380
cutoff4 = 0
cutoff5 = 0
y_int1 = 3.399
y_int2 = 2.692
y_int3 = 3.949


#####FUNCTIONS#############################################
#initialize serial connection 
def init_serial():
COMNUM1 = arduino_com_port #set you COM port # here
COMNUM2 = gps_com_port
global arduino #must be declared in each fxn used
global ser2
arduino = serial.Serial(
                    port = COMNUM1 -1,
                    baudrate = 9600,
                    timeout = 1
                    )
ser2 = serial.Serial(
                    port = COMNUM2 -1,
                    baudrate = 4800,
                    timeout = 1
                    )

if arduino.isOpen():
    print 'Open: ' + arduino.portstr
if ser2.isOpen():
    print 'Open: ' + ser2.portstr

def init_file():
filename = raw_input('Enter save file[name.txt]:')
global fh
fh = open(filename,"w")

def rssi_convert(rssi):
#print ("rssi_convert\n")    
if rssi<=cutoff1 and rssi>=cutoff2:
    rssi_dB=((rssi*0.004888)-y_int1)/slope1
if rssi<=cutoff2 and rssi>=cutoff3:
    rssi_dB=((rssi*0.004888)-y_int2)/slope2
if rssi<=cutoff3 and rssi>=cutoff4:
    rssi_dB=((rssi*0.004888)-y_int3)/slope3
#if rssi<=cutoff4 and rssi>=cutoff5:
 #   rssi_dB=((rssi*0.004888)-2.047)/slope4

return float(rssi_dB)


#####SETUP################################################
#this is a good spot to run your initializations 
init_file()
init_serial()
time.sleep(2)
data_log = "TOD,Lat,Long,Alt,Qual,Ref_ID,Num_Sat,Hor_Dil,RSSI\n"
fh.writelines(data_log)  #write header to file 
rssi = arduino.readline()    
while str(rssi) == "A":
arduino.write("q")
rssi = arduino.readline()

#####MAIN LOOP############################################
while 1:

arduino.flushInput()
try:
    gps = ser2.readline()
except:
    print("Read GPS FAILED\n")

try:    
    gps_msg = pynmea2.parse(gps)
except:
    print("Failed to parse GPS\n")

try:    
    if gps_msg.sentence_type == 'GGA':
        arduino.write("q")
        time.sleep(.2)
        rssi = arduino.readline()

        try:
            rssi_dB = rssi_convert(float(rssi.strip('\0')))
        except:
            print("RSSI Conversion FAILED\n")
        try:
            data_log = str(gps_msg.timestamp) + "," + str(gps_msg.latitude) + "," + str(gps_msg.longitude) + "," + str(gps_msg.altitude) + "," + str(gps_msg.gps_qual) + "," + str(gps_msg.ref_station_id) + "," + str(gps_msg.num_sats) + "," + str(gps_msg.horizontal_dil) + ","  + str(rssi_dB) + "\n"
            print str(ID) + data_log
            fh.writelines(data_log)  #write data to file
            ID = int(ID) + 1
        except:
            pass#ID=ID+1
except:
    print("GPS Sentence Loop Failed")

共有1个答案

符正信
2023-03-14

您可以通过打印异常来获取有关异常的其他信息。

try:
    gps = ser2.readline()
except Exception as e:
    print('Read GPS failed: {0}'.format(e))

您还可以尝试将arduino.flushInput()放在循环之外。根据时间的不同,您可能会丢失一些数据。

 类似资料:
  • 问题内容: 我有一个Java程序,必须读取Arduino发送的信息。我从这里获取了Java代码。现在,我不太了解它是如何工作的,但是我尝试对其进行修改,并且得到了以下信息: 我创建一个对象串行COM口,我需要在主程序,然后我使用和当我需要它。 效果很好,Arduino获取数据并将其显示在LCD显示屏中。问题是。程序运行时,它会不断从串行端口读取数据(大约每40毫秒一次),但这并不意味着Arduin

  • 这是http://www.gravitech.us/7segmentshield.html给出的代码。 那么怎样才能逐行阅读呢?

  • 我读了很多问题和答案,但没有找到任何解决方案。也许我的问题不对,但我需要一些指导。我在Linux中使用串行端口,从我的Arduino设备读取数据。每当我想从Arduino向Linux发送数据时,我首先发送两个字节,这表示将从Arduino发送的总字节数。我将这两个字节转换为整数值,并开始从串行端口读取数据。比如说,我想把300字节从Ardiuno发送到Linux,我只需要先写{1,44},然后用下

  • 我有一个Velleman k8090中继板,我试图从中读取一些数据。我可以很好地写入电路板,但每当我输出读取的数据时,我都会得到奇怪的字符,比如菱形或倒置的问号。以下是我的部分代码: 为什么我会有这些奇怪的角色?文件规定它应该返回年份和星期。 编辑:经过一些搜索和故障排除,我现在非常确定它与Python代码或数据类型有关,而不是与硬件有关。这个论坛包含了一个C语言的例子,它从黑板上读取。我从黑板上

  • 问题内容: 我以下列方式从打开的串行端口读取某些数据时遇到麻烦。我已经多次使用此代码实例,并且一切正常,但是现在,由于某种原因,我无法弄清楚,我完全无法从串行端口读取任何内容。 我能够写,并且在另一端正确接收了所有消息,但是从未收到答复(正确发送)(不,电缆都还好;)) 我用来打开串行端口的代码如下: 端口初始化后,我通过简单的write命令向其中写入一些内容。 hCom是文件描述符(没关系),并

  • 我试图做一些非常简单的东西,按钮计数器,有一个按钮在我的HTML-php当我点击它我发送数据'按'到我的arduino和它使led闪烁,到目前为止,还不错,但然后我想发送信号,当我在arduino中按下按钮,我想让我的php读取字符串"点击次数: N"的串行端口,N是从arduio的推送计数。 这里的问题是,在arduino串行我可以看到他字符串,一切正常,但在PHP我做