跳到主要内容

4G透传Uart Mqtt版(C002D)

[TOC]

一、实现功能简介

基于 FlexLua 《DTU01万能采集器》实现 4G 通信和 Uart 串口通信之间的数据透传,4G接入服务器的方式为 Mqtt。

  • 在 4G 通信链路上,DTU01 和 远端服务器通信数据格式为 HEX 字节流
  • 在 Uart 串口通信链路上,DTU01 和 Uart 设备通信数据格式为 HEX 字节流

diag4

**上行通道举例:**例如当 Uart 设备向 DTU 发送 0x01 0x02 0x03,则 DTU 在收到数据后会封装成 {"Data":"010203"} 这样的 Json 字符串然后通过 4G 发送给远端的 MQTT 服务器。

**下行通道举例:**例如当远端的 MQTT 服务器向 DTU 发送 {"Data":"08090A"} 这样的 Json 字符串后,则 DTU 在收到数据后会解析成 0x08 0x09 0x0A 这样的 Hex 字节流然后发送给 Uart 设备。

二、DTU01 万能采集器介绍

《DTU01万能采集器》内部核心主控采用 ShineBlink C2M 低代码物联网核心模组,使用该主控核心模组不仅在上行端可轻松实现 4G / WiFi / 以太网 / Lora 通信,在下行端也可轻松对接 RS485总线 / Uart TTL串口 / AD电压采集 / Gpio开关量采集。本采集器硬件资料和源代码开放且源码极其精简,所以开发者无论是否有嵌入式单片机开发经验,皆可轻松基于源码进行二次开发(例如:新功能增加、边缘数据处理、逻辑判断、特殊协议解析等)。当然如果使用者对编程不感兴趣也可直接参考下面的技术指导文章即可实现大部分场景的需求。

DTU01

三、实现方法

(1)硬件

由于 DTU01 的硬件接口是可配置的,所以需要确认一下您手上的 DTU01 采集器是否满足要求,如果确认已满足就无需再做任何操作,否则请按《DTU01硬件使用指导书》完成下面的硬件配置:

  • DTU01 电路板上的 ‘A’ 和 ‘B’ 引脚需配置成 Uart 接口的 ‘Tx’ 和 ‘Rx’,即 S1 选择
  • DTU01 电路板正面插上 SB-C17 4G Cat1 通信模块
  • DTU01 电路板上的 ‘+’ 和 ‘-’ 电源输出引脚配置成 12v 输出用来接12v的传感器/仪表/设备(非必须)

《DTU01硬件使用指导书》可在 {FlexLua开源网盘}->{Hardware}->{DTU01万能采集器}->{DTU01硬件使用指导书} 文件夹中找到。

(2)软件

只需将本文章末尾提供的源码拷贝覆盖至设备上的 main.lua 文件中,并根据实际情况修改源码开头部分的配置信息,即可实现大部分场景的需求。

操作方法:首先用TypeC USB数据线将设备和电脑连接,然后在电脑上会自动出现一个1.6MB大小的U盘(如果U盘大小是0MB,则需用FAT32快速格式化该盘),找到 main.lua 代码文件(如果没有请自行创建一个 main.lua文件),然后将本文的源码拷贝覆盖至 main.lua 文件中然后Ctrl+S保存即可,代码更新后在下次重新上电后其会自行编译并运行。

四、本章相关开源资料汇总

(1)硬件开源资料

硬件开源网盘路径
《DTU01万能采集器硬件使用指导书》{FlexLua开源网盘}->{Hardware}->{DTU01万能采集器}->{DTU01硬件使用指导书} 文件夹
《DTU01万能采集器硬件原理图》{FlexLua开源网盘}->{Hardware}->{DTU02万能网关}->{DTU02硬件原理图} 文件夹

(2)其他(非必需)

如对源代码中的实现细节感兴趣,开发者可查阅 《Lua编程学习指导》、《ShineBlink 函数API手册》、《ShineBlink C2M模组资料》:

内容开源网盘路径
《Lua编程学习指导》{FlexLua开源网盘}->{Tutorial}->{Lua编程学习指导} 文件夹
《ShineBlink 函数API手册》{FlexLua开源网盘}->{Tutorial}->{ShineBlink 函数API手册} 文件夹
《ShineBlink C2M模组资料》{FlexLua开源网盘}->{Tutorial}->{ShineBlink C2M模组资料} 文件夹

五、软件源代码

----------------------配置信息开始----------------------
--Part1:4G MQTT 通信配置
ServerAddr = "xxx.com" --MQTT服务器ip地址或域名
ServerPort = 1883 --MQTT服务器端口号
ClientID = "xxxx" --根据实际情况自行配置
UserName = "xxxx" --根据实际情况自行配置
Password = "xxxx" --根据实际情况自行配置
mqtt_sub_topic = "xxx"--订阅用的主题,用于接收服务器下发的数据
mqtt_pub_topic = "xxx" --发布用的主题,用于向服务器发送数据

--Part2:心跳包配置
HeartBeatTimeMs = 300*1000 --心跳包间隔时间300秒,单位:毫秒,设置为0时心跳功能取消
HeartBeatContent = "{\"Data\":\"010203\"}" --心跳包发送内容

--Part3:Uart 通信配置
Rs485BaudRate = "BAUDRATE_9600"
--串口校验设置
Rs485ParitySet = "NoneParity" --"NoneParity","EvenParity","OddParity"
--串口停止位设置
Rs485StopBitSet = "StopBit_1" --"StopBit_1","StopBit_1_5","StopBit_2"
----------------------配置信息结束----------------------

--全局变量定义
HeartBeatTimeMsCnt = 0

--定义10毫秒定时器的回调函数,函数名字必须是LIB_10msTimerCallback
function LIB_10msTimerCallback()
timer_ms = timer_ms + 10
HeartBeatTimeMsCnt = HeartBeatTimeMsCnt + 10
LIB_GpioToggle("D11") --喂硬件看门狗
end

--RGB三色灯控制函数
function RGB(R,G,B)
LIB_GpioWrite("D0",R)
LIB_GpioWrite("D1",G)
LIB_GpioWrite("D3",B)
end

--配置D0,D1,D3为普通GPIO输出,控制LED_R,LED_G,LED_B
LIB_GpioOutputConfig("D0","STANDARD")
LIB_GpioOutputConfig("D1","STANDARD")
LIB_GpioOutputConfig("D3","STANDARD")
RGB(1,1,1) --一上电Led三色灯默认都不亮
--配置D11为普通输出,控制看门狗
LIB_GpioOutputConfig("D11","STANDARD")
--配置Uart1串口工作,D8自动控制收发电平
LIB_Uart1Rs485Config(Rs485BaudRate,"D8",Rs485ParitySet,Rs485StopBitSet)
--配置4G模块以MQTT模式工作,KeepAlive周期600秒
LIB_Cat1MqttEC800Config("UART0","D5","HIGH","D6","HIGH",ServerAddr,ServerPort,ClientID,UserName,Password,600,mqtt_sub_topic,"QOS0","NO_GPS")
--使能系统10毫秒定时器开始工作
timer_ms = 0
LIB_10msTimerConfig("ENABLE")

--开始大循环
while(GC(1) == true)
do
--查询是否收到485数据
flag,tab = LIB_Uart1Recv()
if flag == 1 then
--将收到的HEX字节流数据转换成Ascii形式装入Json字符串中上发给服务器
--例如:将收到的0x01 0x05 0xB3 转换成 {"Data":"0105B3"}
json_str = string.format("{\"Data\":\"%s\"}", LIB_HexTabToHexStr(tab))
LIB_Cat1MqttEC800SendPub("QOS0", mqtt_pub_topic, json_str)
HeartBeatTimeMsCnt = 0
end

--查询是否收到服务器下发的数据
flag,topic,msg = LIB_Cat1MqttEC800RecvSub()
if flag == 1 then
print(string.format("Get datas on topic %s: %s", topic, msg))
--查看服务器是否下发包含"Data"成员的Json字符串信息
--例如:{"Data":"01023B5f"},即0x01 0x02 0x3B 0x5F
json_hex_str = LIB_JsonParse(msg, "$.Data", "String")
if json_hex_str ~= nil then --例如"01023B5f"
--将收到的数据转换成Hex字节流table下发给485端口
LIB_Uart1BlockSend(LIB_HexStrToHexTab(json_hex_str))
end
end

--每隔0.5秒根据4G模状态更新LED灯颜色
if timer_ms >= 500 then
timer_ms = 0
State,IMSI,ICCID,CSQ = LIB_Cat1StatusQuery()
if State == "PowerOn" then --4G模块已上电但没发现sim卡
RGB(0,0,0) --白
elseif State == "SimOK" then --4G模块发现sim卡
RGB(0,1,1) --红
elseif State == "Attached" then --4G模块已连上附近的基站
RGB(1,1,0) --蓝
elseif State == "Connected" then --4G模块已和服务器连结
RGB(1,0,1) --绿
else --4G模块还未开始工作
RGB(1,1,1) --全灭
end
end

--如果心跳保活机制使能
if HeartBeatTimeMs > 0 then
--如果在规定时间内没向服务器发送过数据,就发一包心跳包数据
if HeartBeatTimeMsCnt >= HeartBeatTimeMs then
HeartBeatTimeMsCnt = 0
LIB_Cat1MqttEC800SendPub("QOS0", mqtt_pub_topic, HeartBeatContent)
end
end
end