Olá pessoal,
Hoje vamos ver como utilizar o shield Ethernet para o envio de e-mail. No projeto de acionamento automático de ar condicionado com infravermelho seria interessante que no momento em que houvesse o aumento de temperatura acima do programado o Arduino pudesse enviar algum tipo de aviso por e-mail pois o aviso sonoro e na tela do display só seriam percebidos se alguém estivesse no ambiente em que ele está.
Há algumas considerações:
1) É necessário que a infraestrutura de rede esteja funcionando no momento em que o Arduino for enviar o e-mail. Como o Arduino e os equipamentos estão ligados em um nobreak se houver queda de energia e o ar condicionado desligar o aviso por e-mail vai funcionar.
2) É necessária uma conexão de rede ativa por parte de quem está monitorando. Seja por celular, notebook ou PC se o e-mail for enviado alguém deve estar conectado para poder receber o aviso por e-mail. Se o e-mail for enviado e ninguém lê-lo é a mesma coisa não estar monitorando! Aí talvez implique que você deva ter uma conexão móvel (3G ou qualquer coisa parecida) e manter essa conexão ativa o tempo todo.
Mesmo com essa limitação por parte de monitoramento ainda assim acredito que o envio de e-mail é interessante por registrar a falha e com isso também compormos estatísticas de falhas e tomarmos providências sejam internas ou por parte da concessionária de energia para melhorar a disponibilidade de energia.
Vamos lá então:
Esquema de ligação: o mesmo do projeto de acionamento acrescentado somente o shield Ethernet.
Código:
#include <dht11.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <IRremote.h>
#include <SPI.h>
#include <Ethernet.h>
#include "RTClib.h"
//codigo rawcode capturado do ar condiconado via IRRecvDump
unsigned int powerOn[92] = {8950,4300,650,500,700,450,650,1600,650,500,600,1650,700,450,650,500,650,500,650,450,600,1700,600,550,550,550,600,1700,600,500,600,550,600,550,600,550,600,500,700,450,600,550,600,550,600,500,600,550,600,550,600,550,550,550,600,550,600,550,600,550,550,550,600,550,600,550,600,500,600,550,650,500,600,550,600,500,600,550,600,550,600,550,550,1700,600,550,600,550,550,1700,700};
// this must be unique
static byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
// change network settings to yours
IPAddress ip(192,168,1,177);
// Endereço do seu servidor de e-mail
char server[] = "seuservidordeemail";
EthernetClient client;
boolean enviouEmailDOWN;
boolean enviouEmailUP;
boolean enviouSMSDOWN;
boolean enviouSMSUP;
// Objeto irsend para emissor infrared
IRsend irsend;
// Objeto rtc (relogio de tempo real)
RTC_DS1307 rtc;
// Objeto LCD com 2 linhas e 16 caracteres por linha
#define lcdAddr 0x20LiquidCrystal_I2C lcd(lcdAddr, 4, 5, 6, 0, 1, 2, 3, 7, NEGATIVE);
float sinVal;
int toneVal;
//objeto sensor para DHT11 (sensor de temperatura)
dht11 sensor;
// função que envia e-mail quando desligar o ar condicionado
byte sendEmailDOWN()
{
byte thisByte = 0;
byte respCode;
// testa se há conexão com o servidor de e-mail na porta 25
if(client.connect(server,25)) {
Serial.print(F("connected"));
} else {
Serial.print(F("connection failed"));
return 0;
}
if(!eRcv()) return 0;
Serial.print(F("Sending helo"));
// Mude para o ip do Arduino
client.println(F("helo <seu ip>")); //envia o helo para o servidor de e-mail
if(!eRcv()) return 0;
Serial.print(F("Sending From"));
// Coloque um e-mail váido do seu servidor de e-mail
client.println(F("MAIL From: <arduino1@sorocaba.unesp.br>"));
if(!eRcv()) return 0;
// Coloque o e-mail do destinatário
Serial.print(F("Sending To"));
client.println(F("RCPT To: <destinatario@seudominiodeemail.com>"));
if(!eRcv()) return 0;
// Envie os dados do e-mail
Serial.print(F("Sending DATA"));
client.println(F("DATA"));
if(!eRcv()) return 0;
Serial.print(F("Sending email"));
// Mude para o e-mail do destinatário
client.println(F("To: Fernando <destinatario@seudominiodeemail.com>"));
// change to your address
client.println(F("From: Arduino <arduino1@sorocaba.unesp.br>"));
client.println(F("Subject: Temperatura alta\r\n"));
client.println(F("Temperatura alta no datacenter"));
client.println(F("."));
if(!eRcv()) return 0;
Serial.print(F("Sending QUIT"));
//Saindo da conexão com a porta 25 do servidor de e-mail
client.println(F("QUIT"));
if(!eRcv()) return 0;
client.stop();
Serial.print(F("disconnected"));
enviouEmailDOWN = true; //se enviou e-mail de desligado
return 1;
}
byte sendEmailUP()
{
byte thisByte = 0;
byte respCode;
if(client.connect(server,25)) {
Serial.print(F("connected"));
} else {
Serial.print(F("connection failed"));
return 0;
}
if(!eRcv()) return 0;
Serial.print(F("Sending helo"));
// change to your public ip
client.println(F("helo <seu ip"));
if(!eRcv()) return 0;
Serial.print(F("Sending From"));
// change to your email address (sender)
client.println(F("MAIL From: <arduino1@sorocaba.unesp.br>"));
if(!eRcv()) return 0;
//
Serial.print(F("Sending To"));
client.println(F("RCPT To: <fernando@sorocaba.unesp.br>"));
if(!eRcv()) return 0;
Serial.print(F("Sending DATA"));
client.println(F("DATA"));
if(!eRcv()) return 0;
Serial.print(F("Sending email"));
// Mude para o e-mail de destino
client.println(F("To: Fernando <fernando@sorocaba.unesp.br>"));
// Mude para o e-mail do remetente
client.println(F("From: Arduino <arduino1@sorocaba.unesp.br>"));
client.println(F("Subject: Temperatura normalizada\r\n"));
client.println(F("Temperatura normalizada na SALA DO STI"));
client.println(F("."));
if(!eRcv()) return 0;
Serial.print(F("Sending QUIT"));
client.println(F("QUIT"));
if(!eRcv()) return 0;
client.stop();
Serial.print(F("disconnected"));
enviouEmailUP = true;
return 1;
}
byte eRcv()
{
byte respCode;
byte thisByte;
int loopCount = 0;
while(!client.available()) {
delay(1);
loopCount++;
// Se não receber e-mail por 10 segundos
if(loopCount > 10000) {
client.stop();
Serial.print(F("\r\nTimeout"));
return 0;
}
}
respCode = client.peek();
while(client.available())
{
thisByte = client.read();
Serial.write(thisByte);
}
if(respCode >= '4')
{
efail();
return 0;
}
return 1;
}
void efail()
{
byte thisByte = 0;
int loopCount = 0;
client.print(F("QUIT"));
while(!client.available()) {
delay(1);
loopCount++;
// if nothing received for 10 seconds, timeout
if(loopCount > 10000) {
client.stop();
Serial.print(F("\r\nTimeout"));
return;
}
}
while(client.available())
{
thisByte = client.read();
Serial.write(thisByte);
}
client.stop();
Serial.print(F("disconnected"));
}
void setup() {
Serial.begin(9600); // Inicia conexao serial para monitoramento
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
Ethernet.begin(mac);
delay(1000);
Serial.println("Ethernet iniciada");
lcd.begin(16,2); // inicializa o lcd
lcd.setBacklight(1);
Serial.println("LCD iniciada");
delay(3000);
pinMode(8,OUTPUT); //pino 8 para saida do alto falante
#ifdef AVR
Wire.begin();
#else
Wire1.begin(); // Shield I2C pins connect to alt I2C bus on Arduino Due
#endif
rtc.begin(); //inicia o objeto rtc
//Verifica se o RTC esta funcionando
if (! rtc.isrunning()) {
Serial.print("RTC is NOT running!");
}
// Ajusta o rtc para a data e hora em que o sketch foi compilado
// rtc.adjust(DateTime(__DATE__, __TIME__));
Serial.println("RTC iniciada");
delay(3000);
enviouEmailDOWN = true;
enviouEmailUP = true;
}
void loop() {
DateTime now = rtc.now(); // carrega a data e hora do RTC
Serial.print("Lendo sensor: ");
int chk = sensor.read(2); //le a temperatura
//Verifica o status do DHT11
switch(chk) {
case DHTLIB_OK:
Serial.println("OK");
break;
case DHTLIB_ERROR_CHECKSUM:
Serial.println("Erro no checksum");
break;
case DHTLIB_ERROR_TIMEOUT:
Serial.println("Tempo esgotado");
break;
default:
Serial.println("Erro desconhecido");
}
// Monitora a umidade e temperatura para a conexao serial
Serial.print("Umidade (%): ");
Serial.println(sensor.humidity, 2);
Serial.print("Temperatura (graus Celsius): ");
Serial.println(sensor.temperature, 2);
// Carrega os valores de temperatura e umidade do sensor nas variaveis correspondentes
int temp = sensor.temperature;
int humi = sensor.humidity;
//Se a temperatura for maior que 26 graus Celsius
if (temp > 26) {
// envia o codigo IR para ligar o AC
// Aciona o ar condicionado novamente
irsend.sendRaw(powerOn,92,38);
// Exibe o valor da temperatura lida pelo sensor
lcd.clear(); //limpa o display do LCD.
lcd.home(); // Posiciona o cursos na coluna 0, linha 0
lcd.print("Temp: "); //imprime a string Temp: no display do LCD.
lcd.print(temp); // imprime a temperatura no LCD
lcd.write(B11011111); //Simbolo de graus celsius
lcd.print("C"); // Imprime C
lcd.setCursor(0,1); //posiciona o cursor na coluna 0 linha 1 do LCD.
lcd.print("TEMP. ALTA!"); //Imprime o aviso de temperatura alta no display do LCD.
//Aciona o alarme sonoro. Envia sinal sonoro para o pino 8 - alto falante
for (int x=0; x<180; x++) {
// converte graus para radianos e depois obtem o valor do seno
//Serial.print("Toca o som");
sinVal = (sin(x*(3.1416/180)));
toneVal = 2000+(int(sinVal*1000));
tone(8, toneVal);
delay(2);
}
//Seta a variável enviouEmailUP como false
enviouEmailUP = false;
// Se não enviou e-mail envia com a função sendEmailDOWN. Caso já enviou não envia novamente
if (!enviouEmailDOWN) {
sendEmailDOWN(); //envia e-mail de temperatura alta
}
//Aguarda 5 minutos para enviar novamente o codigo IR caso a temperatura nao baixe
delay(300000);
}
else
{
// Temperatura normal
lcd.clear(); //limpa o display do LCD.
lcd.home(); // Posiciona o cursos na coluna 0, linha 0
lcd.print("Temp: "); //imprime a string no display do LCD.
lcd.print(temp); // Imprime o valor da temperatura
lcd.write(B11011111); //Simbolo de graus celsius
lcd.print("C");
//Exibindo valor da leitura da umidade no display LCD.
lcd.setCursor(0,1); //posiciona o cursor na coluna 0 linha 1 do LCD.
lcd.print("Umidade: "); //imprime a string Umidade: no display do LCD.
lcd.print(humi); // Imprime o valor da umidade
lcd.print("%");
delay(5000);
//Exibe a data e hora no LCD
lcd.clear(); //limpa o display LCD
lcd.home(); // Posiciona o cursos na coluna 0, linha 0 lcd.print("DATA: ");
lcd.print(now.day(), DEC); //imprime o dia
lcd.print('/');
lcd.print(now.month(), DEC); // imprime o mês
lcd.print('/');
lcd.print(now.year(), DEC); //imprime o ano
lcd.setCursor(0,1);
lcd.print("HORA: ");
lcd.print(now.hour(), DEC); //imprime a hora
lcd.print(':');
lcd.print(now.minute(), DEC); //imprime o minuto
lcd.print(':');
lcd.print(now.second(), DEC); //imprime o segundo
delay(2000);
noTone(8); //silencia o alarme sonoro
//seta a variável enviouEmailDOWN como false
enviouEmailDOWN = false;
// Se não enviou e-mail envia com a função sendEmailUP. Caso já enviou não envia novamente
if (!enviouEmailUP) {
sendEmailUP(); //envia o e-mail de temperatura normalizada
}
}
delay(2000);
}
Com isso o projeto de acionamento de ar condicionado com infravermelho conta com a funcionalidade de envio de e-mail quando há o aumento de temperatura e também quando a temperatura volta ao normal.
Como vocês perceberam o sketch está aumentando em tamanho a medida que vamos acrescentando mais componentes e funcionalidades. Este é o assunto para o próximo post.
Até mais!