This tutorial shows how to send captured photos from the ESP32-CAM to your email account using an SMTP Server. We’ll show you a simple example that takes a photo when the ESP32 boots and sends it as an attachment in an email. The last photo taken is temporarily saved in the ESP32 LittleFS filesystem.
Updated 19 September 2023.
To make this project work, the ESP32-CAM needs to be connected to a router with access to the internet – needs to be connected to your local network.
This project is compatible with any ESP32 camera board with the OV2640 camera. You just need to make sure you use the right pin assignment for the board you’re using: ESP32-CAM Camera Boards: Pin and GPIOs Assignment Guide.
ESP Mail Client Library
To send emails with the ESP32-CAM, we’ll use the ESP-Mail-Client library. This library allows the ESP32 to send and receive emails with or without attachments via SMTP and IMAP servers.
In this project, we’ll use SMTP to send an email with an attachment. The attachment is a photo taken with the ESP32-CAM.
SMTP means Simple Mail Transfer Protocol and it is an internet standard for email transmission. To send emails through code, you need to know your SMTP server details. Each email provider has a different SMTP server.
Installing the ESP-Mail-Client Library
Before proceeding with this tutorial, you need to install the ESP-Mail-Client library.
Go to Sketch > Include Library > Manage Libraries and search for ESP Mail Client. Install the ESP Mail Client library by Mobizt.
Sender Email (New Account)
We recommend creating a new email account to send the emails to your main personal email address. Do not use your main personal email to send emails via ESP32. If something goes wrong in your code or if by mistake you make too many requests, you can be banned or have your account temporarily disabled.
We’ll use a newly created Gmail.com account to send the emails, but you can use any other email provider. The receiver email can be your personal email without any problem.
Create a Sender Email Account
Create a new email account for sending emails with the ESP32. If you want to use a Gmail account, go to this link to create a new one.
Create an App Password
You need to create an app password so that the ESP32 is able to send emails using your Gmail account. An App Password is a 16-digit passcode that gives a less secure app or device permission to access your Google Account. Learn more about sign-in with app passwords here.
An app password can only be used with accounts that have 2-step verification turned on.
- Open your Google Account.
- In the navigation panel, select Security.
- Under “Signing in to Google,” select 2-Step Verification > Get started.
- Follow the on-screen steps.
After enabling 2-step verification, you can create an app password.
- Open your Google Account.
- In the search panel, search for App Passwords.
- Open the App Passwords menu.
- Give a name to the app password, for example ESP. Then, click on Create. It will pop-up a window with a password that you’ll use with the ESP32 or ESP8266 to send emails. Save that password (even though it says you won’t need to remember it) because you’ll need it later.
It will pop-up a window with a password that you’ll use with the ESP32 to send emails. Save that password (even though it says you won’t need to remember it) because you’ll need it later.
Now, you should have an app password that you’ll use on the ESP32 code to send the emails.
If you’re using another email provider, check how to create an app password. You should be able to find the instructions with a quick google search “your_email_provider + create app password”.
Gmail SMTP Server Settings
If you’re using a Gmail account, these are the SMTP Server details:
- SMTP Server: smtp.gmail.com
- SMTP username: Complete Gmail address
- SMTP password: Your Gmail password
- SMTP port (TLS): 587
- SMTP port (SSL): 465
- SMTP TLS/SSL required: yes
Outlook SMTP Server Settings
For Outlook accounts, these are the SMTP Server settings:
- SMTP Server: smtp.office365.com
- SMTP Username: Complete Outlook email address
- SMTP Password: Your Outlook password
- SMTP Port: 587
- SMTP TLS/SSL Required: Yes
Live or Hotmail SMTP Server Settings
For Live or Hotmail accounts, these are the SMTP Server settings:
- SMTP Server: smtp.live.com
- SMTP Username: Complete Live/Hotmail email address
- SMTP Password: Your Windows Live Hotmail password
- SMTP Port: 587
- SMTP TLS/SSL Required: Yes
If you’re using another email provider, you need to search for its SMTP Server settings. Now, you have everything ready to start sending emails with the ESP32-CAM.
Code – ESP32-CAM Send Email
The following code takes a photo when the ESP32-CAM first boots and sends it to your email account. Before uploading the code, make sure you insert your sender email settings as well as your recipient email.
/*********
Rui Santos
Complete instructions at https://RandomNerdTutorials.com/esp32-cam-projects-ebook/
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*********/
#include "esp_camera.h"
#include "SPI.h"
#include "driver/rtc_io.h"
#include <ESP_Mail_Client.h>
#include <FS.h>
#include <WiFi.h>
// REPLACE WITH YOUR NETWORK CREDENTIALS
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
// To send Email using Gmail use port 465 (SSL) and SMTP Server smtp.gmail.com
// You need to create an email app password
#define emailSenderAccount "[email protected]"
#define emailSenderPassword "YOUR_EMAIL_APP_PASSWORD"
#define smtpServer "smtp.gmail.com"
#define smtpServerPort 465
#define emailSubject "ESP32-CAM Photo Captured"
#define emailRecipient "[email protected]"
#define CAMERA_MODEL_AI_THINKER
#if defined(CAMERA_MODEL_AI_THINKER)
#define PWDN_GPIO_NUM 32
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 0
#define SIOD_GPIO_NUM 26
#define SIOC_GPIO_NUM 27
#define Y9_GPIO_NUM 35
#define Y8_GPIO_NUM 34
#define Y7_GPIO_NUM 39
#define Y6_GPIO_NUM 36
#define Y5_GPIO_NUM 21
#define Y4_GPIO_NUM 19
#define Y3_GPIO_NUM 18
#define Y2_GPIO_NUM 5
#define VSYNC_GPIO_NUM 25
#define HREF_GPIO_NUM 23
#define PCLK_GPIO_NUM 22
#else
#error "Camera model not selected"
#endif
/* The SMTP Session object used for Email sending */
SMTPSession smtp;
/* Callback function to get the Email sending status */
void smtpCallback(SMTP_Status status);
// Photo File Name to save in LittleFS
#define FILE_PHOTO "photo.jpg"
#define FILE_PHOTO_PATH "/photo.jpg"
void setup() {
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector
Serial.begin(115200);
Serial.println();
// Connect to Wi-Fi
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi...");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
// Print ESP32 Local IP Address
Serial.print("IP Address: http://");
Serial.println(WiFi.localIP());
// Init filesystem
ESP_MAIL_DEFAULT_FLASH_FS.begin();
camera_config_t config;
config.ledc_channel = LEDC_CHANNEL_0;
config.ledc_timer = LEDC_TIMER_0;
config.pin_d0 = Y2_GPIO_NUM;
config.pin_d1 = Y3_GPIO_NUM;
config.pin_d2 = Y4_GPIO_NUM;
config.pin_d3 = Y5_GPIO_NUM;
config.pin_d4 = Y6_GPIO_NUM;
config.pin_d5 = Y7_GPIO_NUM;
config.pin_d6 = Y8_GPIO_NUM;
config.pin_d7 = Y9_GPIO_NUM;
config.pin_xclk = XCLK_GPIO_NUM;
config.pin_pclk = PCLK_GPIO_NUM;
config.pin_vsync = VSYNC_GPIO_NUM;
config.pin_href = HREF_GPIO_NUM;
config.pin_sccb_sda = SIOD_GPIO_NUM;
config.pin_sccb_scl = SIOC_GPIO_NUM;
config.pin_pwdn = PWDN_GPIO_NUM;
config.pin_reset = RESET_GPIO_NUM;
config.xclk_freq_hz = 20000000;
config.pixel_format = PIXFORMAT_JPEG;
config.grab_mode = CAMERA_GRAB_LATEST;
if(psramFound()){
config.frame_size = FRAMESIZE_UXGA;
config.jpeg_quality = 10;
config.fb_count = 1;
} else {
config.frame_size = FRAMESIZE_SVGA;
config.jpeg_quality = 12;
config.fb_count = 1;
}
// Initialize camera
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
Serial.printf("Camera init failed with error 0x%x", err);
return;
}
capturePhotoSaveLittleFS();
sendPhoto();
}
void loop() {
}
// Capture Photo and Save it to LittleFS
void capturePhotoSaveLittleFS( void ) {
// Dispose first pictures because of bad quality
camera_fb_t* fb = NULL;
// Skip first 3 frames (increase/decrease number as needed).
for (int i = 0; i < 3; i++) {
fb = esp_camera_fb_get();
esp_camera_fb_return(fb);
fb = NULL;
}
// Take a new photo
fb = NULL;
fb = esp_camera_fb_get();
if(!fb) {
Serial.println("Camera capture failed");
delay(1000);
ESP.restart();
}
// Photo file name
Serial.printf("Picture file name: %s\n", FILE_PHOTO_PATH);
File file = LittleFS.open(FILE_PHOTO_PATH, FILE_WRITE);
// Insert the data in the photo file
if (!file) {
Serial.println("Failed to open file in writing mode");
}
else {
file.write(fb->buf, fb->len); // payload (image), payload length
Serial.print("The picture has been saved in ");
Serial.print(FILE_PHOTO_PATH);
Serial.print(" - Size: ");
Serial.print(fb->len);
Serial.println(" bytes");
}
// Close the file
file.close();
esp_camera_fb_return(fb);
}
void sendPhoto( void ) {
/** Enable the debug via Serial port
* none debug or 0
* basic debug or 1
*/
smtp.debug(1);
/* Set the callback function to get the sending results */
smtp.callback(smtpCallback);
/* Declare the session config data */
Session_Config config;
/*Set the NTP config time
For times east of the Prime Meridian use 0-12
For times west of the Prime Meridian add 12 to the offset.
Ex. American/Denver GMT would be -6. 6 + 12 = 18
See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets
*/
config.time.ntp_server = F("pool.ntp.org,time.nist.gov");
config.time.gmt_offset = 0;
config.time.day_light_offset = 1;
/* Set the session config */
config.server.host_name = smtpServer;
config.server.port = smtpServerPort;
config.login.email = emailSenderAccount;
config.login.password = emailSenderPassword;
config.login.user_domain = "";
/* Declare the message class */
SMTP_Message message;
/* Enable the chunked data transfer with pipelining for large message if server supported */
message.enable.chunking = true;
/* Set the message headers */
message.sender.name = "ESP32-CAM";
message.sender.email = emailSenderAccount;
message.subject = emailSubject;
message.addRecipient("Sara", emailRecipient);
String htmlMsg = "<h2>Photo captured with ESP32-CAM and attached in this email.</h2>";
message.html.content = htmlMsg.c_str();
message.html.charSet = "utf-8";
message.html.transfer_encoding = Content_Transfer_Encoding::enc_qp;
message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_normal;
message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay;
/* The attachment data item */
SMTP_Attachment att;
/** Set the attachment info e.g.
* file name, MIME type, file path, file storage type,
* transfer encoding and content encoding
*/
att.descr.filename = FILE_PHOTO;
att.descr.mime = "image/png";
att.file.path = FILE_PHOTO_PATH;
att.file.storage_type = esp_mail_file_storage_type_flash;
att.descr.transfer_encoding = Content_Transfer_Encoding::enc_base64;
/* Add attachment to the message */
message.addAttachment(att);
/* Connect to server with the session config */
if (!smtp.connect(&config))
return;
/* Start sending the Email and close the session */
if (!MailClient.sendMail(&smtp, &message, true))
Serial.println("Error sending Email, " + smtp.errorReason());
}
// Callback function to get the Email sending status
void smtpCallback(SMTP_Status status){
/* Print the current status */
Serial.println(status.info());
/* Print the sending result */
if (status.success())
{
Serial.println("----------------");
Serial.printf("Message sent success: %d\n", status.completedCount());
Serial.printf("Message sent failled: %d\n", status.failedCount());
Serial.println("----------------\n");
struct tm dt;
for (size_t i = 0; i < smtp.sendingResult.size(); i++){
/* Get the result item */
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 ? "success" : "failed");
ESP_MAIL_PRINTF("Date/Time: %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("Recipient: %s\n", result.recipients.c_str());
ESP_MAIL_PRINTF("Subject: %s\n", result.subject.c_str());
}
Serial.println("----------------\n");
// You need to clear sending result as the memory usage will grow up.
smtp.sendingResult.clear();
}
}
How the Code Works
Continue reading to learn how the code works, or skip to the Demonstration section. Don’t forget to insert your network credentials and email settings in the code. Also, if you’re using a camera model other than an ESP32-CAM AI-Thinker, don’t forget to change the pin assignment.
Importing Libraries
Import the required libraries. The ESP3_Mail_Client.h is used to send emails, the FS.h is used to access and save files to LittleFS and the WiFi.h library is used to initialize Wi-Fi and connect your ESP32-CAM to your local network.
#include "esp_camera.h"
#include "SPI.h"
#include "driver/rtc_io.h"
#include <ESP_Mail_Client.h>
#include <FS.h>
#include <WiFi.h>
Network Credentials
Insert your network credentials in the following variables:
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
Email Settings
Type the email sender account on the emailSenderAccount variable and its password on the emailSenderPassword variable.
#define emailSenderAccount "[email protected]"
#define emailSenderPassword "SENDER_ACCOUNT_PASSWORD"
Insert the recipient’s email. This is the email that will receive the emails sent by the ESP32:
#define emailRecipient "[email protected]"
Insert your email provider SMTP settings on the following lines. We’re using the settings for a Gmail account. If you’re using a different email provider, replace with the corresponding SMTP settings.
#define smtpServer "smtp.gmail.com"
#define smtpServerPort 465
Write the email subject on the emailSubject variable.
#define emailSubject "ESP32-CAM Photo Captured"
Create a STMPSession object called smtp that contains the data to send via email and all the other configurations.
/* The SMTP Session object used for Email sending */
SMTPSession smtp;
The photo taken with the ESP32 camera will be temporarily saved in LittleFS under the name photo.jpg on the root directory.
#define FILE_PHOTO "photo.jpg"
#define FILE_PHOTO_PATH "/photo.jpg"
ESP32 Camera Pins
Define the pins used by your camera model. We’re using the ESP32-CAM AI-Thinker.
#define PWDN_GPIO_NUM 32
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 0
#define SIOD_GPIO_NUM 26
#define SIOC_GPIO_NUM 27
#define Y9_GPIO_NUM 35
#define Y8_GPIO_NUM 34
#define Y7_GPIO_NUM 39
#define Y6_GPIO_NUM 36
#define Y5_GPIO_NUM 21
#define Y4_GPIO_NUM 19
#define Y3_GPIO_NUM 18
#define Y2_GPIO_NUM 5
#define VSYNC_GPIO_NUM 25
#define HREF_GPIO_NUM 23
#define PCLK_GPIO_NUM 22
setup()
In the setup(), connect the ESP32 to Wi-Fi.
// Connect to Wi-Fi
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi...");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Print the ESP32-CAM IP address:
// Print ESP32 Local IP Address
Serial.print("IP Address: http://");
Serial.println(WiFi.localIP());
In the setup(), you initialize the filesystem using the ESP Mail Client library method. The default filesystem set in the library for the ESP32 is LittleFS (you can change the default in the library file ESP_Mail_FS.h).
// Init filesystem
ESP_MAIL_DEFAULT_FLASH_FS.begin();
The following lines configure the camera and set the camera settings:
camera_config_t config;
config.ledc_channel = LEDC_CHANNEL_0;
config.ledc_timer = LEDC_TIMER_0;
config.pin_d0 = Y2_GPIO_NUM;
config.pin_d1 = Y3_GPIO_NUM;
config.pin_d2 = Y4_GPIO_NUM;
config.pin_d3 = Y5_GPIO_NUM;
config.pin_d4 = Y6_GPIO_NUM;
config.pin_d5 = Y7_GPIO_NUM;
config.pin_d6 = Y8_GPIO_NUM;
config.pin_d7 = Y9_GPIO_NUM;
config.pin_xclk = XCLK_GPIO_NUM;
config.pin_pclk = PCLK_GPIO_NUM;
config.pin_vsync = VSYNC_GPIO_NUM;
config.pin_href = HREF_GPIO_NUM;
config.pin_sccb_sda = SIOD_GPIO_NUM;
config.pin_sccb_scl = SIOC_GPIO_NUM;
config.pin_pwdn = PWDN_GPIO_NUM;
config.pin_reset = RESET_GPIO_NUM;
config.xclk_freq_hz = 20000000;
config.pixel_format = PIXFORMAT_JPEG;
config.grab_mode = CAMERA_GRAB_LATEST;
if(psramFound()){
config.frame_size = FRAMESIZE_UXGA;
config.jpeg_quality = 10;
config.fb_count = 2;
} else {
config.frame_size = FRAMESIZE_SVGA;
config.jpeg_quality = 12;
config.fb_count = 1;
}
Initialize the camera.
// Initialize camera
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
Serial.printf("Camera init failed with error 0x%x", err);
return;
}
After initializing the camera, call the capturePhotoSaveLittleFS() and the sendPhoto() functions. These functions are defined at the end of the code.
capturePhotoSaveLittleFS() function
The capturePhotoSaveLittleFS() function captures a photo and saves it in the ESP32 LittleFS. In the following lines, you take a photo and save it in the framebuffer FB.
Note: sometimes, the first pictures taken with the ESP32-CAM are not good because the sensor has not adjusted the white balance yet. So, to make sure we get a good picture, we discard the first three pictures (that number may vary depending on your board, so adjust accordingly).
//Dispose first pictures because of bad quality
camera_fb_t* fb = NULL;
// Skip first 3 frames (increase/decrease number as needed).
for (int i = 0; i < 3; i++) {
fb = esp_camera_fb_get();
esp_camera_fb_return(fb);
fb = NULL;
}
// Take a new photo
fb = NULL;
fb = esp_camera_fb_get();
if(!fb) {
Serial.println("Camera capture failed");
delay(1000);
ESP.restart();
}
Then, create a new file in LitteFS where the photo will be saved.
Serial.printf("Picture file name: %s\n", FILE_PHOTO_PATH);
File file = LittleFS.open(FILE_PHOTO_PATH, FILE_WRITE);
Check if the file was successfully created. If not, print an error message.
if (!file) {
Serial.println("Failed to open file in writing mode");
}
If a new file was successfully created, “copy” the image from the buffer to that newly created file.
file.write(fb->buf, fb->len); // payload (image), payload length
Serial.print("The picture has been saved in ");
Serial.print(FILE_PHOTO_PATH);
Serial.print(" - Size: ");
Serial.print(fb->len);
Serial.println(" bytes");
Close the file and clear the buffer for future use.
file.close();
esp_camera_fb_return(fb);
sendPhoto() function
After having the photo successfully saved in LittleFS, we’ll send it via email by calling the sendPhoto() function. Let’s take a look at that function.
void sendPhoto( void ) {
Enable debugging via serial port for the email status:
smtp.debug(1);
Set the callback function to get the sending results:
smtp.callback(smtpCallback);
Declare an email session:
Session_Config config;
Configure the time so that the email is timestamped correctly. You may need to adjust the gmt_offset variable depending on your location.
/*Set the NTP config time
For times east of the Prime Meridian use 0-12
For times west of the Prime Meridian add 12 to the offset.
Ex. American/Denver GMT would be -6. 6 + 12 = 18
See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets
*/
config.time.ntp_server = F("pool.ntp.org,time.nist.gov");
config.time.gmt_offset = 0;
config.time.day_light_offset = 1;
Set the server host, port, sender email, and password for this email session:
/* Set the session config */
config.server.host_name = smtpServer;
config.server.port = smtpServerPort;
config.login.email = emailSenderAccount;
config.login.password = emailSenderPassword;
config.login.user_domain = "";
Declare a SMTP_Message class:
SMTP_Message message;
Set the message headers—sender name, email sender, subject, and recipient (you can change the recipient name):
/* Set the message headers */
message.sender.name = "ESP32-CAM";
message.sender.email = emailSenderAccount;
message.subject = emailSubject;
message.addRecipient("Sara", emailRecipient);
In the following lines, set the content of the message in the htmlMsg variable:
String htmlMsg = "<h2>Photo captured with ESP32-CAM and attached in this email.</h2>";
message.html.content = htmlMsg.c_str();
message.html.charSet = "utf-8";
message.html.transfer_encoding = Content_Transfer_Encoding::enc_qp;
Now, we need to take care of the attachments. Create an attachment:
SMTP_Attachment att;
Set the attachment info: document name, mime type, file path, and where the content is saved (in our case it is saved in flash (esp_mail_file_storage_type_flash)):
att.descr.filename = FILE_PHOTO;
att.descr.mime = "image/png";
att.file.path = FILE_PHOTO_PATH;
att.file.storage_type = esp_mail_file_storage_type_flash;
att.descr.transfer_encoding = Content_Transfer_Encoding::enc_base64;
Add the attachment to the message:
/* Add attachment to the message */
message.addAttachment(att);
Connect to the SMTP server:
/* Connect to server with the session config */
if (!smtp.connect(&config))
return;
Finally, the following lines send the message:
/* Start sending the Email and close the session */
if (!MailClient.sendMail(&smtp, &message, true))
Serial.println("Error sending Email, " + smtp.errorReason());
In this example, the email is sent once when the ESP32 boots, that’s why the loop() is empty.
void loop() {
}
To send a new email, you just need to reset your board (press the on-board RESET button).
Demonstration
After making the necessary changes to the code: camera pinout, sender’s email address, sender’s email password, recipient’s email address, and network credentials, you can upload the code to your board.
If you don’t know how to upload code to the ESP32-CAM, read the following post:
After uploading, open the Serial Monitor and press the ESP32-CAM RESET button. The ESP32 should connect to Wi-Fi, take a photo, save it in LittleFS, connect to the SMTP server, and send the email as shown below.
After a few seconds, you should have a new email from the ESP32-CAM in your inbox. As you can see in the image below, the sender’s email name is “ESP32-CAM” as we’ve defined in the code, and the subject “ESP32-CAM Photo Captured”.
Open the email and you should see a photo captured by the ESP32-CAM.
You can open or download the photo to see it in full size.
Wrapping Up
In this tutorial, you’ve learned how to send emails with photos taken with the ESP32-CAM. The example presented is as simple as possible: it takes a photo and sends it via email when the ESP32-CAM first boots. To send another email, you need to reset the board.
This project doesn’t have a practical application, but it is useful to understand how to send an email with an attachment. After this, it should be fairly easy to include this feature in your own ESP32-CAM projects.
Other ESP32-CAM projects you may like:
- ESP32-CAM Post Images to Local or Cloud Server using PHP (Photo Manager)
- ESP32-CAM HTTP POST Photos to Local or Cloud Server
- ESP32-CAM Take Photo and Save to MicroSD Card
- ESP32-CAM Take Photo and Display in Web Server
Learn more about the ESP32-CAM:
Thanks for reading.
Nice effort.
However, how can I trigger the proces by a web url?
Best regards
I think you can trigger it by a web url using IFTTT.
see: https://randomnerdtutorials.com/door-status-monitor-using-the-esp8266/
Caden,
Thanks for your reply.
I am not an expert in IFTTT.
Do you know if it is possible to ‘trigger’ the reset button remote with an IFTTT command which is required to start the capturing process?
Thanks for your help in advance.
BR
Arjen
Arjen, I did some research on IFTTT and they sadly don’t support sending data back to the ESP32-Cam chip, such as asking it to start capturing. I found another option, which would be to set up a server with the ESP32-Cam, and have it run a Event (handleRoot) when its address (Wifi.localIP()) is opened, or “triggered”.
The code would be:
/*********
Rui Santos
Complete instructions at https://RandomNerdTutorials.com/esp32-cam-projects-ebook/
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*********/
#include “esp_camera.h”
#include “SPI.h”
#include “driver/rtc_io.h”
#include “ESP32_MailClient.h”
#include <FS.h>
#include <SPIFFS.h>
#include <WiFi.h>
#include <ESP8266WebServer.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
// REPLACE WITH YOUR NETWORK CREDENTIALS
const char* ssid = “REPLACE_WITH_YOUR_SSID”;
const char* password = “REPLACE_WITH_YOUR_PASSWORD”;
const char* host = “maker.ifttt.com”;
//after you set up your account put your IFTTT key here. (see https://randomnerdtutorials.com/door-status-monitor-using-the-esp8266/)
const char* apiKey = “YOUR_IFTTT_API_KEY”;
// To send Email using Gmail use port 465 (SSL) and SMTP Server smtp.gmail.com
// YOU MUST ENABLE less secure app option https://myaccount.google.com/lesssecureapps?pli=1
#define emailSenderAccount “[email protected]”
#define emailSenderPassword “SENDER_ACCOUNT_PASSWORD”
#define smtpServer “smtp.gmail.com”
#define smtpServerPort 465
#define emailSubject “ESP32-CAM Photo Captured”
#define emailRecipient “[email protected]”
#define CAMERA_MODEL_AI_THINKER
#if defined(CAMERA_MODEL_AI_THINKER)
#define PWDN_GPIO_NUM 32
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 0
#define SIOD_GPIO_NUM 26
#define SIOC_GPIO_NUM 27
#define Y9_GPIO_NUM 35
#define Y8_GPIO_NUM 34
#define Y7_GPIO_NUM 39
#define Y6_GPIO_NUM 36
#define Y5_GPIO_NUM 21
#define Y4_GPIO_NUM 19
#define Y3_GPIO_NUM 18
#define Y2_GPIO_NUM 5
#define VSYNC_GPIO_NUM 25
#define HREF_GPIO_NUM 23
#define PCLK_GPIO_NUM 22
#else
#error “Camera model not selected”
#endif
// The Email Sending data object contains config and data to send
SMTPData smtpData;
// Photo File Name to save in SPIFFS
#define FILE_PHOTO “/photo.jpg”
void handleRoot() {
//take capture and send via email.
capturePhotoSaveSpiffs();
sendPhoto();
server.send(200, “text/plain”, “took capture and sent.”);
}
void handleNotFound() {
digitalWrite(led, 1);
String message = “File Not Found\n\n”;
message += “URI: “;
message += server.uri();
message += “\nMethod: “;
message += (server.method() == HTTP_GET) ? “GET” : “POST”;
message += “\nArguments: “;
message += server.args();
message += “\n”;
for (uint8_t i = 0; i < server.args(); i++) {
message += ” ” + server.argName(i) + “: ” + server.arg(i) + “\n”;
}
server.send(404, “text/plain”, message);
digitalWrite(led, 0);
}
void setup() {
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector
Serial.begin(115200);
Serial.println();
// Connect to Wi-Fi
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.print(“Connecting to WiFi…”);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(“.”);
}
Serial.println();
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
//opening this will trigger a capture
Serial.print(“IP Address: http://“);
Serial.println(WiFi.localIP());
camera_config_t config;
config.ledc_channel = LEDC_CHANNEL_0;
config.ledc_timer = LEDC_TIMER_0;
config.pin_d0 = Y2_GPIO_NUM;
config.pin_d1 = Y3_GPIO_NUM;
config.pin_d2 = Y4_GPIO_NUM;
config.pin_d3 = Y5_GPIO_NUM;
config.pin_d4 = Y6_GPIO_NUM;
config.pin_d5 = Y7_GPIO_NUM;
config.pin_d6 = Y8_GPIO_NUM;
config.pin_d7 = Y9_GPIO_NUM;
config.pin_xclk = XCLK_GPIO_NUM;
config.pin_pclk = PCLK_GPIO_NUM;
config.pin_vsync = VSYNC_GPIO_NUM;
config.pin_href = HREF_GPIO_NUM;
config.pin_sscb_sda = SIOD_GPIO_NUM;
config.pin_sscb_scl = SIOC_GPIO_NUM;
config.pin_pwdn = PWDN_GPIO_NUM;
config.pin_reset = RESET_GPIO_NUM;
config.xclk_freq_hz = 20000000;
config.pixel_format = PIXFORMAT_JPEG;
if(psramFound()){
config.frame_size = FRAMESIZE_UXGA;
config.jpeg_quality = 10;
config.fb_count = 2;
} else {
config.frame_size = FRAMESIZE_SVGA;
config.jpeg_quality = 12;
config.fb_count = 1;
}
// Initialize camera
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
Serial.printf(“Camera init failed with error 0x%x”, err);
return;
}
server.on(“/”, handleRoot);
server.onNotFound(handleNotFound);
server.begin();
Serial.println(“HTTP server started! Ready to take photos.”);
}
void loop() {
// in the original sketch this is empty.
//now we just keep the server up to date.
server.handleClient();
MDNS.update();
}
// Check if photo capture was successful
bool checkPhoto( fs::FS &fs ) {
File f_pic = fs.open( FILE_PHOTO );
unsigned int pic_sz = f_pic.size();
return ( pic_sz > 100 );
}
// Capture Photo and Save it to SPIFFS
void capturePhotoSaveSpiffs( void ) {
camera_fb_t * fb = NULL; // pointer
bool ok = 0; // Boolean indicating if the picture has been taken correctly
do {
// Take a photo with the camera
Serial.println(“Taking a photo…”);
fb = esp_camera_fb_get();
if (!fb) {
Serial.println("Camera capture failed");
return;
}
// Photo file name
Serial.printf("Picture file name: %s\n", FILE_PHOTO);
File file = SPIFFS.open(FILE_PHOTO, FILE_WRITE);
// Insert the data in the photo file
if (!file) {
Serial.println("Failed to open file in writing mode");
}
else {
file.write(fb->buf, fb->len); // payload (image), payload length
Serial.print("The picture has been saved in ");
Serial.print(FILE_PHOTO);
Serial.print(" - Size: ");
Serial.print(file.size());
Serial.println(" bytes");
}
// Close the file
file.close();
esp_camera_fb_return(fb);
// check if file has been correctly saved in SPIFFS
ok = checkPhoto(SPIFFS);
} while ( !ok );
}
void sendPhoto( void ) {
// Preparing email
Serial.println(“Sending email…”);
// Set the SMTP Server Email host, port, account and password
smtpData.setLogin(smtpServer, smtpServerPort, emailSenderAccount, emailSenderPassword);
// Set the sender name and Email
smtpData.setSender(“ESP32-CAM”, emailSenderAccount);
// Set Email priority or importance High, Normal, Low or 1 to 5 (1 is highest)
smtpData.setPriority(“High”);
// Set the subject
smtpData.setSubject(emailSubject);
// Set the email message in HTML format
smtpData.setMessage(”
Photo captured with ESP32-CAM and attached in this email.
“, true);
// Set the email message in text format
//smtpData.setMessage(“Photo captured with ESP32-CAM and attached in this email.”, false);
// Add recipients, can add more than one recipient
smtpData.addRecipient(emailRecipient);
//smtpData.addRecipient(emailRecipient2);
// Add attach files from SPIFFS
smtpData.addAttachFile(FILE_PHOTO, “image/jpg”);
// Set the storage type to attach files in your email (SPIFFS)
smtpData.setFileStorageType(MailClientStorageType::SPIFFS);
smtpData.setSendCallback(sendCallback);
// Start sending Email, can be set callback function to track the status
if (!MailClient.sendMail(smtpData))
Serial.println(“Error sending Email, ” + MailClient.smtpErrorReason());
// Clear all data from Email object to free memory
smtpData.empty();
}
// Callback function to get the Email sending status
void sendCallback(SendStatus msg) {
//Print the current status
Serial.println(msg.info());
}
Create a function that calls capturePhotoSaveSpiffs() and sendPhoto() whenever you send an IFFT trigger to it, then put this function inside main loop(). You wouldn’t need that “reset” function.
sirDaniel’s idea would work if IFTTT had a way to trigger the capturePhotoSaveSpiffs() and sendPhoto() function. might be able to if you use webhooks request.
nice. i like it.
These two methods are what you want to call when the web URL is triggered:
capturePhotoSaveSpiffs();
sendPhoto();
you might have to create your own applet.
The idea would be that you set up a web server, and the IFTTT applet would send info to the server when a web URL is opened.
Hi Rui and Sara,
Great post with interesting features for other projects!
It would be really interesting in future posts to present the code part of the post on both the arduino IDE and also MicroPython.
Do you thing it might be possible?
Regards
Alain
Hi.
Thanks for your comment.
We intend to do some projects with the ESP32-CAM and MicroPython.
However, I don’t know when they’ll be ready.
Regards,
Sara
Love your work! You’re the best!
Thanks 😀
Hi,
I tried this project and could download to the ESP.
In the serial monitor I can see that it do all until connect to the smtp server.
There is an error : Error, could not connect to server.
I have activated as mentioned the lower security of the new created gmail account.
What can I do now?
Thank You and Best Regards
Michael
16:15:57.346 -> Connecting to WiFi….
16:15:58.510 -> SPIFFS mounted successfully
16:15:58.510 -> IP Address: http://192.168.100.242
16:15:59.193 -> Taking a photo…
16:15:59.501 -> Picture file name: /photo.jpg
16:16:01.075 -> The picture has been saved in /photo.jpg – Size: 145792 bytes
16:16:01.110 -> Sending email…
16:16:01.110 -> Connecting to SMTP server…
16:16:01.110 -> Error, could not connect to server
16:16:01.110 -> Error sending Email, could not connect to server
#define smtpServer “smtp.gmail.com”
#define smtpServerPort 465
#define emailSubject “ESP32-CAM Photo Captured”
can ping the ESP in my WiFi Network and it has internet access.
Hi. i am having the same problem. I would be glad if someone who solved the problem could help
WOW.. I just found this site and the many articles covering the ESP32 Cam.. So I see capture and save, capture and email, a PIR triggered send to telegram.. Has anyone done a PIR Capture, save to SD and Email yet?? I am waiting on my board, but hope to achieve this for my board..
hello, I want to thank you for your work.
I would like to know if we can add an HC-SR501 PIR Motion Sensor Module as for telegram.
Thank you for your reply
You can combine these two tutorials: https://randomnerdtutorials.com/telegram-esp32-motion-detection-arduino/
https://randomnerdtutorials.com/esp32-cam-shield-pcb-telegram/
Regards,
Sara
thank you very much for your answer, i will try that. marco 2b
hi there
Thanks for great instructions !!
At the end, after reset the board, on my COM4 monitor I always(!) receive the same:
d⸮⸮⸮⸮⸮888 g⸮{⸮⸮s⸮⸮KG
May be someone can help… Thanks !
Him.
Make sure you have the baud rate of your Serial Monitor at 115200.
Regards,
Sara
I always get this error in the serial terminal:
[E][camera.c:1483] esp_camera_fb_get(): Failed to get the frame on time!
And I receive the email with no photo attached.
I think the problem is not the code because I have tried with the Web server example and that error happens too sometimes. I think the problem is any library… I have no idea. After searching on the Internet, it seems that problem is common (other people reported) but no clear instructions about how to solve it.
I wonder if the SD card is the problem… And the camera is unable to store the photo.
I found out the solution for my case, I hope many others can read this message because I have seen many people frustrated on the Internet with the error ” esp_camera_fb_get(): Failed to get the frame on time!”.
Everything was solved just changing some parameters:
…
config.xclk_freq_hz = 5000000;
…
config.frame_size = FRAMESIZE_SVGA;
If other people found other solution it worth sharing. Because I have seen it is a common issue.
I can’t make it work. I always get
Connecting to SMTP server…
Error, could not connect to server
Error sending Email, could not connect to server
All the credentials are properly set and I can send emails using the same credentials with other programs. What could be wrong?
Many thanks in advance for any hint.
Are you using a gmail account?
Regards,
Sara
Hi Sara, “muito obrigado” for your prompt answer, yes I’m using a Gmail account with Allow less secure apps ON, and I have ESP32 mail client V2.1.1 installed. I’ve tried with V2.1.6 but it failed exactly the same as before.
Help me please! I really need to be able to send a picture from the ESPcam! (my application is for construction tracking)
Thanks
Hi Simon.
Can you try the code in this example to see if it sends a simple email? https://randomnerdtutorials.com/esp32-send-email-smtp-server-arduino-ide/
Tell me if that example is working for you.
Regards,
Sara
Olá Sara, yes it worked like a charm!
So it seems this other library works better with Gmail, unfortunately I’m not that familiar with Arduino as to integrate both examples (the picture taking from the first example and the email part from the second) and would appreciate if you could assist on that. After all it will be a great update to your excellent tutorial.
Obrigado e abraço!
I’ll take a look to try to understand what’s going on and fix any possible issues.
Great, let me know if I can help in any way besides testing obviously.
Thanks
Hi.
I just tested the example and it works for me. I have the ESP32 Mail Client Library version 1.3.0 and ESP32 boards version 1.0.6 (you can check it in Tools > Boards > Boards Manager and search for ESP32).
However, the ESP32 Mail Client Library is deprecated in favor of the ESPMailClient.
So, here’s the example using the ESPMAilClient library instead: https://gist.github.com/sarasantos/30b520472b5f33a1af048b25b1798d12
I didn’t update the tutorial yet because I need to clean up the code a bit before posting, but that link that I’ve sent you is working. I’ve tested it.
I hope this helped.
Regards,
Sara
Hi Sara,
Ive been having this same problem and tried your link below.
https://gist.github.com/sarasantos/30b520472b5f33a1af048b25b1798d12
It does not work for me. Is it possible my problem is I am using the latest esp mail client and if so how do I change to 1.3.0?
Sara, I’m sorry but I’m still having problems 🙁
My board version is the same as yours: 1.0.6
ESP32 Mail Client Library I wasn’t able to find the same version you have (1.3.0) on the Library Managements it jumps from 1.2.3 to 2.0.0. Could you please double check your version?
And using ESP Mail Client V1.3.0 running the last example it gives me the same error
The picture has been saved in /photo.jpg – Size: 75648 bytes
Connecting to SMTP server…
I’m not sure what am I doing wrong…
Hi.
I’m sorry. My mistake.
ESP32MailClient –> version 2.1.6
ESPMailClient –>1.3.0
Dear Sara, I really appreciate your attention to help me.
So I’ve exactly the same versions as you but in my case it works OK with the example with no picture attached and it can’t connect to the mail server when trying to send the picture.
What else could I try? What could I have wrong?
I have been fighting with this for two days now 🙁
Sara, just one additional info that might help, I’ve tried with a different email service provider (UOL a very popular local service) and the issue was exactly the same
The picture has been saved in /photo.jpg – Size: 156544 bytes
Connecting to SMTP server…
I’m sorry, I don’t know what else I can do to solve your issue.
The project is working for me with the conditions I mentioned previously.
Without further details, it is very difficult to find out what might be wrong.
Regards,
Sara
Sara, just as last resource could you please share with me your settings for the
Board’s CPU Frequency and Flash Frequency ??
May be there is something there, just guessing…
Thanks
Hi.
I don’t think that is relevant for the issue.
But, here are my settings:
CPU frequency: 240MHz (WiFi/BT)
Flash Frequency: 80 MHz
Regards,
Sara
Hi Sara, just to share that my ESPcam was indeed with some kind of problem (very strange by the way) and the new board is working properly.
Many thanks again for your help.
Abraço
Great!
I’m glad you find the problem.
Regards,
Sara
Thanks Sara, as you expected it made no difference…
I have ordered a new board because there is nothing else I can think of. Will report back if it works.
Best
ok.
Thanks for keeping me updated.
It can be a bad wi-fi connection. Try putting the board closer to your router.
Regards,
Sara
Hi Sara & Rui
Your project is very cool.
I really appreciate what you are doing.
I am more and more drawn to this project and I am wondering if it is possible (and how) to make esp32-cam send a photo automatically every 24 hours?
Thank you for your help
Regards Adam
Hi Adam.
I think this discussion can help: https://github.com/arkhipenko/TaskScheduler/issues/95
Regards,
Sara
ok,, thx
Hallo, kurze Anfrage: beim hochladen des codes wird mir folgender Fehler angezeigt:
……espressif\esp32/tools/esptool/esptool.exe”: file not exist
Fehler beim Kompilieren für das Board AI Thinker ESP32-Cam
Was muß ich tun ?
LG
XXAL
Hi,
The email is sent OK with the pic attached but it keeps sending the same picture not an updated one. I want to send an updated pic continuously every half hour.
All I changed/added to your code is:
// capturePhotoSaveSpiffs();
// sendPhoto();
}
void loop() {
capturePhotoSaveSpiffs();
sendPhoto();
delay (1800000);
}
Thanks
Hi.
It is supposed to send a new picture. The capturePhotoSaveSpiffs() does exactly that.
Regards,
Sara
It sends the old one over and over not a new one.
I want to send an updated pic continuously every half hour.
This does what I want. It send a pic every half hour if bright enough. Sends the updated pic then removes it from SPIFFS.
It was sending only a partial or no pic so also added a SPIFFS format statement in the setup to correct this.
bool formatted = SPIFFS.format(); //formats SPIFFS if corrupt and only partial picture
void loop() {
if (digitalRead(2) == LOW) digitalWrite(33, LOW); // TURN on LED if dark
if (digitalRead(2) == HIGH) {
digitalWrite(33, HIGH);
delay (100);
capturePhotoSaveSpiffs();
delay (300);
sendPhoto();
SPIFFS.remove("FILE_PHOTO");
delay (1800000);
}
A photoresistor in a voltage divider circuit senses light on input 2. There is no point taking pics if it is dark.
Hello, how do i get a better picture quality?
Thank you very much for the tutorial.
Hello there.
I am keep taking this error
sketch_feb14a:12:30: fatal error: ESP32_MailClient.h: No such file or directory
compilation terminated.
exit status 1
ESP32_MailClient.h: No such file or directory
I am trying to include ESP32_MailClient.h but it does nothing.
does it happened to anyone else ?
Thanks
Hi.
Are you sure you’re installing the right library?
There are libraries with similar names that are not compatible.
Regards,
Sara
Hello Sara.
Thanks for the Reply.
I searched on Library Manager for ESP 32 Mail client Libraries.
I found two (2) libraries:
ESP Mail Client (Version 2.0.3)
ESP32 Mail Client. (Version 2.1.6)
I installed both of them to be sure. but nothing happened.
Just to be sure. I changed the ” ” with < > in the include. But the error is still there.
If you have any idea of what it could be please inform me.
Thanks for your time.
Remove the ESP Mail Client library, and only use the ESP32 Mail Client.
I’m not sure what might be causing the issue.
Regards,
Sara
Error, login password is not valid
Error sending Email, login password is not valid
Guess this is Google’s issue. It used to work properly when I completed the project. The ESP32 CAM was able to send photos and login without any issues. Thanks to Google, it’s no longer working. I can’t think of any other solutions other than trying other email providers.
Hi.
Double-check your credentials.
And make sure you allow less secure apps in your account settings.
Regards,
Sara
Hello Sara, thanks for the reply. Just to update, I found a solution for the issue I was facing not too long after posting the comment.
Basically, I turned on 2 factor authentication and enabled something called “App Passwords”. Next, I generated a 16 pin password with app password and used that in the login credentials field inside the code. The project is able to send email again after doing those.
I would recommend updating the steps for this tutorial. This is because by May 30 2022, Google will no longer support the use of third-party apps or devices which ask you to sign in to your Google Account using only your username and password. Because of that, 2 factor and app password has to be used.
Sorry for the late reply as I was busy and forgotten about replying.
Link for screenshot reference regarding app password: https://drive.google.com/file/d/1mufB6QZtUB731LHnX2S4LONryEU30Bmb/view?usp=sharing
Hi.
Thanks for sharing.
I’ll test that and update the tutorials that use gmail.
Thank you so much.
Regards,
Sara
Great Project. I have added TTGO camera configuration and Sleep Mode:
I thought I would share but excluded my credentials.
/*
// Pin definitions for My ESP32-CAM
#define CAMERA_MODEL_AI_THINKER
#define PWDN_GPIO_NUM 32
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 0
#define SIOD_GPIO_NUM 26
#define SIOC_GPIO_NUM 27
#define Y9_GPIO_NUM 35
#define Y8_GPIO_NUM 34
#define Y7_GPIO_NUM 39
#define Y6_GPIO_NUM 36
#define Y5_GPIO_NUM 21
#define Y4_GPIO_NUM 19
#define Y3_GPIO_NUM 18
#define Y2_GPIO_NUM 5
#define VSYNC_GPIO_NUM 25
#define HREF_GPIO_NUM 23
#define PCLK_GPIO_NUM 22
*/
// Pin definitions for CAMERA_MODEL_TTGO_WHITE (Mine)
#define CAMERA_MODEL_TTGO_WHITE_BME280
#define PWDN_GPIO_NUM 26
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 32
#define SIOD_GPIO_NUM 13
#define SIOC_GPIO_NUM 12
#define Y9_GPIO_NUM 39
#define Y8_GPIO_NUM 36
#define Y7_GPIO_NUM 23
#define Y6_GPIO_NUM 18
#define Y5_GPIO_NUM 15
#define Y4_GPIO_NUM 4
#define Y3_GPIO_NUM 14
#define Y2_GPIO_NUM 5
#define VSYNC_GPIO_NUM 27
#define HREF_GPIO_NUM 25
#define PCLK_GPIO_NUM 19
// Photo File Name to save in SPIFFS
#define PhotoFileName “/photo.jpg”
String Filename() {
return String(FILE).substring(String(FILE).lastIndexOf(“\”) + 1);
}
void setup() {
Serial.begin(115200);
delay(500);
Serial.println(“\nProgram ~ ” + Filename());
Serial.println(“Date Compiled ~ ” + String(DATE) + “\n”);
// CONNECT to WiFi network:
Serial.print(“WiFi Connecting to ” + String(ssid) + ” “);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(300);
Serial.print(“.”);
}
Serial.printf(” ~ Connected OK\n”);
// Print the Signal Strength:
long rssi = WiFi.RSSI() + 100;
Serial.print(“Signal Strength = ” + String(rssi));
if (rssi > 50) Serial.printf(” (>50 – Good)\n”); else Serial.printf(” (Could be Better)\n”);
Serial.setDebugOutput(true);
// Set Up SPIFFS
SPIFFS.begin();
if (!SPIFFS.begin(true)) {
Serial.printf(“An Error has occurred while Mounting SPIFFS\n”);
while (1) {
delay(1000); // Stay here
} else {
Serial.printf(” ~ SPIFFS Mounted Successfully\n”);
}
}
// Configure Camera Settings
camera_config_t config;
config.ledc_channel = LEDC_CHANNEL_0;
config.ledc_timer = LEDC_TIMER_0;
config.pin_d0 = Y2_GPIO_NUM;
config.pin_d1 = Y3_GPIO_NUM;
config.pin_d2 = Y4_GPIO_NUM;
config.pin_d3 = Y5_GPIO_NUM;
config.pin_d4 = Y6_GPIO_NUM;
config.pin_d5 = Y7_GPIO_NUM;
config.pin_d6 = Y8_GPIO_NUM;
config.pin_d7 = Y9_GPIO_NUM;
config.pin_xclk = XCLK_GPIO_NUM;
config.pin_pclk = PCLK_GPIO_NUM;
config.pin_vsync = VSYNC_GPIO_NUM;
config.pin_href = HREF_GPIO_NUM;
config.pin_sscb_sda = SIOD_GPIO_NUM;
config.pin_sscb_scl = SIOC_GPIO_NUM;
config.pin_pwdn = PWDN_GPIO_NUM;
config.pin_reset = RESET_GPIO_NUM;
config.xclk_freq_hz = 20000000;
config.pixel_format = PIXFORMAT_JPEG;
//Initial setting are FRAMESIZE_UXGA (320×240), Reset to SVGA (800×600)
//Initalize with high specs to pre-allocate larger buffers
if (psramFound()) {
Serial.printf(” ~ PSRAM Found OK! Frame Set to SVGA\n”);
config.frame_size = FRAMESIZE_SVGA; // (800×600)
config.jpeg_quality = 10; // 10-63 lower number means higher quality
config.fb_count = 2;
} else {
Serial.printf(“NO PSRAM found, Check Board Configuration !! Frame Set to UXGA\n”);
config.frame_size = FRAMESIZE_UXGA; // (320×240)
config.jpeg_quality = 12;
config.fb_count = 2;
}
// Initialize Camera
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
if (err == 0x105) Serial.printf(“Check Camera Pins Configuration !!\n”);
Serial.printf(“Camera init failed with error 0x%x”, err);
return;
}
sensor_t * s = esp_camera_sensor_get();
//Initial Image is flipped vertically/horzontally and colors are a bit saturated
//s->set_vflip(s, 1); // Flip it back
//s->set_brightness(s, 1); // Up the blightness just a bit
//s->set_saturation(s, -2); // Lower the saturation
if (s->id.PID == OV2640_PID) Serial.printf(” ~ Camera is OV2640\n”);
if (s->id.PID == OV3660_PID) Serial.printf(” ~ Camera is OV3660\n”);
if (s->id.PID == OV5640_PID) Serial.printf(” ~ Camera is OV5640\n”);
Serial.printf(” ~ Camera Set Up OK!\n”);
Serial.printf(“*******************************************\n”);
Capture_Photo_Save_Spiffs();
//Send_Photo(); // Moved “Send_Photo” at end of “Capture_Photo_Save_Spiffs”
//Print the wakeup reason for ESP32
Print_Wakeup_Reason();
// EXTERNAL TRIGGER ~ GPIO_NUM_13 and Input High for ESP32-CAM
esp_sleep_enable_ext0_wakeup(GPIO_NUM_13, 1); // 1 = High, 0 = Low
// EXTERNAL TRIGGER ~ GPIO_NUM_33 and Input High for TTGO
if (PWDN_GPIO_NUM == 26) { // for TTGO
esp_sleep_enable_ext0_wakeup(GPIO_NUM_33, 1); // for TTGO
}
//If you were to use ext1, you would use it like:
//esp_sleep_enable_ext1_wakeup(BUTTON_PIN_BITMASK,ESP_EXT1_WAKEUP_ANY_HIGH);
// TIMED TRIGGER ~ First we configure the wake up source
// We set our ESP32 to wake up every so many miliseconds (60 seconds) ~ TIMED TRIGGER
//esp_sleep_enable_timer_wakeup(1000000 * 60));
Serial.printf(“Going to Sleep now!\n”);
Serial.flush();
esp_deep_sleep_start();
}
void loop() {
// Nothing to do here!!
}
void Print_Wakeup_Reason() {
esp_sleep_wakeup_cause_t wakeup_reason;
wakeup_reason = esp_sleep_get_wakeup_cause();
Serial.printf(“\n”);
switch (wakeup_reason) {
case ESP_SLEEP_WAKEUP_EXT0 : Serial.printf(“Wakeup caused by EXTERNAL Signal using RTC_IO\n”); break;
case ESP_SLEEP_WAKEUP_EXT1 : Serial.printf(“Wakeup caused by EXTERNAL Signal using RTC_CNTL\n”); break;
case ESP_SLEEP_WAKEUP_TIMER : Serial.printf(“Wakeup caused by TIMER\n”); break;
case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.printf(“Wakeup caused by Touchpad\n”); break;
case ESP_SLEEP_WAKEUP_ULP : Serial.println(“Wakeup caused by ULP program\n”); break;
default : Serial.printf(“Wakeup was Not Caused by Deep Sleep: %d\n”, wakeup_reason); break;
}
}
// Capture Photo and Save it to SPIFFS
void Capture_Photo_Save_Spiffs( void ) {
camera_fb_t * fb = NULL; // pointer
bool ok = 0; // Boolean indicating if the picture has been taken correctly
do {
// Take a photo with the camera
//fb = esp_camera_fb_get();
camera_fb_t * fb = esp_camera_fb_get();
if (!fb) {
Serial.printf(“Camera capture FAILED\n”);
return;
}
// Write data to the photo file
File file = SPIFFS.open(PhotoFileName, “w+”); // Changed to “w+”
// Check file
if (!file) {
Serial.printf(“FAILED to open file in writing mode\n”);
return;
} else {
file.write(fb->buf, fb->len); // payload (image), payload length
}
// Close the file
Serial.printf(“Successfully Saved as \t’%s’ – Size: %d bytes\n”, PhotoFileName, file.size());
file.close();
// Return the frame buffer back to the driver for reuse
esp_camera_fb_return(fb);
// check if file has been correctly saved in SPIFFS
ok = Check_Photo(SPIFFS);
} while ( !ok );
Send_Photo();
}
// Check if photo capture was successful
bool Check_Photo( fs::FS &fs ) {
File f_pic = fs.open( PhotoFileName );
unsigned int pic_sz = f_pic.size();
Serial.printf(“Photo Verified as \t’%s’ – Size: %d bytes\n”, PhotoFileName, pic_sz);
return ( pic_sz > 100 );
}
void Send_Photo( void ) {
// Preparing email
// Set the SMTP Server Email host, port, account and password
smtpData.setLogin(smtpServer, smtpServerPort, emailSenderAccount, emailSenderPassword);
// Set the sender name and Email
smtpData.setSender(“ESP32-CAM”, emailSenderAccount);
// Set Email priority or importance High, Normal, Low or 1 to 5 (1 is highest)
smtpData.setPriority(“High”);
// Set the subject
smtpData.setSubject(emailSubject);
// Set the email message in HTML format
smtpData.setMessage(”
Photo captured with ESP32-CAM and attached in this email.
“, true);
// Set the email message in text format
//smtpData.setMessage(“Photo captured with ESP32-CAM and attached in this email.”, false);
// Add recipients, can add more than one recipient
smtpData.addRecipient(emailRecipient);
//smtpData.addRecipient(emailRecipient2);
// Add attach files from SPIFFS
smtpData.addAttachFile(PhotoFileName, “image/jpg”);
// Set the storage type to attach files in your email (SPIFFS)
smtpData.setFileStorageType(MailClientStorageType::SPIFFS);
smtpData.setSendCallback(sendCallback);
// Start sending Email, can be set callback function to track the status
if (!MailClient.sendMail(smtpData))
Serial.printf(“Error sending Email %s\n”, MailClient.smtpErrorReason());
// Clear all data from Email object to free memory
smtpData.empty();
}
// Callback function to get the Email sending status
void sendCallback(SendStatus msg) {
//Print the current status
Serial.println(msg.info());
}
Hi,
I’ve got a TTGO T-Camera (the white version, with a PIR) which won’t wake from deep sleep
when powered via a 3.7V LiPo battery attached to the on-board battery connector.
I have modified this sketch where the Camera goes to Sleep and then Wakes Up, either when PIR is triggered or after a wait period.
Sleep/Wake behaves completely normally when powered via USB.
Interestingly, I’ve noticed that when initially connecting the battery without USB power, the board also won’t power on until I’ve pressed RST.
But with the battery attached and not powered via USB:
If I let it sleep, then trigger a wake within a few seconds, it works.
If I let it sleep, leave it for ~10 seconds or so, it will NOT Wake up again.
Does anyone know how to fix this this issue?
I tried adding:
rtc_gpio_init(GPIO_NUM_14);
rtc_gpio_set_direction(GPIO_NUM_14, RTC_GPIO_MODE_OUTPUT_ONLY);
rtc_gpio_set_level(GPIO_NUM_14, 1);
delay(500);
But it doesn’t work.
Any advice greatly appreciated!
Hello.
Is it possible to send video instead of pictures to an e-mail?
Thanks
Sara,
I hope you don’t mind, but I have posted my version of your program to GitHub. https://github.com/Jpipe001/TTGO-with-Email/blob/main/TTGO_Cam_with_Email_Sleep_05_07_22.ino.
John
#include “ESP32_MailClient.h” has been changed to #include <ESP_Mail_Client.h>
I tried to use the first “include” statement and it comes up “not found”. Note the underscores between ESP and Mail, and Mail and Client.
Hi.
You’re right.
I’ll update the code when I get back to the office.
Regards,
Sara
Helo !
Your’s tutorial is great. 🙂
I have a problem.
In code there is
“define FILE_PHOTO “/photo.jpg”
and
#define emailSubject “Subkect”
My question is, how can I set this names like this “/Photo_2022-06-05_13:00.jpg” or subject as “Subject _2022-06-05_13:00”
Data and time is from actual time.
Thanks for any help.
All The Best
Hi.
You can get the date and time from an NTP server, and then create the names for the pictures based on the time.
To get the date and time, you can check this tutorial: https://randomnerdtutorials.com/esp32-date-time-ntp-client-server-arduino/
Regards,
Sara
Hi.
I wrote the program I wrote about earlier. However, I have a problem.
ESP23-cam takes pictures of the gas meter 9 times a day. E.g. 23:59:00, 00:00:00 00:01:00 then 02:59:00, 03:00:00 then 05: 59: 00.06: 00: 00, 06:01:00 and so on . Why, so many photos for 1 hour – to be sure that one of the three will be correct.
It happens that it takes 3 photos correctly, and sometimes only one. Sometimes the digits are half visible on one of them due to lack of light from backlight.
Below come of the code in which the procedure is called take a photo
// set of commands for each hour
const char * Time_foto0 = “23:59:00”;
const char * Time_foto01 = “00:00:00”;
const char * Time_foto02 = “00:01:00”;
e.t.c
void loop(){
if (strcmp (Time_, Time_foto0) == 0)
digitalWrite (12, HIGH); // turn on the backlight
capturePhotoSaveSpiffs ();
digitalWrite (12, LOW); // turn off the backlight
sendPhoto ();
}
if (strcmp (Time_, Time_foto01) == 0)
digitalWrite (12, HIGH); // turn on the backlight
capturePhotoSaveSpiffs ();
digitalWrite (12, LOW); // turn off the backlight
sendPhoto ();
}
e.t.c
}
Each fixed time triggers a set of commands. ESP takes a picture and sends it to gmail.
Below are the settings and procedures
Camera:
void setup()
camera_config_t config;
config.ledc_channel = LEDC_CHANNEL_0;
config.ledc_timer = LEDC_TIMER_0;
config.pin_d0 = Y2_GPIO_NUM;
config.pin_d1 = Y3_GPIO_NUM;
config.pin_d2 = Y4_GPIO_NUM;
config.pin_d3 = Y5_GPIO_NUM;
config.pin_d4 = Y6_GPIO_NUM;
config.pin_d5 = Y7_GPIO_NUM;
config.pin_d6 = Y8_GPIO_NUM;
config.pin_d7 = Y9_GPIO_NUM;
config.pin_xclk = XCLK_GPIO_NUM;
config.pin_pclk = PCLK_GPIO_NUM;
config.pin_vsync = VSYNC_GPIO_NUM;
config.pin_href = HREF_GPIO_NUM;
config.pin_sscb_sda = SIOD_GPIO_NUM;
config.pin_sscb_scl = SIOC_GPIO_NUM;
config.pin_pwdn = PWDN_GPIO_NUM;
config.pin_reset = RESET_GPIO_NUM;
//config.xclk_freq_hz = 20000000;
config.xclk_freq_hz = 11000000;
config.pixel_format = PIXFORMAT_JPEG;
if (psramFound ()) {
config.frame_size = FRAMESIZE_XGA; // UXGA; // UXGA;
config.jpeg_quality = 7;
config.fb_count = 2;
} else {
config.frame_size = FRAMESIZE_XGA; // SXGA;
config.jpeg_quality = 77;
config.fb_count = 1;
}
// Initialize camera
esp_err_t err = esp_camera_init (& config);
if (err! = ESP_OK) {
Serial.printf (“Camera init failed with error 0x% x”, err);
return;
}
sensor_t * s = esp_camera_sensor_get ();
s-> set_brightness (s, 0); // -2 is 2
s-> set_contrast (s, 2); // -2 is 2
s-> set_saturation (s, 0); // -2 is 2
s-> set_special_effect (s, 0); // 0 to 6 (0 – No Effect, 1 – Negative, 2 – Grayscale, 3 – Red Tint, 4 – Green Tint, 5 – Blue Tint, 6 – Sepia)
s-> set_whitebal (s, 1); // 0 = disable, 1 = enable
s-> set_awb_gain (s, 1); // 0 = disable, 1 = enable
s-> set_wb_mode (s, 0); // 0 to 4 – if awb_gain enabled (0 – Auto, 1 – Sunny, 2 – Cloudy, 3 – Office, 4 – Home)
s-> set_exposure_ctrl (s, 1); // 0 = disable, 1 = enable
s-> set_aec2 (s, 0); // 0 = disable, 1 = enable
s-> set_ae_level (s, -1); // -2 is 2
s-> set_aec_value (s, 300); // 0 to 1200
s-> set_gain_ctrl (s, 1); // 0 = disable, 1 = enable
s-> set_agc_gain (s, 0); // 0 to 30
s-> set_gainceiling (s, (gainceiling_t) 0); // 0 is 6
s-> set_bpc (s, 0); // 0 = disable, 1 = enable
s-> set_wpc (s, 1); // 0 = disable, 1 = enable
s-> set_raw_gma (s, 1); // 0 = disable, 1 = enable
s-> set_lenc (s, 1); // 0 = disable, 1 = enable
s-> set_hmirror (s, 0); // 0 = disable, 1 = enable
s-> set_vflip (s, 1); // 0 = disable, 1 = enable
s-> set_dcw (s, 1); // 0 = disable, 1 = enable
s-> set_colorbar (s, 0); // 0 = disable, 1 = enable
}
// Check if photo capture was successful
bool checkPhoto (fs :: FS & fs) {
File f_pic = fs.open (“/” + FILE_PHOTO);
unsigned int pic_sz = f_pic.size ();
return (pic_sz> 100);
}
// Capture Photo and Save it to SPIFFS
void capturePhotoSaveSpiffs (void) {
camera_fb_t * fb = NULL; // pointer
bool ok = 0; // Boolean indicating if the picture has been taken correctly
to {
// Take a photo with the camera
Serial.println (“I’m taking a photo …”);
delay (200);
// Take a picture
fb = esp_camera_fb_get ();
// After doing
if (! fb) {
Serial.println ("Camera capture failed");
return;
}
// Determine the file name
Serial.printf ("Filename:", FILE_PHOTO);
File file = SPIFFS.open ("/" + FILE_PHOTO, FILE_WRITE);
// Put the data from the photo into the file
if (! file) {
Serial.println ("Problem with switching to writing mode");
}
else {
file.write (fb-> buf, fb-> len); // payload (image), payload length
Serial.print ("Picture Saved In");
Serial.print ("/" + FILE_PHOTO);
Serial.print ("- Size:");
Serial.print (file.size ());
Serial.println ("bytes");
}
// Close the file
file.close ();
esp_camera_fb_return (fb);
// see if the file is saved correctly
Is this config.xclk_freq_hz = 11000000; problem ?
Thanks for help
All The Best 4U
Link how to looks like fotos
https://drive.google.com/drive/folders/1rApKd5eFS5bhWY698qheBEBmDWxotNL3?usp=sharing
Hia, while the project ESP32-cam Take a poto and save on SD card (https://randomnerdtutorials.com/esp32-cam-take-photo-save-microsd-card) works absolutely fine, when I upload and try to run this one, I get camera not found error –
20:34:09.721 -> E (10672) camera: Camera probe failed with error 0x105(ESP_ERR_NOT_FOUND)
20:34:09.721 -> Camera init failed with error 0x105
With the exact same module working fine with another script, how do I solve this? I am powering it with 5V from my PC, via the ESP32-CAM-MB micro usb programmer.
Hi Sara,
Thanks for the sketch “Using ESP32Cam to send photo to email. Worked first time around.
I have a motion sensor and want to use it to send an email everytime motion is detected.
How should I modify the sketch?
Meir
Hi.
You can try to combine it with this project: https://randomnerdtutorials.com/esp32-cam-pir-motion-detector-photo-capture/
Or this one: https://randomnerdtutorials.com/esp32-cam-shield-pcb-telegram/
I hope this helps.
Regards,
Sara
Hello, good time. I can’t send email anymore with esp32cam because google settings to receive programs with less security will be removed. Please help.
You need to create an app password.
See the section of the tutorial with the title “Create an App Password”.
Regards,
Sara
How to fix this problem ???
Arduino: 1.8.19 (Windows 10), Board: “ESP32 Wrover Module, Face Recognition (26211440 bytes), QIO, 80MHz, 921600, None”
C:\Users\Lenovo-PC\OneDrive\Documents\Arduino\libraries\SPI\src\SPI.cpp: In member function ‘void SPIClass::transferBytes(const uint8_t*, uint8_t*, uint32_t)’:
C:\Users\Lenovo-PC\OneDrive\Documents\Arduino\libraries\SPI\src\SPI.cpp:297:43: error: invalid conversion from ‘const uint8_t* {aka const unsigned char}’ to ‘uint8_t {aka unsigned char*}’ [-fpermissive]
spiTransferBytes(_spi, data, out, size);
^
In file included from C:\Users\Lenovo-PC\OneDrive\Documents\Arduino\libraries\SPI\src\SPI.h:26:0,
from C:\Users\Lenovo-PC\OneDrive\Documents\Arduino\libraries\SPI\src\SPI.cpp:22:
C:\Users\Lenovo-PC\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\cores\esp32/esp32-hal-spi.h:108:6: note: initializing argument 2 of ‘void spiTransferBytes(spi_t*, uint8_t*, uint8_t*, uint32_t)’
void spiTransferBytes(spi_t * spi, uint8_t * data, uint8_t * out, uint32_t size);
^
exit status 1
Error compiling for board ESP32 Wrover Module.
This report would have more information with
“Show verbose output during compilation”
option enabled in File -> Preferences.
Hi.
What’s the version of the ESP32 boards that you have installed? Tools > Boards > Boards Manager > ESP32.
Regards,
Sara
Thank you for the work you have put into this tutorial.
Just curious … I notice that there are often multiple attempts at taking the image. The software handles this but what is the reason for this behaviour?
Dave
Hello and Congratulations for your excellent work!
As a beginner to AI-Thinker ESP32, I have faced a problem with this project. Everything works fine (from connecting to WiFi to sending photo). However, the photo taken is too dark (most of the times black). I’ve found relevant code to make changes to the camera settings but with no result. Is there anything I can do or search to solve this.
Thank you !
Hi.
We’ll update this tutorial soon with some fixes that need to be done because of the updates of the ESP32 core.
With the new updates of the ESP32 core, when you get a frame buffer with fb_get(), it saves four different pictures in the buffer. Aditionally, the first picture always comes with a green tint.
How we resolve this issue:
– set config.grab_mode = CAMERA_GRAB_LATEST; to show the latest picture in the buffer
– set config.fb_count = 1; to get only one picture in the buffer.
– to ignore the first picture, we added the following when taking a picture – basically getting the latest picture, clearing the buffer and taking a new picture:
– // Take a photo with the camera
fb = esp_camera_fb_get();
esp_camera_fb_return(fb); // dispose the buffered image
fb = NULL; // reset to capture errors
// Get fresh image
Serial.println(“Taking a photo…”);
fb = esp_camera_fb_get();
if (!fb) {
Serial.println(“Camera capture failed”);
return;
}
I hope this helps.
Regards,
Sara
After using this code for several months I tried to recompile it for a new camera and I get an error saying No module found “serial”
Any ideas on how to fix this?
The original camera and code have been working fine.
Thank You
Hi.
Take a look at the following discussion and see if it helps: https://forum.arduino.cc/t/modulenotfounderror-no-module-named-serial/847838
It seems to be exactly the same problem as yours.
Regards,
Sara
Hello,
I really appreciate what you are doing.
As a beginner to AI-Thinker ESP32, I have faced a problem with this project.
I always get this error in the serial terminal:
E (1889) cam_hal: cam_dma_config(306): frame buffer malloc failed
E (1889) cam_hal: cam_config(390): cam_dma_config failed
E (1889) camera: Camera config failed with error 0xffffffff
Camera init failed with error 0xffffffff
Is there anything I can do or search to solve this.
Thank you.
Hi.
check the connections between the camera and the board.
check the power supply.
The camera may also be broken.
Regards,
Sara
I have the following result:
..
SPIFFS mounted successfully
IP Address: http://192.168.1.95
Taking a photo…
Picture file name: /photo.jpg
cam_hal: EV-EOF-OVF
cam_hal: EV-EOF-OVF
cam_hal: EV-EOF-OVF
cam_hal: EV-EOF-OVF
cam_hal: EV-EOF-OVF
cam_hal: EV-EOF-OVF
The picture has been saved in /photo.jpg – Size: 36864 bytes
Sending email…
Connecting to SMTP server…
[ 9189][I][ssl_client32.cpp:292] start_ssl_client(): WARNING: Use certificates for a more secure communication!
SMTP server connected, wait for response…
Identification…
Authentication…
Sign in…
Sending Email header…
Sending Email body…
Sending attachments…
[ 11859][W][SPIFFS.cpp:71] begin(): SPIFFS Already Mounted!
/photo.jpg
Finalize…
Finished
Email sent successfully
When i check my email i will get an email with an attachment but the photo is completely black,
Any idea why ?
Found it:
When i change:
config.xclk_freq_hz = 20000000;
into
config.xclk_freq_hz = 10000000;
the message cam_hal: EV-EOF-OVF is gone……….
Also i receive now an image via Email.
So it works !
Great!
Thanks for sharing the solution.
Regards,
Sara
Hi.
Can you try using the same code, but replacing “SPIFFS” with “LittleFS”?
Let me know if that solves the issue.
Regards,
Sara
It seems when you call capturePhotoSaveSpiffs two times, for example from the loop by a PIR sensor trigger, the second time the FILE_PHOTO has lenght zero.
To make it work i added a flush and a read file and this solved this for me:
else {
file.write(fb->buf, fb->len); // payload (image), payload length
Serial.println(“flush the data”);
file.flush();
Serial.println(“flush done, now do FILE_READ”);
file = SPIFFS.open(FILE_PHOTO, FILE_READ);
Serial.println(“FILE_READ done”);
delay(1000);
Serial.print(“The picture has been saved in “);
Serial.print(FILE_PHOTO);
Serial.print(” – Size: “);
Serial.print(file.size());
Serial.println(” bytes”);
Another issue is this statement:
smtpData.setFileStorageType(MailClientStorageType::SPIFFS);
I wanted to change SPIFFS in LittleFS but it does not support LittleFS,
only SPIFFS and SD are supported .
I guess LittleFS is too new 🙂
If you guys know a better EMAIL send code with LittleFS, I would be interested.
Regards
Otto
My best kudos for your easy to understand and easy to test tutorials.
Now I’m trying to send photos via e-mail and I probably missed some steps because I get these messages:
19:34:30.386 -> ! E: network connection callback is required
19:34:30.386 -> ! E: network connection status callback is required
19:34:30.386 -> #### Error, client and/or necessary callback functions are not yet assigned
19:34:30.386 -> ! E: client and/or necessary callback functions are not yet assigned
can you help me to solve this problem?
Thanks and still good.
Hi.
Did you copy the whole code?
I think you’re missing the functions definitions ate the end of the code.
Or if you’re using PlatformIO, you need to move the function definitions before the loop() and setup().
Regards,
Sara
Hello and thanks for answering me.
I downloaded the code again and compared with the one that gives me problems.
I added :
#define FORMAT_LITTLEFS_IF_FAILED true
and inside setup :
#ifdef TWOPART
if(!LittleFS.begin(FORMAT_LITTLEFS_IF_FAILED, “/lfs2”, 5, “part2”)){
Serial.println(“part2 Mount Failed”);
return;
}
appendFile(LittleFS, “/hello0.txt”, “World0!\r\n”);
readFile(LittleFS, “/hello0.txt”);
LittleFS.end();
Serial.println( “Done with part2, work with the first lfs partition…” );
#endif
if(!LittleFS.begin(FORMAT_LITTLEFS_IF_FAILED)){
Serial.println(“LittleFS Mount Failed”);
return;
}
The code is otherwise identical to your example.
Can you have any other ideas about this?
Thanks for the kind cooperation.
Are you using PlatformIO or Arduino IDE?
Regards,
Sara
Arduino IDE.
Hi Sarah,
Same problem, identical example previous SMTP and Camera examples work. Same error! See config is a local varialble shared by Camera and SMTP but they are local,,,
Hi Sara,
can you help me with this error?
19:34:30.386 -> ! E: network connection callback is required
19:34:30.386 -> ! E: network connection status callback is required
19:34:30.386 -> #### Error, client and/or necessary callback functions are not yet assigned
19:34:30.386 -> ! E: client and/or necessary callback functions are not yet assigned
thank you.
Hi.
Are you using VS Code?
Move the function definitions to a place before the setup().
Regards,
Sara
Sorry for my ignorance.
What is the VS Code.
What definitions should I move before setup?
Thanks again
If someone has the Problem with Gmail authentication Follow this instruction
https://www.zdnet.com/article/gmail-app-passwords-what-they-are-how-to-create-one-and-why-to-use-them/
Make a second password what google gives you and put it in the sketch
Hello sir, I have already added the the Gmail App password but I am still unable to connect to the SMTP server and send the picture. It says the error:
10:27:47.019 -> < S: 535-5.7.8 Username and Password not accepted. For more information, go to
10:27:47.020 -> < S: 535 5.7.8 https://support.google.com/mail/?p=BadCredentials u26-20020a63235a000000b005c2420fb198sm15596455pgm.37 – gsmtp
10:27:47.020 -> #### Error, authentication failed
10:27:47.020 -> ! E: authentication failed
Hi.
As the error mentions, it’s an authentication problem.
Double-check your app password and email.
Remember that uppercase and lowercase matters and remove any spaces.
Regards,
Sara
Hi,
To whom it may concern;-)
I had some problems to make everything functioning correctly.
Everything looked OK but no picture was sent per e-mail.
I found out that software on mail-servers may function differently.
I changed:
message.enable.chunking = true;
in:
message.enable.chunking = false;
That worked on the mailserver I use.
Regards,
André
Hi.
Thanks for providing that information.
It will definitely be useful for other readers.
Regards,
Sara
The above seems to have an issue sending the actual image in my testing, it seems as if it tries to send it, but takes too long and eventually sends a notice of failure
Hi.
What is exactly the error that you get?
Regards,
Sara
Hi,
After tweaking and testing I have found a low rate of success, I have however been capable of receiving a couple of successful emails. Most of the time the software runs until the part where it tries to send the image and then it fails. Every so often it will also have issues connecting to the smtp server
15:00:53.623 -> < S: 535-5.7.8 Username and Password not accepted. For more information, go to
15:00:53.623 -> < S: 535 5.7.8 https://support.google.com/mail/?p=BadCredentials i4-20020a05600c354400b004101f27737asm8863632wmq.29 – gsmtp
15:00:53.623 -> #### Error, authentication failed
15:00:53.623 -> ! E: authentication failed
Hi.
Make sure you’re using the app password and not the email password.
Check the section “Create an App Password”
Regards,
Sara
Hi Sara,
I’m loving the projects you have on RNT and have worked through several already with good results. I have a question regarding the photo to email sketch(which I have running). Can I manipulate the code in this sketch without causing errors, so that the picture is taken first before the wifi connects and then sends the picture? This is to enable a trigger from an Arduino board to take the picture in the quickest time possible.
Thanks & regards,
Steve
Hi there,
thanks for the code. Just Awesome <3
But I get this output in the serial Monitor whenever I try to run it:
Connecting to WiFi…..
IP Address: http://192.168.0.189
E (1631) esp_littlefs: ./components/esp_littlefs/src/littlefs/lfs.c:1225:error: Corrupted dir pair at {0x0, 0x1}
E (1632) esp_littlefs: mount failed, (-84)
E (1636) esp_littlefs: Failed to initialize LittleFS
E (1674) camera: Camera probe failed with error 0x105(ESP_ERR_NOT_FOUND)
Camera init failed with error 0x105
Can you help ?
According to my personal tests it sometimes works, but most of the time not because either the ntp servers do not respond (timeout) or the connection to the SMTP server fails. Without changing anything, just unplugging and reconnecting, without even touching the code, it works… sometimes.
Nice and simple. Thanks a lot. I just wonder how “ESP” from App Password is linked in the code? Any hint will be appreciated
I am trying to also use Firebase library mobizt/Firebase Arduino Client Library for ESP8266 and ESP32@^4.4.14 but I get all kinds of errors. If I run standalone firebase or mobizt/ESP Mail Client@^3.4.19 run fine. It’s only when I merge them. Do you have any hints that may help me?
Thanks in advance
I ran the code sara everything is perfect. How can I make it send the photo every second?
You would probably find that the SMTP provider will block your traffic.
Dear Sara, dear Rui,
again, your code worked 1:1 out of the box! Thank you very much for this!
Now, I would like to extend the code to trigger a photo two times a day.
However, the internal clock is just updated inside the function SmtpCallback only once.
How can I manage this, to update the clock regularly and extract the time?
Thank you in advance!
Regards,
Juergen
Dear Sara, dear Rui,
I managed it all by myself. Sorry for asking, without having tried everything.
First thing was to get the actual time within the main loop.
Then extract the actual hour as string, convert it into an integer using the function atoi (hour = atoi(hourstr);) and finally program a scheduler to trigger a photo and send it:
if ((hour == 6) && (done == false)) {
capturePhotoSaveLittleFS();
sendPhoto();
done = true;}
The boolean done blocks multiple photos.
Again, thank you very much for the initial code!
Best regards, Juergen
Dear Sara, dear Rui,
the code works ok, it takes two times a day a photo, BUT: the time synced with NTP does not work as expected:
I set the NTP time to UTC + 1h (Germany) plus 1h daylight correction:
config.time.ntp_server = F(“de.pool.ntp.org,pool.ntp.org,time.nist.gov”); //
config.time.gmt_offset = 1; // für uns nur eine Stunde
config.time.day_light_offset = 1;
HOWEVER, when programmed to take a photo at 16:00, it always makes the photo at 16:59.
Do you have an idea why this happens?