1. 小节目标

在本小节中,实现 MQTT 的双向传输,即:

  1. 将从 MQTT 接收到的数据通过串口打印
  2. 将串口接收到的数据发送到 MQTT

2. 思路解析

从之前的学习中,我们已经知道了 ESPlorer 烧录代码是通过串口发送到 ESP8266 上的,当然了,此处肯定是使用了特定格式的代码,如

esp8266串口接收数据 中断 esp8266串口数量_esp8266串口接收数据 中断

  • 通过 file.witeline 往文件中写入行

但是我们又得实现通过接收串口的数据发送到 MQTT 上,那么我们需要自定义的实现串口接收函数,如下:

uart.setup(0, 115200, 8, uart.PARITY_NONE, uart.STOPBITS_1)
uart.on("data","\n",function(data)
   m:publish(x_topic.."/m", data, 0, 0, function(client)
        print("sent")
      end)
end, 0)

但是我们又会面临一个问题,当我们自定义的实现了串口接收函数,烧录代码的功能就失效了。

所以我们需要使用特定的技巧来解决这个问题。

方法一:

我们需要将串口拦截函数存放到一个新的文件中,我们通过 lua 指令,dofile("filename");的方式来执行,这样就只有我们通过串口发送该字符串的时候,才会开始拦截串口的数据,否则就还是烧录代码的操作,通过此方法可以有效的解决此问题。

方法二:

当然我们也可以将连接 WIFI、MQTT、自定义串口接收所有的功能放到一个文件中,命名为 mqtt.lua,然后在 init.lua 中只打印系统运行的操作,我们通过发送

dofile(mqtt.lua)

让 ESP8266 执行mqtt.lua文件,操作 ESP8266 连接 WIFI、MQTT服务器,这样在重启之后也能正常的进行代码烧录。

方法三:

改写串口接收方法,在接收到+++数据的时候复位,就会自动进入 init.lua 文件,接下来就再调用 dofile(mqtt.lua); 来启动 MQTT 连接

uart.setup(0, 115200, 8, uart.PARITY_NONE, uart.STOPBITS_1)
uart.on("data","\n",function(data)
   if data=="+++" then
        node.restart()
   end
   m:publish(x_topic.."/m", data, 0, 0, function(client)
        print("sent")
      end)
end, 0)

3. 完整代码

3.1. mqtt.lua

station_cfg = {}
station_cfg.ssid = "xlu_2.4"
station_cfg.pwd  = "111222333+"
station_cfg.auto = false
station_cfg.save = false
x_id=666
mqtt_cfg = {}
mqtt_cfg.host      = "broker.emqx.io"
mqtt_cfg.port      = 1883
mqtt_cfg.clientid  = "alro_xxx".. x_id
mqtt_cfg.keepalive = 120
mqtt_cfg.username  = "AlvaRocha"
mqtt_cfg.password  = "aio_KO<safety edit>sXwbgtWCboCal"
-- 
x_topic="/topic/ctiot/".. x_id
m=nil

mqtt_ready=false
wifi.setmode(wifi.STATION)
wifi.sta.config(station_cfg)

iot_test = mqtt.Client(mqtt_cfg.clientid, mqtt_cfg.keepalive, mqtt_cfg.username, mqtt_cfg.password)
iot_test:on("offline", function(client)
  print("client offline")
end)
iot_test:on("message", function(client, topic, data)
  if data ~= nil then
    print(data)
  end
end)

function get_broker(mqtt_client)
  mqtt_client:connect(mqtt_cfg.host, mqtt_cfg.port, false,
    function(client)
      client:subscribe(x_topic.."/c", 0, function(client)
        print("subscribe success "..x_topic.."/c")
        mqtt_ready=true
      end)
         m:publish(x_topic.."/m", "success", 0, 0, function(client)
        print("init success")
      end)
    end,
    function(client, reason)
      print('connection failed', reason)
    end)
    m=mqtt_client
end


function startup()
  if file.open("init.lua") == nil then
    print("init.lua deleted or renamed")
  else
    print("Running")
    file.close("init.lua")
    get_broker(iot_test)
  end
end

wifi_connect_event = function(T)
  print("Connection to AP(" .. T.SSID .. ") established!")
  print("Waiting for IP address...")
  if disconnect_ct ~= nil then
    disconnect_ct = nil
  end
end

wifi_got_ip_event = function(T)
  print("Wifi connection is ready! IP address is: " .. T.IP)
  print("Startup will resume momentarily, you have 3 seconds to abort.")
  print("Waiting...")
  tmr.create():alarm(3000, tmr.ALARM_SINGLE, startup)
end

wifi.eventmon.register(wifi.eventmon.STA_CONNECTED, wifi_connect_event)
wifi.eventmon.register(wifi.eventmon.STA_GOT_IP, wifi_got_ip_event)
wifi.sta.connect()

uart.setup(0, 115200, 8, uart.PARITY_NONE, uart.STOPBITS_1)
uart.on("data","\n",function(data)
   if data=="+++\r\n" then
        node.restart()
   end
   if mqtt_ready then
       m:publish(x_topic.."/m", data, 0, 0, function(client)
            print("sent")
          end)
  end
end, 0)

3.2. init.lua

print("ctiot esp8266 start!")

3.3. 烧录代码

忽略该步骤,太简单不用再讲了

3.4. 操作步骤

烧录完代码后,可以看到以下现象

esp8266串口接收数据 中断 esp8266串口数量_串口_02

在这个时候我们可以通过发送

dofile("mqtt.lua");

来运行 mqtt 的连接

发送开始 mqtt.lua 的演示

esp8266串口接收数据 中断 esp8266串口数量_串口_03

发送完成后就可以进行双向的 MQTT 发送了

3.5. MQTT 双向通信演示

MQTTX 发送到 ESP8266,也就是 ESP8266 接收消息

esp8266串口接收数据 中断 esp8266串口数量_junit_04

ESP8266 将串口上的消息发送到 MQTTX上,也就是 ESP8266 接收消息上报

  1. 先订阅主题

esp8266串口接收数据 中断 esp8266串口数量_junit_05

  1. 在 ESP8266 上发送

esp8266串口接收数据 中断 esp8266串口数量_esp8266串口接收数据 中断_06

3.6. 在 XCOM 串口调试组手上测试

esp8266串口接收数据 中断 esp8266串口数量_串口_07

ESP8266 复位之后,发送打开 mqtt.lua 的指令就可以了,非常的简单,各位可以尝试!!!

4. 结语