esp8266 检测有人发送邮件
esp8266 检测有人发送邮件
用 esp8266 当感知到人体活动时,在中断函数中记录一个标志变量,然后 loop 循环判断标志变量是否为 true,如果是则发送邮件通知。
源代码
邮件发送代码做了部分优化
//To use send Email for qq to port 465 (SSL)#include <Arduino.h>#if defined(ESP32) #include <WiFi.h>#elif defined(ESP8266) #include <ESP8266WiFi.h>#endif#include <ESP_Mail_Client.h>// PIR OUTPUT端口 D6 GPIO12 LED端口 D4 GPIO2const int LED = 2;const int PIR_sensor = 12;// 获取当前时间unsigned long now = millis();// 上一次触发中断的时间unsigned long lastTrigger = 0;// boolean humanTrigger = false;/* wifi ssid和密码 */#define WIFI_SSID "xxxx"#define WIFI_PASSWORD "xxxxxx"/* qq 邮箱的 smtp 地址和端口号 */#define SMTP_HOST "smtp.qq.com"#define SMTP_PORT 465/* 你的邮箱和授权码 授权码是QQ邮箱推出的,用于登录第三方客户端的专用密码。 如何获取授权码 https://service.mail.qq.com/cgi-bin/help?subtype=1&&id=28&&no=1001256*/#define AUTHOR_EMAIL "xxxxx@qq.com"#define AUTHOR_PASSWORD "xxxxxx"/* 接收人邮箱地址 email*/#define RECIPIENT_EMAIL "xxxxxxx@qq.com"/* 定义 smtp session 对象*/SMTPSession smtp;ESP_Mail_Session session;/* 获取邮件发送状态的回调函数 */void getSmtpStatusCallback(SMTP_Status status);// 检测人体感应的中断触发函数,将LED置为高电平ICACHE_RAM_ATTR void detectHuman() { Serial.println("Human Detected!!!"); digitalWrite(LED HIGH); humanTrigger = true;}void irSetup(){ // 将人体感应数据口连接的IO口设置为输入上拉模式,使引脚即使在未连接外部组件的时候也能保持确定的逻辑电平。 pinMode(PIR_sensor INPUT_PULLUP); // 将人体感应数据口连接的IO口设置为中断模式 赋值中断函数和将中断模式设置为RISING(当引脚由低电平变为高电平时,触发中断) attachInterrupt(digitalPinToInterrupt(PIR_sensor) detectHuman RISING); pinMode(LED OUTPUT); digitalWrite(LED LOW);}void wifiSetup(){ Serial.println(); Serial.print("连接 Wifi"); WiFi.begin(WIFI_SSID WIFI_PASSWORD); while (WiFi.status() != WL_CONNECTED){ Serial.print("."); delay(200); } Serial.println(""); Serial.println("WiFi 连接成功."); Serial.println("IP 地址: "); Serial.println(WiFi.localIP()); Serial.println();}void smtpSetup(){ /* smtp开启debug,debug信息输出到串口 */ smtp.debug(0); /* 注册回调函数,获取邮件发送状态 */ smtp.callback(getSmtpStatusCallback); /* 设置smtp 相关参数, host port等 */ session.server.host_name = SMTP_HOST; session.server.port = SMTP_PORT; session.login.email = AUTHOR_EMAIL; session.login.password = AUTHOR_PASSWORD; session.login.user_domain = ""; /* 连接smtp服务器 */ if (!smtp.connect(&session)) return;}/* 获取发送状态的回调函数 */void getSmtpStatusCallback(SMTP_Status status){ /* 输出邮件发送状态信息 */ Serial.println(status.info()); /*状态获取成功,打印状态信息 */ if (status.success()){ Serial.println("----------------"); ESP_MAIL_PRINTF("邮件发送成功个数: %d\n" status.completedCount()); ESP_MAIL_PRINTF("邮件发送失败个数: %d\n" status.failedCount()); Serial.println("----------------\n"); struct tm dt; for (size_t i = 0; i < smtp.sendingResult.size(); i++){ /* 依次获取发送邮件状态 */ SMTP_Result result = smtp.sendingResult.getItem(i); time_t ts = (time_t)result.timestamp; localtime_r(&ts &dt); ESP_MAIL_PRINTF("收件人: %s邮件发送状态信息\n" result.recipients); ESP_MAIL_PRINTF("状态: %s\n" result.completed ? "success" : "failed"); ESP_MAIL_PRINTF("发送时间: %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("邮件标题: %s\n" result.subject); } Serial.println("----------------\n"); }}void emailSendHtml(char* subject char* recipient String htmlMsg){ /* 定义smtp message消息类 */ SMTP_Message message; /* 定义邮件消息类的名称,发件人,标题和添加收件人 */ message.sender.name = "Esp8266er"; message.sender.email = AUTHOR_EMAIL; message.subject = subject; message.addRecipient("Sara" recipient); message.html.content = htmlMsg.c_str(); message.html.content = htmlMsg.c_str(); message.text.charSet = "us-ascii"; message.html.transfer_encoding = Content_Transfer_Encoding::enc_7bit; /* 调用发送邮件函数,失败的话,获取失败信息 */ if (!MailClient.sendMail(&smtp &message)) Serial.println("发送邮件失败,失败原因是 " + smtp.errorReason());}void setup(){ Serial.begin(115200); wifiSetup(); irSetup(); smtpSetup(); }void loop(){ if (humanTrigger) { String htmlMsg = "<div style=\"color:#2f4468;\"><h1>Human Detected!!!</h1><p>Send from Esp8266er</p></div>"; emailSendHtml("Esp8266er Email" RECIPIENT_EMAIL htmlMsg); humanTrigger = false; }}
邮件示例
如果将发送邮件放到中断函数里面,板子会不断重启,邮件发送不出去,初步猜测应该是发送邮件有一定的时间,放在中断函数阻塞时间太长了,导致触发了芯片的软件狗重置。