備忘錄_20160105(定位) 修改 回首頁

程式 2026-04-08 17:24:19 1775640259 100
neo-6m (gps) + esp32 lolin d32

neo-6m (gps) + esp32 lolin d32

# rx,tx 用 pin16,17 才不會跟 thonny 所需要的 uart0 相衝 # NEO-6M的 VCC -- esp32的 3.3V # NEO-6M的 RX -- esp32的 TX (gpio17) # NEO-6M的 TX -- esp32的 RX (gpio16) # NEO-6M的 GND -- esp32的 GND # 目前是 led 燈亮,代表有抓到可用的 gps 訊號 from machine import Pin from machine import UART import time import network import urequests import gc def getStrGMTp8(strDDMMYY, strUTCTime): ''' 傳入從 gps 模組得到的 日月年,時分秒 傳出 年(4碼)月(2碼)日(2碼)時(2碼)分(2碼)秒(2碼) ''' strGmtp8="00000000000000" try: iYear=int("20"+strDDMMYY[4:6]) iMonth=int(strDDMMYY[2:4]) iDay=int(strDDMMYY[0:2]) iHour=int(strUTCTime[0:2]) iMinute=int(strUTCTime[2:4]) iSecond=int(strUTCTime[4:6]) oUtcTime=(iYear,iMonth,iDay,iHour,iMinute,iSecond,0,0) oUtcTimestamp=time.mktime(oUtcTime) oGmtp8Time=time.localtime(oUtcTimestamp+8*3600) strGmtp8="{:04d}{:02d}{:02d}{:02d}{:02d}{:02d}".format( oGmtp8Time[0], oGmtp8Time[1], oGmtp8Time[2], oGmtp8Time[3], oGmtp8Time[4], oGmtp8Time[5]) except Exception as oE: #print(oE) pass return strGmtp8 def getFRealDeg(strVal, strDir): """ 把經緯度從文字轉成浮點數,若有任何錯誤,傳回None。 經度 dddmm.mmmm E,W 緯度 ddmm.mmmm N,S """ if not strVal or strDir not in ['N','S','E','W']: return None try: if strDir in ['N','S']: iDegLen=2 else: iDegLen=3 iDeg=int(strVal[:iDegLen]) fMin=float(strVal[iDegLen:]) fFinalDeg=iDeg+fMin/60 if strDir in ['S','W']: fFinalDeg=-fFinalDeg return fFinalDeg except: return None def getBooIsConnected(): global oWlan, lstSSIDPASS, iSSIDPASSIndex, strSSID, strPASS if oWlan.isconnected()==False: oWlan.disconnect() # 清除殘餘狀態 time.sleep_ms(200) try: iSSIDPASSIndex=(iSSIDPASSIndex+1) % len(lstSSIDPASS) strSSID=lstSSIDPASS[iSSIDPASSIndex][0] strPASS=lstSSIDPASS[iSSIDPASSIndex][1] oWlan.connect(strSSID, strPASS) except: return False # 連線錯誤,本次退出。 iTimeout=20 while oWlan.isconnected()==False and iTimeout>0: time.sleep(1) iTimeout=iTimeout-1 if oWlan.isconnected()==False: return False # 網路連不上,本次退出。 return True def sendData(strDDMMYY, strUTCTime, fLat, fLon): global oWlan, iLastTicks, strSSID if fLat is None or fLon is None: return # 數據有問題,本次退出。 if getBooIsConnected()==False: return # 連線失敗,本次退出。 oResponse=None try: strRecTime="20"+strDDMMYY[4:6]+"/"+strDDMMYY[2:4]+"/"+strDDMMYY[0:2]+"%20"+strUTCTime[0:2]+":"+strUTCTime[2:4]+":"+strUTCTime[4:6] strUrl=( "https://web.godroad.tw/api5/getgpstest.aspx?" "lat="+str(fLat)+ "&lng="+str(fLon)+ "&rectime="+strRecTime+ "&cid=5554" ) oResponse=urequests.get(strUrl, timeout=5) iLastTicks=time.ticks_ms() except: pass finally: if oResponse: oResponse.close() oResponse=None try: # GET 方法,可用 http strGmtp8=getStrGMTp8(strDDMMYY, strUTCTime) strUrl=( "http://liujiaje.com/resources/20260408_esp32_lolin_d32_neo-6m-gps/api/gps.php?" "lat="+str(fLat)+ "&lon="+str(fLon)+ "&gmtp8="+strGmtp8+ "&ssid="+strSSID ) oResponse=urequests.get(strUrl, timeout=5) iLastTicks=time.ticks_ms() except: pass finally: if oResponse: oResponse.close() ''' oResponse=None try: # POST 方法,最好用 https strUrl="https://liujiaje.com/temp/20260408_gps/index.php" dictHeader={"Content-Type": "application/x-www-form-urlencoded"} strData="lat="+str(fLat)+"&lon="+str(fLon)+"&ddmmyy="+strDDMMYY+"&utc="+strUTCTime oResponse=urequests.post(strUrl, data=strData, headers=dictHeader, timeout=5) iLastTicks=time.ticks_ms() except: pass finally: if oResponse: oResponse.close() ''' gc.collect() def keepAlive(): global oWlan, iLastTicks, strSSID if getBooIsConnected()==False: return # 連線失敗,本次退出。 oResponse=None try: strUrl=( "http://liujiaje.com/resources/20260408_esp32_lolin_d32_neo-6m-gps/api/keepalive.php?" "&ssid="+strSSID ) oResponse=urequests.get(strUrl, timeout=5) iLastTicks=time.ticks_ms() except: pass finally: if oResponse: oResponse.close() gc.collect() def blink(iTimes, fDelayMs=50): global oLed if not oLed: return try: for _ in range(iTimes): oLed.value(0) # 亮燈 time.sleep_ms(fDelayMs) oLed.value(1) # 暗燈 time.sleep_ms(fDelayMs) except: pass # 連接 wifi 參數 lstSSIDPASS=[ ("godroad", "66666666"), ("ssid2", "pass2"), ("ssid3", "pass3")] iSSIDPASSIndex=-1 strSSID="" strPASS="" iLastTicks=0 # 記錄最後一次送出網路封包的時間 oWlan=network.WLAN(network.STA_IF) oWlan.active(True) # 使用 led 燈號 oLed=Pin(5, Pin.OUT) oLed.value(1) # 與 GPS 模組(neo-6m) 有關 oUart = UART(2, baudrate=9600, tx=17, rx=16, rxbuf=2048) baBuf=b"" while True: #blink(iTimes=1, fDelayMs=10) if time.ticks_diff(time.ticks_ms(), iLastTicks)>30000: # 網路傳輸每隔30秒送一次封包,確保行動網路不被關閉 keepAlive() baData=oUart.read() if baData: baBuf+=baData if len(baBuf)>2048: baBuf=baBuf[-1024:] oLed.value(1) iPos=baBuf.find(b"\n") while iPos!=-1: strLine=baBuf[:iPos] baBuf=baBuf[iPos+1:] iPos=baBuf.find(b"\n") #blink(iTimes=1, fDelayMs=2) strLine=strLine.strip() try: strLine=strLine.decode() except: strLine="" if strLine.startswith('$GPRMC') or strLine.startswith('$GNRMC'): lstPart=strLine.split(',') if len(lstPart)>12: strMessageType=lstPart[0] strUTCTime=lstPart[1] strStatus=lstPart[2] # Void/Active strLatVal=lstPart[3] # strLatDir=lstPart[4] # North/South strLonVal=lstPart[5] # strLonDir=lstPart[6] # East/West if strStatus=="A": fLat=getFRealDeg(strLatVal, strLatDir) fLon=getFRealDeg(strLonVal, strLonDir) oLed.value(0) else: fLat=None fLon=None strSpeedOverGround=lstPart[7] # knots strTrackAngle=lstPart[8] strDDMMYY=lstPart[9] strMagneticVariationVal=lstPart[10] strMagneticVariationDir=lstPart[11] strMode=lstPart[12] # Autonomous/Differential/Estimated try: strChecksum=strMode[1:] strMode=strMode[0:1] except: strChecksum="" strMode="" sendData(strDDMMYY, strUTCTime, fLat, fLon) try: time.sleep_ms(50) except KeyboardInterrupt: break

ver04

若要防水,可用熱熔膠封住瓶口。


ver03


ver02


ver01