uc6228.lua 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. --[[
  2. ]]
  3. local uc6228 = {
  4. version = "1.0.1"
  5. }
  6. local sys = require("sys")
  7. function uc6228.setup(opts)
  8. uc6228.opts = opts
  9. if not uc6228.opts.uart_id then
  10. uc6228.opts.uart_id = 2
  11. end
  12. end
  13. function uc6228.start()
  14. -- 初始化串口
  15. local gps_uart_id = uc6228.opts.uart_id
  16. local opts = uc6228.opts
  17. local write = uc6228.writeCmd
  18. uart.setup(gps_uart_id, 115200)
  19. -- 是否为调试模式
  20. if opts.debug then
  21. libgnss.debug(true)
  22. end
  23. if uc6228.opts.uart_forward then
  24. uart.setup(uc6228.opts.uart_forward, 115200)
  25. libgnss.bind(gps_uart_id, uc6228.opts.uart_forward)
  26. else
  27. libgnss.bind(gps_uart_id)
  28. end
  29. -- 是否需要切换定位系统呢?
  30. if opts.sys then
  31. if type(opts.sys) == "number" then
  32. if opts.sys == 1 then
  33. uart.write(gps_uart_id, "$CFGSYS,H01\r\n")
  34. elseif opts.sys == 2 then
  35. uart.write(gps_uart_id, "$CFGSYS,H10\r\n")
  36. elseif opts.sys == 5 then
  37. uart.write(gps_uart_id, "$CFGSYS,H101\r\n")
  38. else
  39. uart.write(gps_uart_id, "$CFGSYS,H11\r\n")
  40. end
  41. end
  42. end
  43. if not opts.nmea_ver or opts.nmea_ver == 41 then
  44. uart.write(gps_uart_id, "$CFGNMEA,h51\r\n") -- 切换到NMEA 4.1
  45. end
  46. -- 打开全部NMEA语句
  47. if opts.rmc_only then
  48. uart.write(gps_uart_id, "$CFGMSG,0,0,0\r\n")
  49. sys.wait(20)
  50. uart.write(gps_uart_id, "$CFGMSG,0,1,0\r\n")
  51. sys.wait(20)
  52. uart.write(gps_uart_id, "$CFGMSG,0,2,0\r\n")
  53. sys.wait(20)
  54. uart.write(gps_uart_id, "$CFGMSG,0,3,0\r\n")
  55. sys.wait(20)
  56. uart.write(gps_uart_id, "$CFGMSG,0,4,1\r\n")
  57. sys.wait(20)
  58. uart.write(gps_uart_id, "$CFGMSG,0,5,0\r\n")
  59. sys.wait(20)
  60. uart.write(gps_uart_id, "$CFGMSG,0,6,0\r\n")
  61. sys.wait(20)
  62. uart.write(gps_uart_id, "$CFGMSG,0,7,0\r\n")
  63. sys.wait(20)
  64. elseif uc6228.opts.no_nmea then
  65. uart.write(gps_uart_id, "$CFGMSG,0,0,0\r\n")
  66. sys.wait(20)
  67. uart.write(gps_uart_id, "$CFGMSG,0,1,0\r\n")
  68. sys.wait(20)
  69. uart.write(gps_uart_id, "$CFGMSG,0,2,0\r\n")
  70. sys.wait(20)
  71. uart.write(gps_uart_id, "$CFGMSG,0,3,0\r\n")
  72. sys.wait(20)
  73. uart.write(gps_uart_id, "$CFGMSG,0,4,0\r\n")
  74. sys.wait(20)
  75. uart.write(gps_uart_id, "$CFGMSG,0,5,0\r\n")
  76. sys.wait(20)
  77. uart.write(gps_uart_id, "$CFGMSG,0,6,0\r\n")
  78. sys.wait(20)
  79. uart.write(gps_uart_id, "$CFGMSG,0,7,0\r\n")
  80. sys.wait(20)
  81. else
  82. uart.write(gps_uart_id, "$CFGMSG,0,0,1\r\n") -- GGA
  83. sys.wait(10)
  84. uart.write(gps_uart_id, "$CFGMSG,0,1,1\r\n") -- GLL
  85. sys.wait(10)
  86. uart.write(gps_uart_id, "$CFGMSG,0,2,1\r\n") -- GSA
  87. sys.wait(10)
  88. uart.write(gps_uart_id, "$CFGMSG,0,3,1\r\n") -- GSV
  89. sys.wait(10)
  90. uart.write(gps_uart_id, "$CFGMSG,0,4,1\r\n") -- RMC
  91. sys.wait(10)
  92. uart.write(gps_uart_id, "$CFGMSG,0,5,1\r\n") -- VTG
  93. sys.wait(10)
  94. uart.write(gps_uart_id, "$CFGMSG,0,6,1\r\n") -- ZDA
  95. sys.wait(10)
  96. -- uart.write(gps_uart_id, "$CFGMSG,0,7,1\r\n") -- GST
  97. -- sys.wait(10)
  98. end
  99. end
  100. function uc6228.writeCmd(cmd)
  101. log.info("uc6228", "写入指令", cmd:trim())
  102. uart.write(uc6228.opts.uart_id, cmd)
  103. end
  104. function uc6228.reboot(mode)
  105. local cmd = "$RESET,0,"
  106. if not mode then
  107. mode = 0
  108. end
  109. if mode == 2 then
  110. cmd = cmd .. "hff\r\n"
  111. elseif mode == 1 then
  112. cmd = cmd .. "h01\r\n"
  113. else
  114. cmd = cmd .. "h00\r\n"
  115. end
  116. uart.write(uc6228.opts.uart_id, cmd)
  117. if mode == 2 then
  118. uc6228.agps_tm = nil
  119. end
  120. libgnss.clear()
  121. end
  122. function uc6228.stop()
  123. uart.close(uc6228.opts.uart_id)
  124. end
  125. local function do_agps()
  126. -- 首先, 发起位置查询
  127. local lat, lng
  128. if mobile then
  129. mobile.reqCellInfo(6)
  130. sys.waitUntil("CELL_INFO_UPDATE", 6000)
  131. local lbsLoc2 = require("lbsLoc2")
  132. lat, lng = lbsLoc2.request(5000)
  133. -- local lat, lng, t = lbsLoc2.request(5000, "bs.openluat.com")
  134. log.info("lbsLoc2", lat, lng)
  135. if lat and lng then
  136. lat = tonumber(lat)
  137. lng = tonumber(lng)
  138. log.info("lbsLoc2", lat, lng)
  139. end
  140. elseif wlan then
  141. -- wlan.scan()
  142. -- sys.waitUntil("WLAN_SCAN_DONE", 5000)
  143. end
  144. if not lat then
  145. -- 获取最后的本地位置
  146. local locStr = io.readFile("/hxxtloc")
  147. if locStr then
  148. local jdata = json.decode(locStr)
  149. if jdata and jdata.lat then
  150. lat = jdata.lat
  151. lng = jdata.lng
  152. end
  153. end
  154. end
  155. -- 然后, 判断星历时间和下载星历
  156. local now = os.time()
  157. local agps_time = tonumber(io.readFile("/hxxt_tm") or "0") or 0
  158. if now - agps_time > 3600 then
  159. local url = uc6228.opts.url
  160. if not uc6228.opts.url then
  161. if uc6228.opts.sys and 2 == uc6228.opts.sys then
  162. -- 单北斗
  163. url = "http://download.openluat.com/9501-xingli/HXXT_BDS_AGNSS_DATA.dat"
  164. else
  165. url = "http://download.openluat.com/9501-xingli/HXXT_GPS_BDS_AGNSS_DATA.dat"
  166. end
  167. end
  168. local code = http.request("GET", url, nil, nil, {dst="/hxxt.dat"}).wait()
  169. if code and code == 200 then
  170. log.info("uc6228", "下载星历成功", url)
  171. io.writeFile("/hxxt_tm", tostring(now))
  172. else
  173. log.info("uc6228", "下载星历失败", code)
  174. end
  175. else
  176. log.info("uc6228", "星历不需要更新", now - agps_time)
  177. end
  178. local gps_uart_id = uc6228.opts.uart_id or 2
  179. -- 写入星历
  180. local agps_data = io.readFile("/hxxt.dat")
  181. if agps_data and #agps_data > 1024 then
  182. log.info("uc6228", "写入星历数据", "长度", #agps_data)
  183. for offset=1,#agps_data,512 do
  184. log.info("gnss", "AGNSS", "write >>>", #agps_data:sub(offset, offset + 511))
  185. uart.write(gps_uart_id, agps_data:sub(offset, offset + 511))
  186. sys.wait(100) -- 等100ms反而更成功
  187. end
  188. -- uart.write(gps_uart_id, agps_data)
  189. else
  190. log.info("uc6228", "没有星历数据")
  191. return
  192. end
  193. -- 写入参考位置
  194. -- "lat":23.4068813,"min":27,"valid":true,"day":27,"lng":113.2317505
  195. if not lat or not lng then
  196. -- lat, lng = 23.4068813, 113.2317505
  197. log.info("uc6228", "没有GPS坐标", lat, lng)
  198. return -- TODO 暂时不写入参考位置
  199. end
  200. if socket.sntp then
  201. socket.sntp()
  202. sys.waitUntil("NTP_UPDATE", 1000)
  203. end
  204. local date = os.date("!*t")
  205. if date.year > 2023 then
  206. local str = string.format("$AIDTIME,%d,%d,%d,%d,%d,%d,000", date["year"], date["month"], date["day"],
  207. date["hour"], date["min"], date["sec"])
  208. log.info("uc6228", "参考时间", str)
  209. uart.write(gps_uart_id, str .. "\r\n")
  210. sys.wait(20)
  211. end
  212. local str = string.format("$AIDPOS,%.7f,%s,%.7f,%s,1.0\r\n",
  213. lat > 0 and lat or (0 - lat), lat > 0 and 'N' or 'S',
  214. lng > 0 and lng or (0 - lng), lng > 0 and 'E' or 'W')
  215. log.info("uc6228", "写入AGPS参考位置", str)
  216. uart.write(gps_uart_id, str)
  217. -- 结束
  218. uc6228.agps_tm = now
  219. end
  220. function uc6228.agps(force)
  221. -- 如果不是强制写入AGPS信息, 而且是已经定位成功的状态,那就没必要了
  222. if not force and libgnss.isFix() then return end
  223. -- 先判断一下时间
  224. local now = os.time()
  225. if force or not uc6228.agps_tm or now - uc6228.agps_tm > 3600 then
  226. -- 执行AGPS
  227. log.info("uc6228", "开始执行AGPS")
  228. do_agps()
  229. else
  230. log.info("uc6228", "暂不需要写入AGPS")
  231. end
  232. end
  233. function uc6228.saveloc(lat, lng)
  234. if not lat or not lng then
  235. if libgnss.isFix() then
  236. local rmc = libgnss.getRmc(3)
  237. if rmc then
  238. lat, lng = rmc.lat, rmc.lng
  239. end
  240. end
  241. end
  242. if lat and lng then
  243. log.info("待保存的GPS位置", lat, lng)
  244. local locStr = string.format('{"lat":%7f,"lng":%7f}', lat, lng)
  245. log.info("uc6228", "保存GPS位置", locStr)
  246. io.writeFile("/hxxtloc", locStr)
  247. end
  248. end
  249. sys.subscribe("GNSS_STATE", function(event)
  250. if event == "FIXED" then
  251. uc6228.saveloc()
  252. end
  253. end)
  254. return uc6228