SISTEMA DE DETECÇÃO DE NÍVEL DE LUZ (IOT) BASEADO NO PROTOCOLO SMTP
O objetivo do
trabalho é fazer uma aplicação rodando no nodeMCU que iria enviar para o e-mail
cadastrado uma mensagem quando o nível da luz de onde o nodeMCU se encontra
estiver abaixo de um valor que pode ser definido.
A linguagem
utilizada foi C e utilizamos a ferramenta Arduino IDE, para fazer o envio do
e-mail foi utilizado o serviço do smtp2go. A linguagem C foi escolhida pois foi
a que o grupo melhor se adaptou, já havíamos trabalhado com ela previamente,
então isso ajudou com o desenvolvimento do trabalho.
Foi utilizado
um sensor de luminosidade, conectado ao nodeMCU, para fazer a medição da
luminosidade do ambiente onde o aparelho se encontra. A figura 1 mostra como
ele está montado.
Figura 1 – NodeMCU utilizado
Fonte: Autor
Para que o
nodeMCU soubesse para qual e-mail enviar e a partir de qual nível de
luminosidade ele deveria enviar o valor, foi criada uma página web simples,
conforme figura 2, que contém dois campos, um com o e-mail e outro o valor,
basta preencher eles e clicar em enviar que o nodeMCU passará a enviar para
esse e-mail cadastrado.
Figura 2 – Página web criada
Fonte: Autor
Uma
das dificuldades encontradas foi que ninguém do grupo sabia como enviar um
e-mail pelo C, foi necessário algum tempo de pesquisa para descobrir. Outro
ponto foi que nenhum de nós conhecia o C muito bem, então foram necessárias
várias tentativas até acertar o código como deveria ser.
O
procedimento para rodar o programa no nodeMCU foi bem simples, apenas
necessário conectá-lo ao computador por meio de um USB, e no programa do
Arduino IDE foi apenas preciso mandar o programa rodar.
A
seguir o código fonte:
#include <SPI.h>
#include <IPAddress.h>//import muvium.compatibility.arduino.IPAddress;
//import
muvium.compatibility.arduino.EthernetServer;
//import
muvium.compatibility.arduino.EthernetClient;
//import
muvium.compatibility.arduino.EthernetUDP;
//#include
<Ethernet.h>
#include <ESP8266WiFi.h>
#include <ThingSpeak.h>
#include <ESP8266WebServer.h>
#include <FS.h>
/*import
muvium.compatibility.arduino.Arduino;
import
muvium.compatibility.arduino.StringUtils; */
//#include
<SPI.h>
//#include
<Ethernet.h>
//
Enter a MAC address for your controller below.
//
Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte
mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
char serverName[] = "mail.smtp2go.com";
//
change server to your email server ip or domain
//
IPAddress server( 1, 2, 3, 4 );
//
Initialize the Ethernet client library
//
with the IP address and port of the server
//
that you want to connect to (port 80 is default for HTTP):
WiFiClient
client;
IPAddress
ip(192, 168, 56, 1);
const char* ssid = "GL-iNet-866";
const char* password = "goodlife";
int valorCorte = 50000;
String
email = "paulo.f.piva@gmail.com";
const char* host = "api.thingspeak.com";
const char* url = "/update?api_key=CB5G8LNYZFX9H69Z&field1=";
ESP8266WebServer
server ( 80 );
char htmlResponse[3000];
bool loadConfig() {
File f = SPIFFS.open("/config.txt", "r");
if (!f) {
Serial.println("Arquivo
ainda não existe");
return false;
}
valorCorte = f.readStringUntil(';').toInt();
email = f.readStringUntil(';');
Serial.print("Loaded
valorCorte: ");
Serial.println(valorCorte);
Serial.print("Loaded
email: ");
Serial.println(email);
return true;
}
bool saveConfig() {
String conteudoArquivo = String(valorCorte) + ";" + email + ";";
SPIFFS.format();
File f = SPIFFS.open("/config.txt", "w");
if (!f) {
Serial.println("Failed
to open config file for writing");
return false;
}
f.print(conteudoArquivo);
f.close();
return true;
}
void handleRoot() {
Serial.println("Escrevendo
HTML");
String
html = String("<!DOCTYPE
html>\
<html>\
<head>\
<title>\
Trabalho 3\
</title>\
</head>\
<body>\
<script src=\"https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js\">\
</script>\
<div id=\"title\">\
<h1>\
Trabalho 3\
</h1>\
</div>\
<hr>\
<div class=\"table\">\
<form>\
<table>\
<tr>\
<td>\
<span>Valor
limite</span>\
</td>\
<td>\
<input type=\"text\" id=\"treshold\" value=\""+String(valorCorte)+"\"/>\
</td>\
</tr>\
<tr>\
<td>\
<span>E-mail</span>\
</td>\
<td>\
<input type=\"text\" id=\"email\" value=\""+email+"\"/>\
</td>\
</tr>\
<table>\
<input type=\"submit\" id=\"send\"></input>\
</form>\
</div>\
<style>\
div{\
margin:auto;\
width: 150px;\
}\
.table{\
margin:auto;\
width: 259px;\
}\
</style>\
<script>\
$('#send').click(function(e){\
e.preventDefault();\
$.get('/save?email=' + $('#email').val()
+ '&treshold=' + $('#treshold').val(), function(data){\
console.log(data);\
});\
});
\
</script>\
</body>\
</html>");
const char* charHTML = html.c_str();
//html.toCharArray(charHTML,html.length());
Serial.println(charHTML);
snprintf ( htmlResponse, 3000, charHTML );
server.send ( 200,
"text/html", htmlResponse );
}
void handleSave() {
if (server.arg("email")!= ""){
Serial.println("Email:
" + server.arg("email"));
email = server.arg("email");
}
if (server.arg("treshold")!= ""){
Serial.println("Luz
minima: " + server.arg("treshold"));
valorCorte = server.arg("treshold").toInt();
}
saveConfig();
}
void setup() {
//
start the serial library:
Serial.begin(9600);
Serial.println("comecando");
//
start the WiFi connection:
Serial.println();
Serial.println();
Serial.print("Connecting
to ");
Serial.println(ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status()
!= WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi
connected");
Serial.println("IP
address: ");
Serial.println(WiFi.localIP());
SPIFFS.begin();
loadConfig();
server.on ( "/",
handleRoot );
server.on ("/save", handleSave);
server.begin();
}
void loop()
{
server.handleClient();
delay(5000);
int luz = analogRead(A0);
Serial.println("mensagem:
"+String(luz));
if (luz > valorCorte)
{
enviarEmail("mensagem:
"+String(luz));
enviaThingSpeak(luz);
}
}
void enviarEmail(String mensagem)
{
if (client.connect(serverName, 2525)) {
Serial.println("conexao
feita com sucesso");
client.println("ehlo
mail.smtp2go.com");
Serial.println("batata");
if(!eRcv()){
Serial.println("sai helo");
}
client.println("auth
login");
if(!eRcv()){
Serial.println("sai auth");
}
client.println("ZXhlbXBsb0BleGVtcGxvLmNvbQ==");//Email em base64
if(!eRcv()){
Serial.println("sai usuario");
}
client.println("ZXhlbXBsbw==");//Senha em base64
if(!eRcv()){
Serial.println("sai senha");
}
client.println("MAIL
From: neissmann@furb.br");
if(!eRcv()){
Serial.println("sai mail from");
}
client.println("RCPT
To: " + email);
if(!eRcv()){
Serial.println("sai rcpt to");
}
client.println("DATA");
if(!eRcv()){
Serial.println("sai DATA");
}
client.println("To:
You");
if(!eRcv()){
Serial.println("sai To You");
}
client.println("From:
Nicollas <neissmann@furb.br>");
if(!eRcv()){
Serial.println("sai From Nicollas");
}
client.println("Subject:
ESP8266 email test\r\n");
if(!eRcv()){
Serial.println("sai Subject");
}
client.println(mensagem);
if(!eRcv()){
Serial.println("sai mensagem");
}
client.println(".");
if(!eRcv()){
Serial.println("sai .");
}
client.println("QUIT");
if(!eRcv()){
Serial.println("sai QUIT");
}
while(client.available() > 0){
Serial.print((char) client.read());
}
client.stop();
Serial.println("disconnected");
}
else {
//
kf you didn't get a connection to the server:
Serial.println("connection
failed");
}
}
void enviaThingSpeak(int luz){
ThingSpeak.begin(client);
ThingSpeak.writeField(553858, 1, luz, "BJVQ6CRAJL1SBJYO");
}
boolean
eRcv()
{
byte respCode;
byte thisByte;
int loopCount = 0;
Serial.println((char)client.read());
while(client.available() == 0)
{
delay(1);
loopCount++;
Serial.println("
1--456-=5 " + client.available());
//
if nothing received for 10 seconds, timeout
if(loopCount > 10000) {
client.stop();
Serial.println("\r\nTimeout");
return false;
}
}
return true;
}
Ao
iniciar, o nodeMCU procura se já há alguma configuração guardada em sua
memória, caso tenha, ele irá carrega-la e já começará a atuar, caso não, irá
esperar receber alguma coisa. Qual alguém tenta carregar a página, o nodeMCU
irá enviar ela com os valores que já estão cadastrados, caso haja algum; o
método handleRoot() cuida dessa
parte.
Caso
seja informado um novo e-mail ou valor, o nodeMCU irá salvar esses valores em
memória e irá começar a utilizar eles; o método handleSave() cuida dessa parte.
A
parte principal do programa está no método loop(),
ele é que fica verificando o valor que está sendo lido do sensor, e caso
esse valor seja maior que o estipulado, ele irá chamar o método enviarEmail(), esse método fará a ação
de enviar o e-mail.
Alunos:
Daniel Rossato Martini, drmartini@furb.br
Gabriel Domingos, gabdomingos@furb.br
Nicollas Pierre Eissmann, neissmann@furb.br
Paulo Felipe Piva dos Santos, paulopiva@furb.br