| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354 |
- -- LuaTools需要PROJECT和VERSION这两个信息
- PROJECT = "gnsstest"
- VERSION = "1.0.1"
- --[[
- 本demo需要很多流量!!!
- 注意: 室内无信号!! 无法定位!!!
- 本demo对应的网页是 https://iot.openluat.com/iot/device-gnss
- ]]
- -- sys库是标配
- local sys = require("sys")
- require("sysplus")
- -- Air780E的AT固件默认会为开机键防抖, 导致部分用户刷机很麻烦
- if rtos.bsp() == "EC618" and pm and pm.PWK_MODE then
- pm.power(pm.PWK_MODE, false)
- end
- local gps_uart_id = 2
- local mqttc = nil
- -- libgnss库初始化
- libgnss.clear() -- 清空数据,兼初始化
- -- LED和ADC初始化
- LED_GNSS = 24
- LED_VBAT = 26
- gpio.setup(LED_GNSS, 0) -- GNSS定位成功灯
- gpio.setup(LED_VBAT, 0) -- 低电压警告灯
- adc.open(adc.CH_VBAT)
- adc.open(adc.CH_CPU)
- -- 串口初始化
- uart.setup(gps_uart_id, 115200)
- -- TODO 做成agnss.lua
- function exec_agnss()
- local url = "http://download.openluat.com/9501-xingli/HXXT_GPS_BDS_AGNSS_DATA.dat"
- local dat_done = false
- sys.waitUntil("NTP_UPDATE", 1000)
- if io.fileSize("/6228.bin") > 1024 then
- local date = os.date("!*t")
- log.info("当前系统时间", os.date())
- if date.year < 2023 then
- date = os.date("!*t")
- end
- if date.year > 2022 then
- local tm = io.readFile("/6226_tm")
- if tm then
- local t = tonumber(tm)
- if t and (os.time() - t < 3600*2) then
- log.info("agnss", "重用星历文件")
- local body = io.readFile("/6228.bin")
- for offset = 1, #body, 512 do
- uart.write(gps_uart_id, body:sub(offset, offset + 511))
- sys.wait(100)
- end
- dat_done = true
- else
- log.info("星历过期了")
- end
- else
- log.info("星历时间有问题")
- end
- else
- log.info("时间有问题")
- end
- end
- if http and not dat_done then
- -- AGNSS 已调通
- while 1 do
- local code, headers, body = http.request("GET", url).wait()
- log.info("gnss", "AGNSS", code, body and #body or 0)
- if code == 200 and body and #body > 1024 then
- for offset = 1, #body, 512 do
- log.info("gnss", "AGNSS", "write >>>", #body:sub(offset, offset + 511))
- uart.write(gps_uart_id, body:sub(offset, offset + 511))
- -- sys.waitUntil("UART2_SEND", 100)
- sys.wait(100) -- 等100ms反而更成功
- end
- -- sys.waitUntil("UART2_SEND", 1000)
- io.writeFile("/6228.bin", body)
- local date = os.date("!*t")
- if date.year > 2022 then
- io.writeFile("/6226_tm", tostring(os.time()))
- end
- break
- end
- sys.wait(60 * 1000)
- end
- end
- sys.wait(20)
- -- "$AIDTIME,year,month,day,hour,minute,second,millisecond"
- local date = os.date("!*t")
- if date.year > 2022 then
- local str = string.format("$AIDTIME,%d,%d,%d,%d,%d,%d,000", date["year"], date["month"], date["day"],
- date["hour"], date["min"], date["sec"])
- log.info("gnss", str)
- uart.write(gps_uart_id, str .. "\r\n")
- sys.wait(20)
- end
- -- 读取之前的位置信息
- local gnssloc = io.readFile("/gnssloc")
- if gnssloc then
- str = "$AIDPOS," .. gnssloc
- log.info("POS", str)
- uart.write(gps_uart_id, str .. "\r\n")
- str = nil
- gnssloc = nil
- else
- -- TODO 发起基站定位
- uart.write(gps_uart_id, "$AIDPOS,3432.70,N,10885.25,E,1.0\r\n")
- end
- end
- -- function upload_stat()
- -- -- if mqttc == nil or not mqttc:ready() then return end
- -- local stat = {
- -- csq = mobile.csq(),
- -- rssi = mobile.rssi(),
- -- rsrq = mobile.rsrq(),
- -- rsrp = mobile.rsrp(),
- -- -- iccid = mobile.iccid(),
- -- snr = mobile.snr(),
- -- vbat = adc.get(adc.CH_VBAT),
- -- temp = adc.get(adc.CH_CPU),
- -- memsys = {rtos.meminfo("sys")},
- -- memlua = {rtos.meminfo()},
- -- fixed = libgnss.isFix()
- -- }
- -- sys.publish("uplink", "/gnss/" .. mobile.imei() .. "/up/stat", (json.encode(stat)), 1)
- -- end
- -- sys.timerLoopStart(upload_stat, 60 * 1000)
- sys.taskInit(function()
- sys.waitUntil("IP_READY")
- -- Air780EG默认波特率是115200
- local nmea_topic = "/gnss/" .. mobile.imei() .. "/up/nmea"
- log.info("GPS", "start")
- pm.power(pm.GPS, true)
- libgnss.on("raw", function(data)
- sys.publish("uplink", nmea_topic, data, 1)
- end)
- -- 调试日志,可选
- libgnss.debug(true)
- sys.wait(200) -- GPNSS芯片启动需要时间,大概150ms
- -- 显示串口配置
- -- uart.write(gps_uart_id, "$CFGPRT,1\r\n")
- -- sys.wait(20)
- -- 增加显示的语句,可选
- uart.write(gps_uart_id, "$CFGMSG,0,1,1\r\n") -- GLL
- sys.wait(20)
- uart.write(gps_uart_id, "$CFGMSG,0,5,1\r\n") -- VTG
- sys.wait(20)
- uart.write(gps_uart_id, "$CFGMSG,0,6,1\r\n") -- ZDA
- sys.wait(20)
- -- 定位成功后,使用GNSS时间设置RTC, 暂不可用
- -- libgnss.rtcAuto(true)
-
- -- 绑定uart,底层自动处理GNSS数据
- -- 这里延后到设置命令发送完成后才开始处理数据,之前的数据就不上传了
- libgnss.bind(gps_uart_id)
- log.debug("提醒", "室内无GNSS信号,定位不会成功, 要到空旷的室外,起码要看得到天空")
- exec_agnss()
- end)
- sys.taskInit(function()
- while 1 do
- sys.wait(5000)
- -- 6228CI, 查询产品信息, 可选
- -- uart.write(gps_uart_id, "$PDTINFO,*62\r\n")
- -- uart.write(gps_uart_id, "$AIDINFO\r\n")
- -- sys.wait(100)
- -- uart.write(gps_uart_id, "$CFGSYS\r\n")
- -- uart.write(gps_uart_id, "$CFGMSG,6,4\r\n")
- log.info("RMC", json.encode(libgnss.getRmc(2) or {}, "7f"))
- log.info("INT", libgnss.getIntLocation())
- -- log.info("GGA", libgnss.getGga(3))
- -- log.info("GLL", json.encode(libgnss.getGll(2) or {}, "7f"))
- -- log.info("GSA", json.encode(libgnss.getGsa(2) or {}, "7f"))
- -- log.info("GSV", json.encode(libgnss.getGsv(2) or {}, "7f"))
- -- log.info("VTG", json.encode(libgnss.getVtg(2) or {}, "7f"))
- -- log.info("ZDA", json.encode(libgnss.getZda(2) or {}, "7f"))
- -- log.info("date", os.date())
- log.info("sys", rtos.meminfo("sys"))
- log.info("lua", rtos.meminfo("lua"))
- end
- end)
- -- 订阅GNSS状态编码
- sys.subscribe("GNSS_STATE", function(event, ticks)
- -- event取值有
- -- FIXED 定位成功
- -- LOSE 定位丢失
- -- ticks是事件发生的时间,一般可以忽略
- local onoff = libgnss.isFix() and 1 or 0
- log.info("GNSS", "LED", onoff)
- gpio.set(LED_GNSS, onoff)
- log.info("gnss", "state", event, ticks)
- if event == "FIXED" then
- local locStr = libgnss.locStr()
- log.info("gnss", "locStr", locStr)
- if locStr then
- io.writeFile("/gnssloc", locStr)
- end
- end
- end)
- -- mqtt 上传任务
- sys.taskInit(function()
- -- sys.waitUntil("IP_READY", 15000)
- mqttc = mqtt.create(nil, "lbsmqtt.airm2m.com", 1886) -- mqtt客户端创建
- mqttc:auth(mobile.imei(), mobile.imei(), mobile.muid()) -- mqtt三元组配置
- log.info("mqtt", mobile.imei(), mobile.imei(), mobile.muid())
- mqttc:keepalive(30) -- 默认值240s
- mqttc:autoreconn(true, 3000) -- 自动重连机制
- mqttc:on(function(mqtt_client, event, data, payload) -- mqtt回调注册
- -- 用户自定义代码,按event处理
- -- log.info("mqtt", "event", event, mqtt_client, data, payload)
- if event == "conack" then -- mqtt成功完成鉴权后的消息
- sys.publish("mqtt_conack") -- 小写字母的topic均为自定义topic
- -- 订阅不是必须的,但一般会有
- mqtt_client:subscribe("/gnss/" .. mobile.imei() .. "/down/#")
- elseif event == "recv" then -- 服务器下发的数据
- log.info("mqtt", "downlink", "topic", data, "payload", payload)
- local dl = json.decode(data)
- if dl then
- -- 检测命令
- if dl.cmd then
- -- 直接写uart
- if dl.cmd == "uart" and dl.data then
- uart.write(gps_uart_id, dl.data)
- -- 重启命令
- elseif dl.cmd == "reboot" then
- rtos.reboot()
- elseif dl.cmd == "stat" then
- upload_stat()
- end
- end
- end
- elseif event == "sent" then -- publish成功后的事件
- log.info("mqtt", "sent", "pkgid", data)
- end
- end)
- -- 发起连接之后,mqtt库会自动维护链接,若连接断开,默认会自动重连
- mqttc:connect()
- -- sys.waitUntil("mqtt_conack")
- -- log.info("mqtt连接成功")
- sys.timerStart(upload_stat, 3000) -- 一秒后主动上传一次
- while true do
- sys.wait(60*1000)
- end
- mqttc:close()
- mqttc = nil
- end)
- sys.taskInit(function()
- while 1 do
- sys.wait(3600 * 1000) -- 一小时检查一次
- local fixed, time_fixed = libgnss.isFix()
- if not fixed then
- exec_agnss()
- end
- end
- end)
- sys.timerLoopStart(upload_stat, 60000)
- sys.taskInit(function()
- local msgs = {}
- while 1 do
- local ret, topic, data, qos = sys.waitUntil("uplink", 30000)
- if ret then
- if topic == "close" then
- break
- end
- log.info("mqtt", "publish", "topic", topic)
- -- if #data > 512 then
- -- local start = mcu.ticks()
- -- local cdata = miniz.compress(data)
- -- local endt = mcu.ticks() - start
- -- if cdata then
- -- log.info("miniz", #data, #cdata, endt)
- -- end
- -- end
- if mqttc:ready() then
- local tmp = msgs
- if #tmp > 0 then
- log.info("mqtt", "ready, send buff", #tmp)
- msgs = {}
- for k, msg in pairs(tmp) do
- mqttc:publish(msg.topic, msg.data, 0)
- end
- end
- mqttc:publish(topic, data, qos)
- else
- log.info("mqtt", "not ready, insert into buff")
- if #msgs > 60 then
- table.remove(msgs, 1)
- end
- table.insert(msgs, {
- topic = topic,
- data = data
- })
- end
- end
- end
- end)
- -- 适配GNSS测试设备的GPIO
- sys.taskInit(function()
- while 1 do
- local vbat = adc.get(adc.CH_VBAT)
- log.info("vbat", vbat)
- if vbat < 3400 then
- gpio.set(LED_VBAT, 1)
- sys.wait(100)
- gpio.set(LED_VBAT, 0)
- sys.wait(900)
- else
- sys.wait(1000)
- end
- end
- end)
- sys.subscribe("NTP_UPDATE", function()
- if not libgnss.isFix() then
- -- "$AIDTIME,year,month,day,hour,minute,second,millisecond"
- local date = os.date("!*t")
- local str = string.format("$AIDTIME,%d,%d,%d,%d,%d,%d,000",
- date["year"], date["month"], date["day"], date["hour"], date["min"], date["sec"])
- log.info("gnss", str)
- uart.write(gps_uart_id, str .. "\r\n")
- end
- end)
- if socket.sntp then
- sys.subscribe("IP_READY", function()
- socket.sntp()
- end)
- end
- -- 用户代码已结束---------------------------------------------
- -- 结尾总是这一句
- sys.run()
- -- sys.run()之后后面不要加任何语句!!!!!
|