1、主要功能
自动配网,smartConfig 配网方式,断网断电重连
自动连接 mqtt 服务器,接收 mqtt 命令进行拍照动作,并将照片保存 TF 卡和发送照片
到自己的邮箱
局域网 WEB 界面界面操控,可旋转、拍照、查看最近一次拍摄的照片
2、参考资料
https://github.com/RuiSantosdotme/ESP32-CAM-Arduino-IDE
https://github.com/mobizt/ESP32-Mail-Client
https://blog.csdn.net/solar_Lan/article/details/80050066?ops_requ
est_misc=%257B%2522request%255Fid%2522%253A%252215970742061972484
6462417%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255
Fall.%2522%257D&request_id=159707420619724846462417&biz_id=0&utm_
medium=distribute.pc_search_result.none-task-blog-2~all~first_ran
k_ecpm_v3~pc_rank_v3-13-80050066.pc_ecpm_v3_pc_rank_v3&utm_term=e
sp32%2Bmqtt+arduino&spm=1018.2118.3001.4187
http://www.lingsky.net/post/2017/04/20/esp8266-smartconfig-wifi
https://blog.csdn.net/chenchen2360060/article/details/107589305
3、主要代码
需要更改的是里面的 mqtt 服务器 ip 和 port,还有就是你的邮件服务器,发件人邮件名称,
邮件授权码,还有最后的是收件人的邮箱,同时自动配网 smartConfig 在第一次需要收手机
下载自动配网 app,苹果是 esptouch,安卓的应该也有类似的。
/*********
Rui Santos
Complete
project
details
at
https://RandomNerdTutorials.com/esp32-cam-take-photo-display-web-server/
IMPORTANT!!!
- Select Board "AI Thinker ESP32-CAM"
- GPIO 0 must be connected to GND to upload a sketch
- After connecting GPIO 0 to GND, press the ESP32-CAM on-board RESET button to put your
board in flashing mode
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
*********/
// SD Card ESP32
#include "SD_MMC.h"
#include "WiFi.h"
#include "time.h"
#include "esp_camera.h"
#include "esp_timer.h"
#include "img_converters.h"
#include "Arduino.h"
#include "soc/soc.h"
#include "soc/rtc_cntl_reg.h"
#include "driver/rtc_io.h"
#include
#include
#include
#include
#include
#include "ESP32_MailClient.h"
#include
const char* mqttServer = "175.28.178.53";
const int mqttPort = 1883;
const char* mqttUser = "";
const char* mqttPassword = "";
// Disable brownour problems
// Disable brownour problems
// read and write from flash memory
WiFiClient espClient;
PubSubClient client(espClient);
// define the number of bytes you want to access
#define EEPROM_SIZE 40
// Create AsyncWebServer object on port 80
AsyncWebServer server(80);
//The Email Sending data object contains config and data to send
SMTPData smtpData;
//Callback function to get the Email sending status
void sendCallback(SendStatus info);
boolean takeNewPhoto = false;
const char* ntpServer = "pool.ntp.org";
const long
const int
gmtOffset_sec = 28800;
daylightOffset_sec = 0;
// Photo File Name to save in SPIFFS
#define FILE_PHOTO "/photo.jpg"
32
// OV2640 camera module pins (CAMERA_MODEL_AI_THINKER)
#define PWDN_GPIO_NUM
#define RESET_GPIO_NUM
#define XCLK_GPIO_NUM
#define SIOD_GPIO_NUM
#define SIOC_GPIO_NUM
#define Y9_GPIO_NUM
#define Y8_GPIO_NUM
#define Y7_GPIO_NUM
#define Y6_GPIO_NUM
#define Y5_GPIO_NUM
#define Y4_GPIO_NUM
#define Y3_GPIO_NUM
#define Y2_GPIO_NUM
#define VSYNC_GPIO_NUM
#define HREF_GPIO_NUM
#define PCLK_GPIO_NUM
-1
0
26
27
35
34
39
36
21
19
18
5
25
23
22
// Keep track of number of pictures
unsigned int pictureNumber = 0;
//Stores the camera configuration parameters
camera_config_t config;
const char index_html[] PROGMEM = R"rawliteral(
ESP32-CAM Last Photo
It might take more than 5 seconds to capture a photo.
)rawliteral";
void setup() {
// Serial port for debugging purposes
Serial.begin(115200);
if (!autoConfig())
{
Serial.println("Start module");
smartConfig();
}
client.setServer(mqttServer, mqttPort);
client.setCallback(callback);
while (!client.connected()) {
Serial.println("Connectingto MQTT...");
if (client.connect("ESP32Client", mqttUser, mqttPassword )) {
Serial.println("connected");
} else {
Serial.print("failedwith state ");
Serial.print(client.state());
delay(2000);
}
}
client.subscribe("esp32cam");
//init and get the time
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
if (!SPIFFS.begin(true)) {
Serial.println("An Error has occurred while mounting SPIFFS");
ESP.restart();
}
else {
delay(500);
Serial.println("SPIFFS mounted successfully");
}
// Print ESP32 Local IP Address
Serial.print("IP Address: http://");
Serial.println(WiFi.localIP());
// Turn-off the 'brownout detector'
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);
//Initialize the camera
Serial.print("Initializing the camera module...");
configInitCamera();
Serial.println("Ok!");
//Initialize MicroSD
Serial.print("Initializing the MicroSD card module... ");
initMicroSDCard();
// Route for root / web page
server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
request->send_P(200, "text/html", index_html);
});
server.on("/capture", HTTP_GET, [](AsyncWebServerRequest * request) {
takeNewPhoto = true;
request->send_P(200, "text/plain", "Taking Photo");
});
server.on("/saved-photo", HTTP_GET, [](AsyncWebServerRequest * request) {
request->send(SPIFFS, FILE_PHOTO, "image/jpg", false);
});
// Start server
server.begin();
}
void printLocalTime()
{
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
Serial.println("Failed to obtain time");
return;
}
//Serial.println(&timeinfo, "%A, %Y-%m-%d %H:%M:%S");
const int& sec = timeinfo.tm_sec;
const int& mit = timeinfo.tm_min;
if (sec == 0 && mit % 5 == 0) {
capturePhotoSaveSpiffs();
sendM();
}
}
/**
一键配网关键代码
*/
void smartConfig()
{
WiFi.mode(WIFI_STA);
Serial.println("\r\nWait for Smartconfig");
delay(2000);
// 等待配网
WiFi.beginSmartConfig();
while (1)
{
Serial.print(".");
delay(500);
if (WiFi.smartConfigDone())
{
Serial.println("SmartConfig Success");
Serial.printf("SSID:%s\r\n", WiFi.SSID().c_str());
Serial.printf("PSW:%s\r\n", WiFi.psk().c_str());
WiFi.setAutoConnect(true);
break;
// 设置自动连接