In this guide, you’ll learn how to make HTTP POST requests using the ESP32-CAM board with Arduino IDE to send photos to a server. We’ll show how to post a JPG image to a local server (Raspberry Pi LAMP server) or to a cloud server (that you can access from anywhere). To save the images on the server, we’ll use PHP.
Updated on 27 March 2023
To build this project, you need to follow the next steps. Follow the LAMP Server or the Hosting Server instructions depending on if you want to access the photos locally or from anywhere.
- Hosting your PHP Application
- PHP scripts to save and display photos in the server
- Program the ESP32-CAM with Arduino IDE
- Testing and Final Demonstration
1. Hosting Your PHP Application
The goal of this project is to have a local or cloud server to store and access your ESP32-CAM photos.
1. Raspberry Pi local server:
With a Raspberry Pi LAMP server, you can access your images locally (as illustrated below).
- You can run a LAMP (Linux, Apache, MySQL, PHP) server on a Raspberry Pi to access data in your local network. Raspberry Pi LAMP Server: Local Linux server that you use to access your images locally.
2. Cloud server (Bluehost hosting solution)
You also can visualize the ESP32-CAM photos from anywhere in the world by accessing your own server + domain. Here’s a high level overview on how it works:
- Bluehost (user-friendly with cPanel): free domain name when you sign up for the 3-year plan. I recommend choosing the unlimited websites option; Note that any hosting service that offers PHP will work with this tutorial. If you don’t have a hosting account, I recommend signing up for Bluehost.
Get Hosting and Domain Name with Bluehost »
When buying a hosting account, you’ll also have to purchase a domain name. This is what makes this project interesting: you’ll be able to go your domain name (http://example.com) and see your ESP32-CAM photos. If you like our projects, you might consider signing up to Bluehost, because you’ll be supporting our work.
2.1. Preparing Your .php File and uploads Folder (Raspberry Pi LAMP Server)
This section prepares your .php file and uploads folder for your Raspberry Pi LAMP Server. If you’re using your own server + domain name, skip to the next section.
Having a Raspberry Pi running Apache and PHP, in the Raspberry Pi board terminal window navigate to the /var/www/html/ directory:
pi@raspberrypi:~ $ cd /var/www/html/
Create a new folder called uploads:
pi@raspberrypi:/var/www/html $ mkdir uploads
pi@raspberrypi:/var/www/html $ ls
uploads
At the moment, /var/www/html is owned by root, use the next commands to change to the pi user and give it all permissions so that you can save photos using a PHP script later on.
sudo chown -R pi:pi /var/www/html
chmod -R 777 /var/www/html/
Finally, create a new upload.php file:
pi@raspberrypi:/var/www/html $ nano upload.php
This PHP script is responsible for receiving incoming images from the ESP32-CAM, rename the images with a timestamp and store them in the uploads folder. Edit the newly created file (upload.php) and copy the following snippet:
<?php
// Rui Santos
// Complete project details at https://RandomNerdTutorials.com/esp32-cam-post-image-photo-server/
// Code Based on this example: w3schools.com/php/php_file_upload.asp
$target_dir = "uploads/";
$datum = mktime(date('H')+0, date('i'), date('s'), date('m'), date('d'), date('y'));
$target_file = $target_dir . date('Y.m.d_H:i:s_', $datum) . basename($_FILES["imageFile"]["name"]);
$uploadOk = 1;
$imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));
// Check if image file is a actual image or fake image
if(isset($_POST["submit"])) {
$check = getimagesize($_FILES["imageFile"]["tmp_name"]);
if($check !== false) {
echo "File is an image - " . $check["mime"] . ".";
$uploadOk = 1;
}
else {
echo "File is not an image.";
$uploadOk = 0;
}
}
// Check if file already exists
if (file_exists($target_file)) {
echo "Sorry, file already exists.";
$uploadOk = 0;
}
// Check file size
if ($_FILES["imageFile"]["size"] > 500000) {
echo "Sorry, your file is too large.";
$uploadOk = 0;
}
// Allow certain file formats
if($imageFileType != "jpg" && $imageFileType != "png" && $imageFileType != "jpeg"
&& $imageFileType != "gif" ) {
echo "Sorry, only JPG, JPEG, PNG & GIF files are allowed.";
$uploadOk = 0;
}
// Check if $uploadOk is set to 0 by an error
if ($uploadOk == 0) {
echo "Sorry, your file was not uploaded.";
// if everything is ok, try to upload file
}
else {
if (move_uploaded_file($_FILES["imageFile"]["tmp_name"], $target_file)) {
echo "The file ". basename( $_FILES["imageFile"]["name"]). " has been uploaded.";
}
else {
echo "Sorry, there was an error uploading your file.";
}
}
?>
Save your file and exit (Ctrl+X, Y, and Enter key):
2.2. Preparing Your .php Files and uploads Folder (Hosting Service)
If you prefer to run your server remotely and access the photos from anywhere, you need a hosting account. After signing up for a hosting account and setting up a domain name, you can login to your cPanel or similar dashboard. After that, open the File Manager.
Open the “Advanced” tab and select “File Manager“:
Then, select the public_html option. Press the “+ File” button to create a new upload.php file and a new gallery.php file. Then, click the “+Folder” button to create the Uploads folder.
With the three items created, edit the upload.php file:
This PHP script is responsible for receiving incoming images from the ESP32-CAM, rename the images with a timestamp and store them in the uploads folder. Edit the newly created file (upload.php) and copy the snippet below. Save your file and exit.
<?php
// Rui Santos
// Complete project details at https://RandomNerdTutorials.com/esp32-cam-post-image-photo-server/
// Code Based on this example: w3schools.com/php/php_file_upload.asp
$target_dir = "uploads/";
$datum = mktime(date('H')+0, date('i'), date('s'), date('m'), date('d'), date('y'));
$target_file = $target_dir . date('Y.m.d_H:i:s_', $datum) . basename($_FILES["imageFile"]["name"]);
$uploadOk = 1;
$imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));
// Check if image file is a actual image or fake image
if(isset($_POST["submit"])) {
$check = getimagesize($_FILES["imageFile"]["tmp_name"]);
if($check !== false) {
echo "File is an image - " . $check["mime"] . ".";
$uploadOk = 1;
}
else {
echo "File is not an image.";
$uploadOk = 0;
}
}
// Check if file already exists
if (file_exists($target_file)) {
echo "Sorry, file already exists.";
$uploadOk = 0;
}
// Check file size
if ($_FILES["imageFile"]["size"] > 500000) {
echo "Sorry, your file is too large.";
$uploadOk = 0;
}
// Allow certain file formats
if($imageFileType != "jpg" && $imageFileType != "png" && $imageFileType != "jpeg"
&& $imageFileType != "gif" ) {
echo "Sorry, only JPG, JPEG, PNG & GIF files are allowed.";
$uploadOk = 0;
}
// Check if $uploadOk is set to 0 by an error
if ($uploadOk == 0) {
echo "Sorry, your file was not uploaded.";
// if everything is ok, try to upload file
}
else {
if (move_uploaded_file($_FILES["imageFile"]["tmp_name"], $target_file)) {
echo "The file ". basename( $_FILES["imageFile"]["name"]). " has been uploaded.";
}
else {
echo "Sorry, there was an error uploading your file.";
}
}
?>
3. ESP32-CAM HTTP Post Images/Photos to Server
Now that you have your server ready (Raspberry Pi LAMP server or cloud server), it’s time to prepare the ESP32-CAM with the code to publish a new image to your server every 30 seconds. Before proceeding with this tutorial, make sure you complete the following prerequisites.
Parts Required
To follow this tutorial you need the following components:
- ESP32-CAM with OV2640 – read Best ESP32-CAM Dev Boards
- FTDI programmer
- Female-to-female jumper wires
- 5V power supply for ESP32-CAM
- Local server:
- Cloud server (alternative): Bluehost
You can use the preceding links or go directly to MakerAdvisor.com/tools to find all the parts for your projects at the best price!
Arduino IDE
We’ll program the ESP32-CAM using Arduino IDE, so make sure you have the ESP32 add-on installed.
Check the PHP URL
You should try to open the Raspberry Pi local IP address or your external example.com domain name, followed by /upload.php that should return:
Sorry, only JPG, JPEG, PNG & GIF files are allowed.Sorry, your file was not uploaded.
If you see that message save your URL/domain name and path, your server should be ready and you can continue with this guide.
ESP32-CAM Code
If you’re using a local server without TLS/SSL, or a cloud server that doesn’t support HTTPS, use the HTTP POST Request Code.
If you’re using a cloud server that requires HTTPS requests, use this code instead: HTTPS POST Request Code.
ESP32-CAM HTTP POST Request
The next sketch posts the image to a server using HTTP POST. Copy the code below to your Arduino IDE.
/*
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 = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
String serverName = "192.168.1.XXX"; // 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 = 30000; // time between each HTTP POST image
unsigned long previousMillis = 0; // last time image was sent
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_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;
// 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() {
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";
uint32_t imageLen = fb->len;
uint32_t extraLen = head.length() + tail.length();
uint32_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;
}
ESP32-CAM HTTPS POST Request
The next sketch posts the image to a server using HTTPS POST. Copy the code below to your Arduino IDE.
/*
Rui Santos
Complete project details at:
https://RandomNerdTutorials.com/esp32-cam-http-post-php-arduino/
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 <WiFiClientSecure.h>
#include "soc/soc.h"
#include "soc/rtc_cntl_reg.h"
#include "esp_camera.h"
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
String serverName = "example.com"; //REPLACE WITH YOUR DOMAIN NAME
String serverPath = "/upload.php"; // The default serverPath should be upload.php
const int serverPort = 443; //server port for HTTPS
WiFiClientSecure 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 = 30000; // time between each HTTP POST image
unsigned long previousMillis = 0; // last time image was sent
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_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;
// 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() {
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);
client.setInsecure(); //skip certificate validation
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";
uint32_t imageLen = fb->len;
uint32_t extraLen = head.length() + tail.length();
uint32_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;
}
Learn more about HTTPS Requests with the ESP32: ESP32 HTTPS Requests (Arduino IDE).
Inserting your Network Credentials, Camera, and Server Details
Before uploading the code, you need to insert your network credentials in the following variables:
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
Make sure you select the right camera module. In this case, we’re using the AI-THINKER Model. If you’re using another camera model, you can read this Guide ESP32-CAM Camera Boards: Pin and GPIOs Assignment.
Add your Raspberry Pi IP address or use the server domain name:
String serverName = "192.168.1.XXX"; // 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
Upload Code to ESP32-CAM
Now you can upload the code to your ESP32-CAM board. Connect the ESP32-CAM board to your computer using an FTDI programmer.
Follow the next schematic diagram:
Many FTDI programmers have a jumper that allows you to select 3.3V or 5V. Make sure the jumper is in the right place to select 5V.
Important: GPIO 0 needs to be connected to GND so that you’re able to upload code.
ESP32-CAM | FTDI Programmer |
GND | GND |
5V | VCC (5V) |
U0R | TX |
U0T | RX |
GPIO 0 | GND |
To upload the code, follow the next steps:
- Go to Tools > Board and select AI-Thinker ESP32-CAM.
- Go to Tools > Port and select the COM port the ESP32 is connected to.
- Then, click the upload button to upload the code.
- When you start to see these dots on the debugging window as shown below, press the ESP32-CAM on-board RST button.
After a few seconds, the code should be successfully uploaded to your board.
If you have troubles uploading the code, read our ESP32-CAM Troubleshooting Guide.
How the Code Works
Here’s a quick explanation on how the code works:
- Imports all libraries;
- Defines the needed variables;
- Defines the camera pins;
- In the setup() you establish a Wi-Fi connection and initialize the ESP32 camera.
- The loop() has a timer that calls the sendPhoto() function every 30 seconds. You can change that delay time in the timerInterval variable.
The sendPhoto() function is the part that actually takes a photo and sends it to your server. You can use that function in other of your projects that require taking and publishing a photo to a server.
4. Testing and Final Demonstration
After uploading the code to your board, open the Arduino IDE Serial Monitor and you should see a similar message being printed every 30 seconds:
The file esp32-cam.jpg has been uploaded.
If you go to your local server URL http://IP-Address/uploads, or to your cloud server URL http://example.com/uploads you should have a folder with all your stored photos.
You can click on each link to open a new page with the full image:
Wrapping Up
That’s it! Now, you can send your ESP32-CAM photos to any server using HTTP POST. Modify this project to best suit your needs, for example take a photo and send to a server when motion is detected.
Other ESP32 tutorials you might be interested in:
- ESP32 HTTP GET and HTTP POST
- ESP32 HTTP GET Web APIs
- ESP32 HTTP POST Web APIs
- ESP32 HTTPS Requests (Arduino IDE)
Learn more about the ESP32-CAM:
Thanks for reading.
I like the ESP32-CAM and am wondering if we could build a fridge cam with it. It should then preferably be able to operate on batteries for a long time, wake up when there is light, make a photo, connect to WiFi and send it to the server. Technically, it should be easy. But will it be fast enough, especially when it has to wake up from sleep mode and connect to WiFi in the short time that the fridge door is open? And will the batteries last long enough, especially in this cold environment?
Hi.please, fix
uint16_t imageLen = fb->len;
uint16_t extraLen = head.length() + tail.length();
uint16_t totalLen = imageLen + extraLen;
to
uint32_t imageLen = fb->len;
uint32_t extraLen = head.length() + tail.length();
uint32_t totalLen = imageLen + extraLen;
for upload file sizes > 65 kb.
otherwise you reciebe “BAD REQUEST 404”
Please i have tried this and still receiving ‘400 bad request’.
What else can I do?
Please, I don’t know why this is happening. I keep seeing something like this on my serial monitor.
400 bad request
400 bad request
openresty
Moreover, it is reconnecting to the servername writing connection successfully again and again.
Please what can I do?
To add to it. The 400 bad request I am seeing is written in html tags like center, body, h1 etc
Please help!
Hello…were you able to solve the issue. I am experiencing a similar problem
I have the same issue, but is because i am using Heroku my own flask API, are you using the PHP script that is included in the tutorial?
Hi I am a complete noob. I want to send some data(temperature values) along with the photos that is been sent to the webserver. How do I do that. How to insert content in the body of the data packet that is been sent?
Hi,
what would be the code modification to send a CSV file? Could you make a tutorial on that?
Thanks for your time.
Hi,
How do I change the captured pics file names so my software recognizes thm as a sequence for time lapse video?
Hi.
You can include unix time in the name of your photos.
Regards,
Sara
Hello let me congratulate you for sharing your knowledge with all of us in this blog, as I have been very helpful. I have implemented this example and it works, only I have the problem that when the photo is taken it does not send what was in front of the camera, ie the photos are sent with delay sometimes sends 4 photos before sending what I want, I hope you can help me.
Thanks so much for these great, clearly written examples. BTW when taking snapshots with the frame buffer count greater than one be sure to set the grab mode to latest. Otherwise you’ll get stale photos. Might be extremely important if the snapshots are triggered by a motion sensor.
config.grab_mode = CAMERA_GRAB_LATEST;
Connecting to server: 192.168
Connection successful!
Sorry, there was an error uploading your file.
Connecting to server: 192.168
Connection successful!
Check “uploads” folder permission. Write enabled for public solved my problem
Thank you this solved the problem, you are a star
Little bit late…
How can I remove the Photos from /uploads or gallery.php or move it to another folder. This is still an endless frame… Is it possible that I can include a timer for ect. 10 minutes?
Thank´s for answering.
Problem connecting to Bluehost!!
When I try: https://XXXmybluehost.me/upload.php
I do get the required response: “Sorry, only JPG, JPEG, PNG & GIF files are allowed.Sorry, your file was not uploaded.”
However, when I run the Arduino program, the serial monitor gives:
Connecting to wumpy
…..
ESP32-CAM IP Address: 192.168.0.128
Connecting to server: XXXmybluehost.me
Connection to gpq.jvy.mybluehost.me failed.
Connecting to server: gpq.jvy.mybluehost.me
Connection to gpq.jvy.mybluehost.me failed
Any ideas please?
Hope you do a TWO-DIMENSIONAL code is another tutorial, can realize ESP32CAM two-dimensional code and the information with serial communication transmission.
Thanks for this tutorial. I added a fisheye lens and put the camera to my roof top to take photos from the southern sky. From the photos I can estimate if there is any sense to install solar panels.
400 BAD REQUEST
Hi, I have lighttpd server on my raspberry.
All was running fine on Raspbian Stretch.
Now i updated to Raspbian Buster, and when i try to upload a photo, i get 400 Bad Request.
In /var/log/lighttpd/error.log i find the following:
request-URI parse error -> 400 for: esp32-cam/upload1.php
I gave all permissions like
– sudo chown -R pi:pi /var/www/html
– chmod -R 777 /var/www/html/
but no change.
Within another project, php scripts are working fine.
I found the solution:
I forgot the “/” character at the beginning of the server php path:
const String uploadServerPath = “/esp32-cam/upload1.php”;
It’s funny that it worked with lighttpd on Raspbian Stretch, but don’t work on Buster.
Finally i tested it with Apache on Windows:
“Error 404”. After some digging i found, that Windows doesn’t like the “:” characters of the date string in the filename. I replaced it by “-” and it worked…
Thank you… this solved my problem! 🙂
👍😊
Hi,
Would it be possible to share the sketch to send the pictures via HTTPS protocol?
Hi.
In the following tutorial you can see how to make an HTTPS request with the ESP32.
You just need to adjust for the request you want to make: https://randomnerdtutorials.com/esp32-https-requests/
Regards,
SAra
Hi,
I have adjusting the request with https. The code tested OK with Http GET. but when I use it to POST image file like this tutorial, it returns 400:Bad Request.
Any suggestion to check what could go wrong?
Regards,
Sukron
Hi, I have implemented this example and I have the problem that when the photo is taken it does not send to upload folder and php script warning.
Serial Monitor
Connecting to server: 192.168.1.6/esp32/upload.php
Connection successful!
.
Connecting to server: 192.168.1.6/esp32/upload.php
Connection successful!
.
On php Script a warning
Warning: Undefined array key “imageFile” in C:\xampp\htdocs\esp32\upload.php on line 8
Warning: Trying to access array offset on value of type null in C:\xampp\htdocs\esp32\upload.php on line 8
Warning: Undefined array key “imageFile” in C:\xampp\htdocs\esp32\upload.php on line 34
Warning: Trying to access array offset on value of type null in C:\xampp\htdocs\esp32\upload.php on line 34
Hi bahtera.
I get the same warnings,
have you found a solution.
running wampserver64 on windows 10.
Why is a pointer used for ssid and password ?
301 Moved Permanently
Moved Permanently
The document has moved here.
no matter what I try keep getting this error, needs help
Hi.
This is an issue related to the server redirecting HTTP to https requests.
We intend to update this tutorial in the next few days to be compatible with HTTPS requests.
So stay tuned.
Regards,
Sara
I know you don’t have any tutorial on this topic,
but is it possible to change this
to run on another local Windows PC
running a wamp server.
instead of running it on a raspberry pi.
Hi.
If you install a wamp server, it will work the same.
Regards,
Sara
Ok, I’ll give it a try and see if I can get it to work.
If anyone is interested, I made it work in xampp,
by changing the php script that you can download here.
https://drive.google.com/drive/folders/1BfC8PjNjtIfoQ8r-9n-URpK96tPYOAco?usp=sharing.
hi Rui and Sara
there is a problem with clearing ESP32-CAM Frame buffer.
as described here.
https://stackoverflow.com/questions/72457769/arduino-esp32-cam-frame-buffer-clear.
the same image is uploaded several times
before a new one is sent.
Hi.
Did you make the suggested changes mentioned in that discussion?
Did it fix the issue?
Regards,
Sara
Hi Sara.
I’m not sure if that fixed it.
I haven’t tested it enough yet.
it works with this.
camera_fb_t * fb = NULL;
fb = esp_camera_fb_get();
esp_camera_fb_return(fb); // dispose of the buffered image
fb = NULL; // reset to capture errors
fb = esp_camera_fb_get();
esp_camera_fb_return(fb); // dispose of the buffered image
fb = NULL; // reset to capture errors
fb = esp_camera_fb_get(); // get fresh image
if(!fb) {
Serial.println(“Camera capture failed”);
delay(1000);
ESP.restart();
}
I don’t know if this is the right way to do it.
the best solution will probably be
to let the esp-cam go to sleep
and wake it up on timer interrupt
maybe, what do you think.
I implemented the tutorial as written, used it a lot with no problems.
That’s a good idea.
I just need to fix the code one more time,
since config.fb_count = 1,
was set to 2 here with me.
so this is enough.
camera_fb_t * fb = NULL;
fb = esp_camera_fb_get();
esp_camera_fb_return(fb); // dispose of the buffered image
fb = NULL; // reset to capture errors
fb = esp_camera_fb_get(); // get fresh image
if(!fb) {
Serial.println(“Camera capture failed”);
delay(1000);
ESP.restart();
}
Great.
Thanks for sharing.
With an updated on the ESP32 core, when you take a picture, it saves foud pictures into the frame buffer 😐
Regards,
Sara
Hi Sara.
I’d like to give you and Rui a big thanks,
for all the work you put into your tutorials.
Thank you so much!
Hi, for some reason when I upload the code to my esp32 it just says connecting to internet and then does an endless line of ……
On the same board I used a different sketch that connects to wifi so I know the board is ok I’ve triple checked that I have the right wifi name and password, any idea?
Ryan
I am trying to create the solution instead of using php, using node. And I am not able to:
I have a node js script:
http.createServer((request, response) => {
const { headers, method, url } = request;
let body = [];
request.on(‘error’, (err) => {
Log.error(“Error in server: ” + error);
}).on(‘data’, (chunk) => {
body.push(chunk);
}).on(‘end’, () => {
if (url == '/service') {
const file = fs.createWriteStream('esp32-cam.jpg');
response.pipe(file);
file.on('finish', () => {
file.close();
console.log(`Image downloaded`);
});
}
}}
);
}).listen(port);
Could you please help me?
Hi thanks for all the great tutorials, how to do this with motion detection? instead of sending pics every 30 seconds. Thanks
Hi.
Try to combine with this project: https://randomnerdtutorials.com/esp32-cam-pir-motion-detector-photo-capture/
Regards,
Sara
Hello,
Great tutorials, muito obrigado!!
So if I adjust the frame size my camera just crashed,
config.frame_size = FRAMESIZE_XGA;
config.jpeg_quality = 60; //0-63 lower number means higher quality
config.fb_count = 1;
so only changing to lower resolution FRAMESIZE_SVGA it works, but its not 800x
Debugging:
SP32-CAM IP Address: 192.168.100.48
FRAMESIZE_XGAE (1183) camera: Camera probe failed with error 0x105(ESP_ERR_NOT_FOUND)
Camera init failed with error 0x105ets Jul 29 2019 12:21:46
rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:1184
load:0x40078000,len:13260
load:0x40080400,len:3028
entry 0x400805e4
Is this a hardware limitation?
Obrigado,
Thanks, this really came through for a recent project of mine, I needed to send photo to a flask server.