uc6228.lua 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  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. -- 转换单位
  140. local lat_dd,lat_mm = math.modf(lat)
  141. local lng_dd,lng_mm = math.modf(lng)
  142. lat = lat_dd * 100 + lat_mm * 60
  143. lng = lng_dd * 100 + lng_mm * 60
  144. end
  145. elseif wlan then
  146. -- wlan.scan()
  147. -- sys.waitUntil("WLAN_SCAN_DONE", 5000)
  148. end
  149. if not lat then
  150. -- 获取最后的本地位置
  151. local locStr = io.readFile("/hxxtloc")
  152. if locStr then
  153. local jdata = json.decode(locStr)
  154. if jdata and jdata.lat then
  155. lat = jdata.lat
  156. lng = jdata.lng
  157. end
  158. end
  159. end
  160. -- 然后, 判断星历时间和下载星历
  161. local now = os.time()
  162. local agps_time = tonumber(io.readFile("/hxxt_tm") or "0") or 0
  163. if now - agps_time > 3600 then
  164. local url = uc6228.opts.url
  165. if not uc6228.opts.url then
  166. if uc6228.opts.sys and 2 == uc6228.opts.sys then
  167. -- 单北斗
  168. url = "http://download.openluat.com/9501-xingli/HXXT_BDS_AGNSS_DATA.dat"
  169. else
  170. url = "http://download.openluat.com/9501-xingli/HXXT_GPS_BDS_AGNSS_DATA.dat"
  171. end
  172. end
  173. local code = http.request("GET", url, nil, nil, {dst="/hxxt.dat"}).wait()
  174. if code and code == 200 then
  175. log.info("uc6228", "下载星历成功", url)
  176. io.writeFile("/hxxt_tm", tostring(now))
  177. else
  178. log.info("uc6228", "下载星历失败", code)
  179. end
  180. else
  181. log.info("uc6228", "星历不需要更新", now - agps_time)
  182. end
  183. local gps_uart_id = uc6228.opts.uart_id or 2
  184. -- 写入星历
  185. local agps_data = io.readFile("/hxxt.dat")
  186. if agps_data and #agps_data > 1024 then
  187. log.info("uc6228", "写入星历数据", "长度", #agps_data)
  188. for offset=1,#agps_data,512 do
  189. log.info("gnss", "AGNSS", "write >>>", #agps_data:sub(offset, offset + 511))
  190. uart.write(gps_uart_id, agps_data:sub(offset, offset + 511))
  191. sys.wait(100) -- 等100ms反而更成功
  192. end
  193. -- uart.write(gps_uart_id, agps_data)
  194. else
  195. log.info("uc6228", "没有星历数据")
  196. return
  197. end
  198. -- 写入参考位置
  199. -- "lat":23.4068813,"min":27,"valid":true,"day":27,"lng":113.2317505
  200. if not lat or not lng then
  201. -- lat, lng = 23.4068813, 113.2317505
  202. log.info("uc6228", "没有GPS坐标", lat, lng)
  203. return -- TODO 暂时不写入参考位置
  204. end
  205. if socket.sntp then
  206. socket.sntp()
  207. sys.waitUntil("NTP_UPDATE", 1000)
  208. end
  209. local date = os.date("!*t")
  210. if date.year > 2023 then
  211. local str = string.format("$AIDTIME,%d,%d,%d,%d,%d,%d,000", date["year"], date["month"], date["day"],
  212. date["hour"], date["min"], date["sec"])
  213. log.info("uc6228", "参考时间", str)
  214. uart.write(gps_uart_id, str .. "\r\n")
  215. sys.wait(20)
  216. end
  217. local str = string.format("$AIDPOS,%.7f,%s,%.7f,%s,1.0\r\n",
  218. lat > 0 and lat or (0 - lat), lat > 0 and 'N' or 'S',
  219. lng > 0 and lng or (0 - lng), lng > 0 and 'E' or 'W')
  220. log.info("uc6228", "写入AGPS参考位置", str)
  221. uart.write(gps_uart_id, str)
  222. -- 结束
  223. uc6228.agps_tm = now
  224. end
  225. function uc6228.agps(force)
  226. -- 如果不是强制写入AGPS信息, 而且是已经定位成功的状态,那就没必要了
  227. if not force and libgnss.isFix() then return end
  228. -- 先判断一下时间
  229. local now = os.time()
  230. if force or not uc6228.agps_tm or now - uc6228.agps_tm > 3600 then
  231. -- 执行AGPS
  232. log.info("uc6228", "开始执行AGPS")
  233. do_agps()
  234. else
  235. log.info("uc6228", "暂不需要写入AGPS")
  236. end
  237. end
  238. function uc6228.saveloc(lat, lng)
  239. if not lat or not lng then
  240. if libgnss.isFix() then
  241. local rmc = libgnss.getRmc(3)
  242. if rmc then
  243. lat, lng = rmc.lat, rmc.lng
  244. end
  245. end
  246. end
  247. if lat and lng then
  248. log.info("待保存的GPS位置", lat, lng)
  249. local locStr = string.format('{"lat":%7f,"lng":%7f}', lat, lng)
  250. log.info("uc6228", "保存GPS位置", locStr)
  251. io.writeFile("/hxxtloc", locStr)
  252. end
  253. end
  254. sys.subscribe("GNSS_STATE", function(event)
  255. if event == "FIXED" then
  256. uc6228.saveloc()
  257. end
  258. end)
  259. return uc6228