欢迎光临散文网 会员登陆 & 注册

Luat Air780E/Air700E使用定位模块获取设备经纬度

2023-04-05 21:50 作者:TOP_SC  | 我要投稿

来自星星笔记(cxing.top):链接先左键选中再右键点击打开(直接复制打开可能打不开)➡️https://cxing.top/archives/34.html

先来代码

-- LuaTools需要PROJECT和VERSION这两个信息

PROJECT = "uart_gps"

VERSION = "1.0.0"


log.info("main", PROJECT, VERSION)


-- 引入必要的库文件(lua编写), 内部库不需要require

sys = require("sys")


if wdt then

    --添加硬狗防止程序卡死,在支持的设备上启用这个功能

    wdt.init(9000)--初始化watchdog设置为9s

    sys.timerLoopStart(wdt.feed, 3000)--3s喂一次狗

end


log.info("main", "uart demo")


local uartid = 2 -- 根据实际设备选取不同的uartid


--初始化

local result = uart.setup(

    uartid,--串口id

    9600,--波特率

    8,--数据位

    1--停止位

)


-- 收取数据会触发回调, 这里的"receive" 是固定值

uart.on(uartid, "receive", function(id, len)

    local s = ""

    repeat

        -- 如果是air302, len不可信, 传1024

        -- s = uart.read(id, 1024)

        s = uart.read(id, len)

        if #s > 0 then -- #s 是取字符串的长度

            -- log.info("uart", "receive", id, #s, s)

            local utc_time, lat, lat_ns, lon, lon_ew = string.match(s, "%$GNGGA,(%d+%.%d+),(%d+%.%d+),(%a),(%d+%.%d+),(%a),")

            if utc_time and lat and lat_ns and lon and lon_ew then

                log.info("uart", "UTC Time", utc_time)

                local hour = tonumber(utc_time:sub(1,2))

                local minute = tonumber(utc_time:sub(3,4))

                local second = tonumber(utc_time:sub(5,6))

                hour = hour +8

                if hour >=24 then

                    hour = hour -24

                end

                local time_str = string.format("%02d:%02d:%02d", hour, minute, second) -- 转换为时分秒格式

                log.info("uart", "Beijing Time", time_str)


                -- 转换经纬度为GPS坐标格式

                local lat_deg = math.floor(tonumber(lat) / 100)

                local lat_min = tonumber(lat) % 100

                local lat_google = lat_deg + lat_min / 60

                if lat_ns == "S" then

                    lat_google = -lat_google

                end

                log.info("uart", "Latitude", lat_google)

                local lon_deg = math.floor(tonumber(lon) / 100)

                local lon_min = tonumber(lon) % 100

                local lon_google = lon_deg + lon_min / 60

                if lon_ew == "W" then

                    lon_google = -lon_google

                end

                log.info("uart", "Longitude", lon_google)

            end

        end

        if #s == len then

            break

        end

    until s == ""

end)


-- 用户代码已结束---------------------------------------------

-- 结尾总是这一句

sys.run()

-- sys.run()之后后面不要加任何语句!!!!!

代码解释

这段代码实现了通过UART串口读取GPS模块发送的数据,并对数据进行解析和处理,最终输出解析后的结果。具体解释如下:


1、设置项目名称和版本号:

首先通过 PROJECT 和 VERSION 变量分别设置了项目名称和版本号。


2、输出项目名称和版本号:

使用 log.info() 函数输出项目名称和版本号。


3、引入必要的库文件:

使用 require() 函数引入了系统库 sys,用于后续的定时器操作和系统运行。


4、如果硬件支持硬狗,初始化并启用硬狗功能:

检查系统是否支持硬狗,如果支持则通过 wdt.init() 函数初始化硬狗并设置喂狗时间,通过 sys.timerLoopStart() 函数循环定时喂狗,以避免程序卡死等异常情况。


5、输出提示信息:

使用 log.info() 函数输出提示信息,表示进入了GPS数据读取和处理的代码段。


6、设置UART串口ID:

通过 uartid 变量设置了UART串口的ID,这里设置为2。


7、初始化UART串口:

使用 uart.setup() 函数初始化UART串口,设置波特率为9600,数据位为8位,停止位为1位。


8、注册UART串口数据接收回调函数:

使用 uart.on() 函数注册UART串口数据接收回调函数,当串口接收到数据时会自动触发回调函数,并将接收到的数据长度作为参数传入回调函数。


9、处理UART串口接收到的数据:

在回调函数中,使用 uart.read() 函数循环读取串口数据,并使用 string.match() 函数对读取到的数据进行正则匹配,提取出其中的经纬度和时间等信息,然后进行格式转换和计算,并使用 log.info() 函数输出解析后的信息。


10、最后,运行代码:

通过 sys.run() 函数启动系统运行,让代码可以正常执行。

重点代码解释

1、定位模块输出(波特率为9600):

```c

$GNGGA,084852.000,2236.9453,N,11408.4790,E,1,05,3.1,89.7,M,0.0,M,,*48

$GNGLL,2236.9453,N,11408.4790,E,084852.000,A,A*4C

$GPGSA,A,3,10,18,31,,,,,,,,,,6.3,3.1,5.4*3E

$BDGSA,A,3,06,07,,,,,,,,,,,6.3,3.1,5.4*24

$GPGSV,3,1,09,10,78,325,24,12,36,064,,14,26,307,,18,67,146,27*71

$GPGSV,3,2,09,21,15,188,,24,13,043,,25,55,119,,31,36,247,30*7F

$GPGSV,3,3,09,32,42,334,*43

$BDGSV,1,1,02,06,68,055,27,07,82,211,31*6A

$GNRMC,084852.000,A,2236.9453,N,11408.4790,E,0.53,292.44,141216,,,A*7

5

$GNVTG,292.44,T,,M,0.53,N,0.98,K,A*2D

$GNZDA,084852.000,14,12,2016,00,00*48

$GPTXT,01,01,01,ANTENNA OK*35

```


2、获取经纬度及北京时间:

(1)首先使用 uart.read() 函数从串口读取一行数据。


使用 string.match() 函数对读取到的数据进行正则匹配,以提取出 "$GNGGA" 行中的经纬度和时间信息。正则表达式为:

 `"%$GNGGA,(%d+%.%d+),(%d+%.%d+),(%a),(%d+%.%d+),(%a),"` 

 其中,括号中的内容表示正则表达式匹配到的结果需要提取出来,具体匹配结果如下:


第一个括号 (%d+%.%d+) 表示匹配一个或多个数字,可能包含小数点,表示UTC时间,例如:"084852.000"

第二个括号 (%d+%.%d+) 表示匹配一个或多个数字,可能包含小数点,表示纬度,例如:"2236.9453"

第三个括号 (%a) 表示匹配一个字母,表示纬度方向,可能为 "N" 或 "S"

第四个括号 (%d+%.%d+) 表示匹配一个或多个数字,可能包含小数点,表示经度,例如:"11408.4790"

第五个括号 (%a) 表示匹配一个字母,表示经度方向,可能为 "E" 或 "W"

(2)使用 tonumber() 函数将读取到的经纬度和时间信息从字符串类型转换为数字类型,并根据具体格式进行转换。例如,对于UTC时间信息,可以使用 string.sub() 函数获取小时、分钟、秒等信息,再进行格式化输出。


(3)将经纬度转换为Google Maps格式,即将度分格式转换为十进制格式,并根据方向调整正负值。


(4)使用 log.info() 函数输出解析后的结果,包括北京时间、纬度和经度等信息。


注:其中,string.match() 函数的正则表达式 "%$GNGGA,(%d+%.%d+),(%d+%.%d+),(%a),(%d+%.%d+),(%a)," 表示匹配以 "$GNGGA" 开头的行,并从中提取出符合规则的内容。具体解释如下:


(1)%d+%.%d+ 表示匹配一个或多个数字,可能包含小数点,例如 "084852.000" 和 "2236.9453"

(2)%a 表示匹配一个字母,例如 "N" 和 "E"

(3)() 表示将括号中的内容作为一个匹配组,需要在 string.match() 函数的返回值中获取。

解析出经纬度和时间后,通过数学运算和字符串格式化等操作,将其转换为可以直接使用的格式,并使用 log.info() 函数输出解析后的结果。


Luat Air780E/Air700E使用定位模块获取设备经纬度的评论 (共 条)

分享到微博请遵守国家法律