Vamos a hacer que este dispositivo pueda recibir mensajes a través de mqtt y encienda cualquier dispositivo que esté enchufado a él.
Objetivo: Recibir mensajes a través de MQTT con el ESP Relay Board de Electrodragon. Lo programaremos en lua. Este dispositivo tiene la ventaja de que se conecta directamente a la corriente. Viene a costar unos 6€ más costes de envío. En este proyecto el dispositivo estará escuchando en un servidor mqtt (test.mosquitto.org), en el topic my-home/<id-del dispositivo>. A este aparato se le pueden conectar dos enchufes. Si recibe ON1 el relé del primer enchufe dejará pasar corriente y encenderá lo que tengamos conectado. Si recibe OFF1 apagará lo que tenemos conectado al enchufe 1. Lo mismo será con el enchufe 2 (ON2,OFF2).
Necesitamos:
- Wifi IoT Relay Board: La versión que tenemos es la R1.0 : http://www.electrodragon.com/product/wifi-iot-relay-board-based-esp8266/
- Un convertidor USB a TTL que proporcione +5V de salida. (Buscar en google USB to TTL)
- Cables para conectar con el dispositivo. (Buscar en google female to female jumpers)
Para documentación sobre el dispositivo ver http://www.electrodragon.com/w/ESP_Relay_Board
Para documentación de comandos “Lua” usaremos: http://nodemcu.readthedocs.io/en/master/
El dispositivo en cuestión es este:
Viene encapsulado para protegerlo y para protegernos de “calambrazos”.
Crear el firmware
Podemos bajarnos el firmware que ya compilé en este enlace: firmware.
Este firmware ya contiene los módulos: cjson,file,gpio,mqtt,net,node,tmr,uart,wifi
Si queremos crear un firmware nuevo tenemos que ir a la página: http://nodemcu-build.com/
En ella rellenaremos los campos para que nos envíen el firmware creado por email. En unos minutos lo tenemos ya en nuestro buzón de correo. Nos generará 2 ficheros. uno es si solo queremos trabajar con números enteros en nuestro dispositivo y otro firmware de mayor tamaño para trabajar con números decimales.
Seleccionamos la rama master ya que la de desarrollo puede darnos problemas.
Seleccionamos los siguientes módulos: (Siempre depende de lo que quieras hacer con el dispositivo. Recuerda que la memoria es limitada):
A continuación le damos a start your build y nos encolará la petición.
Reemplazar el firmware
Ahora tenemos que meter el nuevo firmware dentro del dispositivo.
Para ello necesitamos un convertidor USB a TTL.
Realizamos las conexiones tal como se ve en la siguiente imagen.
Atención: También hay que conectar GND a GND y +5V a +5V para darle corriente.
Debemos tener python instalado en nuestro Linux.
sudo apt-get update; sudo apt-get install python
Nos bajamos un script de python que realiza el flasheo:
wget https://raw.githubusercontent.com/themadinventor/esptool/master/esptool.py
Lo hace,os ejecutable:
chmod +x ./esptool.py
Conectamos el dispositivo al ordenador mediante un cable microusb. Al hacerlo en linux se me creará un archivo de dispositivo nuevo en /dev/
En mi caso es /dev/ttyUSB0
Para que el dispositivo entre en modo de flasheo de firmware hay que alimentarlo con el botón 2 pulsado.
Pasos:
1º Conectar los cables del usb a TTL exceptuando el de +5V.
2º Mantener pulsado el botón 2 del dispositivo y al mismo tiempo conectar el cable de +5V.
3º Dejar de pulsar el botón 2 del dispositivo.
Lo flasheamos con el siguiente comando:
./esptool.py --port /dev/ttyUSB0 write_flash 0x00000 /home/mipc/nodemcu-master-9-modules-integer.bin
En mi caso he puesto la ruta y nombre del archivo a flashear completa en verde. Tú debes poner la tuya y el nombre del dispositivo.
Ejecutando ESPlorer
Para descargar ESPlorer lo haremos desde aquí: http://esp8266.ru/esplorer-latest/?f=ESPlorer.zip
Para ejecutar ESPlorer debemos tener instalado Java en nuestro equipo. En mi Linux Mint lo ejecuto así con el botón derecho:
Esta aplicación se puede ejecutar tanto en Linux como en Windows.
Para conectarnos con el dispositivo le damos al botón Open :
Si no conecta probamos con menor velocidad de transmisión:
A mi a veces me tarda en conectar. A veces lo hace a la primera y otras tengo que intentarlo más. Desconectando el dispositivo y volviendo a conectarlo suele funcionar.
A veces al conectar y desconectar el USB, mi linux le asigna otro nombre de dispositivo pasando a ser /dev/ttyUSB1. En Esplorer
El código
He creando una lengüeta por cada archivo que voy a introducir en el dispositivo.
Archivo config.lua
Aquí cambiaremos el nombre de mi router WiFi y la contraseña por la de nuestro router.
-- file: config.lua local module = {} module.SSID = {} module.SSID["WLAN-ROUTER"] = "supercontrasenadelamuerte" module.HOST = "test.mosquitto.org" module.PORT = 1883 module.ID = node.chipid() -- module.ID = "ValorQueDesees" en caso de no querer que se publique el id de tu chip. module.ENDPOINT = "my-home/" -- El topic donde publicará será my-home/id_del_chip -- Nº de GPIO que vamos a usar de entrada module.GPIO1 = 1 gpio.mode(6, gpio.OUTPUT) gpio.write(6, gpio.LOW) gpio.mode(7, gpio.OUTPUT) gpio.write(7, gpio.LOW) return module
Archivo setup.lua
-- file: setup.lua local module = {} local function wifi_wait_ip() if wifi.sta.getip()== nil then print("IP unavailable, Waiting...") else tmr.stop(1) print("\n====================================") print("ESP8266 mode is: " .. wifi.getmode()) print("MAC address is: " .. wifi.ap.getmac()) print("IP is "..wifi.sta.getip()) print("====================================") app.start() end end local function wifi_start(list_aps) if list_aps then for key,value in pairs(list_aps) do if config.SSID and config.SSID[key] then wifi.setmode(wifi.STATION); wifi.sta.config(key,config.SSID[key]) wifi.sta.connect() print("Connecting to " .. key .. " ...") --config.SSID = nil -- can save memory tmr.alarm(1, 2500, 1, wifi_wait_ip) end end else print("Error getting AP list") end end function module.start() print("Configuring Wifi ...") wifi.setmode(wifi.STATION); wifi.sta.getap(wifi_start) end return module
Archivo application.lua :
-- file : application.lua
local module = {}
m = nil
-- Sends a simple ping to the broker
local function send_ping()
m:publish(config.ENDPOINT .. "ping","id=" .. config.ID,0,0)
end
-- Sends my id to the broker for registration
local function register_myself()
m:subscribe(config.ENDPOINT .. config.ID,0,function(conn)
print("Successfully subscribed to data endpoint")
end)
end
local function mqtt_start()
m = mqtt.Client(config.ID, 120)
-- register message callback beforehand
m:on("message", function(conn, topic, data)
if data ~= nil then
print(topic .. ": " .. data)
execute_command(data)
end
end)
-- Connect to broker
m:connect(config.HOST, config.PORT, 0, 1, function(con)
register_myself()
-- And then pings each 1000 milliseconds
tmr.stop(6)
tmr.alarm(6, 1000, 1, send_ping)
end)
end
function module.start()
mqtt_start()
end
-- Funcion para controlar comandos
function execute_command(command)
if command == "ON1" then
gpio.write(6, gpio.HIGH)
end
if command == "ON2" then
gpio.write(7, gpio.HIGH)
end
if command == "OFF1" then
gpio.write(6, gpio.LOW)
end
if command == "OFF2" then
gpio.write(7, gpio.LOW)
end
end
return module
Archivo init.lua
-- file : init.lua app = require("application") config = require("config") setup = require("setup") setup.start()
Paso uno a uno al dispositivo y en orden cada archivo mediante el siguiente botón:
Para ver si están todos los archivos en el dispositivo le damos a la pestaña Commands y luego a List files
El resultado debe ser parecido al siguiente (la imagen de abajo es una imagen genérica que no se corresponde a este proyecto):
En caso de que haya un error y se te quede colgado el dispositivo repitiendo el mismo error una y otra vez, puedes eliminar el archivo init.lua del dispositivo. Lo harás con el siguiente comando que introducirás en un cuadro de texto en la parte inferior del ESPlorer:
=file.remove("init.lua")Una vez arreglado el error vuelve a subir los archivos que modificaste y el init.lua.
Para borrar todos los archivos del dispositivo usa el siguiente comando:
=file.format()
Probando el sistema
En el ESPlorer pulsa el botón “Chip ID”. Nos devolverá el identificador único del chip de ti dispositivo.
En mi caso es 12123451. Debes cambiarlo por el tuyo.
mosquitto_pub -h test.mosquitto.org -t "my-home/12123451" -p 1883 -m ON1 mosquitto_pub -h test.mosquitto.org -t "my-home/12123451" -p 1883 -m OFF1 mosquitto_pub -h test.mosquitto.org -t "my-home/12123451" -p 1883 -m ON2 mosquitto_pub -h test.mosquitto.org -t "my-home/12123451" -p 1883 -m OFF2
recibiremos en el ESPlorer:
Configuring Wifi ... > Connecting to WLAN-ROUTER ... IP unavailable, Waiting... IP unavailable, Waiting... ==================================== ESP8266 mode is: 1 MAC address is: 5e:cf:7f:XX:XX:XX IP is 192.168.XX.XX ==================================== Successfully subscribed to data endpoint my-home/12123451: ON1 my-home/12123451: OFF1 my-home/12123451: ON2 my-home/12123451: OFF2
Hay que recordar que cada segundo, el dispositivo está enviando una señal que en el ejemplo lo llama “ping” en el servidor mqtt. Para verificar si el dispositivo está conectado al servidor usamos lo siguiente:
mosquitto_sub -h test.mosquitto.org -t "my-home/ping"