Hi Sara, how are you?
One quick question: I like a lot this project, but I would like to add some other features as follows:
1) To allow to post a picture using a PIR not only with timed mode (30 seconds);
2) To allow to have the live streaming.
Is it to much complicated to get it ? Thanks a lot and I continue to stay tuned!
Hi Domenico.
Yes, you can add a PIR motion sensor. However, setting up an interrupt with the ESP32-CAM is slightly different than with the ESP32.
Create a acallback function for the interrupt, for example:
// Indicates when motion is detected
static void IRAM_ATTR detectsMovement(void * arg){
Serial.println("MOTION DETECTED!!!");
motionDetected = true;
}add the following to your setup function to set GPIO 13 as an interrupt:
// PIR Motion Sensor mode INPUT_PULLUP
//err = gpio_install_isr_service(0);
err = gpio_isr_handler_add(GPIO_NUM_13, &detectsMovement, (void *) 13);
if (err != ESP_OK) {
Serial.printf("handler add failed with error 0x%x \r\n", err);
}
err = gpio_set_intr_type(GPIO_NUM_13, GPIO_INTR_POSEDGE);
if (err != ESP_OK) {
Serial.printf("set intr type failed with error 0x%x \r\n", err);
}
Then, in the loop() check the state of the control variable to take and send the photo when needed.
As for the video, at the moment we don’t have any project with that.
Regards,
Sara
I’m answering this question from my smartphone. I’m sorry about the mess in the code indentation.
Dear Sara, no problem!
I got your indications and it seems to me working fine; I need now to better fine tune something else, because often the attachment into the email looks like corrupted or incomplete.
The only thing I saw is that the ESP32CAM at booting stage crashs often before connecting successfully with IP address to allow right communication with email account.
Now, if possible, I would like to add the WebServer and use part of the “ESP32-CAM Post Images to Local using PHP (Photo Manager)” project with Raspy o, as an alternative, as a preliminary job, to run the Webserver into the ESP32 sketch.
Should be it possible ? I think so, thanks a lot !
Problem Sara!
Now I am getting those errors: no connection anymore …any ideas? thanks.
—————————————
14:50:29.857 -> Connecting to Vodafone-27261031
14:50:29.857 -> ………..E (8317) wifi: esf_buf: t=2 l=76 max:32, alloc:32 no eb, TXQ_BLOCK=0
14:50:35.365 -> ..E (9160) wifi: esf_buf: t=2 l=76 max:32, alloc:32 no eb, TXQ_BLOCK=0
14:50:36.113 -> E (9280) wifi: esf_buf: t=2 l=76 max:32, alloc:32 no eb, TXQ_BLOCK=0
14:50:36.249 -> E (9401) wifi: esf_buf: t=2 l=76 max:32, alloc:32 no eb, TXQ_BLOCK=0
14:50:36.351 -> .E (9521) wifi: esf_buf: t=2 l=76 max:32, alloc:32 no eb, TXQ_BLOCK=0
14:50:36.488 -> E (9642) wifi: esf_buf: t=2 l=76 max:32, alloc:32 no eb, TXQ_BLOCK=0
14:50:36.623 -> E (9763) wifi: esf_buf: t=2 l=76 max:32, alloc:32 no eb, TXQ_BLOCK=0
14:50:36.724 -> E (9883) wifi: esf_buf: t=2 l=76 max:32, alloc:32 no eb, TXQ_BLOCK=0
14:50:36.860 -> E (10004) wifi: esf_buf: t=2 l=76 max:32, alloc:32 no eb, TXQ_BLOCK=0
14:50:36.860 -> .E (10124) wifi: esf_buf: t=2 l=76 max:32, alloc:32 no eb, TXQ_BLOCK=0
14:50:37.098 -> E (10245) wifi: esf_buf: t=2 l=76 max:32, alloc:32 no eb, TXQ_BLOCK=0
14:50:37.200 -> E (10365) wifi: esf_buf: t=2 l=76 max:32, alloc:32 no eb, TXQ_BLOCK=0
14:50:37.371 -> ..E (11208) wifi: esf_buf: t=2 l=76 max:32, alloc:32 no eb, TXQ_BLOCK=0
14:50:38.184 -> E (11329) wifi: esf_buf: t=2 l=76 max:32, alloc:32 no eb, TXQ_BLOCK=0
14:50:38.286 -> E (11449) wifi: esf_buf: t=2 l=76 max:32, alloc:32 no eb, TXQ_BLOCK=0
14:50:38.354 -> .E (11570) wifi: esf_buf: t=2 l=76 max:32, alloc:32 no eb, TXQ_BLOCK=0
Can I use some sketch to delete or cancel something is causing no IP address connection ?
Thanks !!
Seems to be solved as follows:
1.pip install esptool
2.esptool.py –chip esp32 –port com14 erase_flash
C:\>esptool.py –chip esp32 –port com14 erase_flash
esptool.py v2.8
Serial port com14
Connecting…….._
Chip is ESP32D0WDQ6 (revision 1)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme
None
Crystal is 40MHz
MAC: 3c:71:bf:59:97:8c
Uploading stub…
Running stub…
Stub running…
Erasing flash (this may take a while)…
Chip erase completed successfully in 7.7s
Hard resetting via RTS pin…
16:28:30.856 -> Connecting to WiFi……………..
16:28:38.431 -> SPIFFS mounted successfully
16:28:38.431 -> IP Address: http://192.168.1.13
Dear sara, it seems to me no working; could you please double check from even your side, if any BIG mistake??
thanks.
================================ w/PIR
/*
Rui Santos
Complete project details at https://RandomNerdTutorials.com/esp32-cam-post-image-photo-server/
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 <Arduino.h>
#include <WiFi.h>
#include “soc/soc.h”
#include “soc/rtc_cntl_reg.h”
#include “esp_camera.h”
const char* ssid = “Vodafone-27261031”;
const char* password = “******************”;
String serverName = “192.168.1.15”; // REPLACE WITH YOUR Raspberry Pi IP ADDRESS
//String serverName = “example.com”; // OR REPLACE WITH YOUR DOMAIN NAME
String serverPath = “/upload.php”; // The default serverPath should be upload.php
const int serverPort = 80;
WiFiClient client;
// 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
const int timerInterval = 60000; // time between each HTTP POST image
unsigned long previousMillis = 0; // last time image was sent
// —————————— PIR OPTION START
bool takePicture = false;
static void IRAM_ATTR detectsMovement(void * arg) {
Serial.println(“Motion Detected”);
takePicture = true;
}
void enableInterrupt(){
esp_err_t err = gpio_isr_handler_add(GPIO_NUM_14, &detectsMovement, (void *) 1);
if (err != ESP_OK) {
Serial.printf(“handler add failed with error 0x%x \r\n”, err);
}
err = gpio_set_intr_type(GPIO_NUM_14, GPIO_INTR_POSEDGE);
if (err != ESP_OK) {
Serial.printf(“set intr type failed with error 0x%x \r\n”, err);
}
}
// —————————— PIR OPTION END
void setup() {
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);
Serial.begin(115200);
WiFi.mode(WIFI_STA);
Serial.println();
Serial.print(“Connecting to “);
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
Serial.print(“.”);
delay(500);
}
Serial.println();
Serial.print(“ESP32-CAM IP Address: “);
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;
// init with high specs to pre-allocate larger buffers
if(psramFound()){
config.frame_size = FRAMESIZE_SVGA;
config.jpeg_quality = 10; //0-63 lower number means higher quality
config.fb_count = 2;
} else {
config.frame_size = FRAMESIZE_CIF;
config.jpeg_quality = 12; //0-63 lower number means higher quality
config.fb_count = 1;
}
// camera init
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
Serial.printf(“Camera init failed with error 0x%x”, err);
delay(1000);
ESP.restart();
}
sendPhoto();
}
void loop() {
if (takePicture){
//capturePhotoSaveSpiffs();
sendPhoto();
takePicture=false;
}
/*
unsigned long currentMillis = millis();
if (currentMillis – previousMillis >= timerInterval) {
sendPhoto();
previousMillis = currentMillis;
}
*/
}
String sendPhoto() {
String getAll;
String getBody;
camera_fb_t * fb = NULL;
fb = esp_camera_fb_get();
if(!fb) {
Serial.println(“Camera capture failed”);
delay(1000);
ESP.restart();
}
Serial.println(“Connecting to server: ” + serverName);
if (client.connect(serverName.c_str(), serverPort)) {
Serial.println(“Connection successful!”);
String head = “–RandomNerdTutorials\r\nContent-Disposition: form-data; name=\”imageFile\”; filename=\”esp32-cam.jpg\”\r\nContent-Type: image/jpeg\r\n\r\n”;
String tail = “\r\n–RandomNerdTutorials–\r\n”;
uint16_t imageLen = fb->len;
uint16_t extraLen = head.length() + tail.length();
uint16_t totalLen = imageLen + extraLen;
client.println(“POST ” + serverPath + ” HTTP/1.1″);
client.println(“Host: ” + serverName);
client.println(“Content-Length: ” + String(totalLen));
client.println(“Content-Type: multipart/form-data; boundary=RandomNerdTutorials”);
client.println();
client.print(head);
uint8_t *fbBuf = fb->buf;
size_t fbLen = fb->len;
for (size_t n=0; n<fbLen; n=n+1024) {
if (n+1024 < fbLen) {
client.write(fbBuf, 1024);
fbBuf += 1024;
}
else if (fbLen%1024>0) {
size_t remainder = fbLen%1024;
client.write(fbBuf, remainder);
}
}
client.print(tail);
esp_camera_fb_return(fb);
int timoutTimer = 10000;
long startTimer = millis();
boolean state = false;
while ((startTimer + timoutTimer) > millis()) {
Serial.print(“.”);
delay(100);
while (client.available()) {
char c = client.read();
if (c == ‘\n’) {
if (getAll.length()==0) { state=true; }
getAll = “”;
}
else if (c != ‘\r’) { getAll += String(c); }
if (state==true) { getBody += String(c); }
startTimer = millis();
}
if (getBody.length()>0) { break; }
}
Serial.println();
client.stop();
Serial.println(getBody);
}
else {
getBody = “Connection to ” + serverName + ” failed.”;
Serial.println(getBody);
}
return getBody;
}
===================================
Hi.
When you say it doesn’t work, what exactly happens?
Do you get any errors?
Can you share your code using pastebin or github? Otherwise, it is very difficult to troubleshoot.
Regards,
Sara
Dear Sara, I am sorry; I was less clear before. You can find the code as follows:-
https://pastebin.com/9mDZNzzv
This sketch is able ONLY to send a timed pic (every 60sec) to the Raspberry web server (LAMP server) and successfully, but not able to send a pic when the motion is captured. Most likely there is some syntax error, even if I get no indication into the Serial Monitoring.
Thanks a lot, Domenico
Hi.
In your code, you created the enableInterrupt() function, but you never called it. So, the interrupts are not enabled.
Call the enableInterrupt() function in your setup after initializing the camera.
Additionally, you have the following line:
esp_err_t err = gpio_isr_handler_add(GPIO_NUM_14, &detectsMovement, (void *) 1);
and it should be
esp_err_t err = gpio_isr_handler_add(GPIO_NUM_14, &detectsMovement, (void *) 14);
Regards,
Sara
Hi Sara, you are fully right !
I will try and tomorrow morning will let know you, thanks.
Have a good evening!
Dear Sara, unfortunately no works !
Attached sketch and serial monitoring, thanks.
https://pastebin.com/vmc0u7ZN
https://pastebin.com/6sGZP1mR
Ops, my mistake, now it seems to run like a charme ! I will let know you on the progress !!
Hi Sara, can I ask 1 thing?
I want to improve the “config.frame_size = FRAMESIZE_SVGA”; what I need to select ? i tried by myself to modify to “FRAMESIZE_UXGA” unsuccessfully because I got error from the LAMP server connection, thanks.
I found as follows:
The frame size can be set to one of these options:
- FRAMESIZE_UXGA (1600 x 1200)
- FRAMESIZE_QVGA (320 x 240)
- FRAMESIZE_CIF (352 x 288)
- FRAMESIZE_VGA (640 x 480)
- FRAMESIZE_SVGA (800 x 600)
- FRAMESIZE_XGA (1024 x 768)
- FRAMESIZE_SXGA (1280 x 1024)
I tried this : SXGA but no works.
Hi.
One of our readers suggested the following:
Replace the following
uint16_t imageLen = fb->len;
uint16_t extraLen = head.length() + tail.length();
uint16_t totalLen = imageLen + extraLen;
with
uint32_t imageLen = fb->len;
uint32_t extraLen = head.length() + tail.length();
uint32_t totalLen = imageLen + extraLen;
Let me know if this works.
Regards,
Sara
That makes sense. An unsigned 16-bit integer can only hold 65,535. An unsigned 32-bit integer can hold ~4.2billion. An image at SXGA would be 1280 x 1024 x 4 (4 bytes for color RGBA) = 5,242,880.
Who said you don’t use math after school?
Hi guys, it works fine, thanks; first step is completed.
PS: I’d like to use a Cloud server instead of the Raspberry; you suggested “Bluehost hosting solution” but I am not sure it will be for free. I used in the past ngrok.com; question is : can I use Ngrok instead of Bluehost ?
Hi.
I’m glad it worked.
If you want to make it accessible from anywhere (and still use raspberry pi), you can use ngrok. You just need to make the Raspberry Pi IP address accessible from anywhere.
Regards,
Sara
I’ll mark this issue as resolved.
If you need further help, you just need to open a new question in our forum.
Regards,
Sara
Dear sara, unfortunately I need still yr help!
After many trial runs, I found a “place/location” for this project outdoor my home. But, after one night only, I have found thousands of “pics” on the LAMP server. Very strange!
I checked those files, and found that often the “pic timing” differs only for 7 to 10 seconds; in other cases few minutes; consider that I fine tuned the trimmers at minimum value for both sensitivitiy and timing.
I make assure that the project went Okay before to place in to the “final destination”.
What happened? Thanks.
Hi Domenico.
Is the project inside an enclosure? Where is the PIR located?
Can you check the wiring?
The wi-fi signal or other signals might interfere in the PIR and cause false positives (I never add that problem, but some of our readers have reported that issue).
Try placing the PIR in a different position in relation to the ESP32-CAM.
I hope this helps.
Regards,
Sara
Dear Sara,
first, the project is inside an enclosure like a dummy cam. So, the PIR is located close to the ESP32-CAM.
The wiring should be okay, due to inside my house I had none problems.
I guess you are right, the wi-fi signal or other signals might interfere in the PIR and cause false positives.
I will get yr suggestion, trying to place the PIR in a different position than to the ESP32-CAM.
I guess this will fix and I will hope this helps.
Regards,
Domenico
Hi Domenico.
If your project is inside a dumy camera, the PIR motion sensor must be placed outside.
At least, with our experiment, and with the dummy camera we used, it only worked well if the PIR was on the outside.
You can see a photo of our setup here: https://randomnerdtutorials.com/wp-content/uploads/2020/08/ESP32-CAM-AI-Thinker-Module-Shield-PCB-Final-Demonstration-Fake-dummy-surveillance-camera.jpg
I hope this helps.
Regards,
Sara