From e262e7c8f5de978dbd1ef145c938c0b59c2ff07d Mon Sep 17 00:00:00 2001 From: Wendal Chen Date: Fri, 21 Jun 2024 06:36:54 +0800 Subject: [PATCH] =?utf8?q?add:=20=E5=AF=B9air780eg=5Fgnsstest=E8=BF=9B?= =?utf8?q?=E8=A1=8C=E6=94=B9=E9=80=A0,=E6=8B=86=E5=88=86=E5=A4=9A=E4=B8=AA?= =?utf8?q?=E6=96=87=E4=BB=B6,6228=E7=8B=AC=E7=AB=8B=E6=88=90=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- demo/air780eg_gnsstest/main.lua | 394 ++++-------------------------------- demo/air780eg_gnsstest/testGnss.lua | 50 +++++ demo/air780eg_gnsstest/testGpio.lua | 23 +++ demo/air780eg_gnsstest/testMqtt.lua | 127 ++++++++++++ demo/air780eg_gnsstest/testTcp.lua | 190 +++++++++++++++++ demo/air780eg_gnsstest/uc6228.lua | 271 +++++++++++++++++++++++++ 6 files changed, 696 insertions(+), 359 deletions(-) rewrite demo/air780eg_gnsstest/main.lua (96%) create mode 100644 demo/air780eg_gnsstest/testGnss.lua create mode 100644 demo/air780eg_gnsstest/testGpio.lua create mode 100644 demo/air780eg_gnsstest/testMqtt.lua create mode 100644 demo/air780eg_gnsstest/testTcp.lua create mode 100644 demo/air780eg_gnsstest/uc6228.lua diff --git a/demo/air780eg_gnsstest/main.lua b/demo/air780eg_gnsstest/main.lua dissimilarity index 96% index de7e5c8c..4d9be3cf 100644 --- a/demo/air780eg_gnsstest/main.lua +++ b/demo/air780eg_gnsstest/main.lua @@ -1,359 +1,35 @@ --- 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 发起基站定位 - 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, "$CFGSYS,H01\r\n") -- GPS L1+SBAS+QZSS 联合定位 - -- sys.wait(20) - -- uart.write(gps_uart_id, "$CFGSYS,H10\r\n") -- 单北斗 BDS B1 - -- sys.wait(20) - -- uart.write(gps_uart_id, "$CFGSYS,H01\r\n") -- GPS L1+BDS B1+QZSS 联合定位,默认 - -- 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) - - -- 绑定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()之后后面不要加任何语句!!!!! +-- LuaTools需要PROJECT和VERSION这两个信息 +PROJECT = "gnsstest" +VERSION = "1.0.1" +PRODUCT_KEY = "" -- 基站定位需要用到 + +--[[ +本demo需要很多流量!!! +注意: 室内无信号!! 无法定位!!! +]] + +-- sys库是标配 +_G.sys = require("sys") +require("sysplus") + +_G.gps_uart_id = 2 + +-- 演示GNSS定位, 含AGPS +require "testGnss" + +-- 演示上报到MQTT服务器 对应的网页是 https://iot.openluat.com/iot/device-gnss +-- require "testMqtt" + +-- 演示定位成功后切换GPIO高低电平 +-- require "testGpio" + +-- 本TCP演示是连接到 gps.nutz.cn 19002 端口, irtu的自定义包格式 +-- 网页是 https://gps.nutz.cn/ 输入IMEI号可参考当前位置 +-- 微信小程序是 irtu寻物, 点击IMEI号, 扫描模块的二维码可查看当前位置和历史轨迹 +-- 服务器源码地址: https://gitee.com/wendal/irtu-gps +require "testTcp" + +-- 用户代码已结束--------------------------------------------- +-- 结尾总是这一句 +sys.run() +-- sys.run()之后后面不要加任何语句!!!!! diff --git a/demo/air780eg_gnsstest/testGnss.lua b/demo/air780eg_gnsstest/testGnss.lua new file mode 100644 index 00000000..43e86b99 --- /dev/null +++ b/demo/air780eg_gnsstest/testGnss.lua @@ -0,0 +1,50 @@ + +-- libgnss库初始化 +libgnss.clear() -- 清空数据,兼初始化 + +-- LED和ADC初始化 +LED_GNSS = 24 +gpio.setup(LED_GNSS, 0) -- GNSS定位成功灯 + +local gnss = require("uc6228") + +sys.taskInit(function() + log.debug("提醒", "室内无GNSS信号,定位不会成功, 要到空旷的室外,起码要看得到天空") + gnss.setup({ + uart_id=2, + uart_forward = uart.VUART_0, -- 转发到虚拟串口,方便对接GnssToolKit3 + debug=true + }) + pm.power(pm.GPS, true) + gnss.start() + gnss.agps() +end) + +sys.taskInit(function() + while 1 do + sys.wait(5000) + -- 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(1) 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) +end) + diff --git a/demo/air780eg_gnsstest/testGpio.lua b/demo/air780eg_gnsstest/testGpio.lua new file mode 100644 index 00000000..7e732e0f --- /dev/null +++ b/demo/air780eg_gnsstest/testGpio.lua @@ -0,0 +1,23 @@ + + +LED_VBAT = 26 +gpio.setup(LED_VBAT, 0) -- 低电压警告灯 + +adc.open(adc.CH_CPU) + +-- 适配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) + diff --git a/demo/air780eg_gnsstest/testMqtt.lua b/demo/air780eg_gnsstest/testMqtt.lua new file mode 100644 index 00000000..3a822d1e --- /dev/null +++ b/demo/air780eg_gnsstest/testMqtt.lua @@ -0,0 +1,127 @@ + +local mqttc = nil + +-- 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) + +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) + diff --git a/demo/air780eg_gnsstest/testTcp.lua b/demo/air780eg_gnsstest/testTcp.lua new file mode 100644 index 00000000..b41f1948 --- /dev/null +++ b/demo/air780eg_gnsstest/testTcp.lua @@ -0,0 +1,190 @@ +--[[ +连到gps.nutz.cn 19002 端口, irtu的自定义包格式 +]] + +-- LuaTools需要PROJECT和VERSION这两个信息 +PROJECT = "scdemo" +VERSION = "1.0.0" + +log.info("main", PROJECT, VERSION) + +-- 一定要添加sys.lua !!!! +sys = require("sys") +sysplus = require("sysplus") +libnet = require "libnet" + +if pm and pm.PWK_MODE then + pm.power(pm.PWK_MODE, false) +end + +if wdt then + --添加硬狗防止程序卡死,在支持的设备上启用这个功能 + wdt.init(9000)--初始化watchdog设置为9s + sys.timerLoopStart(wdt.feed, 3000)--3s喂一次狗 +end + +adc.open(adc.CH_VBAT) + +--============================================================= +-- 本TCP演示是连接到 gps.nutz.cn 19002 端口, irtu的自定义包格式 +-- 网页是 https://gps.nutz.cn/ 输入IMEI号可参考当前位置 +-- 微信小程序是 irtu寻物, 点击IMEI号, 扫描模块的二维码可查看当前位置和历史轨迹 +local host = "gps.nutz.cn" -- 服务器ip或者域名, 都可以的 +local port = 19002 -- 服务器端口号 +local is_udp = false -- 如果是UDP, 要改成true, false就是TCP +local is_tls = false -- 加密与否, 要看服务器的实际情况 +--============================================================= + +-- 处理未识别的网络消息 +local function netCB(msg) + log.info("未处理消息", msg[1], msg[2], msg[3], msg[4]) +end + +local socket_ready = false +local taskName = "sc" +local topic = taskName .. "_txrx" +log.info("socket", "event topic", topic) + +-- 演示task +local function sockettest() + sys.waitUntil("IP_READY") + + -- 开始正在的逻辑, 发起socket链接,等待数据/上报心跳 + local txqueue = {} + sysplus.taskInitEx(sockettask, taskName, netCB, taskName, txqueue, topic) + while 1 do + local result, tp, data = sys.waitUntil(topic, 30000) + -- log.info("event", result, tp, data) + if not result then + -- 等很久了,没数据上传/下发, 发个日期心跳包吧 + table.insert(txqueue, string.char(0)) + sys_send(taskName, socket.EVENT, 0) + elseif tp == "uplink" then + -- 上行数据, 主动上报的数据,那就发送呀 + table.insert(txqueue, data) + sys_send(taskName, socket.EVENT, 0) + elseif tp == "downlink" then + -- 下行数据,接收的数据, 从ipv6task来的 + -- 其他代码可以通过 sys.publish() + log.info("socket", "收到下发的数据了", #data) + end + end +end + + + +function sockettask(d1Name, txqueue, rxtopic) + -- 打印准备连接的服务器信息 + log.info("socket", host, port, is_udp and "UDP" or "TCP", is_tls and "TLS" or "RAW") + + -- 准备好所需要的接收缓冲区 + local rx_buff = zbuff.create(1024) + local netc = socket.create(nil, d1Name) + socket.config(netc, nil, is_udp, is_tls) + log.info("任务id", d1Name) + + while true do + -- 连接服务器, 15秒超时 + log.info("socket", "开始连接服务器") + sysplus.cleanMsg(d1Name) + local result = libnet.connect(d1Name, 15000, netc, host, port) + if result then + log.info("socket", "服务器连上了") + local tmp = {imei=mobile.imei(),iccid=mobile.iccid()} + libnet.tx(d1Name, 0, netc, json.encode(tmp)) + socket_ready = true + else + log.info("socket", "服务器没连上了!!!") + end + while result do + -- 连接成功之后, 先尝试接收 + -- log.info("socket", "调用rx接收数据") + local succ, param = socket.rx(netc, rx_buff) + if not succ then + log.info("服务器断开了", succ, param, ip, port) + break + end + -- 如果服务器有下发数据, used()就必然大于0, 进行处理 + if rx_buff:used() > 0 then + log.info("socket", "收到服务器数据,长度", rx_buff:used()) + local data = rx_buff:query() -- 获取数据 + sys.publish(rxtopic, "downlink", data) + rx_buff:del() + end + -- log.info("libnet", "调用wait开始等待消息") + -- 等待事件, 例如: 服务器下发数据, 有数据准备上报, 服务器断开连接 + result, param, param2 = libnet.wait(d1Name, 15000, netc) + log.info("libnet", "wait", result, param, param2) + if not result then + -- 网络异常了, 那就断开了, 执行清理工作 + log.info("socket", "服务器断开了", result, param) + break + elseif #txqueue > 0 then + -- 有待上报的数据,处理之 + while #txqueue > 0 do + local data = table.remove(txqueue, 1) + if not data then + break + end + result,param = libnet.tx(d1Name, 15000, netc,data) + -- log.info("libnet", "发送数据的结果", result, param) + if not result then + log.info("socket", "数据发送异常", result, param) + break + end + end + end + -- 循环尾部, 继续下一轮循环 + end + socket_ready = false + -- 能到这里, 要么服务器断开连接, 要么上报(tx)失败, 或者是主动退出 + libnet.close(d1Name, 5000, netc) + -- log.info(rtos.meminfo("sys")) + sys.wait(3000) -- 这是重连时长, 自行调整 + end +end + +sys.taskInit(sockettest) + + +sys.taskInit(function() + sys.waitUntil("IP_READY") + local stat_t = 0 + local buff = zbuff.create(64) + while true do + if socket_ready then + -- 发送设备状态 >b7IHb == 1*7+4+2+1 = 14 + if os.time() - stat_t > 30 then + -- 30秒上报一次 + local vbat = adc.get(adc.CH_VBAT) + buff:seek(0) + buff:pack(">b7IHb", 0x55, 0, 0, 0, 0, 0, 0, 0, vbat, mobile.csq()) + sys.publish(topic, "uplink", buff:query()) + stat_t = os.time() + sys.wait(100) + end + -- 发送位置信息 >b2i3H2b3 == 1*2+4*3+2*2+1*3 == 2+12+4+3 = 21 + if true then + local rmc = libgnss.getRmc(1) + local gsa = libgnss.getGsa() + local gsv = libgnss.getGsv() + -- log.info("socket", "rmc", rmc.lat, rmc.lng, rmc.alt, rmc.course, rmc.speed) + buff:seek(0) + buff:pack(">b2i3H2b3", 0xAA, libgnss.isFix() and 1 or 0, + os.time(), + rmc and rmc.lng or 0, + rmc and rmc.lat or 0, + 0, -- rmc and rmc.alt or 0, + math.floor(rmc and rmc.course or 0), + math.floor(rmc and rmc.speed or 0), + gsa and #gsa.sats or 0, -- msg.sateCno + gsv and gsv.total_sats or 0 -- msg.sateCnt + ) + sys.publish(topic, "uplink", buff:query()) + end + sys.wait(1000) + else + sys.wait(100) + end + end +end) diff --git a/demo/air780eg_gnsstest/uc6228.lua b/demo/air780eg_gnsstest/uc6228.lua new file mode 100644 index 00000000..831f7a24 --- /dev/null +++ b/demo/air780eg_gnsstest/uc6228.lua @@ -0,0 +1,271 @@ +--[[ + +]] + +local uc6228 = { + version = "1.0.1" +} + +local sys = require("sys") + +function uc6228.setup(opts) + uc6228.opts = opts + if not uc6228.opts.uart_id then + uc6228.opts.uart_id = 2 + end +end + +function uc6228.start() + -- 初始化串口 + local gps_uart_id = uc6228.opts.uart_id + local opts = uc6228.opts + local write = uc6228.writeCmd + uart.setup(gps_uart_id, 115200) + -- 是否为调试模式 + if opts.debug then + libgnss.debug(true) + end + libgnss.bind(gps_uart_id) + + -- 是否需要切换定位系统呢? + if opts.sys then + if type(opts.sys) == "number" then + if opts.sys == 1 then + uart.write(gps_uart_id, "$CFGSYS,H01\r\n") + elseif opts.sys == 2 then + uart.write(gps_uart_id, "$CFGSYS,H10\r\n") + elseif opts.sys == 5 then + uart.write(gps_uart_id, "$CFGSYS,H101\r\n") + else + uart.write(gps_uart_id, "$CFGSYS,H11\r\n") + end + end + end + + if not opts.nmea_ver or opts.nmea_ver == 41 then + uart.write(gps_uart_id, "$CFGNMEA,h51\r\n") -- 切换到NMEA 4.1 + end + + -- 打开全部NMEA语句 + if opts.rmc_only then + uart.write(gps_uart_id, "$CFGMSG,0,0,0\r\n") + sys.wait(20) + uart.write(gps_uart_id, "$CFGMSG,0,1,0\r\n") + sys.wait(20) + uart.write(gps_uart_id, "$CFGMSG,0,2,0\r\n") + sys.wait(20) + uart.write(gps_uart_id, "$CFGMSG,0,3,0\r\n") + sys.wait(20) + uart.write(gps_uart_id, "$CFGMSG,0,4,1\r\n") + sys.wait(20) + uart.write(gps_uart_id, "$CFGMSG,0,5,0\r\n") + sys.wait(20) + uart.write(gps_uart_id, "$CFGMSG,0,6,0\r\n") + sys.wait(20) + uart.write(gps_uart_id, "$CFGMSG,0,7,0\r\n") + sys.wait(20) + elseif uc6228.opts.no_nmea then + uart.write(gps_uart_id, "$CFGMSG,0,0,0\r\n") + sys.wait(20) + uart.write(gps_uart_id, "$CFGMSG,0,1,0\r\n") + sys.wait(20) + uart.write(gps_uart_id, "$CFGMSG,0,2,0\r\n") + sys.wait(20) + uart.write(gps_uart_id, "$CFGMSG,0,3,0\r\n") + sys.wait(20) + uart.write(gps_uart_id, "$CFGMSG,0,4,0\r\n") + sys.wait(20) + uart.write(gps_uart_id, "$CFGMSG,0,5,0\r\n") + sys.wait(20) + uart.write(gps_uart_id, "$CFGMSG,0,6,0\r\n") + sys.wait(20) + uart.write(gps_uart_id, "$CFGMSG,0,7,0\r\n") + sys.wait(20) + else + uart.write(gps_uart_id, "$CFGMSG,0,0,1\r\n") -- GGA + sys.wait(10) + uart.write(gps_uart_id, "$CFGMSG,0,1,1\r\n") -- GLL + sys.wait(10) + uart.write(gps_uart_id, "$CFGMSG,0,2,1\r\n") -- GSA + sys.wait(10) + uart.write(gps_uart_id, "$CFGMSG,0,3,1\r\n") -- GSV + sys.wait(10) + uart.write(gps_uart_id, "$CFGMSG,0,4,1\r\n") -- RMC + sys.wait(10) + uart.write(gps_uart_id, "$CFGMSG,0,5,1\r\n") -- VTG + sys.wait(10) + uart.write(gps_uart_id, "$CFGMSG,0,6,1\r\n") -- ZDA + sys.wait(10) + -- uart.write(gps_uart_id, "$CFGMSG,0,7,1\r\n") -- GST + -- sys.wait(10) + end +end + +function uc6228.writeCmd(cmd) + log.info("uc6228", "写入指令", cmd:trim()) + uart.write(uc6228.opts.uart_id, cmd) +end + +function uc6228.reboot(mode) + local cmd = "$RESET,0," + if not mode then + mode = 0 + end + if mode == 2 then + cmd = cmd .. "hff\r\n" + elseif mode == 1 then + cmd = cmd .. "h01\r\n" + else + cmd = cmd .. "h00\r\n" + end + uart.write(uc6228.opts.uart_id, cmd) + if mode == 2 then + uc6228.agps_tm = nil + end + libgnss.clear() +end + +function uc6228.stop() + uart.close(uc6228.opts.uart_id) +end + +local function do_agps() + -- 首先, 发起位置查询 + local lat, lng + if mobile then + mobile.reqCellInfo(6) + sys.waitUntil("CELL_INFO_UPDATE", 6000) + local lbsLoc2 = require("lbsLoc2") + lat, lng = lbsLoc2.request(5000) + -- local lat, lng, t = lbsLoc2.request(5000, "bs.openluat.com") + log.info("lbsLoc2", lat, lng) + if lat and lng then + lat = tonumber(lat) + lng = tonumber(lng) + log.info("lbsLoc2", lat, lng) + end + elseif wlan then + -- wlan.scan() + -- sys.waitUntil("WLAN_SCAN_DONE", 5000) + end + if not lat then + -- 获取最后的本地位置 + local locStr = io.readFile("/hxxtloc") + if locStr then + local jdata = json.decode(locStr) + if jdata and jdata.lat then + lat = jdata.lat + lng = jdata.lng + end + end + end + -- 然后, 判断星历时间和下载星历 + local now = os.time() + local agps_time = tonumber(io.readFile("/hxxt_tm") or "0") or 0 + if now - agps_time > 3600 then + local url = uc6228.opts.url + if not uc6228.opts.url then + if uc6228.opts.sys and 2 == uc6228.opts.sys then + -- 单北斗 + url = "http://download.openluat.com/9501-xingli/HXXT_BDS_AGNSS_DATA.dat" + else + url = "http://download.openluat.com/9501-xingli/HXXT_GPS_BDS_AGNSS_DATA.dat" + end + end + local code = http.request("GET", url, nil, nil, {dst="/hxxt.dat"}).wait() + if code and code == 200 then + log.info("uc6228", "下载星历成功", url) + io.writeFile("/hxxt_tm", tostring(now)) + else + log.info("uc6228", "下载星历失败", code) + end + else + log.info("uc6228", "星历不需要更新", now - agps_time) + end + + local gps_uart_id = uc6228.opts.uart_id or 2 + + -- 写入星历 + local agps_data = io.readFile("/hxxt.dat") + if agps_data and #agps_data > 1024 then + log.info("uc6228", "写入星历数据", "长度", #agps_data) + for offset=1,#agps_data,512 do + log.info("gnss", "AGNSS", "write >>>", #agps_data:sub(offset, offset + 511)) + uart.write(gps_uart_id, agps_data:sub(offset, offset + 511)) + sys.wait(100) -- 等100ms反而更成功 + end + -- uart.write(gps_uart_id, agps_data) + else + log.info("uc6228", "没有星历数据") + return + end + + -- 写入参考位置 + -- "lat":23.4068813,"min":27,"valid":true,"day":27,"lng":113.2317505 + if not lat or not lng then + -- lat, lng = 23.4068813, 113.2317505 + log.info("uc6228", "没有GPS坐标", lat, lng) + return -- TODO 暂时不写入参考位置 + end + if socket.sntp then + socket.sntp() + sys.waitUntil("NTP_UPDATE", 1000) + end + local date = os.date("!*t") + if date.year > 2023 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("uc6228", "参考时间", str) + uart.write(gps_uart_id, str .. "\r\n") + sys.wait(20) + end + + local str = string.format("$AIDPOS,%.7f,%s,%.7f,%s,1.0\r\n", + lat > 0 and lat or (0 - lat), lat > 0 and 'N' or 'S', + lng > 0 and lng or (0 - lng), lng > 0 and 'E' or 'W') + log.info("uc6228", "写入AGPS参考位置", str) + uart.write(gps_uart_id, str) + + -- 结束 + uc6228.agps_tm = now +end + +function uc6228.agps(force) + -- 如果不是强制写入AGPS信息, 而且是已经定位成功的状态,那就没必要了 + if not force and libgnss.isFix() then return end + -- 先判断一下时间 + local now = os.time() + if force or not uc6228.agps_tm or now - uc6228.agps_tm > 3600 then + -- 执行AGPS + log.info("uc6228", "开始执行AGPS") + do_agps() + else + log.info("uc6228", "暂不需要写入AGPS") + end +end + +function uc6228.saveloc(lat, lng) + if not lat or not lng then + if libgnss.isFix() then + local rmc = libgnss.getRmc(3) + if rmc then + lat, lng = rmc.lat, rmc.lng + end + end + end + if lat and lng then + log.info("待保存的GPS位置", lat, lng) + local locStr = string.format('{"lat":%7f,"lng":%7f}', lat, lng) + log.info("uc6228", "保存GPS位置", locStr) + io.writeFile("/hxxtloc", locStr) + end +end + +sys.subscribe("GNSS_STATE", function(event) + if event == "FIXED" then + uc6228.saveloc() + end +end) + + +return uc6228 -- 2.11.4.GIT