Neste post, será mostrado como enviar e-mail’s com o ESP32 através de um servidor SMTP, utilizando serviços do Gmail (Google), contendo mensagem de texto ou de HTML e anexos. Também será abordado um projeto de envio de e-mail de alerta quando uma porta for aberta.
SMTP, acrônimo de Simple Mail Transfer Protocol (Protocolo de transferência de correio simples), é um protocolo de servidor para envio de mensagens de e-mail através da Internet entre dois dispositivos computacionais. O SMTP tem a função somente de envio. Por isso, não permite que um usuário descarregue/solicite as mensagens de um servidor. Assim, para a leitura, é necessário o uso de um software cliente de e-mail com suporte ao protocolo de leitura POP ou IMAP.
Para permitir que o ESP32 envie e-mail’s utilizando uma conta Gmail do Google, é necessário, primeiro, se ter uma conta Gmail.
Nota: Não é recomendável utilizar uma conta pessoal para o envio de e-mail’s pelo ESP32. Caso extrapole o limite de envios de e-mail’s (500 e-mails em um dia), sua conta pode ser bloqueada para fazer novos envios de e-mail’s de 1 a 24 horas como uma medida para evitar spam e manter as contas seguras.
Para criar uma nova conta Gmail, acesse google.com/gmail/about e clique em ‘Crie uma conta’;
Siga as etapas na tela para configurar sua conta e conclua a criação de conta Gmail.
Para permitir que o ESP32 acesse sua Conta do Google, é necessário ter a funcionalidade ‘senhas de app‘. Para ativar as senhas de app, a verificação em duas etapas deve estar ativa.
Em seguida, use a conta que você criou para acessar o Gerenciador de Conta Google através do endereço myaccount.google.com. No painel de navegação (localizado na lateral esquerda ou superior), clique em Segurança
Em seguida, na seção Como fazer login no Google, clique em Verificação em duas etapas;
Clique em ‘Primeiros Passos’, e siga as etapas exibidas na tela.
Em Gerenciador de Conta Google, no painel de navegação, clique em Segurança. Em seguida, na seção Como fazer login no Google, clique em Senhas de app;
Na parte inferior da próxima tela:
Após configurar, clique em Gerar (3):
Após gerar a Senha de app, anote a senha de 16 caracteres gerada, pois iremos utilizar no sketch de envio de e-mail com ESP32.
Para o envio de e-mail com o ESP32, é necessário se ter a biblioteca ESP Mail Client na Arduino IDE. Para instalá-la na Arduino IDE:
Esta biblioteca permite o envio de e-mail com vários anexos suportados e oferece mais confiabilidade e flexibilidade de usos. Além de suportar ESP32 e ESP8266 da Espressif, também suporta placas Ethernet SPI W5100,W5500 e ENC28J60, que podem ser conectadas à qualquer versão de Arduino que suporte comunicação SPI.
Mais detalhes sobre a biblioteca, você encontra em github.com/mobizt/ESP-Mail-Client.
Para o Funcionamento dos seguintes algoritmos, faça as seguintes substituições:
<O_SSID_de_sua_rede_WiFi>
para o SSID de sua rede WiFi;<A_senha_de_sua_rede_WiFi>
para a senha de sua rede WiFi;<O_email_remetente>
para o seu e-mail cadastrado em Senhas de app;<A_senha_de_app_do_email_remetente>
para a Senha de app do e-mail;<O_email_destinatario>
para o endereço de e-mail ao qual irá enviar o e-mail;O seguinte algoritmo envia um e-mail com o corpo de texto com texto simples.
/******************************************************************************* Algoritmo de envio de e-mail com texto simples com ESP32 Sketch Principal Criado em 01 abr. 2022 por Michel Galvão Eletrogate - Loja de Arduino \\ Robótica \\ Automação \\ Apostilas \\ Kits https://www.eletrogate.com/ *******************************************************************************/ // Inclusão da(s) biblioteca(s) #include <WiFi.h> // Biblioteca nativa do ESP32 #include <ESP_Mail_Client.h> // Biblioteca de cliente de e-mail do // Arduino para enviar. // Referência: https://github.com/mobizt/ESP-Mail-Client // Configurações da rede WiFi à se conectar #define WIFI_SSID "<O_SSID_de_sua_rede_WiFi>" #define WIFI_PASSWORD "<A_senha_de_sua_rede_WiFi>" // Configurações do SMTP host #define SMTP_HOST "smtp.gmail.com" // SMTP host #define SMTP_PORT 465 // SMTP port // As credenciais de login #define AUTOR_EMAIL "<O_email_remetente>" #define AUTOR_SENHA "<A_senha_de_app_do_email_remetente>" // O objeto de sessão SMTP usado para envio de e-mail SMTPSession smtp; // Protótipos das Funções void smtpCallback(SMTP_Status status); bool enviaEmail_TXT(String nomeRemetente, String emailRemetente, String senhaRemetente, String assunto, String nomeDestinatario, String emailDestinatario, String messageTXT, String stmpHost, int stmpPort); void setup() { // Inicia Serial Serial.begin(115200); Serial.println(); delay(1000); // Inicia conexão WiFi Serial.println("Conectando à rede WiFi"); WiFi.begin(WIFI_SSID, WIFI_PASSWORD); while (WiFi.status() != WL_CONNECTED) // Enquanto o status de conexão ao WiFi // não for bem sucedido, ... { Serial.print("."); delay(200); } // Mostra na Serial que a conexão está realizada e mostra o IP do ESP32 na rede Serial.println("\nWiFi conectado."); // Habilita a depuração via porta serial: // 0: nenhuma depuração // 1: depuração básica smtp.debug(0); // Define a função de retorno de chamada para obter os resultados de envio smtp.callback(smtpCallback); //Define a mensagem de texto a ser enviada String messageTXT = "Olá mundo! Teste de envio de E-mail com somente texto."; // função que envia o e-mail enviaEmail_TXT("Michel Galvão", AUTOR_EMAIL, AUTOR_SENHA, "Teste de E-mail", "Michel Galvão", "<O_email_destinatario>", messageTXT, SMTP_HOST, SMTP_PORT); while (1); // loop infinito } void loop() {} /** Envia um e-mail para um destinatário. @param nomeRemetente - o nome ao qual será mostrado do remetente @param emailRemetente - o email do remetente @param senhaRemetente - a senha criada em Senhas de app @param assunto - o assunto do e-mail @param nomeDestinatario - o nome do destinatário @param emailDestinatario - o email do destinatário @param messageTXT - a mensagem de texto do e-mail @param stmpHost - o servidor SMTP @param stmpPort - a porta SSL do servidor SMTP @return - true se envio foi bem sucedido ou false se houve alguma falha */ bool enviaEmail_TXT(String nomeRemetente, String emailRemetente, String senhaRemetente, String assunto, String nomeDestinatario, String emailDestinatario, String messageTXT, String stmpHost, int stmpPort) { // Objeto para declarar os dados de configuração da sessão ESP_Mail_Session session; // Defina os dados de configuração da sessão session.server.host_name = stmpHost; session.server.port = stmpPort; session.login.email = emailRemetente; session.login.password = senhaRemetente; session.login.user_domain = ""; // Defina o tempo de configuração do NTP session.time.ntp_server = F("time.google.com"); // Utilizado o NTP do Google: // https://developers.google.com/time session.time.gmt_offset = -3; // define o deslocamento em segundos // do fuso horário local em relação ao // GMT do Meridiano de Greenwich. session.time.day_light_offset = 0; // define o deslocamento em segundos do // fuso horário local. Este valor costuma // ser 3600 para horário de verão +1h ou // 0 para fusos sem horário de verão. // Instanciação do objeto da classe de mensagem SMTP_Message message; // Definição os cabeçalhos das mensagens message.sender.name = nomeRemetente; message.sender.email = emailRemetente; message.subject = assunto; message.addRecipient(nomeDestinatario, emailDestinatario); message.text.content = messageTXT.c_str(); // O conjunto de caracteres de mensagem de texto html, por exemplo: // us-ascii // utf-8 // utf-7 // O valor padrão é utf-8 message.text.charSet = "utf-8"; // A codificação de transferência de conteúdo. Ex: // enc_7bit ou "7bit" (não codificado) // enc_qp ou "quoted-printable" (codificado) // enc_base64 ou "base64" (codificado) // enc_binary ou "binary" (não codificado) // enc_8bit ou "8bit" (não codificado) // O valor padrão é "7bit" message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit; // A prioridade da mensagem: // esp_mail_smtp_priority_high ou 1 // esp_mail_smtp_priority_normal ou 3 // esp_mail_smtp_priority_low ou 5 // O valor padrão é esp_mail_smtp_priority_low message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low; // As notificações de status de entrega, Ex: // esp_mail_smtp_notify_never // esp_mail_smtp_notify_success // esp_mail_smtp_notify_failure // esp_mail_smtp_notify_delay // O valor padrão é esp_mail_smtp_notify_never message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; // Conecte-se ao servidor com a configuração da sessão if (!smtp.connect(&session)) return false; // Começa a enviar e-mail e fecha a sessão if (!MailClient.sendMail(&smtp, &message)) { Serial.println("Erro ao enviar e-mail, " + smtp.errorReason()); return false; } return true; } /** * Função de retorno de chamada para obter o status de envio de e-mail */ void smtpCallback(SMTP_Status status) { // Imprime o status atual Serial.println(status.info()); // Imprima o resultado do envio if (status.success()) { Serial.println("----------------"); ESP_MAIL_PRINTF("Mensagem enviada com sucesso: %d\n", status.completedCount()); ESP_MAIL_PRINTF("Falha na mensagem enviada: %d\n", status.failedCount()); Serial.println("----------------\n"); struct tm dt; for (size_t i = 0; i < smtp.sendingResult.size(); i++) { /* Obter o item de resultado */ SMTP_Result result = smtp.sendingResult.getItem(i); time_t ts = (time_t)result.timestamp; localtime_r(&ts, &dt); ESP_MAIL_PRINTF("Message No: %d\n", i + 1); ESP_MAIL_PRINTF("Status: %s\n", result.completed ? "sucesso" : "fracassado"); ESP_MAIL_PRINTF("Data/Hora: %d/%d/%d %d:%d:%d\n", dt.tm_year + 1900, dt.tm_mon + 1, dt.tm_mday, dt.tm_hour, dt.tm_min, dt.tm_sec); ESP_MAIL_PRINTF("Recebedor: %s\n", result.recipients); ESP_MAIL_PRINTF("Sujeito: %s\n", result.subject); } Serial.println("----------------\n"); } }
Primeiro, fazemos a inclusão das bibliotecas.
Em seguida, definimos o SSID e a senha da rede WiFi. Também definimos o endereço do host e a porta do host SMTP. Em seguida, definimos o endereço e a senha do e-mail que será o remetente.
Logo após, criamos o objeto da classe SMTPSession
. Este objeto será usado para o envio de e-mail.
Logo abaixo, criamos os protótipos das funções utilizados no algoritmo.
Em void setup()
, iniciamos o WiFi com as credenciais de rede. Também entramos em uma estrutura de repetição para esperarmos o ESP32 conectar na rede WiFi.
Em seguida, ainda em void setup()
, há a opção de habilitar a depuração via Serial. Para habilitar, basta alterar o parâmetro para 1. Também definimos a função que será usada para callback dos resultados de envio do e-mail.
Seguidamente, definimos a mensagem de texto que será o corpo de texto do e-mail. Com o corpo de texto definido, chamamos a função responsável pelo envio do e-mail. Após o envio do e-mail, entramos em um loop infinito, já que no void loop()
, não fazemos mais nada.
A função bool enviaEmail_TXT()
, é responsável pelo envio de e-mail para um único destinatário especificado nos parâmetros da função. Esta função retorna true
se o envio for bem sucedido e false
se ocorreu algum erro no envio. Nesta função, devemos passar os parâmetros listados na imagem abaixo:
Dentro desta função, criamos um objeto da classe ESP_Mail_Session
, responsável por configurar os dados da sessão de envio do e-mail. Estes dados são: o nome do host SMTP, a porta do host SMTP, o e-mail do remetente e a senha do e-mail do remetente.
Também definimos as configurações do servidor NTP. Estas configurações podem ser vistas com mais detalhes no post Salvando preferências no ESP32, aqui mesmo, no blog eletrogate.
É definido, em seguida, o objeto da classe SMTP_Message
, que é responsável por definir os dados da mensagem do e-mail. Estes dados incluem o nome do remetente, o e-mail do remetente, o assunto do e-mail, o nome e o e-mail do destinatário e o texto do corpo do e-mail. Outros dados definidos estão detalhados abaixo.
Após as definições de dados da mensagem do e-mail, conectamo-nos ao servidor SMTP com as configurações de sessão definidas anteriormente. Caso haja falha na conexão, retornamos false
para a chamada da função.
Caso, na conexão, não tenha ocorrido nenhuma falha, enviamos o e-mail e fechamos a sessão. Se ocorreu algum erro, também retornamos false
para a chamada da função.
No final da função, retornamos true
para a chamada da função.
A função de callback stmpCallback mostra na Serial o status após o envio do e-mail (se foi enviado com sucesso ou houve falha).
Ao executar o programa no ESP32, a saída do Monitor Serial é:
20:17:44.371 -> Conectando à rede WiFi 20:17:44.473 -> ................ 20:17:47.664 -> WiFi conectado. 20:17:47.664 -> Acquiring time from NTP server... 20:17:47.698 -> 20:17:48.310 -> Connecting to SMTP server... 20:17:50.245 -> 20:17:50.245 -> SMTP server connected, wait for greeting... 20:17:50.279 -> 20:17:50.279 -> Sending greeting response... 20:17:50.483 -> 20:17:50.483 -> Logging in... 20:17:50.824 -> 20:17:50.824 -> Sending Email... 20:17:50.824 -> 20:17:50.824 -> Sending message header... 20:17:51.367 -> 20:17:51.367 -> Sending message body... 20:17:51.673 -> 20:17:51.673 -> Finishing the message sending... 20:17:52.387 -> 20:17:52.387 -> Closing the session... 20:17:52.795 -> 20:17:52.795 -> Message sent successfully 20:17:52.795 -> 20:17:52.795 -> ---------------- 20:17:52.795 -> Mensagem enviada com sucesso: 1 20:17:52.829 -> Falha na mensagem enviada: 0 20:17:52.829 -> ---------------- 20:17:52.829 -> 20:17:52.829 -> Message No: 1 20:17:52.829 -> Status: sucesso 20:17:52.829 -> Data/Hora: 2022/4/1 20:17:56 20:17:52.829 -> Recebedor: |⸮⸮? 20:17:52.829 -> Sujeito: {⸮? 20:17:52.829 -> ---------------- 20:17:52.829 ->
No Gmail do endereço do destinatário, é recebido o e-mail enviado pelo ESP32:
O seguinte algoritmo envia um e-mail com o corpo de texto com HTML.
/******************************************************************************* Algoritmo de envio de e-mail com corpo de texto HTML com ESP32 Sketch Principal Criado em 01 abr. 2022 por Michel Galvão Eletrogate - Loja de Arduino \\ Robótica \\ Automação \\ Apostilas \\ Kits https://www.eletrogate.com/ *******************************************************************************/ // Inclusão da(s) biblioteca(s) #include <WiFi.h> // Biblioteca nativa do ESP32 #include <ESP_Mail_Client.h> // Biblioteca de cliente de e-mail do // Arduino para enviar. // Referência: https://github.com/mobizt/ESP-Mail-Client // Configurações da rede WiFi à se conectar #define WIFI_SSID "<O_SSID_de_sua_rede_WiFi>" #define WIFI_PASSWORD "<A_senha_de_sua_rede_WiFi>" // Configurações do SMTP host #define SMTP_HOST "smtp.gmail.com" // SMTP host #define SMTP_PORT 465 // SMTP port // As credenciais de login #define AUTOR_EMAIL "<O_email_remetente>" #define AUTOR_SENHA "<A_senha_de_app_do_email_remetente>" // O objeto de sessão SMTP usado para envio de e-mail SMTPSession smtp; // Protótipos das Funções void smtpCallback(SMTP_Status status); bool enviaEmail_HTML(String nomeRemetente, String emailRemetente, String senhaRemetente, String assunto, String nomeDestinatario, String emailDestinatario, String messageHTML, String stmpHost, int stmpPort);; void setup() { // Inicia Serial Serial.begin(115200); Serial.println(); delay(1000); // Inicia conexão WiFi Serial.println("Conectando à rede WiFi"); WiFi.begin(WIFI_SSID, WIFI_PASSWORD); while (WiFi.status() != WL_CONNECTED) // Enquanto o status de conexão ao WiFi // não for bem sucedido, ... { Serial.print("."); delay(200); } // Mostra na Serial que a conexão está realoizado e mostra o IP do ESP32 na rede Serial.println("\nWiFi conectado."); // Habilita a depuração via porta serial: // 0: nenhuma depuração // 1: deburação básica smtp.debug(0); // Define a função de retorno de chamada para obter os resultados de envio smtp.callback(smtpCallback); //Define a mensagem de texto à ser enviada String messageHTML = R"rawliteral( <!DOCTYPE html> <html> <head> </head> <body style="background-color: rgb(250, 241, 192);"> <h1>Teste de HTML!</h1> <p>Este é um corpo de texto criado em HTML.</p> <h3>Exemplos de funcionalidades</h3> <ol> <li> Exemplo de link: <a href="https://google.com.br" target="_blank" rel="noopener"> google.com.br</a> </li> <li>Exemplo de Tabela:</li> </ol> <table style="border-collapse: collapse; width: 13.0593%; height: 37px;" border="1"> <tbody> <tr> <td style="width: 33.3333%;">Coluna 1</td> <td style="width: 33.3333%;">Coluna 2</td> </tr> <tr> <td style="width: 33.3333%;">1.1</td> <td style="width: 33.3333%;">1.2</td> </tr> </tbody> </table> <ul> <li> Exemplo de imagem: <img src= "https://blog.eletrogate.com/wp-content/themes/blog-eletrogate/dist/img/image/logo.png" alt="" width="484" height="52" /> </li> </ul> <p> </p> <ul> <li> Exemplo de <span style="font-family: 'comic sans ms', sans-serif;"> <span style="background-color: #eccafa;">Formatação</span> de <span style="color: #169179;">Texto</span> </span> : <strong>Negrito</strong>, <em>Itálico</em>, <span style="text-decoration: underline;">Sublinhado</span>, <span style="text-decoration: line-through;">Tachado</span>, x<sup>2</sup>, H<sub>2</sub>O, <code>CODE;</code>, 😄 </li> </ul> <p> </p> </body> </html> )rawliteral"; // "Fim de raw text // função que envia o e-mail enviaEmail_HTML("Michel Galvão", AUTOR_EMAIL, AUTOR_SENHA, "Teste de E-mail com HTML", "Michel Galvão", "<O_email_destinatario>", messageHTML, SMTP_HOST, SMTP_PORT); while (1); // loop infinito } void loop() {} /** Envia um e-mail para um destinatário. @param nomeRemetente - o nome ao qual será mostrado do remetente @param emailRemetente - o email do remetente @param senhaRemetente - a senha criada em Senhas de app @param assunto - o assunto do e-mail @param nomeDestinatario - o nome do destinatário @param emailDestinatario - o email do destinatário @param messageTXT - a mensagem de texto do e-mail @param stmpHost - o servidor SMTP @param stmpPort - a porta SSL do servidor SMTP @return - true se envio foi bem sucedido ou false se houve alguma falha */ bool enviaEmail_HTML(String nomeRemetente, String emailRemetente, String senhaRemetente, String assunto, String nomeDestinatario, String emailDestinatario, String messageHTML, String stmpHost, int stmpPort) { // Objeto para declarar os dados de configuração da sessão ESP_Mail_Session session; // Defina os dados de configuração da sessão session.server.host_name = stmpHost; session.server.port = stmpPort; session.login.email = emailRemetente; session.login.password = senhaRemetente; session.login.user_domain = ""; // Defina o tempo de configuração do NTP session.time.ntp_server = F("time.google.com"); // Utilizado o NTP do Google: // https://developers.google.com/time session.time.gmt_offset = -3; // define o deslocamento em segundos // do fuso horário local em relação ao // GMT do Meridiano de Greenwich. session.time.day_light_offset = 0; // define o deslocamento em segundos do // fuso horário local. Este valor costuma // ser 3600 para horário de verão +1h ou // 0 para fusos sem horário de verão. // Instanciação do objeto da classe de mensagem SMTP_Message message; // Definição os cabeçalhos das mensagens message.sender.name = nomeRemetente; message.sender.email = emailRemetente; message.subject = assunto; message.addRecipient(nomeDestinatario, emailDestinatario); message.html.content = messageHTML.c_str(); // O conjunto de caracteres de mensagem de texto html, por exemplo: // us-ascii // utf-8 // utf-7 // O valor padrão é utf-8 message.text.charSet = "utf-8"; // A codificação de transferência de conteúdo. Ex: // enc_7bit ou "7bit" (não codificado) // enc_qp ou "quoted-printable" (codificado) // enc_base64 ou "base64" (codificado) // enc_binary ou "binary" (não codificado) // enc_8bit ou "8bit" (não codificado) // O valor padrão é "7bit" message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit; // A prioridade da mensagem: // esp_mail_smtp_priority_high ou 1 // esp_mail_smtp_priority_normal ou 3 // esp_mail_smtp_priority_low ou 5 // O valor padrão é esp_mail_smtp_priority_low message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low; // As notificações de status de entrega, Ex: // esp_mail_smtp_notify_never // esp_mail_smtp_notify_success // esp_mail_smtp_notify_failure // esp_mail_smtp_notify_delay // O valor padrão é esp_mail_smtp_notify_never message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; // Conecte-se ao servidor com a configuração da sessão if (!smtp.connect(&session)) return false; // Começa a enviar e-mail e fecha a sessão if (!MailClient.sendMail(&smtp, &message)) { Serial.println("Erro ao enviar e-mail, " + smtp.errorReason()); return false; } return true; } /** * Função de retorno de chamada para obter o status de envio de e-mail */ void smtpCallback(SMTP_Status status) { // Imprime o status atual Serial.println(status.info()); // Imprima o resultado do envio if (status.success()) { Serial.println("----------------"); ESP_MAIL_PRINTF("Mensagem enviada com sucesso: %d\n", status.completedCount()); ESP_MAIL_PRINTF("Falha na mensagem enviada: %d\n", status.failedCount()); Serial.println("----------------\n"); struct tm dt; for (size_t i = 0; i < smtp.sendingResult.size(); i++) { /* Obter o item de resultado */ SMTP_Result result = smtp.sendingResult.getItem(i); time_t ts = (time_t)result.timestamp; localtime_r(&ts, &dt); ESP_MAIL_PRINTF("Message No: %d\n", i + 1); ESP_MAIL_PRINTF("Status: %s\n", result.completed ? "sucesso" : "fracassado"); ESP_MAIL_PRINTF("Data/Hora: %d/%d/%d %d:%d:%d\n", dt.tm_year + 1900, dt.tm_mon + 1, dt.tm_mday, dt.tm_hour, dt.tm_min, dt.tm_sec); ESP_MAIL_PRINTF("Recebedor: %s\n", result.recipients); ESP_MAIL_PRINTF("Sujeito: %s\n", result.subject); } Serial.println("----------------\n"); } }
Este algoritmo é semelhante ao Algoritmo de envio do e-mail com corpo de texto simples. Apenas tem divergência na criação da mensagem de texto do corpo do e-mail, que agora é HTML:
//Define a mensagem de texto à ser enviada String messageHTML = R"rawliteral( <!DOCTYPE html> <html> <head> </head> <body style="background-color: rgb(250, 241, 192);"> <h1>Teste de HTML!</h1> <p>Este é um corpo de texto criado em HTML.</p> <h3>Exemplos de funcionalidades</h3> <ol> <li> Exemplo de link: <a href="https://google.com.br" target="_blank" rel="noopener"> google.com.br</a> </li> <li>Exemplo de Tabela:</li> </ol> <table style="border-collapse: collapse; width: 13.0593%; height: 37px;" border="1"> <tbody> <tr> <td style="width: 33.3333%;">Coluna 1</td> <td style="width: 33.3333%;">Coluna 2</td> </tr> <tr> <td style="width: 33.3333%;">1.1</td> <td style="width: 33.3333%;">1.2</td> </tr> </tbody> </table> <ul> <li> Exemplo de imagem: <img src= "https://blog.eletrogate.com/wp-content/themes/blog-eletrogate/dist/img/image/logo.png" alt="" width="484" height="52" /> </li> </ul> <p> </p> <ul> <li> Exemplo de <span style="font-family: 'comic sans ms', sans-serif;"> <span style="background-color: #eccafa;">Formatação</span> de <span style="color: #169179;">Texto</span> </span> : <strong>Negrito</strong>, <em>Itálico</em>, <span style="text-decoration: underline;">Sublinhado</span>, <span style="text-decoration: line-through;">Tachado</span>, x<sup>2</sup>, H<sub>2</sub>O, <code>CODE;</code>, 😄 </li> </ul> <p> </p> </body> </html> )rawliteral"; // "Fim de raw text
Na definição da mensagem HTML do corpo do e-mail, é utilizada a funcionalidade de String bruto da linguagem C++. Uma String de literal bruto é uma string na qual os caracteres de escape como \n , \t ou \” de C++ não são processados. A sintaxe dela é: R “delimiter(raw_characters)delimiter”, em que delimiter pode ter qualquer nome. O conteúdo da string deve estar em raw_characters, podendo ter até quebra de linha.
E também tem divergência na função enviaEmail_HTML()
, especificamente na parte de Definição da mensagem:
Ao executar o programa no ESP32, a saída do Monitor Serial é:
22:52:29.606 -> Conectando à rede WiFi 22:52:29.743 -> ................ 22:52:32.938 -> WiFi conectado. 22:52:32.938 -> Acquiring time from NTP server... 22:52:32.938 -> 22:52:33.108 -> Connecting to SMTP server... 22:52:35.147 -> 22:52:35.147 -> SMTP server connected, wait for greeting... 22:52:35.452 -> 22:52:35.452 -> Sending greeting response... 22:52:35.792 -> 22:52:35.792 -> Logging in... 22:52:36.098 -> 22:52:36.098 -> Sending Email... 22:52:36.098 -> 22:52:36.098 -> Sending message header... 22:52:36.676 -> 22:52:36.676 -> Sending message body... 22:52:37.326 -> 22:52:37.326 -> Finishing the message sending... 22:52:38.041 -> 22:52:38.041 -> Closing the session... 22:52:38.345 -> 22:52:38.345 -> Message sent successfully 22:52:38.345 -> 22:52:38.345 -> ---------------- 22:52:38.345 -> Mensagem enviada com sucesso: 1 22:52:38.345 -> Falha na mensagem enviada: 0 22:52:38.345 -> ---------------- 22:52:38.345 -> 22:52:38.345 -> Message No: 1 22:52:38.345 -> Status: sucesso 22:52:38.345 -> Data/Hora: 2022/4/1 22:52:41 22:52:38.345 -> Recebedor: 22:52:38.345 -> Sujeito: ⸮⸮⸮? 22:52:38.345 -> ---------------- 22:52:38.345 ->
No Gmail do endereço do destinatário, é recebido o e-mail enviado pelo ESP32:
Primeiro, devemos armazenar os arquivos que serão anexos ao e-mail. Para isso, iremos utilizar a SPIFFS (veja mais detalhes sobre no post SPIFFS: Armazenamento de Arquivos do ESP32, aqui mesmo do blog eletrogate).
Para armazenar os arquivos, na IDE Arduino, vá em Sketch → Mostrar a página do sketch.
Na pasta que abrir, crie uma nova pasta chamada data.
Dentro desta pasta coloque os arquivos que você queira armazenar para posterior envio de e-mail com anexo. No nosso caso utilizamos um arquivo de texto chamado arquivo de exemplo.txt e um arquivo de imagem chamado exemplo de imagem.png (ambos podem ser baixados aqui)
Após colocar os arquivos na pasta, novamente na IDE Arduino, vá em Ferramentas → ESP32 Sketch Data upload com o ESP32 conectado na porta USB.
Após a partição SPIFFS estar carregada no ESP32, carregue o seguinte Sketch:
/******************************************************************************* Algoritmo de envio de e-mail com anexo de arquivos da SPIFFS com ESP32 Sketch de Exemplo Criado em 01 abr. 2022 por Michel Galvão Eletrogate - Loja de Arduino \\ Robótica \\ Automação \\ Apostilas \\ Kits https://www.eletrogate.com/ *******************************************************************************/ // Inclusão da(s) biblioteca(s) #include <WiFi.h> // Biblioteca nativa do ESP32 #include <ESP_Mail_Client.h> // Biblioteca de cliente de e-mail do // Arduino para enviar. // Referência: https://github.com/mobizt/ESP-Mail-Client // Configurações da rede WiFi à se conectar #define WIFI_SSID "<O_SSID_de_sua_rede_WiFi>" #define WIFI_PASSWORD "<A_senha_de_sua_rede_WiFi>" // Configurações do SMTP host #define SMTP_HOST "smtp.gmail.com" // SMTP host #define SMTP_PORT 465 // SMTP port // As credenciais de login #define AUTOR_EMAIL "<O_email_remetente>" #define AUTOR_SENHA "<A_senha_de_app_do_email_remetente>" // O objeto de sessão SMTP usado para envio de e-mail SMTPSession smtp; // Protótipos das Funções void smtpCallback(SMTP_Status status); void setup() { // Inicia Serial Serial.begin(115200); Serial.println(); delay(1000); // Inicia conexão WiFi Serial.println("Conectando à rede WiFi"); WiFi.begin(WIFI_SSID, WIFI_PASSWORD); while (WiFi.status() != WL_CONNECTED) // Enquanto o status de conexão ao WiFi // não for bem sucedido, ... { Serial.print("."); delay(200); } // Mostra na Serial que a conexão está realoizado e mostra o IP do ESP32 na rede Serial.println("\nWiFi conectado."); // Habilita a depuração via porta serial: // 0: nenhuma depuração // 1: deburação básica smtp.debug(0); // Define a função de retorno de chamada para obter os resultados de envio smtp.callback(smtpCallback); //Define a mensagem de texto à ser enviada String messageTXT = "Teste de envio de E-mail com anexos."; // função que envia o e-mail // Objeto para declarar os dados de configuração da sessão ESP_Mail_Session session; // Defina os dados de configuração da sessão session.server.host_name = SMTP_HOST; session.server.port = SMTP_PORT; session.login.email = AUTOR_EMAIL; session.login.password = AUTOR_SENHA; session.login.user_domain = ""; // Defina o tempo de configuração do NTP session.time.ntp_server = F("time.google.com"); // Utilizado o NTP do Google: // https://developers.google.com/time session.time.gmt_offset = -3; // define o deslocamento em segundos // do fuso horário local em relação ao // GMT do Meridiano de Greenwich. session.time.day_light_offset = 0; // define o deslocamento em segundos do // fuso horário local. Este valor costuma // ser 3600 para horário de verão +1h ou // 0 para fusos sem horário de verão. // Instanciação do objeto da classe de mensagem SMTP_Message message; // Definição os cabeçalhos das mensagens message.sender.name = "Michel Galvão"; message.sender.email = AUTOR_EMAIL; message.subject = "Teste de E-mail com Anexo"; message.addRecipient("Michel Galvão", "<O_email_destinatario>"); message.text.content = messageTXT.c_str(); // O conjunto de caracteres de mensagem de texto html, por exemplo: // us-ascii // utf-8 // utf-7 // O valor padrão é utf-8 message.text.charSet = "utf-8"; // A codificação de transferência de conteúdo. Ex: // enc_7bit ou "7bit" (não codificado) // enc_qp ou "quoted-printable" (codificado) // enc_base64 ou "base64" (codificado) // enc_binary ou "binary" (não codificado) // enc_8bit ou "8bit" (não codificado) // O valor padrão é "7bit" message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit; // A prioridade da mensagem: // esp_mail_smtp_priority_high ou 1 // esp_mail_smtp_priority_normal ou 3 // esp_mail_smtp_priority_low ou 5 // O valor padrão é esp_mail_smtp_priority_low message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low; // As notificações de status de entrega, Ex: // esp_mail_smtp_notify_never // esp_mail_smtp_notify_success // esp_mail_smtp_notify_failure // esp_mail_smtp_notify_delay // O valor padrão é esp_mail_smtp_notify_never message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; // O item de dados do anexo SMTP_Attachment att; // Defina as informações do anexo, por exemplo: nome do arquivo, tipo MIME, // caminho do arquivo, tipo de armazenamento do arquivo, codificação de // transferência e codificação de conteúdo. att.descr.filename = "exemplo de imagem.png"; att.descr.mime = "image/png"; //binary data att.file.path = "/exemplo de imagem.png"; att.file.storage_type = esp_mail_file_storage_type_flash; att.descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; // Adiciona anexo à mensagem message.addAttachment(att); message.resetAttachItem(att); // limpa os dados internos do item de anexo // para estar pronto para reutilização. att.descr.filename = "arquivo de exemplo.txt"; // nome do arquivo att.descr.mime = "text/plain"; // tipo do arquivo att.file.path = "/arquivo de exemplo.txt"; // o caminho do arquivo att.file.storage_type = esp_mail_file_storage_type_flash; // O tipo de armazenamento att.descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; //A opção de // codificar o conteúdo para transferência de dados. // Adiciona anexo à mensagem message.addAttachment(att); // Conecte-se ao servidor com a configuração da sessão if (!smtp.connect(&session)) return; // Começa a enviar e-mail e fecha a sessão if (!MailClient.sendMail(&smtp, &message)) { Serial.println("Erro ao enviar e-mail, " + smtp.errorReason()); } while (1); // loop infinito } void loop() {} /** Função de retorno de chamada para obter o status de envio de e-mail */ void smtpCallback(SMTP_Status status) { // Imprime o status atual Serial.println(status.info()); // Imprima o resultado do envio if (status.success()) { Serial.println("----------------"); ESP_MAIL_PRINTF("Mensagem enviada com sucesso: %d\n", status.completedCount()); ESP_MAIL_PRINTF("Falha na mensagem enviada: %d\n", status.failedCount()); Serial.println("----------------\n"); struct tm dt; for (size_t i = 0; i < smtp.sendingResult.size(); i++) { /* Obter o item de resultado */ SMTP_Result result = smtp.sendingResult.getItem(i); time_t ts = (time_t)result.timestamp; localtime_r(&ts, &dt); ESP_MAIL_PRINTF("Message No: %d\n", i + 1); ESP_MAIL_PRINTF("Status: %s\n", result.completed ? "sucesso" : "fracassado"); ESP_MAIL_PRINTF("Data/Hora: %d/%d/%d %d:%d:%d\n", dt.tm_year + 1900, dt.tm_mon + 1, dt.tm_mday, dt.tm_hour, dt.tm_min, dt.tm_sec); ESP_MAIL_PRINTF("Recebedor: %s\n", result.recipients); ESP_MAIL_PRINTF("Sujeito: %s\n", result.subject); } Serial.println("----------------\n"); } }
Este algoritmo é semelhante aos dois anteriores, tendo apenas a divergência que o algoritmo da função bool enviaEmail_TXT()
está dentro do void setup()
(no lugar onde era a chamada da função). Para enviar o e-mail junto de anexo, é criado um objeto da classe SMTP_Attachment
que armazenará as informações dos anexos. Em seguida, definimos as informações do primeiro anexo (uma imagem): nome do arquivo, tipo do arquivo, caminho do arquivo na SPIFFS, o tipo de armazenamento do arquivo e o tipo codificação de transferência e codificação de conteúdo. Após definirmos as informações do anexo, adicionamos o anexo ao e-mail.
Em seguida limpamos os dados internos do item de anexo para nós o reutilizarmos novamente para outro anexo.
Definimos as informações do segundo anexo (um arquivo de texto): nome do arquivo, tipo do arquivo, caminho do arquivo na SPIFFS, o tipo de armazenamento do arquivo e o tipo codificação de transferência e codificação de conteúdo. Após definirmos as informações do anexo, adicionamos o anexo ao e-mail..
Ao executar o programa no ESP32, a saída do Monitor Serial é:
15:28:07.659 -> Conectando à rede WiFi 15:28:07.799 -> .................. 15:28:11.403 -> WiFi conectado. 15:28:11.403 -> Acquiring time from NTP server... 15:28:11.403 -> 15:28:11.637 -> Connecting to SMTP server... 15:28:13.697 -> 15:28:13.697 -> SMTP server connected, wait for greeting... 15:28:14.105 -> 15:28:14.105 -> Sending greeting response... 15:28:14.406 -> 15:28:14.406 -> Logging in... 15:28:14.697 -> 15:28:14.697 -> Sending Email... 15:28:14.697 -> 15:28:14.697 -> Sending message header... 15:28:15.142 -> 15:28:15.142 -> Sending message body... 15:28:15.446 -> 15:28:15.446 -> Sending attachments... 15:28:15.446 -> 15:28:15.446 -> exemplo de imagem.png 15:28:15.561 -> upload "exemplo de imagem.png", 0% 15:28:15.561 -> upload "exemplo de imagem.png", 5% 15:28:15.561 -> upload "exemplo de imagem.png", 10% 15:28:15.655 -> upload "exemplo de imagem.png", 15% 15:28:15.655 -> upload "exemplo de imagem.png", 20% 15:28:15.655 -> upload "exemplo de imagem.png", 25% 15:28:15.702 -> upload "exemplo de imagem.png", 30% 15:28:15.749 -> upload "exemplo de imagem.png", 35% 15:28:15.782 -> upload "exemplo de imagem.png", 40% 15:28:15.830 -> upload "exemplo de imagem.png", 45% 15:28:15.830 -> upload "exemplo de imagem.png", 50% 15:28:15.830 -> upload "exemplo de imagem.png", 55% 15:28:15.923 -> upload "exemplo de imagem.png", 60% 15:28:15.923 -> upload "exemplo de imagem.png", 65% 15:28:15.970 -> upload "exemplo de imagem.png", 70% 15:28:16.003 -> upload "exemplo de imagem.png", 75% 15:28:16.037 -> upload "exemplo de imagem.png", 80% 15:28:16.079 -> upload "exemplo de imagem.png", 85% 15:28:16.125 -> upload "exemplo de imagem.png", 90% 15:28:16.172 -> upload "exemplo de imagem.png", 95% 15:28:16.206 -> upload "exemplo de imagem.png", 100% 15:28:16.206 -> 15:28:16.206 -> arquivo de exemplo.txt 15:28:16.308 -> upload "arquivo de exemplo.txt", 0% 15:28:16.308 -> upload "arquivo de exemplo.txt", 7% 15:28:16.308 -> upload "arquivo de exemplo.txt", 15% 15:28:16.308 -> upload "arquivo de exemplo.txt", 23% 15:28:16.308 -> upload "arquivo de exemplo.txt", 31% 15:28:16.308 -> upload "arquivo de exemplo.txt", 39% 15:28:16.308 -> upload "arquivo de exemplo.txt", 47% 15:28:16.308 -> upload "arquivo de exemplo.txt", 55% 15:28:16.308 -> upload "arquivo de exemplo.txt", 63% 15:28:16.308 -> upload "arquivo de exemplo.txt", 71% 15:28:16.308 -> upload "arquivo de exemplo.txt", 78% 15:28:16.308 -> upload "arquivo de exemplo.txt", 86% 15:28:16.308 -> upload "arquivo de exemplo.txt", 94% 15:28:16.308 -> upload "arquivo de exemplo.txt", 100% 15:28:16.308 -> 15:28:16.308 -> Finishing the message sending... 15:28:17.162 -> 15:28:17.162 -> Closing the session... 15:28:17.470 -> 15:28:17.470 -> Message sent successfully 15:28:17.504 -> 15:28:17.504 -> ---------------- 15:28:17.504 -> Mensagem enviada com sucesso: 1 15:28:17.504 -> Falha na mensagem enviada: 0 15:28:17.504 -> ---------------- 15:28:17.504 -> 15:28:17.504 -> Message No: 1 15:28:17.504 -> Status: sucesso 15:28:17.504 -> Data/Hora: 2022/4/4 15:28:13 15:28:17.504 -> Recebedor: ls⸮? 15:28:17.504 -> Sujeito: ⸮⸮⸮? 15:28:17.504 -> ---------------- 15:28:17.504 ->
No Gmail do endereço do destinatário, é recebido o e-mail enviado pelo ESP32:
Material necessário para o projeto E-mail de Abertura de Porta:
Tendo já estes materiais, monte o circuito de acordo com o seguinte esquemático:
Na parte superior direita de uma porta, está fixado um suporte de alumínio que é mais largo que o próprio sensor ultrassônico.
O ESP32 e seus sensores estão instalados em uma parede (fixa) na parte superior de uma porta.
Para este projeto, além da biblioteca ESP Mail Client (instruções de instalação descritas anteriormente), é necessário ter a biblioteca HCSR04 ultrasonic sensor.
Para instalá-la na Arduino IDE:
Esta biblioteca permite que uma placa Arduino use um ou mais módulos HCSR04 para obter a distância atual em cm.
Após instalar a biblioteca, carregue o seguinte programa para o ESP32, substituindo:
<O_SSID_de_sua_rede_WiFi>
para o SSID de sua rede WiFi;<A_senha_de_sua_rede_WiFi>
para a senha de sua rede WiFi;<O_email_remetente>
para o seu e-mail cadastrado em Senhas de app;<A_senha_de_app_do_email_remetente>
para a Senha de app do e-mail;<O_email_destinatario>
para o endereço de e-mail ao qual irá enviar o e-mail;/****************************************************************************** Alarme de porta com notificação por e-mail com ESP32 Sketch Principal Criado em 31 mar. 2022 por Michel Galvão Eletrogate - Loja de Arduino \\ Robótica \\ Automação \\ Apostilas \\ Kits https://www.eletrogate.com/ ******************************************************************************/ // Inclusão da(s) biblioteca(s) #include <WiFi.h> #include <ESP_Mail_Client.h> #include <HCSR04.h> #define TRIGGER_PIN 4 #define ECHO_PIN 5 #define PIN_BUZZER 16 // Configurações da rede WiFi à se conectar #define WIFI_SSID "<O_SSID_de_sua_rede_WiFi>" #define WIFI_PASSWORD "<A_senha_de_sua_rede_WiFi>" // Configurações do SMTP host #define SMTP_HOST "smtp.gmail.com" // SMTP host #define SMTP_PORT 465 // SMTP port // As credenciais de login #define AUTOR_EMAIL "<O_email_remetente>" #define AUTOR_SENHA "<A_senha_de_app_do_email_remetente>" // E-mail do destinatário #define DESTINATARIO_NOME "ADM Alarme" #define DESTINATARIO_EMAIL "<O_email_destinatario>" // Objeto para leitura de distância por ultrassom HCSR04 ultrasonic(TRIGGER_PIN, ECHO_PIN); // O objeto de sessão SMTP usado para envio de e-mail SMTPSession smtp; // Variáveis Globais const int segundosDeAlarme = 15000; // 15 segundos de alarme tocando, mesmo // após a porta ter sido fechada. unsigned long startAlarm;// controle de temporizador de quanto tempo // o alarme deve ficar tocando. bool alarmeAtivado; // controla se o alarme deve ou não tocar bool permiteEnvioEmail = false; // controle se deve ou não enviar e-mail. Este // controle permite que somente um e-mail seja // enviado a cada abertura da porta, mesmo que o // tempo de alarme pré-defindo seja ultrapassado. // Função de retorno de chamada para obter o status de envio de e-mail void smtpCallback(SMTP_Status status); bool enviaEmail_TXT(String nomeRemetente, String emailRemetente, String senhaRemetente, String assunto, String nomeDestinatario, String emailDestinatario, String messageTXT, String stmpHost, int stmpPort); // Função de envio de e-mail void setup() { // Inicia Serial Serial.begin(115200); Serial.println(); delay(1000); pinMode(PIN_BUZZER, OUTPUT); digitalWrite(PIN_BUZZER, HIGH); delay(100); digitalWrite(PIN_BUZZER, LOW); // Inicia conexão WiFi Serial.println("Conectando à rede WiFi"); WiFi.begin(WIFI_SSID, WIFI_PASSWORD); while (WiFi.status() != WL_CONNECTED) // Enquanto o status de conexão ao WiFi // não for bem sucedido, ... { Serial.print("."); delay(200); } // Mostra na Serial que a conexão está realizada Serial.println("\nWiFi conectado."); Serial.println(); digitalWrite(PIN_BUZZER, HIGH); delay(1000); digitalWrite(PIN_BUZZER, LOW); // Habilita a depuração via porta serial: // 0: nenhuma depuração // 1: deburação básica smtp.debug(0); // Define a função de retorno de chamada para obter os resultados de envio smtp.callback(smtpCallback); } void loop() { if (alarmeAtivado) { // se o alarme deve tocar, ... Serial.println("Alarme executando"); // Toca o alarme digitalWrite(PIN_BUZZER, LOW); delay(100); digitalWrite(PIN_BUZZER, HIGH); delay(200); if (millis() - startAlarm >= segundosDeAlarme) // se o tempo do alarme // pré-defindo for // ultrapassado, ... { alarmeAtivado = false; // não deixa o alarme tocar mais digitalWrite(PIN_BUZZER, LOW); // desliga o buzzer startAlarm = millis(); // atualiza o tempo do controle de temporizador } } else // se não (alarme NÃO deve tocar), ... { float distanciaCm = ultrasonic.dist(); // calcula a distância em centímetros. startAlarm = millis(); // atualiza o tempo do controle de temporizador Serial.print("distanciaCm: "); Serial.println(distanciaCm); if (distanciaCm >= 17) // se a distância for maior ou igual à 17 cm, ... { alarmeAtivado = true; // deixa o alarme if (permiteEnvioEmail == true) // se deve e-mail, ... { enviaEmail_TXT("ESP32 Alarme de Porta", AUTOR_EMAIL, AUTOR_SENHA, "Alarme da Porta Ativado", DESTINATARIO_NOME, DESTINATARIO_EMAIL, "Foi detectado a abertura da porta", SMTP_HOST, SMTP_PORT); // envia o e-mail com os dados em parâmetros permiteEnvioEmail = false; // não deixa enviar e-mail } } else // se não, ... { permiteEnvioEmail = true; // deixa enviar e-mail } delay(100); // pausa de 0,1 segundos } } bool enviaEmail_TXT(String nomeRemetente, String emailRemetente, String senhaRemetente, String assunto, String nomeDestinatario, String emailDestinatario, String messageTXT, String stmpHost, int stmpPort) { // Objeto para declarar os dados de configuração da sessão ESP_Mail_Session session; // Defina os dados de configuração da sessão session.server.host_name = stmpHost; session.server.port = stmpPort; session.login.email = emailRemetente; session.login.password = senhaRemetente; session.login.user_domain = ""; // Defina o tempo de configuração do NTP session.time.ntp_server = F("time.google.com"); // Utilizado o NTP do Google: // https://developers.google.com/time session.time.gmt_offset = -3; session.time.day_light_offset = 0; // Instanciação do objeto da classe de mensagem SMTP_Message message; // Definição os cabeçalhos das mensagens message.sender.name = nomeRemetente; message.sender.email = emailRemetente; message.subject = assunto; message.addRecipient(nomeDestinatario, emailDestinatario); message.text.content = messageTXT.c_str(); // O conjunto de caracteres de mensagem de texto html, por exemplo: // us-ascii // utf-8 // utf-7 // O valor padrão é utf-8 message.text.charSet = "utf-8"; // A codificação de transferência de conteúdo. Ex: // enc_7bit ou "7bit" (não codificado) // enc_qp ou "quoted-printable" (codificado) // enc_base64 ou "base64" (codificado) // enc_binary ou "binary" (não codificado) // enc_8bit ou "8bit" (não codificado) // O valor padrão é "7bit" message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit; // A prioridade da mensagem: // esp_mail_smtp_priority_high ou 1 // esp_mail_smtp_priority_normal ou 3 // esp_mail_smtp_priority_low ou 5 // O valor padrão é esp_mail_smtp_priority_low message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low; // As notificações de status de entrega, Ex: // esp_mail_smtp_notify_never // esp_mail_smtp_notify_success // esp_mail_smtp_notify_failure // esp_mail_smtp_notify_delay // O valor padrão é esp_mail_smtp_notify_never message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; // Conecte-se ao servidor com a configuração da sessão if (!smtp.connect(&session)) return false; // Começa a enviar e-mail e fecha a sessão if (!MailClient.sendMail(&smtp, &message)) { Serial.println("Erro ao enviar e-mail, " + smtp.errorReason()); return false; } return true; } /* Função de retorno de chamada para obter o status de envio de e-mail */ void smtpCallback(SMTP_Status status) { /* Imprima o status atual */ Serial.println(status.info()); /* Imprima o resultado do envio */ if (status.success()) { Serial.println("----------------"); ESP_MAIL_PRINTF("Mensagem enviada com sucesso: %d\n", status.completedCount()); ESP_MAIL_PRINTF("Falha na mensagem enviada: %d\n", status.failedCount()); Serial.println("----------------\n"); struct tm dt; for (size_t i = 0; i < smtp.sendingResult.size(); i++) { /* Obter o item de resultado */ SMTP_Result result = smtp.sendingResult.getItem(i); time_t ts = (time_t)result.timestamp; localtime_r(&ts, &dt); ESP_MAIL_PRINTF("Message No: %d\n", i + 1); ESP_MAIL_PRINTF("Status: %s\n", result.completed ? "sucesso" : "fracassado"); ESP_MAIL_PRINTF("Data/Hora: %d/%d/%d %d:%d:%d\n", dt.tm_year + 1900, dt.tm_mon + 1, dt.tm_mday, dt.tm_hour, dt.tm_min, dt.tm_sec); ESP_MAIL_PRINTF("Recebedor: %s\n", result.recipients); ESP_MAIL_PRINTF("Sujeito: %s\n", result.subject); } Serial.println("----------------\n"); } }
O código começa incluindo as bibliotecas:
Em seguida, definimos os pinos do Sensor ultrassônico e do buzzer.
Em seguida, definimos o SSID e a senha da rede WiFi.Também definimos o endereço do host e a porta do host SMTP. Em seguida, definimos o endereço e a senha do e-mail ao qual será o remetente. Também definimos o nome e o e-mail do destinatário.
Instanciamos, também, os objetos das classes responsáveis pelo sensor ultrassônico e pelo envio de e-mail.
Declaramos as variáveis globais.
Criamos os protótipos das funções utilizadas no algoritmo.
Em void setup()
, iniciamos a Serial.
Iniciamos o pino do buzzer.
E também iniciamos a conexão WiFi.
Após a conexão de WiFi ser bem sucedida, indicamos isso através da Serial e do buzzer.
Ainda em void setup()
, desabilitamos a depuração via Serial e definimos a função stmpCallback
como callback de resultado de envio.
Em void loop()
, verificamos se a variável de controle se o alarme deve ou não tocar está com o valor true
. Caso esteja com este valor, tocamos o buzzer para sinalizar que a porta foi aberta. Caso o tempo pré-definido de duração da execução do alarme (definido como 15 segundos nas variáveis globais) seja ultrapassado, desligamos o buzzer, damos o valor false
à variável de controle se o alarme deve ou não tocar e atualizamos o valor da variável de temporizador com o valor de millis()
.
Caso o valor da variável de controle se o alarme deve ou não tocar estiver com o valor false
, fazemos a leitura de distância do sensor ultrassônico em centímetros e atualizamos o valor da variável de temporizador com o valor de millis()
.
Caso a leitura de distância do sensor ultrassônico seja igual ou maior que 17 centímetros, damos o valor true
à variável de controle se o alarme deve ou não tocar. Caso a variável de controle se deve ou não enviar e-mail tenha o valor true
, fazemos o envio de e-mail de notificação e em seguida damos o valor false
à variável de controle se deve ou não enviar e-mail.
Caso a leitura de distância do sensor ultrassônico seja menor que 17 centímetros, permitimos o envio de e-mail.
Por fim, damos um atraso de 100 milissegundos.
Ao alimentar o ESP32, é tentado à conexão WiFi. Se houver algum reinicio no ESP32 (como por exemplo, ao for detectado Brownout detector was triggered), o buzzer irá ficar sendo acionado a cada 100 milissegundos.
Após a conexão bem-sucedida do ESP32, e a distância detectada for maior que 17 cm (quando a porta for aberta) o ESP32 enviará um único e-mail de alerta de porta aberta e em seguida disparará o Buzzer.
Enquanto a porta ficar aberta, o alarme ficará acionada mas não enviará novos e-mails. Após fechar a porta, o buzzer soará ainda por 15 segundos. Se uma nova abertura de porta for detectada, um novo e-mail será enviado e o Buzzer será disparado. Este ciclo será repetido sempre.
Veja, no vídeo abaixo, o funcionamento prático do projeto:
Antes do acionamento do alarme, no Gmail do destinatário foi recebido o e-mail de alerta:
Com os conceitos aprendidos neste post, é possível criar projetos mais avançados, como o envio de e-mail de alerta, e-mail de status, e-mail contendo informações (como leitura do sensor), e assim por diante. Ainda, é possível desenvolver projetos para enviar uma foto tirada pelo Módulo ESP32-CAM com Camera OV2640 2MP por e-mail após o acionamento de algum alarme. Curtiu o post? Avalie e deixe um comentário! Siga-nos também no Instagram e nos marque quando fizer algum projeto nosso: @eletrogate. Até a próxima!
Conheça a Metodologia Eletrogate e ofereça aulas de robótica em sua escola!
|
A Eletrogate é uma loja virtual de componentes eletrônicos do Brasil e possui diversos produtos relacionados à Arduino, Automação, Robótica e Eletrônica em geral.
Conheça a Metodologia Eletrogate e Lecione um Curso de Robótica nas Escolas da sua Região!