Post your best Lua script examples here

User avatar
By Lawrence_jeff
#7657 This is great stuff - I am an absolute beginner with both LUA and MQTT, using an ESP-01 I came up with a pretty simple example that uses the ESP-01 as both an input device (button) and an output device (LED). You can have it send a MQTT message on button press as well as receive commands to control the LED. I thought the example might help other beginners. If there are better ways to do this please reply.
(I do see issues with this code when ran for init.lua, it looks the subscribe command runs before the connection is fully setup so it doesn't actually subscribe. I tried adding some delays in both the connect callback function and before the subscribe but it doesn't seem to address it. Any ideas appreciated. (Copying the code manually or through ESPlorer works correctly (just make sure you get both a 'Connected" and a "Subscribe success" response))
Code: Select all--Setup using ESP-01 and the NodeMCU version with MQTT Support
--GPIO2 - connected to 300 Ohm restistor -> LED -> Ground
--GPIO0 - Connected to Normally open button with other button leg connected to ground
-- Setup Mqtt-Spy with a subscription to /topicOut and to send to /topicIn
-- Chnage the IP and Port to your broker (I use mosquitto)
-- If you push the button you should see Pin0Down in mqttspy
-- If you send ON in mqttspy the LED should light, send off it should go OFF
--SetupMQTT
mqtt = net.createConnection(net.TCP, 0)
mqtt:mqtt("ESP8266-2", 30, "user", "password")
-- on connection event (all event inherit from net module)
mqtt:on("connection", function(con) print("connected") end)
mqtt:connect(8443,"192.168.0.32")
--Setup MQTT Sending
--Pin 3 is GPIO 0 on the ESP-01 - Connected to Normally open button connected to ground
gpio.mode(3,gpio.INPUT,gpio.PULLUP)
gpio.trig(3, "down",function (level)
     mqtt:send("/topicOut","Pin0Down",0,0)
     print("Sent MQTT Message to /topicOut")   
end)
--Setup MQTT Recieve
--Pin 4 is GPIO2 on the ESP-01 - connected to 300 Ohm restistor -LED -Ground
gpio.mode(4,gpio.OUTPUT)
gpio.write(4,gpio.LOW)
-- on publish message receive event
mqtt:on("receive", function(conn, topic, data)
      print("Recieved:" .. topic .. ":" .. data)
      if (data=="ON") then
          print("Enabling LED")
          gpio.write(4,gpio.HIGH)
     elseif (data=="OFF") then
          print("Disabling LED")
          gpio.write(4,gpio.LOW)
     else
          print("Invalid - Ignoring")
     end
end)
mqtt:subscribe("/topicIn",0, function(conn) print("subscribe success:TopicIn") end)

User avatar
By gwizz
#7714 Zeroday has commented on this issue here: https://github.com/nodemcu/nodemcu-firmware/issues/37

"yes, tmr.delay stop the world."

Instead, there is a better way... :)

Toshik gave this contribution, I think it makes the way forward clear

"@nrbrt Why you do not use simple timer? It is best solution for such behavior.

Code: Select alltimerId = 0           -- can be 0-6
timerDelay = 5000     -- delay in ms = 5 seconds
tmr.alarm(timerId, timerDelay, 1, function()
-- your routine to run every 5 seconds goes here
end)

In your case - you are in endless loop and it does not allows MCU to actually send data, because it always busy to handle your loop."

So thanks to Toshik for making this clear - for us setting up and needing to pause between each step, we can start a series of one-off alarms, each one set to 500ms after each other. A couple of the calls just register stuff, they don't seem to take time. So:
Code: Select allmqtt = net.createConnection(net.TCP, 0)
-- on connection event (all event inherit from net module)
mqtt:on("connection", function(con) print("connected") end)

tmr.alarm(0, 500, 0, function()
   mqtt:mqtt("ESP8266-2", 30, "user", "password")
end)

tmr.alarm(0, 1000, 0, function()
mqtt:connect(8443,"192.168.0.32")
end)

and so on..

Hope that helps

G