开发需求
具备有4G插卡控制功能(4G)
具备有位置定位功能(4G)
网口
wifi
具备有短信功能(4G)
支持MQTT功能
支持变化上传
支持MODBUS转JSON格式
可以远程升级
M D 区域 分别有保持和不保持
主站读取2路485的modbus存放到M D 区域
跟从站一个意思
--[[
w d 区块 为保持寄存器 50000 以内 16位 无符号 大端
]]
从站就是被 2路485和网口 读写 M D 区域
X区域 Y区域,8进8出,映射MODBUS地址
具备网页更改,2路485的参数,设置参数功能,远程配置,变化上报配置,定时上报配置,触发上报配置 网口参数 控制输入输出的功能,2路485,指定1个自动上报范围
原理图核心板线路图 画板
编码转换
Unicode与中文互转|16进制Unicode编码在线转换|反斜杠u(\u)编码|Java转义字符还原-站长工具 (msxindl.com)
ASCII码 - 基本ASCII码和扩展ASCII码,最全的ASCII码对照表 (asciim.cn)
s配置区
-- 所有区块长度65535
-- w d 区块 为保持寄存器 50000 以内 16位 无符号 大端 (50000 在main.lua 设置)
--[[
使用 modbus
03功能码读
06 10 功能码 写
]]
--以\000结束
--[[
配置区块地址 50000 - 65535
下面的地址都需要 + 50000
]]
--wifi 账号 长度32 + 0 共33个 字符串类型
wifi_ssid 0-32
--wifi密码 长度64 字符串类型
CWJAP_p 33-97
--ap 账号 长度32 + 0 共33个 字符串类型
wifi_ssid 800-832
--ap密码 长度64 字符串类型
CWJAP_p 833-897
--以太网
--静态ip 15 + 0 共16个 字符串类型
eth_ip 900 - 915
--子网掩码 15 + 0 共16个 字符串类型
eth_netmask 916 - 931
--网关 15 + 0 共16个 字符串类型
eth_gw 932 - 947
--mqtt id 长度 23 + 0 共24个 字符串类型
umqttclientId 98-122
--mqtt用户名 64 字符串类型
umqttu = 123- 187
--mqtt密码 64 字符串类型
umqttpassword = 188 - 252
--mqtt地址 128 字符串类型
umqttaddress = 253 - 381
--端口 4字节整数 382 383 384 385 整数不用 + 0
umqttport 382 - 385
-- 订阅主题 99 + 0 共100 字符串类型
umqttsub 501 - 600
-- 发布主题 99 + 0 共100 字符串类型
umqttpub 601 - 700
--变化上报
--开始地址
vr_start_address 750 - 753
--结束地址 整数 4个字节
vr_end_address 754 - 757
--定时上报
--开始地址
sr_start_address 1050 - 1053
--结束地址 整数 4个字节
sr_end_address 1054 - 1057
--上报周期间隔 4个字节 最大值 2147483647 单位秒
sr_report_time 1058 - 1061
--触发上报
--开始地址
tr_start_address 1350 - 1353
--结束地址 整数 4个字节
tr_end_address 1354 - 1357
--自动上报
--开始地址
ar_start_address 1650 - 1653
--结束地址 整数 4个字节
ar_end_address 1654 - 1657
--串口1配置
--配置
--站: 0主 1从
STA1 394 - 397
--波特率
BAUD1 398-401
--数据位
DATABITS1 402-405
--校验位 1=uart.PAR_EVEN 2=uart.PAR_ODD 3=uart.PAR_NONE
PARITY1 406-409
--停止位 1=uart.STOP_1 2=uart.STOP_2
STOPBITS1 410-413
--485地址 从站地址1-247
RS485ADDRESS1 414-417
--串口3配置
--配置
--站: 0主 1从
STA1 418 - 421
--波特率
BAUD1 422 - 425
--数据位
DATABITS1 426 - 429
--校验位 1=uart.PAR_EVEN 2=uart.PAR_ODD 3=uart.PAR_NONE
PARITY1 430 - 433
--停止位 1=uart.STOP_1 2=uart.STOP_2
STOPBITS1 434 - 437
--485地址 从站地址1-247
RS485ADDRESS1 438- 441
--地址1-n 线圈 有读写功能 没有保存功能 直接填对应的io
WRCOIL = {pio.P0_0,pio.P0_2,pio.P0_3,pio.P0_9,pio.P0_10,pio.P0_11,pio.P0_12,pio.P0_13}
--地址1-n 离散输入 只能读 没有保存功能 直接填对应的io
-- 8输入
INPUTCOIL1 = {pio.P0_16, pio.P0_17, pio.P0_19,pio.P0_22,pio.P0_23,pio.P0_24,pio.P0_25,pio.P0_26}
modbus 测试
测试配置
测试程序
设置波特率
网页配置
统一提交方式
提交方式 post
数据交互 json
为识别返回 {state: -1, mgs: '未能识别设置'}
注意 设备重启后之前连接到设备热点的客户端会被断开热点 如果没有显示被断开也得过一段时间才会自动连接 没有连接成功之前打不开192.198.4.1
设置wifi 读取wifi
设置完成后 重启设备生效
//设置wifi
/*
提交数据
*/
{tab: "wifi", wifi_ssid: "9999", wifi_password: "88888"}
/*
返回数据
*/
{state: 1, tab: 'wifi', mgs: '成功'}
//读取wifi
/*
提交 wifi_ssid为空字符串时 为读取
*/
{tab: "wifi", wifi_ssid: "", wifi_password: ""}
/*
返回
*/
{state: 1, wifi_ssid: '9999', mgs: '成功', tab: 'wifi', wifi_password: '88888'}
设置ap 读ap
设置完成后 重启设备生效
设备默认 ap:12345678 密码:12345678
//设置
{tab: 'ap', ap_ssid: '66666666', ap_password: '66666666'}
//返回
{state: 1, tab: 'ap', mgs: '成功'}
//读
{tab: 'ap', ap_ssid: '', ap_password: ''}
//返回
{state: 1, wifi_ssid: '66666666', mgs: '成功', tab: 'ap', wifi_password: '66666666'}
设置以太网 读以太网
设置完成后 重启设备生效
默认由路由器分配ip
//设置
{
"tab": "eth",
"eth_ip": "192.168.1.11",
"eth_netmask": "255.255.255.0",
"eth_gw": "192.168.1.1"
}
//返回
{
"state": 1,
"tab": "eth",
"mgs": "成功"
}
//读
{tab: 'eth', eth_ip: '', eth_netmask: '', eth_gw: ''}
//返回
{
"tab": "eth",
"eth_netmask": "255.255.255.0",
"mgs": "成功",
"eth_gw": "192.168.1.1",
"state": 1,
"eth_ip": "192.168.1.10"
}
485_1
默认 站=从站 波特率=115200 数据位=8 校验位=NONE 停止位=1 485地址=1
//站: 0主 1从
//波特率大于等于300
//数据位 只能8位
//奇偶校验 0 =uart.PAR_EVEN 1=uart.PAR_ODD 2=uart.PAR_NONE
//485地址 1-247
//停止位 1 = STOP_1 2 = STOP_2
//设置
{
"tab": "4851",
"sta": "1",
"baud": "115200",
"databits": "8",
"parity": "",
"stopbits": "",
"rs485address": ""
}
/*
必填参数
sta 站
baud 波特率
*/
//返回
{
"state": 1,
"tab": "4851",
"mgs": "成功"
}
//读取
{
"tab": "4851",
"sta": "",
"baud": "",
"databits": "",
"parity": "",
"stopbits": "",
"rs485address": ""
}
//返回
{
"parity": "3",
"baud": "115200",
"mgs": "成功",
"stopbits": "1",
"state": 1,
"sta": "1",
"databits": "8",
"rs485address": "1",
"tab": "4851"
}
485_2
默认 站=从站 波特率=115200 数据位=8 校验位=NONE 停止位=1 485地址=1
//站: 0主 1从
//波特率大于等于300
//数据位 只能8位
//奇偶校验 0 =uart.PAR_EVEN 1=uart.PAR_ODD 2=uart.PAR_NONE
//485地址 1-247
//停止位 1 = STOP_1 2 = STOP_2
//设置
{
"tab": "4852",
"sta": "1",
"baud": "115200",
"databits": "8",
"parity": "2",
"stopbits": "1",
"rs485address": "1"
}
/*
必填参数
sta 站
baud 波特率
*/
//返回
{
"state": 1,
"tab": "4852",
"mgs": "成功"
}
//读取
{
"tab": "4852",
"sta": "",
"baud": "",
"databits": "",
"parity": "",
"stopbits": "",
"rs485address": ""
}
//返回
{
"parity": "3",
"baud": "115200",
"mgs": "成功",
"stopbits": "1",
"state": 1,
"sta": "1",
"databits": "8",
"rs485address": "1",
"tab": "4852"
}
变化上报
地址范围 0 - 50000
//设置
{
"tab": "vr",
"vr_start_address": "0",
"vr_end_address": "1000"
}
//返回
{
"state": 1,
"tab": "vr",
"mgs": "成功"
}
//读
{
"tab": "vr",
"vr_start_address": "",
"vr_end_address": ""
}
//返回
{
"tab": "vr",
"vr_start_address": "0",
"mgs": "成功",
"state": 1,
"vr_end_address": "1000"
}
定时上报
地址范围 0 - 50000
//设置
{
"tab": "sr",
"sr_start_address": "5",
"sr_end_address": "555",
"sr_report_time": "2147483647"
}
//返回
{
"state": 1,
"tab": "sr",
"mgs": "成功"
}
//读
{
"tab": "sr",
"sr_start_address": "",
"sr_end_address": "",
"sr_report_time": ""
}
//返回
{
"tab": "sr",
"sr_end_address": "555",
"mgs": "成功",
"sr_report_time": "2147483647",
"sr_start_address": "5",
"state": 1
}
触发上报
地址范围 0 - 50000
//设置
{
"tab": "tr",
"tr_start_address": "1",
"tr_end_address": "123"
}
//返回
{
"state": 1,
"tab": "tr",
"mgs": "成功"
}
//读
{
"tab": "tr",
"tr_start_address": "",
"tr_end_address": ""
}
//返回
{
"tab": "tr",
"tr_start_address": "1",
"mgs": "成功",
"tr_end_address": "123",
"state": 1
}
自动上报
地址范围 0 - 50000
//设置
{
"tab": "ar",
"ar_start_address": "3",
"ar_end_address": "456"
}
//返回
{
"state": 1,
"tab": "ar",
"mgs": "成功"
}
//读
{
"tab": "ar",
"ar_start_address": "",
"ar_end_address": ""
}
//返回
{
"tab": "ar",
"ar_end_address": "456",
"mgs": "成功",
"state": 1,
"ar_start_address": "3"
}
设置io输出
//设置io
{
"tab": "but",
"but": "1",
"text": "ON"
}
//成功返回
{
"tab": "but",
"mgs": "成功",
"text": "OFF",
"state": 1,
"but": "1"
}
//失败返回
{
"state": -1,
"but": "8",
"tab": "but",
"mgs": "but 无效"
}
//读io
读外部输入io
/*
这个接口比较特殊 可能需要高频率访问 所以数据是保存在esp32的
提交地址
http://192.168.4.1/getpin
提交数据
{}
提交方式
post
*/
//返回
{"state":1,"STATE":[1,1,1,1],"tab":"getpin","mgs":""}
网页获取配置
提交方式
post
地址
http://192.168.4.1/get
提交内容
{tab: 'wifi'}
{tab: 'ap'}
{tab: 'ethernet'}
{tab: 'mqtt'}
{tab: '485_1'}
{tab: '485_2'}
{tab: 'variable-report'}
{tab: 'scheduled-report'}
{tab: 'input-output'}
{tab: 'get'}
设置mqtt 读mqtt
设置完成后 重启设备生效
连接失败后会一直尝试连接
--设置
{
"tab": "mqtt",
"mqtt_client_id": "",
"mqtt_username": "456",
"mqtt_password": "789",
"mqtt_address": "lbsmqtt.airm2m.com",
"mqtt_port": "1884",
"mqtt_sub": "qqqq",
"mqtt_pub": "qqqq"
}
/*
mqtt_client_id 为空时 代码自动生成模块 imei 为id
设置时必填参数
mqtt_address
mqtt_port
mqtt_sub
mqtt_pub
*/
//返回
{
"state": 1,
"tab": "mqtt",
"mgs": "成功"
}
//读
{
"tab": "mqtt",
"mqtt_client_id": "",
"mqtt_username": "",
"mqtt_password": "",
"mqtt_address": "",
"mqtt_port": "",
"mqtt_sub": "",
"mqtt_pub": ""
}
//返回
{
"tab": "mqtt",
"mqtt_username": "456",
"mgs": "成功",
"state": 1,
"mqtt_address": "lbsmqtt.airm2m.com",
"mqtt_pub": "qqqq",
"mqtt_sub": "qqqq",
"mqtt_port": "1884",
"mqtt_client_id": "868739057056859",
"mqtt_password": "789"
}
lua读写配置示例
--写串口1配置
local STA1,BAUD1,DATABITS1,PARITY1,STOPBITS1,RS485ADDRESS1 = 1,115200,8,3,1,1--赋值
set_uart1_config(STA1,BAUD1,DATABITS1,PARITY1,STOPBITS1,RS485ADDRESS1)--写
STA1,BAUD1,DATABITS1,PARITY1,STOPBITS1,RS485ADDRESS1 = get_uart1_config()--读
log.warn("u_mxfs.lua读串口1配置",STA1,BAUD1,DATABITS1,PARITY1,STOPBITS1,RS485ADDRESS1)--打印
--写wifi配置
local ssid,p="ssid123546567989555","ghfghfgh5465gf465h4fg65h"
set_wifi_config(ssid,p)--写
ssid,p=get_wifi_config()--读
if ssid ~="" then--判断
log.warn("u_mxfs.luawifi 正常")--打印
else
log.warn("u_mxfs.luawifi 不正常")--打印
end
local umqttclientId,umqttu,umqttpassword,umqttaddress,umqttport,umqttsub,umqttpub = "0123","0123","0123","lbsmqtt.airm2m.com",1884,"emq","emq"
set_mqtt_config(umqttclientId,umqttu,umqttpassword,umqttaddress,umqttport,umqttsub,umqttpub)--写
umqttclientId,umqttu,umqttpassword,umqttaddress,umqttport,umqttsub,umqttpub = get_mqtt_config()--读
log.fatal("mqtt配置",umqttclientId,umqttu,umqttpassword,umqttaddress,umqttport,umqttsub,umqttpub)
mqtt连接
u_mqtt.lua
while UMQTTADDRESS == ""
or UMQTTPORT < 0
or UMQTTSUB == ""
or UMQTTPUB == "" do
sys.wait(5000)
log.fatal("u_mqtt.luamqtt没配置")
UMQTTCLIENTID,UMQTTU,UMQTTPASSWORD,UMQTTADDRESS,UMQTTPORT,UMQTTSUB,UMQTTPUB = u_mxfs.get_mqtt_config()--读
log.fatal("u_mqtt.lua*mqtt配置:",UMQTTCLIENTID,UMQTTU,UMQTTPASSWORD,UMQTTADDRESS,UMQTTPORT,UMQTTSUB,UMQTTPUB)
end
UMQTTADDRESS == "" or UMQTTPORT < 0 or UMQTTSUB == ""or UMQTTPUB == ""
-- 这几个值有效时就会进行mqtt连接
mqtt指令
mqtt接收和发送topic可以通过网页设置
返回说明
//json解析 错误返回
{
CODE = "-1",
MGS = "json error",
}
//未知指令
{
CODE = "-2",
MGS = "CMD error",
}
写寄存器
{
CMD:"M10",
INDEX:11,
BYTESTR:"abc123456"
}
/*
CMD:命令
INDEX:开始写的位置
BYTESTR:数据
*/
读寄存器
示例1
读数据并删除0以及0后面的数据
发送数据解释
{
"CMD":"M03",//命令标识
"INDEX":50253,//0-50000为 D M区 设置区s +50000 253为 mqtt地址
"DELETE0":"y",//删除 '\0' 及后面的数据
"LEN":128//读128个字节
}
发送数据示例
{
"CMD":"M03",
"INDEX":50253,
"DELETE0":"y",
"LEN":128
}
返回
{
"RETURN":"M03",//命令标识
"MGS":"lbsmqtt.airm2m.com",//读回的数据
"CODE":"0"//0位正常
}
示例2
发送数据解释
{
"CMD":"M03",
"INDEX":50382,//0-50000为 D M区 设置区s +50000 253为 mqtt地址
"LEN":4//读4个字节
}
发送数据示例
{
"CMD":"M03",
"INDEX":50382,
"LEN":4
}
返回
{
"RETURN":"M03",//命令标识
"MGS":"\\\u0007\u0000\u0000",//16进制为 5C 07 00 00 转字符串5c=92=\ 07=\u0007 00=\u0000 00=\u0000 合起来转整数=1884
"CODE":"0"//正常
}
变化上报
/*
1设置变化上报 范围
2通过mqtt或者串口修改md寄存器
*/
//示例
//使用mqtt发送
{
"CMD":"M10",//写寄存器指令
"INDEX":11,//开始写地址
"BYTESTR":"abc123456"//写数据
}
//返回 VR代表变化上报
{"INDEX":11,"RETURN":"VR","MGS":"abc123456"}
定时上报
/*
1设置变化上报 范围 和 上报周期
2通过mqtt或者串口修改md寄存器
*/
//示例
//使用mqtt发送指令写内容到寄存器
{
"CMD":"M10",//写寄存器指令
"INDEX":1,//开始写地址
"BYTESTR":"abc12345622"//写数据
}
//返回 SR代表变化上报
{"INDEX":1,"RETURN":"SR","MGS":"abc12345622"}
//没内容时返回
{"INDEX":1,"RETURN":"SR","MGS":"\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000"}
触发上报
跟变化上报一样
自动上报
跟定时上报一样
GPS
GPS 指令文档
20220418181112278_Air530定位模块使用手册V2.1.pdf (openluat.com)
//mqtt透传指令到 GPS
{
"CMD":"GPS",
"MGS":"$PGKC242,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0*"
}
//返回
{"RETURN":"GPS","MGS":"OK","CODE":"0"}
//读GPS
{
"CMD":"GPS",
"MGS":""
}
//返回
{"RETURN":"GPS","MGS":",1,00,1*75\r\n$GNRMC,015356.069,V,,,,,0.00,,060180,,,N,V*33\r\n$GNVTG,,,,,,,,,N*2E\r\n$GNGGA,015357.069,,,,,0,00,,,,,,,*6C\r\n$GNGLL,,,,,,V,N*7A\r\n$GNGSA,A,1,,,,,,,,,,,,,,,,1*1D\r\n$GNGSA,A,1,,,,,,,,,,,,,,,,4*18\r\n$GPGSV,1,1,00,1*64\r\n$BDGSV,1,1,00,1*75\r\n$GNRMC,01535\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","CODE":"0"}
设置io输出
//CMD 命令
//STATE 每个io的状态 0低电平 1高电平 2其他则不设置
{
"CMD": "SETPIN",
"STATE": [1,1,2,2,1,0,1]
}
//成功返回
{"STATE":[1,1,0,0,1,0],"RETURN":"SETPIN","MGS":"","CODE":"0"}
//失败返回
{"STATE":{},"RETURN":"SETPIN","MGS":"没有那么多io","CODE":-1}
读io输入
//读外部输入的值
{
"CMD": "GETPIN"
}
//返回 外部输入变化也会触发上报
{"STATE":[1,1,1,1],"RETURN":"GETPIN","MGS":"","CODE":"0"}
短信
接收短信后会将短信发送到mqtt
{
CODE = "0",
RETURN = "SMS",
NUM = num,--手机号码
DSATA = data,--短信内容
DATETIME = datetime,--时间
}
发送短信
{
"CMD": "SENDSMS",--命令
"NUM":"1521000000",--手机号码
"STR":"XXXXX"--短信内容
}
升级724固件
升级需要用到的固件
升级需要差分工具
https://doc.openluat.com/chafen
Luatools v2工具
https://luatos.com/luatools/download/last
具体升级流程
上面三个东西都下载
打开 Luatools
代码生成固件 (生产固件 升级固件)
下载固件到724
用 底层固件+升级固件 生成 差分固件
差分固件上传到服务器
724上电 串口2连接电脑 等待724连接到网络
通过724串口2波特率115200发送升级命令升级
以上8个步骤缺一不可
下面介绍具体操作
打开
https://doc.openluat.com/chafen
升级指令
{"CMD":"UP","URL":"142536.vip/esp32/ota/11111.bin"}
成功返回
{
CODE = "0",
RETURN = "UP",
MGS = "升级成功",
}
失败返回
{
CODE = "-1",
RETURN = "UP",
MGS = "升级失败",
}
各种疑难杂症 可以看看下面官网的文档
官方升级教程
特殊问题可参考官方文档