main.lua 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. -- LuaTools需要PROJECT和VERSION这两个信息
  2. PROJECT = "gnsstest"
  3. VERSION = "1.0.1"
  4. --[[
  5. 本demo需要很多流量!!!
  6. 注意: 室内无信号!! 无法定位!!!
  7. ]]
  8. -- sys库是标配
  9. local sys = require("sys")
  10. require("sysplus")
  11. local gps_uart_id = 2
  12. local mqttc = nil
  13. -- libgnss库初始化
  14. libgnss.clear() -- 清空数据,兼初始化
  15. -- LED和ADC初始化
  16. LED_GNSS = 24
  17. LED_VBAT = 26
  18. gpio.setup(LED_GNSS, 0) -- GNSS定位成功灯
  19. gpio.setup(LED_VBAT, 0) -- 低电压警告灯
  20. adc.open(adc.CH_VBAT)
  21. adc.open(adc.CH_CPU)
  22. -- 串口初始化
  23. uart.setup(gps_uart_id, 115200)
  24. -- TODO 做成agnss.lua
  25. function exec_agnss()
  26. local url = "http://download.openluat.com/9501-xingli/HXXT_GPS_BDS_AGNSS_DATA.dat"
  27. local dat_done = false
  28. sys.waitUntil("NTP_UPDATE", 1000)
  29. if io.fileSize("/6228.bin") > 1024 then
  30. local date = os.date("!*t")
  31. log.info("当前系统时间", os.date())
  32. if date.year < 2023 then
  33. date = os.date("!*t")
  34. end
  35. if date.year > 2022 then
  36. local tm = io.readFile("/6226_tm")
  37. if tm then
  38. local t = tonumber(tm)
  39. if t and (os.time() - t < 3600*2) then
  40. log.info("agnss", "重用星历文件")
  41. local body = io.readFile("/6228.bin")
  42. for offset = 1, #body, 512 do
  43. uart.write(gps_uart_id, body:sub(offset, offset + 511))
  44. sys.wait(100)
  45. end
  46. dat_done = true
  47. else
  48. log.info("星历过期了")
  49. end
  50. else
  51. log.info("星历时间有问题")
  52. end
  53. else
  54. log.info("时间有问题")
  55. end
  56. end
  57. if http and not dat_done then
  58. -- AGNSS 已调通
  59. while 1 do
  60. local code, headers, body = http.request("GET", url).wait()
  61. log.info("gnss", "AGNSS", code, body and #body or 0)
  62. if code == 200 and body and #body > 1024 then
  63. for offset = 1, #body, 512 do
  64. log.info("gnss", "AGNSS", "write >>>", #body:sub(offset, offset + 511))
  65. uart.write(gps_uart_id, body:sub(offset, offset + 511))
  66. -- sys.waitUntil("UART2_SEND", 100)
  67. sys.wait(100) -- 等100ms反而更成功
  68. end
  69. -- sys.waitUntil("UART2_SEND", 1000)
  70. io.writeFile("/6228.bin", body)
  71. local date = os.date("!*t")
  72. if date.year > 2022 then
  73. io.writeFile("/6226_tm", tostring(os.time()))
  74. end
  75. break
  76. end
  77. sys.wait(60 * 1000)
  78. end
  79. end
  80. sys.wait(20)
  81. -- "$AIDTIME,year,month,day,hour,minute,second,millisecond"
  82. local date = os.date("!*t")
  83. if date.year > 2022 then
  84. local str = string.format("$AIDTIME,%d,%d,%d,%d,%d,%d,000", date["year"], date["month"], date["day"],
  85. date["hour"], date["min"], date["sec"])
  86. log.info("gnss", str)
  87. uart.write(gps_uart_id, str .. "\r\n")
  88. sys.wait(20)
  89. end
  90. -- 读取之前的位置信息
  91. local gnssloc = io.readFile("/gnssloc")
  92. if gnssloc then
  93. str = "$AIDPOS," .. gnssloc
  94. log.info("POS", str)
  95. uart.write(gps_uart_id, str .. "\r\n")
  96. str = nil
  97. gnssloc = nil
  98. else
  99. -- TODO 发起基站定位
  100. uart.write(gps_uart_id, "$AIDPOS,3432.70,N,10885.25,E,1.0\r\n")
  101. end
  102. end
  103. -- function upload_stat()
  104. -- -- if mqttc == nil or not mqttc:ready() then return end
  105. -- local stat = {
  106. -- csq = mobile.csq(),
  107. -- rssi = mobile.rssi(),
  108. -- rsrq = mobile.rsrq(),
  109. -- rsrp = mobile.rsrp(),
  110. -- -- iccid = mobile.iccid(),
  111. -- snr = mobile.snr(),
  112. -- vbat = adc.get(adc.CH_VBAT),
  113. -- temp = adc.get(adc.CH_CPU),
  114. -- memsys = {rtos.meminfo("sys")},
  115. -- memlua = {rtos.meminfo()},
  116. -- fixed = libgnss.isFix()
  117. -- }
  118. -- sys.publish("uplink", "/gnss/" .. mobile.imei() .. "/up/stat", (json.encode(stat)), 1)
  119. -- end
  120. -- sys.timerLoopStart(upload_stat, 60 * 1000)
  121. sys.taskInit(function()
  122. sys.waitUntil("IP_READY")
  123. -- Air780EG默认波特率是115200
  124. local nmea_topic = "/gnss/" .. mobile.imei() .. "/up/nmea"
  125. log.info("GPS", "start")
  126. pm.power(pm.GPS, true)
  127. libgnss.on("raw", function(data)
  128. sys.publish("uplink", nmea_topic, data, 1)
  129. end)
  130. -- 调试日志,可选
  131. libgnss.debug(true)
  132. sys.wait(200) -- GPNSS芯片启动需要时间,大概150ms
  133. -- 显示串口配置
  134. -- uart.write(gps_uart_id, "$CFGPRT,1\r\n")
  135. -- sys.wait(20)
  136. -- 增加显示的语句,可选
  137. uart.write(gps_uart_id, "$CFGMSG,0,1,1\r\n") -- GLL
  138. sys.wait(20)
  139. uart.write(gps_uart_id, "$CFGMSG,0,5,1\r\n") -- VTG
  140. sys.wait(20)
  141. uart.write(gps_uart_id, "$CFGMSG,0,6,1\r\n") -- ZDA
  142. sys.wait(20)
  143. -- 定位成功后,使用GNSS时间设置RTC, 暂不可用
  144. -- libgnss.rtcAuto(true)
  145. -- 绑定uart,底层自动处理GNSS数据
  146. -- 这里延后到设置命令发送完成后才开始处理数据,之前的数据就不上传了
  147. libgnss.bind(gps_uart_id)
  148. log.debug("提醒", "室内无GNSS信号,定位不会成功, 要到空旷的室外,起码要看得到天空")
  149. exec_agnss()
  150. end)
  151. sys.taskInit(function()
  152. while 1 do
  153. sys.wait(5000)
  154. -- 6228CI, 查询产品信息, 可选
  155. -- uart.write(gps_uart_id, "$PDTINFO,*62\r\n")
  156. -- uart.write(gps_uart_id, "$AIDINFO\r\n")
  157. -- sys.wait(100)
  158. -- uart.write(gps_uart_id, "$CFGSYS\r\n")
  159. -- uart.write(gps_uart_id, "$CFGMSG,6,4\r\n")
  160. log.info("RMC", json.encode(libgnss.getRmc(2) or {}))
  161. -- log.info("GGA", libgnss.getGga(3))
  162. -- log.info("GLL", json.encode(libgnss.getGll(2) or {}))
  163. -- log.info("GSA", json.encode(libgnss.getGsa(2) or {}))
  164. -- log.info("GSV", json.encode(libgnss.getGsv(2) or {}))
  165. -- log.info("VTG", json.encode(libgnss.getVtg(2) or {}))
  166. -- log.info("ZDA", json.encode(libgnss.getZda(2) or {}))
  167. -- log.info("date", os.date())
  168. log.info("sys", rtos.meminfo("sys"))
  169. log.info("lua", rtos.meminfo("lua"))
  170. end
  171. end)
  172. -- 订阅GNSS状态编码
  173. sys.subscribe("GNSS_STATE", function(event, ticks)
  174. -- event取值有
  175. -- FIXED 定位成功
  176. -- LOSE 定位丢失
  177. -- ticks是事件发生的时间,一般可以忽略
  178. local onoff = libgnss.isFix() and 1 or 0
  179. log.info("GNSS", "LED", onoff)
  180. gpio.set(LED_GNSS, onoff)
  181. log.info("gnss", "state", event, ticks)
  182. if event == "FIXED" then
  183. local locStr = libgnss.locStr()
  184. log.info("gnss", "locStr", locStr)
  185. if locStr then
  186. io.writeFile("/gnssloc", locStr)
  187. end
  188. end
  189. end)
  190. -- mqtt 上传任务
  191. sys.taskInit(function()
  192. -- sys.waitUntil("IP_READY", 15000)
  193. mqttc = mqtt.create(nil, "lbsmqtt.airm2m.com", 1886) -- mqtt客户端创建
  194. mqttc:auth(mobile.imei(), mobile.imei(), mobile.muid()) -- mqtt三元组配置
  195. log.info("mqtt", mobile.imei(), mobile.imei(), mobile.muid())
  196. mqttc:keepalive(30) -- 默认值240s
  197. mqttc:autoreconn(true, 3000) -- 自动重连机制
  198. mqttc:on(function(mqtt_client, event, data, payload) -- mqtt回调注册
  199. -- 用户自定义代码,按event处理
  200. -- log.info("mqtt", "event", event, mqtt_client, data, payload)
  201. if event == "conack" then -- mqtt成功完成鉴权后的消息
  202. sys.publish("mqtt_conack") -- 小写字母的topic均为自定义topic
  203. -- 订阅不是必须的,但一般会有
  204. mqtt_client:subscribe("/gnss/" .. mobile.imei() .. "/down/#")
  205. elseif event == "recv" then -- 服务器下发的数据
  206. log.info("mqtt", "downlink", "topic", data, "payload", payload)
  207. local dl = json.decode(data)
  208. if dl then
  209. -- 检测命令
  210. if dl.cmd then
  211. -- 直接写uart
  212. if dl.cmd == "uart" and dl.data then
  213. uart.write(gps_uart_id, dl.data)
  214. -- 重启命令
  215. elseif dl.cmd == "reboot" then
  216. rtos.reboot()
  217. elseif dl.cmd == "stat" then
  218. upload_stat()
  219. end
  220. end
  221. end
  222. elseif event == "sent" then -- publish成功后的事件
  223. log.info("mqtt", "sent", "pkgid", data)
  224. end
  225. end)
  226. -- 发起连接之后,mqtt库会自动维护链接,若连接断开,默认会自动重连
  227. mqttc:connect()
  228. -- sys.waitUntil("mqtt_conack")
  229. -- log.info("mqtt连接成功")
  230. sys.timerStart(upload_stat, 3000) -- 一秒后主动上传一次
  231. while true do
  232. sys.wait(60*1000)
  233. end
  234. mqttc:close()
  235. mqttc = nil
  236. end)
  237. sys.taskInit(function()
  238. while 1 do
  239. sys.wait(3600 * 1000) -- 一小时检查一次
  240. local fixed, time_fixed = libgnss.isFix()
  241. if not fixed then
  242. exec_agnss()
  243. end
  244. end
  245. end)
  246. sys.timerLoopStart(upload_stat, 60000)
  247. sys.taskInit(function()
  248. local msgs = {}
  249. while 1 do
  250. local ret, topic, data, qos = sys.waitUntil("uplink", 30000)
  251. if ret then
  252. if topic == "close" then
  253. break
  254. end
  255. log.info("mqtt", "publish", "topic", topic)
  256. -- if #data > 512 then
  257. -- local start = mcu.ticks()
  258. -- local cdata = miniz.compress(data)
  259. -- local endt = mcu.ticks() - start
  260. -- if cdata then
  261. -- log.info("miniz", #data, #cdata, endt)
  262. -- end
  263. -- end
  264. if mqttc:ready() then
  265. local tmp = msgs
  266. if #tmp > 0 then
  267. log.info("mqtt", "ready, send buff", #tmp)
  268. msgs = {}
  269. for k, msg in pairs(tmp) do
  270. mqttc:publish(msg.topic, msg.data, 0)
  271. end
  272. end
  273. mqttc:publish(topic, data, qos)
  274. else
  275. log.info("mqtt", "not ready, insert into buff")
  276. if #msgs > 60 then
  277. table.remove(msgs, 1)
  278. end
  279. table.insert(msgs, {
  280. topic = topic,
  281. data = data
  282. })
  283. end
  284. end
  285. end
  286. end)
  287. -- 适配GNSS测试设备的GPIO
  288. sys.taskInit(function()
  289. while 1 do
  290. local vbat = adc.get(adc.CH_VBAT)
  291. log.info("vbat", vbat)
  292. if vbat < 3400 then
  293. gpio.set(LED_VBAT, 1)
  294. sys.wait(100)
  295. gpio.set(LED_VBAT, 0)
  296. sys.wait(900)
  297. else
  298. sys.wait(1000)
  299. end
  300. end
  301. end)
  302. sys.subscribe("NTP_UPDATE", function()
  303. if not libgnss.isFix() then
  304. -- "$AIDTIME,year,month,day,hour,minute,second,millisecond"
  305. local date = os.date("!*t")
  306. local str = string.format("$AIDTIME,%d,%d,%d,%d,%d,%d,000",
  307. date["year"], date["month"], date["day"], date["hour"], date["min"], date["sec"])
  308. log.info("gnss", str)
  309. uart.write(gps_uart_id, str .. "\r\n")
  310. end
  311. end)
  312. if socket.sntp then
  313. sys.subscribe("IP_READY", function()
  314. socket.sntp()
  315. end)
  316. end
  317. -- 休眠测试, V1103会有问题
  318. -- mobile.flymode(0, false)
  319. -- sys.taskInit(function()
  320. -- while 1 do
  321. -- sys.wait(60000)
  322. -- if libgnss.isFix() then
  323. -- pm.dtimerStart(0, 30000)
  324. -- pm.request(pm.HIB)
  325. -- pm.power(pm.USB, false)
  326. -- mobile.flymode(0, true)
  327. -- end
  328. -- end
  329. -- end)
  330. -- 用户代码已结束---------------------------------------------
  331. -- 结尾总是这一句
  332. sys.run()
  333. -- sys.run()之后后面不要加任何语句!!!!!