如何为Raspberry Pi 4的NEO 6M GPS模块向PubNub发送经纬度数据设置间隔以避免Google Maps崩溃?
解决GPS数据推送间隔问题,避免Google Maps崩溃
你遇到的核心问题是每秒向PubNub推送一次GPS数据,导致前端Google Maps需要高频更新地图标记,超出了浏览器的处理能力,最终引发崩溃。我们可以通过在后端设置独立的数据推送间隔(和打印日志的间隔分开)来缓解这个问题,下面是具体的实现步骤和修改后的代码:
实现思路
- 保留原有的1秒一次的GPS状态打印(方便调试),但将PubNub的推送间隔调整为更长的时间(比如5秒、10秒,可根据你的需求调整)
- 新增一个专门记录上次推送时间的变量,只当时间差达到设定的间隔时才发送数据
修改后的完整代码
import RPi.GPIO as GPIO import time import board import busio import adafruit_gps import pubnub from pubnub.pnconfiguration import PNConfiguration from pubnub.pubnub import PubNub from pubnub.callbacks import SubscribeCallback from pubnub.enums import PNOperationType, PNStatusCategory def publish_callback(result, status): pass pnconfig = PNConfiguration() pnconfig.subscribe_key = "" pnconfig.publish_key = "" pnconfig.ssl = False pubnub = PubNub(pnconfig) import serial uart = serial.Serial("/dev/ttyAMA0", baudrate=9600, timeout=10) gps = adafruit_gps.GPS(uart, debug=False) gps.send_command(b"PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0") gps.send_command(b"PMTK220,1000") GPIO.setmode(GPIO.BCM) GPIO.setwarnings(False) last_print = time.monotonic() # 新增:设置PubNub推送间隔(单位:秒,可根据需求调整) PUBLISH_INTERVAL = 5 last_publish = time.monotonic() while True: gps.update() current = time.monotonic() if current - last_print >= 1.0: last_print = current if not gps.has_fix: print("Waiting for fix...") continue print("=" * 40) print( "Fix timestamp: {}/{}/{} {:02}:{:02}:{:02}".format( gps.timestamp_utc.tm_mon, gps.timestamp_utc.tm_mday, gps.timestamp_utc.tm_year, gps.timestamp_utc.tm_hour, gps.timestamp_utc.tm_min, gps.timestamp_utc.tm_sec, ) ) print("Latitude: {0:.6f} degrees".format(gps.latitude)) print("Longitude: {0:.6f} degrees".format(gps.longitude)) print("Fix quality: {}".format(gps.fix_quality)) if gps.satellites is not None: print("# satellites: {}".format(gps.satellites)) if gps.altitude_m is not None: print("Altitude: {} meters".format(gps.altitude_m)) if gps.speed_knots is not None: print("Speed: {} knots".format(gps.speed_knots)) if gps.track_angle_deg is not None: print("Track angle: {} degrees".format(gps.track_angle_deg)) if gps.horizontal_dilution is not None: print("Horizontal dilution: {}".format(gps.horizontal_dilution)) if gps.height_geoid is not None: print("Height geo ID: {} meters".format(gps.height_geoid)) # 新增:判断是否达到推送间隔,再发送数据 if current - last_publish >= PUBLISH_INTERVAL: last_publish = current dictionary = {"latitude": gps.latitude, "longitude": gps.longitude} pubnub.publish().channel("CHANNEL").message(dictionary).pn_async(publish_callback) print(f"Published GPS data to PubNub (interval: {PUBLISH_INTERVAL}s)")
关键修改点说明
- 新增了
PUBLISH_INTERVAL常量,你可以根据实际场景调整这个值(比如移动速度慢的场景用10秒,快速移动用3秒) - 新增
last_publish变量记录上次推送的时间,只有当当前时间与上次推送时间的差大于等于设定间隔时,才执行PubNub推送操作 - 保留了每秒一次的日志打印,方便你调试GPS状态,但不会频繁推送数据给前端
额外建议
如果调整后端间隔后仍然偶尔出现崩溃,你可以在前端Google Maps代码中添加防抖处理:比如即使收到新的GPS数据,也只在固定时间间隔内更新一次地图标记(比如2秒内只更新一次),进一步减轻前端的渲染压力。
内容的提问来源于stack exchange,提问作者T bow
相关产品推荐
相关产品推荐

