Mandar e-mail con ESP8266

          En esta articulo veremos como nuestro módulo esp8266 puede mandarnos un correo electrónico para, por ejemplo, avisarnos de un evento o una alarma.
         
          El esp8266 puede actuar activado por un Arduino o solo, ya que sabemos que el módulo lleva un microprocesador completo y fácilmente programable con el firmware nodemcu y el lenguaje Lua
 
          Se da por supuesto que se sabe cargar dicho firmware. Se ha utilizado el esp8266 modelo esp-12, ya que tiene todos los pines disponibles, incluso uno analógico. El módulo lo he montado sobre una placa de prueba que me permite simular una entrada con un pulsador, salidas LED para control y cargar firmware con un puente y un conector para el USB/Serie. El propio esp-12 esta soldado a otra placa que facilita esta conexión y el añadirle un integrado ams1117 para 3,3v lo que permite alimentarlo sin miedo con voltajes superiores. ¡¡Ojo!!, esta placa tiene un error y el ams1117 tiene que montarse "atravesado" y con un puentecito y NO como las pistas dan a entender. También hay que desoldar una resistencia marcada con 000 (cero ohmios) que hace de puente y es necesario eliminar.
--init.lua
--Joaquín Paredes. 03/2015

wifi.setmode(wifi.STATION);
print('set mode=STATION (mode='..wifi.getmode()..')')
print('MAC: ',wifi.sta.getmac())
print('chip: ',node.chipid())
print('heap: ',node.heap())
wifi.sta.config("SSID","clave");             --Ponemos nuestro usuario y clave de la Wifi
print(wifi.sta.getip())                             --Nos dice via serie la IP asignada 192.168.1.xxx
gpio.mode(5, gpio.OUTPUT)                  --GPIO14
gpio.mode(2, gpio.INPUT)                      --GPIO4
gpio.mode(2,gpio.INPUT,gpio.PULLUP)  --Resistencia PullUp activada
dofile("server.lua")                                --Para ver en Web los valores de Temperatura y detector de gas

tmr.alarm(0, 1000, 1, function() print("Hola Don Pepito")   --Imprime via serie para debug y ejecuta el IF cada segundo
if( gpio.read(2)==0) then          --Detecta nivel bajo de sensor y
  dofile("email.lua")                     --manda email
  gpio.write(5, gpio.HIGH);         --enciende GPIO 14 durante  0,3''
  tmr.delay(300000) ;            
  gpio.write(5, gpio.LOW);
end
end)
conn=net.createConnection(net.TCP, 0)
conn:on("receive", function(conn, payload)
    print(payload)
    end)

conn:on("disconnection", function(conn,payload)
     print("desconectado")
     conn:close()
end)

conn:on("connection", function(conn,payload)
print("sending...")
conn:send("EHLO smtp.xxxxxxxx.xxx\r\n");       --Nuestro smtp
conn:send("AUTH LOGIN\r\n");
conn:send("XXXXXXXXXXXXXXXX\r\n");       --username en  base64
conn:send("XXXXXXXXXXXX\r\n");              --password en  base64
conn:send("HELO smtp.xxxxxxxxx.xxx\r\n")     --Nuestro smtp
conn:send("MAIL FROM: <xxxxxxxxx@xxxxx.xxx>\r\n");
conn:send("RCPT TO: <xxxxxxx@xxxxx.xxx>\r\n");
conn:send("DATA\r\n");
conn:send("From: Esp8266<xxxxxxxxx@xxxxx.xxx>\r\n");
conn:send("To: xxxxxxxxxx@xxxxx.xxx\r\n");
conn:send("Subject: Mail desde esp8266\r\n");
                                                         --A partir de aquí, va el mensaje
if( gpio.read(2)==0) then
  conn:send("Detección de gas: NEGATIVO");
else
  conn:send("Detección de gas: POSITIVO");
end
conn:send(" ");
conn:send(".\r\n");
conn:send("Temperatura en la cocina: ");
conn:send(adc.read(0)/10);
conn:send(" °C");
conn:send(".\r\n");
conn:send(".\r\n");

end)

conn:dns('smtp.XXXXXXXX.XXX',function(conn,ip) ipaddr=ip;    --Nuestro smtp
     print(ipaddr)
     conn:connect(25,ipaddr)    --puerto 25
end)
          El programa para el esp8266, como es habitual, está en dos (o mas partes). Una es el init.lua que arranca nada mas dar tensión al módulo y otro (u otros) que se ejecutan según queramos o a requerimiento de eventos. Tanto en asociación con Arduino como en solitario, el programa es el mismo. Lo único que cambia es el evento (cambio de estado del pin) que en un caso es ocasionado por el Arduino y en el otro por un sensor, en este caso un detector de gas para la cocina 

          Veamos el primero, el init.lua, que arranca automáticamente en cuanto damos tensión al esp8266, modelo esp-12
          La idea es construir un sistema de alarma para gas y temperatura para la cocina. El sensor puede detectar butano y gas ciudad. Lo de la temperatura, es porque alguna vez se ha quedado el horno encendido tras cocinar y al volver a casa había como 40º en al cocina. Tanto el MQ2 en una entrada digital como un LM35 en la analógica están conectados al esp8266. Tenemos así, un sistema de alarma local (si conectamos un zumbador al módulo) y una alarma por email a nuestro móvil y/o ordenador.

          Y ya de paso, aprovechándonos de este fantástico esp8266, lo he puesto a funcionar como Server para ver la temperatura vía Internet.
          Por tanto, hay cargados tres programas (funciones): init.lua, email.lua y server.lua 
       email.lua
srv=net.createServer(net.TCP)
srv:listen(8080,function(conn)
if( gpio.read(2)==0) then
  gas="NEGATIVO";
else
  gas="POSITIVO";
end
conn:send("HTTP/1.1 200 OK\n\n")
--          conn:send("<META HTTP-EQUIV=\"REFRESH\" CONTENT=\"15\">")
conn:send("<html><title>LOG Server - ESP8266</title><body>")
conn:send("<h2>Temperatura y gas en cocina con ESP8266</h2>")

print(gas)
conn:send("<B><font color=black size=4>Detección de gas: <B><font color=red size=4>" .. gas .."\n\n")
conn:send("<BR>")   
conn:send("<font color=black>Temperatura: <B><font color=red size=4>" .. adc.read(0)/10 .. " °C \n\n")
conn:send("</html></body>") 
conn:on("sent",function(conn) conn:close() end)
end)
       server.lua
       init.lua
          Función para mandar el email. Modificado de los foros porque tenia algunos errores.
    
          El smtp hay que ponerlo en tres sitios y el correo saliente y el entrante en dos. Por supuesto, podemos mandarnos un correo a otras cuentas propias.

          La única precaución es que hay que hacer una conversión de nuestro nombre de usuario y clave a base 64. Se hace fácilmente en la Web  https://www.base64encode.org/



          Cuando esp8266 recibe un nivel bajo del sensor, envía el correo. Tarda unos 5-6 segundos en mandarlo. Por supuesto, también puede activarse por elevación de temperatura o cualquier otro evento en otros pines.           

          Lo interesante es que el email puede ser personalizado con información. Por ejemplo, en este nos manda el mensaje con el estado del sensor de gas y la temperatura de un LM35D.

          Hay que tener en cuenta que el pin analógico del esp8266 tiene un rango máximo de entrada de 1 voltio. Como el LM35D nos da 10mv por grado centígrado no hay peligro de saturarlo o dañarlo. En caso contrario, habría que usar un divisor resistivo.
Se configura el módulo con nuestra Wifi y nos dice la IP que le asigna nuestro router en modo DHCP o forzada según MAC.

Configura GPIO14 como salida para un LED

Configura GPIO4 como entrada para el sensor de gas y activa su resistencia PULLUP.

Ejecuta la rutina server.lua para ver en un explorador los datos de temperatura y estado del sensor de gas tecleando la ip asignada y en el puerto 8080.
ip:8080

Arranca un temporizador de 1000ms que imprime continuamente por puerto serie (solo para comprobar que el sistema esta en marcha) y también monitoriza cada segundo el estado de GPIO14 (2) para mandar un email si baja a LOW. 
          Configuración de un server en el puerto 8080   y con la IP que nos proporcione el router.


Menu