跳转至

TCP远程控制灯的亮和灭

介绍

用电脑浏览器通过Air780E控制灯的亮和灭

编写脚本

Air780E开发板购买链接

Air780E开发板设计资料

通过UDP连接Air780E控制灯的亮灭程序源码demo

合宙的TCP/UDP测试服务器

API接口说明

1、实现流程图

这个demo看似程序不少,实际上打印日志和判断返回值的内容有很多,主要函数并不多,接下来我将带你过一遍程序。

这个流程图只画了我们需要用到的流程,demo里还有一些功能是我们现在用不到的,先不看。

socket连接服务器后,Air780E等待服务器下发的数据,如果下发ledon指令则控制灯亮,如果下发ledoff指令则控制灯灭。

5a725229-fbc0-495c-84df-7809a774de29

2、程序详解

第一步:等待联网

sys.waitUntil("IP_READY")

第二步:联网成功后,创建socket

-- 申请一个socket_ctrl
--[[
    @param1 适配的网卡,nil为采用默认网卡
    @param2 消息通知的taskName,此处先随意填一个即可
]]
local netc = socket.create(nil,"MySocket")

第三步:配置network信息

--[[配置network一些信息
        @param1 socket_ctrl
        @param2 本地端口号,不写会自动分配一个
        @parma3 是否是UDP
        @param4 是否是加密传输
    ]]
    socket.config(netc, nil, is_udp, false)

第四步:连接服务器。

--[[
     @param1 socket_ctrl
     @param2 ip地址
     @parma3 端口号
]]
local result = socket.connect(netc, host, port)

第五步:连接服务器成功后,先新建一个数组,然后接收服务器的数据

-- 创建一个用于接收UDP服务器下发数据的数组
local rx_buff = zbuff.create(1024)
--[[
     @param1 socket_ctrl
     @param2 用于接收数据的数组
]]
local succ, rx_len = socket.rx(netc, rx_buff)

第六步:判断接收的数据是否为空,如果不为空就public一个消息。

--[[对接收到的数据进行处理
                rx_buff:used()代表rx_buff内的数据长度
            ]]
            if rx_buff:used() > 0 then
                --rx_buff:query():取出数组内的数据
                local rx_data = rx_buff:query()
                log.info("socket", "接收到的数据为:", rx_data)
                --[[发布一个消息sc_txrx,并连同数据rx_data一同发送。
                    接收方为第八步的sys.waitUntil("sc_txrx", 30000)
                ]]
                sys.publish("sc_txrx", rx_data)
                rx_buff:del()
            end

第七步:我们建一个task任务。

sys.taskInit(function()
    -- 你要执行的函数
end)

第八步:我们在task中写一个while循环,等待sys.publish("sc_txrx", rx_data)的消息,当接收到消息 或等待时间超过设定的30000ms 后继续执行。

--[[
     @param1 等待的消息
     @param2 超时时间
     return result 等待到消息,result为true,否则为false
     return rx_data  等待的数据中,携带的参数
]]
local result, rx_data = sys.waitUntil("sc_txrx", 30000)

第九步:如果我们等待到了消息,则开始判断收到的参数是否为ledon或ledoff,如果为ledon则执行gpio.set(27,1),将27号引脚置高电平,开灯;如果为ledoff则执行gpio.set(27, 0),将27号引脚置低电平,关灯。

if result then
            log.info("sys.waitUntil接收到数据")
            --[[在接收的数据rx_data中,寻找ledon出现的位置,如果找到
                会返回第一次出现的位置和最后出现的位置。
            ]]
            local s, e = string.find(rx_data, "ledon")
            if s == 1 and e == 5 then
                gpio.set(27, 1)
                log.info("开灯")
            end
            local s2, e2 = string.find(rx_data, "ledoff")
            if s2 == 1 and e2 == 6 then
                gpio.set(27, 0)
                log.info("关灯")
            end
else

第十步:如果我们sys.waitUntil()30秒后还没接收到数据,则会发布一个心跳的消息。

            log.info("发布keepalive,waitUntil的返回值为: ", result)
            -- 发送心跳
            sys.publish("keepalive")
        end

第十一步:我们可以在连接函数中添加这个消息的订阅,当收到这个消息的publish后就会向服务器发送一次心跳。

    -- 订阅心跳消息
    sys.subscribe("keepalive", function()
        succ, full, result = socket.tx(netc, "keepalive" .. os.date())
        log.info("socket", "心跳包发送数据的结果", succ, full, result)
    end)

验证功能

1、连接服务器

合宙的 TCP/UDP 测试服务器:wstool

打开web服务器,将ip地址和端口号复制后复制给程序的host和port

009e3136-f015-43b3-924a-de282af35266

5f300570-9137-4833-bf02-1b6d41ce2eb0

将上面的ip地址和端口号复制到程序的host和port位置:

3e9758c4-7209-4fc0-bc3c-67934b484dc3

2、效果展示

Air780E开发板的27号灯所在位置:

efd3ab38-ab2a-4917-8bbc-04a21ea1119f

效果展示:

我们需要在浏览器的消息发送框中,先选择字符模式,再输入ledon或ledoff,点击发送,来控制灯的亮灭。

s

a2da0609-86ab-410a-b931-736e0f919585

总结

本节我们实现了使用电脑浏览器,通过udp连接,实现灯的远程控制。

除此之外还学会了如何判断字符串。