跳到主要内容

4G远程继电器

注意:本例程使用的 4G 模块为 SB-C17(EC800 4G 模块),ML302 4G 模块由于停产这里并不推荐使用。

一、实现的功能描述

远端TCP Server通过发送一包Hex数据流指令来控制本地开发板上继电器的吸合。

本例程的通信是基于TCP方式,如果希望改成UDP、MQTT方式,或者更多详细细节,可以参考前面的

《4G通信(TCP/UDP/MQTT)》教程。

二、本实验教学目的

掌握基于ShineBlink的:

  • 4G TCP通信

  • GPIO控制继电器(继电器连接开发板上的D4引脚)

三、本实验涉及的模块

4G模块和继电器模块在开发板上的位置如下:

C2DevKit

四、完整源代码

源码(ML302,已停产)

UID = "001" ----也可以用芯片内部的唯一码,UID = LIB_GetSysUniID()
server_addr = "47.92.146.210" --这里也可以写服务器域名,比如"abc.com"等
server_port = 8888
--初始化4G TCP模式
LIB_Cat1TcpUdpConfig("UART0","D5","HIGH","D6","HIGH",server_addr,server_port,0,"TCP","NO_GPS")
--使能10毫秒定时器开始工作
LIB_10msTimerConfig("ENABLE")
timer0 = 0
timer1 = 0
--定义10毫秒定时器回调函数
function LIB_10msTimerCallback()
timer0 = timer0 + 10
timer1 = timer1 + 10
end
--配置绿色LED的GPIO为输出(D9),用来指示4G连接状态
LIB_GpioOutputConfig("D9","STANDARD")
--配置连接继电器的GPIO为输出(D4)
LIB_GpioOutputConfig("D4","STANDARD")
--开始大循环
while(GC(1) == true)
do
--每隔3秒向服务器上传一串json字符串,包含自身UID
if timer0 >= 3000 then
timer0 = 0
json_str = string.format("{\"id\":%s}", UID)
--TCP发送时需要将字符串转换成table数组才能发送
LIB_Cat1TcpUdpSend(LIB_StrToTab(json_str))
end
--查询是否收到远端tcp server下发的数据
recv_flag,data = LIB_Cat1TcpUdpRecv()
if recv_flag == 1 then
if data[1] == 0xAA and data[2] == 0xAA and data[3] == 0x01 then
--如果收到的数据包为AA AA 01就闭合继电器
LIB_GpioWrite("D4", 1)
elseif data[1] == 0xAA and data[2] == 0xAA and data[3] == 0x00 then
--如果收到的数据包为AA AA 00就断开继电器
LIB_GpioWrite("D4", 0)
end
end
--每隔一秒读取一次4G状态信息
if timer1 >= 1000 then
timer1 = 0
State,IMSI,ICCID,CSQ = LIB_Cat1StatusQuery()
if State == "Connected" then
LIB_GpioWrite("D9", 0) --4G模块已和服务器建立连接,绿灯亮
else
LIB_GpioWrite("D9", 1) --4G模块未和服务器建立连接,绿灯灭
end
end
end

源码(EC800,推荐)

UID = "001" ----也可以用芯片内部的唯一码,UID = LIB_GetSysUniID()
server_addr = "47.92.146.210" --这里也可以写服务器域名,比如"abc.com"等
server_port = 8888
--初始化4G TCP模式
LIB_Cat1TcpUdpEC800Config("UART0","D5","HIGH","D6","HIGH",server_addr,server_port,0,"TCP","NO_GPS")
--使能10毫秒定时器开始工作
LIB_10msTimerConfig("ENABLE")
timer0 = 0
timer1 = 0
--定义10毫秒定时器回调函数
function LIB_10msTimerCallback()
timer0 = timer0 + 10
timer1 = timer1 + 10
end
--配置绿色LED的GPIO为输出(D9),用来指示4G连接状态
LIB_GpioOutputConfig("D9","STANDARD")
--配置连接继电器的GPIO为输出(D4)
LIB_GpioOutputConfig("D4","STANDARD")
--开始大循环
while(GC(1) == true)
do
--每隔3秒向服务器上传一串json字符串,包含自身UID
if timer0 >= 3000 then
timer0 = 0
json_str = string.format("{\"id\":%s}", UID)
--TCP发送时需要将字符串转换成table数组才能发送
LIB_Cat1TcpUdpEC800Send(LIB_StrToTab(json_str))
end
--查询是否收到远端tcp server下发的数据
recv_flag,data = LIB_Cat1TcpUdpEC800Recv()
if recv_flag == 1 then
if data[1] == 0xAA and data[2] == 0xAA and data[3] == 0x01 then
--如果收到的数据包为AA AA 01就闭合继电器
LIB_GpioWrite("D4", 1)
elseif data[1] == 0xAA and data[2] == 0xAA and data[3] == 0x00 then
--如果收到的数据包为AA AA 00就断开继电器
LIB_GpioWrite("D4", 0)
end
end
--每隔一秒读取一次4G状态信息
if timer1 >= 1000 then
timer1 = 0
State,IMSI,ICCID,CSQ = LIB_Cat1StatusQuery()
if State == "Connected" then
LIB_GpioWrite("D9", 0) --4G模块已和服务器建立连接,绿灯亮
else
LIB_GpioWrite("D9", 1) --4G模块未和服务器建立连接,绿灯灭
end
end
end

**注意:**上面代码中每隔3秒中将开发板自身的设备 UID 发送给TCP服务器的用意是帮助服务器识别当前开发板的身份,因为在很多TCP/UDP通信场景中是无法通过IP地址来识别Client身份的。

  • UID可以通过LIB_GetSysUniID()函数获取到每个C2M模块的唯一UID用来帮助服务器识别硬件的身份,这样可以保证设备身份的唯一性:
--以下代码会给 UID 赋予一个9字节的唯一ID字符串,例如"0AB95E15E803F78402"
UID= LIB_GetSysUniID()
  • UID也可以由开发者自己定义,如果设备数量不多的话
UID = "001"

开发者可以通过在产品量产的过程中通过UART串口将UID批量打印出来贴在产品外壳上面,shineblink.com官网技术文档中有如何通过热敏打印机批量自动化打印每个设备唯一二维码标签的教程,感兴趣请查阅。

五、实验现象

注意:为了完成这个实验,开发者需要自己搭建一个远程TCP服务器来模拟数据下发操作,如果没有服务器的话尝试用花生壳试用版本通过内网穿透的方式在自己电脑上搭建一个具有独立域名的远程服务器,然后在本地电脑上运行《网络调试助手》工具来开启一个TCP服务器。

将代码复制到开发板的虚拟TF卡中开始运行后,接下来就可以通过TCP服务器向开发板下发Hex指令数据流。例如下发"AA AA 01"会让继电器闭合,下发"AA AA 00"会让继电器断开,