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/JPEG image to a local server (Raspberry Pi LAMP server) or to a cloud server (that you can access from anywhere). The photos will be displayed in a gallery where you can view or delete the photos. To save the images in the server and create the gallery, we’ll use PHP scripts.
![ESP32-CAM Camera Board Send Post Images to Local Cloud Server HTTP POST Arduino IDE](https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2023/03/ESP32-CAM-Cloud-Photo-Manager-f.jpg?resize=828%2C466&quality=100&strip=all&ssl=1)
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).
![ESP32-CAM Camera Board Send Photo Image to Raspberry Pi LAMP Server PHP gallery Script Arduino](https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2020/06/ESP32-CAM-Camera-Board-Send-Photo-Image-to-Raspberry-Pi-LAMP-Server-PHP-gallery-Script-Arduino.png?resize=828%2C742&quality=100&strip=all&ssl=1)
- 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:
![ESP32-CAM Camera Board Send Photo Image to Cloud Server PHP gallery Script Arduino](https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2020/06/ESP32-CAM-Camera-Board-Send-Photo-Image-to-Cloud-Server-PHP-gallery-Script-Arduino.png?resize=828%2C713&quality=100&strip=all&ssl=1)
- 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.
HTTP POST Request Method
The Hypertext Transfer Protocol (HTTP) works as a request-response protocol between a client and server. Here’s an example:
- The ESP32 (client) submits an HTTP request to a Server (for example: local RPi Lamp Server or example.com);
- The server returns a response to the ESP32 (client);
HTTP POST is used to send data to a server to create/update a resource. For example, publish an image to a server.
POST /upload.php HTTP/1.1
Host: example.com
Content-Type: image/jpeg
2.1. Preparing Your .php Files and uploads Folder (Raspberry Pi LAMP Server)
This section prepares your .php files 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.";
}
}
?>
Your upload.php file should look like this. Save your file and exit (Ctrl+X, Y, and Enter key):
![Upload images to server local or cloud using the ESP32-CAM board Arduino IDE upload.php file](https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2020/06/upload-php-script-save-images-to-server-ESP32-CAM.png?resize=828%2C846&quality=100&strip=all&ssl=1)
Then, create a new gallery.php file:
pi@raspberrypi:/var/www/html $ nano gallery.php
Edit the newly created file (gallery.php) and copy the following snippet:
<!--
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.
-->
<!DOCTYPE html>
<html>
<head>
<title>ESP32-CAM Photo Gallery</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
.flex-container {
display: flex;
flex-wrap: wrap;
}
.flex-container > div {
text-align: center;
margin: 10px;
}
</style>
</head><body>
<h2>ESP32-CAM Photo Gallery</h2>
<?php
// Image extensions
$image_extensions = array("png","jpg","jpeg","gif");
// Check delete HTTP GET request - remove images
if(isset($_GET["delete"])){
$imageFileType = strtolower(pathinfo($_GET["delete"],PATHINFO_EXTENSION));
if (file_exists($_GET["delete"]) && ($imageFileType == "jpg" || $imageFileType == "png" || $imageFileType == "jpeg") ) {
echo "File found and deleted: " . $_GET["delete"];
unlink($_GET["delete"]);
}
else {
echo 'File not found - <a href="gallery.php">refresh</a>';
}
}
// Target directory
$dir = 'uploads/';
if (is_dir($dir)){
echo '<div class="flex-container">';
$count = 1;
$files = scandir($dir);
rsort($files);
foreach ($files as $file) {
if ($file != '.' && $file != '..') {?>
<div>
<p><a href="gallery.php?delete=<?php echo $dir . $file; ?>">Delete file</a> - <?php echo $file; ?></p>
<a href="<?php echo $dir . $file; ?>">
<img src="<?php echo $dir . $file; ?>" style="width: 350px;" alt="" title=""/>
</a>
</div>
<?php
$count++;
}
}
}
if($count==1) { echo "<p>No images found</p>"; }
?>
</div>
</body>
</html>
This PHP script is responsible for displaying the images on the gallery. Your gallery.php file should look like this. Save your file and exit (Ctrl+X, Y, and Enter key):
![gallery PHP script save and view images server ESP32-CAM](https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2020/06/gallery-php-script-save-images-to-server-ESP32-CAM.png?resize=828%2C595&quality=100&strip=all&ssl=1)
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“:
![Bluehost open advanced and file manager files to create upload.php file and uploads folder](https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2020/06/ESP32-CAM-Advanced-open-File-Manager.png?resize=794%2C543&quality=100&strip=all&ssl=1)
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.
![ESP32-CAM Camera board CPanel Create New Upload PHP File Uploads Folder](https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2020/06/ESP32-CAM-Camera-CPanel-Create-New-Upload-PHP-File-Uploads-Folder.png?resize=828%2C337&quality=100&strip=all&ssl=1)
With the three items created, edit the upload.php file:
![ESP32-CAM Camera board CPanel Create New PHP Files and Uploads Folder](https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2020/06/ESP32-CAM-PHP-files-and-folder-created.png?resize=828%2C376&quality=100&strip=all&ssl=1)
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.
Then, edit the gallery.php file and copy the following snippet. This is responsible for displaying the images in the gallery.
<!--
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.
-->
<!DOCTYPE html>
<html>
<head>
<title>ESP32-CAM Photo Gallery</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
.flex-container {
display: flex;
flex-wrap: wrap;
}
.flex-container > div {
text-align: center;
margin: 10px;
}
</style>
</head><body>
<h2>ESP32-CAM Photo Gallery</h2>
<?php
// Image extensions
$image_extensions = array("png","jpg","jpeg","gif");
// Check delete HTTP GET request - remove images
if(isset($_GET["delete"])){
$imageFileType = strtolower(pathinfo($_GET["delete"],PATHINFO_EXTENSION));
if (file_exists($_GET["delete"]) && ($imageFileType == "jpg" || $imageFileType == "png" || $imageFileType == "jpeg") ) {
echo "File found and deleted: " . $_GET["delete"];
unlink($_GET["delete"]);
}
else {
echo 'File not found - <a href="gallery.php">refresh</a>';
}
}
// Target directory
$dir = 'uploads/';
if (is_dir($dir)){
echo '<div class="flex-container">';
$count = 1;
$files = scandir($dir);
rsort($files);
foreach ($files as $file) {
if ($file != '.' && $file != '..') {?>
<div>
<p><a href="gallery.php?delete=<?php echo $dir . $file; ?>">Delete file</a> - <?php echo $file; ?></p>
<a href="<?php echo $dir . $file; ?>">
<img src="<?php echo $dir . $file; ?>" style="width: 350px;" alt="" title=""/>
</a>
</div>
<?php
$count++;
}
}
}
if($count==1) { echo "<p>No images found</p>"; }
?>
</div>
</body>
</html>
Save your file and exit. That’s it! Your server is ready.
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.
![ESP32-CAM Testing the upload.php URL](https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2020/06/ESP32-CAM-Camera-Board-Upload-Files-Image.png?resize=705%2C326&quality=100&strip=all&ssl=1)
If you see that message save your URL/domain name and path, your server should be ready and you can continue with this guide.
Additionally, try to access the /gallery.php path. You should get something as shown below:
![ESP32-CAM Camera Board gallery PHP file view delete photos](https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2020/06/ESP32-CAM-Camera-Board-gallery-PHP-file-view-delete-photos.png?resize=752%2C411&quality=100&strip=all&ssl=1)
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_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() {
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_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() {
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:
![ESP32-CAM connected to an FTDI Programmer to upload program using Arduino IDE](https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2024/06/ESP32-CAM-FTDI-programmer.png?resize=828%2C502&quality=100&strip=all&ssl=1)
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.
![ESP32-CAM camera board upload new Arduino IDE sketch press RESET button](https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2019/12/dots-uploading-code.png?resize=828%2C75&quality=100&strip=all&ssl=1)
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 of 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.
![ESP32-CAM file esp32-cam.jpg has been uploaded Arduino IDE Serial Monitor testing project](https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2020/06/ESP32-CAM-esp32-cam-jpg-file-Arduino-IDE-Serial-Monitor.png?resize=767%2C492&quality=100&strip=all&ssl=1)
If you go to your local server URL http://IP-Address/uploads, or to your cloud server URL https://example.com/uploads you should have a folder with all your stored photos.
![ESP32-CAM Camera Board Uploads Folder Images stored server Demonstration](https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2020/06/ESP32-CAM-Camera-Board-Uploads-Folder-Images-stored-server.png?resize=691%2C496&quality=100&strip=all&ssl=1)
You can open each link to open a new page with the full image:
![ESP32-CAM Upload Photo or Image to Server PHP Arduino IDE](https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2020/06/ESP32-CAM-Upload-Photo-to-Server-PHP-Arduino-IDE.jpg?resize=828%2C531&quality=100&strip=all&ssl=1)
Now, if you go to your local server URL http://IP-Address/gallery.php, or to your cloud server URL https://example.com/gallery.php, you can access the gallery page, where you can view and delete the photos.
![ESP32-CAM Camera Photo Gallery view PHP file](https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2020/06/ESP32-CAM-Camera-Photo-Gallery-view-PHP-f.jpg?resize=828%2C583&quality=100&strip=all&ssl=1)
To delete any photo, just click on the “Delete file” link next to each image.
![ESP32-CAM delete file from gallery php](https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2020/06/ESP32-CAM-delete-file-from-gallery-php.jpg?resize=828%2C468&quality=100&strip=all&ssl=1)
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.
gallery.php seems horribly broken (and doesn’t work as supplied)
Can you take a look at it and make sure it’s ok?
Upload.php works just as you describe, but gallery.php is a no-go
Hi Greg.
I’m sorry about that.
You are right. Something went wrong while copying the code.
We fixed the problem, and it should be working now.
Regards,
Sara
gallery.php is working fine. I can view the pictures. upload.php is not working.
192.168.86.xxx/upload.php give me the following….
Sorry, only JPG, JPEG, PNG & GIF files are allowed.Sorry, your file was not uploaded.
The same problem happened when pictures are uploaded to Bluehpost.
gallery.php is working fine.
upload.php is given the same problem.
………. Sorry, only JPG, JPEG, PNG & GIF files are allowed.Sorry, your file was not uploaded.
Sorry. I found my own problem. My own mistake. Nothing wrong with upload.php file.
TO access the uploaded picture files , I should type 192.168.86.xxx/uploads (Not 192.168.86.xxx/upload.php)
Hi Sara, how are you? One quick question: I like this project, but I would like to add some other features as follows:
1) To allow a post a picture using a PIR;
2) To allow to have live streaming as well.
Is it to much complicated to get it ? Thanks a lot and I continue to stay tuned!
Hello,
I keep getting an error message:
‘Sorry, there was an error uploading your file.’
the connection to the server was successful.
please help
Make sure you’ve selected the right board and COM Port. If you continue to see the error, it might mean that you have the wiring incorrect or the ESP32-CAM is not in flashing mode (GPIO not connected to GND). Take a look at this dedicated uploading Guide How to Program / Upload Code to ESP32-CAM AI-Thinker (Arduino IDE): https://randomnerdtutorials.com/program-upload-code-esp32-cam/
Thanks for the reply.
The problem was solved by changing the ‘:’ in the file name, as Mirtt wrote in his comment
Please advise, is the ESP32-CAM available for OTA?
Hi Everybody,
if you use it with WAMP server, then set the file name without “:”, for example:
date(‘Y_m_d_H_i_s_’, $datum)
I hope it helps you too
Thanks for letting me know!
Thank you!!!!
Solved the error message
Yes it helped Thanks
Hi Sara, Rui,
I have one question:
At first, everything works fine, ESP32 is connected.
But in the serial monitor are the following lines, I think there is something wrong:
“connection successful!
301 Moved Permanently
Moved Permanently
The document has moved here.
Apache Server at turtle-home.de Port 80
”
Do you have an idea, why it is not working as expected and instead of a picture the upper error is visible?
Thanks in advance,
Bernd
This works for me: medium.com/@sanghviyash6/migrating-any-http-request-to-https-on-esp32-5545a6de7845
i have the same error. anyone have a fix?
Sara,Rui,
I have 2 ESP32-CAM and I want to setup two folders for uploading pictures, saving pictures in uploads and uploads1 directories. And I used serverPath = “/upload.php” and “/upload1.php” for ESP32-CAM .I also setup two php files, upload.php and uploads1.php in the /var/www/html directory.
Only ESP32-CAM ,with uploads.php works.
ESP32-CAM with upload1.php is not sending picture file to uploads1 directory, showing error message as follow….
…..Sorry, there was an error uploading your file
Please help.
Maybe you need check the authority of the usr of apache.
You can add “echo exec(‘whoami’);” in your upload.php, to see who is the usr.
Then give it all permissions like this:
sudo chown -R yourusr /var/www/html
chmod -R 777 /var/www/html/
Hi wsz,
Could you tell me how I can do the “echo exec” in my upload.php?
The upload.php is a text file and you put linux command in your example.
Excuseme but I am newbie and I do not know how to do this.
I have the typycal problem (…..Sorry, there was an error uploading your file)
All things are working fine.
Thank you
Ramón
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;
2) To allow to have the live streaming as well.
Is it to much complicated to get it ? Thanks a lot and I continue to stay tuned!
@Sara & @Rui: +1 could you please consider this feature request and let us know if this is feasible? Thanks.
If you have a github repo for these, we can get contributions from the community as well.
Thanks for the great post.
Hello there! Your tutorials are amazing! Can you please post a post example to a JSP or Java Servlet instead of a PHP? Thanks in advance!
Hi.
Unfortunately, we don’t have anything like that at the moment.
Regards,
sara
Hello Sara, actually i have coded the JSP servlet that is fully compatible with your current code. Maybe it helps someone, or maybe you can add it to the body of the article.
JSP CODE, JUST CUSTOMIZE IMAGESPATH TO YOUR NEEDS:
<%
String imagesPath = “/opt/tomcat9/webapps/uploads/temp”;
File file ;
int maxFileSize = 5000 * 1024;
int maxMemSize = 5000 * 1024;
ServletContext context = pageContext.getServletContext();
String filePath = imagesPath + “/”;
// Verify the content type
String contentType = request.getContentType();
if ((contentType.indexOf(“multipart/form-data”) >= 0)) {
DiskFileItemFactory factory = new DiskFileItemFactory();
// maximum size that will be stored in memory
factory.setSizeThreshold(maxMemSize);
// Location to save data that is larger than maxMemSize.
factory.setRepository(new File(imagesPath));
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
// maximum file size to be uploaded.
upload.setSizeMax( maxFileSize );
try {
// Parse the request to get file items.
List fileItems = upload.parseRequest(request);
// Process the uploaded file items
Iterator i = fileItems.iterator();
while ( i.hasNext () ) {
FileItem fi = (FileItem)i.next();
if ( !fi.isFormField () ) {
// Get the uploaded file parameters
String fieldName = fi.getFieldName();
String fileName = fi.getName();
boolean isInMemory = fi.isInMemory();
long sizeInBytes = fi.getSize();
// Write the file
if( fileName.lastIndexOf("\\") >= 0 ) {
file = new File( filePath + fileName.substring( fileName.lastIndexOf("\\"))) ;
} else {
file = new File( filePath + fileName.substring(fileName.lastIndexOf("\\")+1)) ;
}
fi.write( file ) ;
System.out.println("uploads/upload.jsp: Uploaded Filename: " + filePath + fileName);
}
}
out.println("200");
} catch(Exception ex) {
System.out.println("uploads/upload.jsp: 1006-error");
System.out.println(ex);
out.println("500:ex1006");
}
} else {
System.out.println(“uploads/upload.jsp: no file”);
out.println(“500:ex-no-file”);
}
%>
hi, i am getting below error, can you help???
400 Bad Request
Bad Request
Your browser sent a request that this server could not understand.
Apache/2.4.10 (Debian) Server at 103.110.113.54 Port 80
Seems my commet didn’t showed up.
I have this error:
ESP32-CAM IP Address: 192.168.0.15
Connecting to server: 192.168.0.19
Connection successful!
.
400 Bad Request
Bad Request
Your browser sent a request that this server could not understand.
Apache/2.4.38 (Raspbian) Server at 192.168.0.19 Port 80
I’ve modified the upload.php file to change the “:” by “_” with no effect it seems.
I’m stuck cause i don’t understand what is the issue.
Can you help me here ?
Thanks in advance !
Solved this error. I’ve done a mistake by myself. Please ignore it.
I’ve got another error; this time is seems the server is not getting the needed image format. At this point, don’t know if it is the script on the esp32 that is sending a wrong image format or the server side that has issue.
Feel free to help 🙂
I’ve got an error; this time is seems the server is not getting the needed image format.
At this point, don’t know if it is the script on the esp32 that is sending a wrong image format or the server side that has issue :
Connecting to server: 192.168.0.19
Connection successful!
.
Sorry, only JPG, JPEG, PNG & GIF files are allowed.Sorry, your file was not uploaded.
Please what can I do.
I keep getting 400 bad request enclosed in html tags like center, head, h1 etc what can I do?
facing the same problem
Someone should please help
dont include the https:// in your domain
thank you, it works
I’d love to use this concept for timelapse photography. Is there any way to download all pixs at once.
Ignore my previous comment about downloading all pics. I did not read enough.
Is it possible to use a larger framesize than SVGA?
If I try to use larger framesize, I get errors.
Hi,
I have installed and configured a number of times now but sadly I still get the error :
19:11:47.664 -> The file esp32-cam.jpg has not been uploaded. Sorry, there was an error uploading your file.
19:11:49.157 -> Connecting to server: 192.168.1.216
19:11:52.311 -> Connection successful!
Has anyone any thoughts?
Upload.php tells me the file is rejected due to it not being the correct image file type.
Thanks
D
Doah!!
It’s okay.
I found MY error
All works as expected now although my rpi is interminably s l o w
All the best
Keep safe
David
Hi Sara!,
Thanks for the code!
How can we modify the time zone? It shows pictures with 3 hours time ahead.
Thanks,
MoZen
Hi, Thanks for this super tutorial, I search about POST request to send parameter, but all tutorials using HttpClient to create the POST request, this ESP32-CAM Tutorial used WiFiClient to create the request. We can pass more parameters like temperature to get in PHP with $_POST?
My family keeps horses and our stables are out in the wilds without electricity and so lighting and tools are run from 12vdc lorry batteries and these are kept topped-up with solar panels. Could you perhaps publish a guide to running eg this project from a 12vdc battery and what you would consider to be an ideal psu and where to connect it – I am using the TTGO 800sim for the cloud server and this ESP32 cam to take images when a pir is tripped by wildlife – this saves to the sd card and sends to the server and displayed in the gallery as described above.
It works perfect with my old http server. Thank you! But it fails in case of https. Seems to be much more effort. I guess it would need something like WiFiClientSecure.h or is it much easier?
This works for me: medium.com/@sanghviyash6/migrating-any-http-request-to-https-on-esp32-5545a6de7845
Hello,
Everithing seem working fine, but no picture on the server !
This below is what I get in the serial monitor every 30 secs :
16:33:57.110 -> Connecting to server: http://www.ABCDEF.GH
16:33:57.144 -> Connection successful!
16:33:57.144 -> ..
16:33:57.753 ->
16:33:57.753 ->
16:33:57.753 ->
16:33:57.753 -> 301 Moved Permanently
16:33:57.753 ->
16:33:57.753 ->
Moved Permanently
16:33:57.753 ->
The document has moved here.
16:33:57.753 ->
16:33:57.753 ->
Is it something about server configuration ?
Hi There,
Great work! Can you do the same in MicroPython with ESP-CAM?
Thanks
Hi Everybody,
Is it feasible to use handphone (with sim card) instead of router?
How to achieve?
Regards,
Frank
Hi Sara & Rui
I would like to post these pictures to a website and want to use username and/or password protection.
How would this be implemented in the ESP32 code ?
Thanks for this brilliant tutorial.
Regards
It would be really usefull ! Btw : Thank you for your work 🙂
Upon some corrections the upload become 100% reliable with TinyGSM and BearSSL
sslClient.print(tail);
sslClient.flush();
esp_camera_fb_return(fb);
unsigned long timoutTimer = 10000;
unsigned long startTimer = millis();
boolean state = false;
while ((startTimer + timoutTimer) > millis()) {
Serial.print(".");
delay(250);
while (sslClient.available()) {
char c = sslClient.read();
Here sslClient.flush(); added, (Don’t just copy/paste, set an correct client name for your own sketch) the delay(100); set to delay(250), timoutTimer and startTimer set to “unsigned long” type.
Gracias tía Sara, la amo
Gracias 🙂
Hi, I try to understand how the image is stored into the memory. I used 800×600 pixel (SVGA) setting. When the setting of No Function (s, 0) 39,117 bytes will be transmitted to the server. If I set to Grayscale (s, 2) 30,970 bytes will be transmitted to server. The values exclude head and tail sizes. I cannot relate these values with 800×600 (should be 480,000 bytes). If you can direct me to any information source, please do so.
Its unfortunate, but I did not not manage to setup according to the guide. My esp32 works fine with the default webcamserver program, which means the pin usage should be the same as your setup (CAMERA_MODEL_AI_THINKER), but somehow my PHP file is not getting the image. I get an error on the php saying:
“[proxy_fcgi:error] [pid 11033:tid 139886463997696] [client 192.168.6.15:64826] AH01071: Got error ‘PHP message: PHP Warning: move_uploaded_file(uploads/2021.10.10_09:32:21_esp32-cam.jpg): failed to open stream: No such file or directory in /var/www/html/upload.php on line 50PHP message: PHP Warning: move_uploaded_file(): Unable to move ‘/var/www/html/tmp/phpuPQRSj’ to ‘uploads/2021.10.10_09:32:21_esp32-cam.jpg’ in /var/www/html/upload.php on line 50′”
I am using ubuntu server and started playing around with tmp being in different places when I realized the image does not land in tmp no matter what I do even though the www-data user has permission to create a file.
Then I was looking at the code and it seems somehow the image is not taken correctly or something similar. Any ideas?
16:36:10.149 -> Connection successful!
16:36:10.181 -> ..
16:36:10.394 ->
16:36:10.394 -> 2e
16:36:10.394 -> Sorry, there was an error uploading your file.
16:36:10.394 -> 0
16:36:10.394 ->
16:36:10.394 ->
Hello, Anonim,
Have you solved the problem of “2e… Sorry, there…”?
I am having the same problem and cannot find any information about how to solve it.
Thank you
Example: Send picture used only esp-idf library
static const char *TAG = "server";
#define MAX_HTTP_OUTPUT_BUFFER 2048
esp_err_t send_picture_server_self() {// https://randomnerdtutorials.com/esp32-cam-post-image-photo-server/
esp_err_t result = ESP_FAIL;
camera_fb_t *fb = NULL;
fb = esp_camera_fb_get();
if(!fb) {
custom_delay(1);
esp_restart();
}
esp_http_client_config_t config = {};
config.url = "http://192.168.0.104:4000/picture";
config.event_handler = _http_event_handler;
config.method = HTTP_METHOD_POST;
config.is_async = true;
config.timeout_ms = 5000;
esp_http_client_handle_t client = esp_http_client_init(&config);
std::string head = "--RandomNerdTutorials\r\nContent-Disposition: form-data; name=\"imageFile\"; filename=\"p.jpg\"\r\nContent-Type: image/jpeg\r\n\r\n";
std::string tail = "\r\n--RandomNerdTutorials--\r\n";
size_t imageLen = fb->len;
size_t fbLen = fb->len;
size_t extraLen = head.length() + tail.length();
size_t totalLen = imageLen + extraLen;
esp_http_client_set_method(client, HTTP_METHOD_POST);
ESP_LOGI(TAG, "fb->len = %d", fb->len );
esp_http_client_set_header(client,"Access-Control-Allow-Origin","*");
esp_http_client_set_header(client,"Content-Type","multipart/form-data; boundary=RandomNerdTutorials");
esp_err_t err_open = esp_http_client_open(client,totalLen);
if(err_open!=ESP_OK){
ESP_LOGE(TAG, "Failed to open HTTP connection: %s", esp_err_to_name(err_open));
}else{
int wlen = 0;
int content_length = 0;
char output_buffer[MAX_HTTP_OUTPUT_BUFFER] = {0};
wlen = esp_http_client_write(client,(const char*)head.c_str(),head.length());
if (wlen < 0) {
ESP_LOGE(TAG, "Write failed head");
}
uint8_t *fbBuf = fb->buf;
for (size_t n=0; n<fbLen; n=n+1024) {
if (n+1024 < fbLen) {
wlen = esp_http_client_write(client,(const char*)fbBuf, 1024);
if (wlen < 0) {
ESP_LOGE(TAG, "Write failed chank %d",n);
}
fbBuf += 1024;
}
else if ( (fbLen&10000000000) >0 ) {
//fbLen%1024>0
size_t remainder = fbLen%1024;// or fbLen-n
wlen = esp_http_client_write(client,(const char*)fbBuf, remainder);
if (wlen < 0) {
ESP_LOGE(TAG, "Write failed last chank %d",n);
}
}
}
wlen = esp_http_client_write(client,(const char*)tail.c_str(),tail.length());
if (wlen < 0) {
ESP_LOGE(TAG, "Write failed tail");
}
content_length = esp_http_client_fetch_headers(client);
if (content_length < 0) {
ESP_LOGE(TAG, "HTTP client fetch headers failed");
} else {
int data_read = esp_http_client_read_response(client, output_buffer, MAX_HTTP_OUTPUT_BUFFER);
if (data_read >= 0) {
ESP_LOGI(TAG, "HTTP POST Status = %d, content_length = %lld",
esp_http_client_get_status_code(client),
esp_http_client_get_content_length(client));
ESP_LOG_BUFFER_HEX(TAG, output_buffer, strlen(output_buffer));
} else {
ESP_LOGE(TAG, "Failed to read response");
}
}
}
esp_camera_fb_return(fb);
esp_http_client_cleanup(client);
result = ESP_OK:
return result;
}
is it required to have a router between the esp32-cam and the pi server?
If you set your RPi up as an access point, you should be able to connect your ESP32 to that network, therefore not needing a router. However, you would need to connect your Pi to Ethernet cable for it to be able to connect to the internet (if needed for updates, upgrades, etc)
Hi
I followed you , I can connected server.
But not send image to server.
Serial monitor :
Connecting to server: sittikorndev.rf.gd
Connection successful!
.
/aes.jsfunction toNumbers(d){var e=[];d.replace(/(..)/g,function(d){e.push(parseInt(d,16))});return e}function toHex(){for(var d=[],d=1==arguments.length&&arguments[0].constructor==Array?arguments[0]:arguments,e=””,f=0;fd[f]?”0″:””)+d[f].toString(16);return e.toLowerCase()}var a=toNumbers(“f655ba9d09a112d4968c63579db590b4”),b=toNumbers(“98344c2eee86c3994890592585b49f80”),c=toNumbers(“e7410910f5edeedacac348ba53b2411d”);document.cookie=”__test=”+toHex(slowAES.decrypt(c,2,a,b))+”; expires=Thu, 31-Dec-37 23:55:55 GMT; path=/”; location.href=”http://sittikorndev.rf.gd/test/upload.php?i=1″;This site requires Javascript to work, please enable Javascript in your browser or use a browser with Javascript supportHTTP/1.1 400 Bad Request
Server: nginx
Date: Mon, 28 Feb 2022 21:27:23 GMT
Content-Type: text/html
Content-Length: 150
Connection: close
400 Bad Request
400 Bad Request
nginx
I have followed the steps for bluehost but am getting an error when I try to access the site “Forbidden
You don’t have permission to access this resource.
Additionally, a 403 Forbidden error was encountered while trying to use an ErrorDocument to handle the request.”
any ideas?
I have resolved this issue. Please see new issue below.
I can see the gallery.php but there are only file names not images. When I look in the upload folder the images are there for download so I am not sure what is wrong. I am using cPanel and Bluehost.
Would appreciate some help.
String head = “–RandomNerdTutorials\r\nContent-Disposition: form-data; name=\”imageFile\”; filename=\”001.jpg\”\r\nContent-Type: image/jpeg\r\n\r\n”;
Can you explain this code?
I want to change the name of my photo on the server.
Use Bluetooth to configure the name of photos in real time.
Use a variable instead of esp32-cam in filename=\”esp32-cam.jpg\ ”
thanks a lot!!
What have you tried so far?
What data type are photos stored on esp32cam?
Are the photos uploaded to the server in batches according to 1024b?
Finally, how does the server read the received data into photos?
I am a rookie, thank you for your help!
I really hope you can help. This works like a charm on our local network, but the moment I try it from another WiFi network it does not connect. I changed permissions, made the _ changes in the file and event the php files are working online. I even tried from both Windows and Linux servers and all ports (443, 80, other random ports) where allowed and tested. Its only something stopping it from reading/ uploading over a network. Thanks for a great tutorial.
Never mind, I created a Linux server and everything worked. Our Microsoft server setup was just creating problems and not even our IT team could find the problem. At least I know now that the code is working fantastic.
Which line can we need to add in to call the GPIO13 to sense the PIR motion sensor. Either trigger by motion or every predefine period of time to capture and upload the photo image to the web server.
I recently used this to build some of my home security system, thank you!
If you run into delayed images coming from the frame buffer, add
to your config section. There are two image grabbing modes and my esp_camera.h was defaulting to the other one – causing ten to 20 second delays.
If your converting to https, you can use ->setInsecure() or .setInsucre() along with the other guide posted here to enable https without SSL certification.
Hi.
Thanks for sharing that.
I wasn’t aware of thart configuration.
Regards,
Sara
You save my life. Thank you a lot.
Thank you so much, I had the same issue and tried to understand what was happening. This comment helped so much.
hi i worked some day good but now i have a problem an my pic not uploaded
the Error is
[ 61290][E][WiFiClient.cpp:404] write(): fail on fd 48, errno: 104, “Connection reset by peer”
and i can not find any trig tio soild it ..
please lead me to solve it thanks .
I have the same exact problem on anything larger than VGA
HAs anyone been able to replicate the client with micropython?
Thanks
In case of using a PC as a server and xamp as a host, what should I modify?
Hello, I did all the steps of the tutorial and everything seems to be ok, but when I run the program in ESP CAM and open the serial monitor nothing appears and no photo is sent to the created local server, it seems that the program is stopped somewhere but not I can find the problem, does anyone know how to solve it?
The messages in the Arduino IDE when I run the program are as follows:
esptool.py v3.0-dev
Serial port COM6
Connecting…..
Chip is ESP32-D0WDQ6 (revision 1)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
Crystal is 40MHz
MAC: 3c:61:05:31:03:90
Uploading stub…
Running stub…
Stub running…
Changing baud rate to 460800
Changed.
Configuring flash size…
Auto-detected Flash size: 4MB
Compressed 8192 bytes to 47…
Writing at 0x0000e000… (100 %)
Wrote 8192 bytes (47 compressed) at 0x0000e000 in 0.0 seconds (effective 5041.2 kbit/s)…
Hash of data verified.
Compressed 18656 bytes to 12053…
Writing at 0x00001000… (100 %)
Wrote 18656 bytes (12053 compressed) at 0x00001000 in 0.3 seconds (effective 531.1 kbit/s)…
Hash of data verified.
Compressed 783040 bytes to 454218…
Writing at 0x00010000… (3 %)
Writing at 0x00014000… (7 %)
Writing at 0x00018000… (10 %)
Writing at 0x0001c000… (14 %)
Writing at 0x00020000… (17 %)
Writing at 0x00024000… (21 %)
Writing at 0x00028000… (25 %)
Writing at 0x0002c000… (28 %)
Writing at 0x00030000… (32 %)
Writing at 0x00034000… (35 %)
Writing at 0x00038000… (39 %)
Writing at 0x0003c000… (42 %)
Writing at 0x00040000… (46 %)
Writing at 0x00044000… (50 %)
Writing at 0x00048000… (53 %)
Writing at 0x0004c000… (57 %)
Writing at 0x00050000… (60 %)
Writing at 0x00054000… (64 %)
Writing at 0x00058000… (67 %)
Writing at 0x0005c000… (71 %)
Writing at 0x00060000… (75 %)
Writing at 0x00064000… (78 %)
Writing at 0x00068000… (82 %)
Writing at 0x0006c000… (85 %)
Writing at 0x00070000… (89 %)
Writing at 0x00074000… (92 %)
Writing at 0x00078000… (96 %)
Writing at 0x0007c000… (100 %)
Wrote 783040 bytes (454218 compressed) at 0x00010000 in 10.9 seconds (effective 572.6 kbit/s)…
Hash of data verified.
Compressed 3072 bytes to 119…
Writing at 0x00008000… (100 %)
Wrote 3072 bytes (119 compressed) at 0x00008000 in 0.0 seconds (effective 1755.4 kbit/s)…
Hash of data verified.
Leaving…
Hard resetting via RTS pin…
I have the same problem. Has anyone here already found a solution?
Hi
how can i send esp32 cam image to HW125 module by Arduino UNO?
Hi, I’m trying to use the code, but it only shows this
ESP32-CAM IP Address: 192.168.1.xx
Connecting to server: abc.com
Connection successful!
…………………………………………………………………………..
But no files uploaded. Can anyone help me ? Thanks
hello, I’m having a problem with upload.php where it shows a warning when I try it.
Warning: Undefined array key “imageFile” in C:\xampp\htdocs\upload.php on line 8
Warning: Trying to access array offset on value of type null in C:\xampp\htdocs\upload.php on line 8
Warning: Undefined array key “imageFile” in C:\xampp\htdocs\upload.php on line 32
Warning: Trying to access array offset on value of type null in C:\xampp\htdocs\upload.php on line 32
please help, thank you.
I Have same warning. for that issue downgrade to old version xampp-win32-1.7.0 work well.
Hi @sara, thank you for such an amazing opportunity
Firstly I tried to implement these with sdcard, where I save clips in my sdcard, then upload to server via Http, but failed ,
Secondly I don’t know if it’s as a result of the post boundary format that I am using , (boundary —-WebKitFormBoundary7MA4YWxkTrZ
Is there any way to make esp32cam upload to Instagram or Facebook or some other social media?
Hi.
If you have access to an API to do that, yes, it should be possible with an HTTPS request.
Unfortunatley, we don’t have any tutorials covering that subject.
Regards,
Sara
Hi, I have tried this 5 different ways. I have a LAMP server set up on rpi4 as per your instructions with an esp32-cam thinker. I’ve tried the suggestions in the previous comments. I just can’t seem to get it to work. Serial monitor output.
..
Sorry, there was an error uploading your file.
Connecting to server: 192.168.my.ip
Connection successful!
…
This is every 30 sec. please help I’m new to farily this.
Thanks in advance Bill
hi, I got this project to work for me a while back and that I am back at it, I get this error no matter what i do, ” i redid the whole project with the same error, I need help?
Connecting to server: pabline.com
Connection successful!
…..
301 Moved Permanently
Moved Permanently
The document has moved here.
Hi.
You need to make an HTTPS request instead. The hosting is redirecting the HTTP requests to HTTPS.
We’ll update the tutorial soon with the HTTPS code.
Regards,
Sara
Hi, i am trying to implement this project but when i try to upload the image i get the following response on arduino serial monitor:
12:55:45.900 ->
12:55:45.900 ->
12:55:45.900 ->
12:55:45.900 ->
12:55:45.947 -> 301 Moved Permanently
12:55:45.947 ->
12:55:45.947 ->
12:55:45.947 ->
12:55:45.947 -> 301
12:55:45.947 -> Moved Permanently
12:55:45.947 ->
12:55:45.947 -> The document has been permanently moved.
12:55:45.994 ->
On the upload.php site i get this message:
Warning: Undefined array key “imageFile” in /home/u643723852/domains/myproject.com/public_html/upload.php on line 7
Warning: Trying to access array offset on value of type null in /home/u643723852/domains/myproject.com/public_html/upload.php on line 7
Warning: Undefined array key “imageFile” in /home/u643723852/domains/myproject.com/public_html/upload.php on line 35
Warning: Trying to access array offset on value of type null in /home/u643723852/domains/myproject.com/public_html/upload.php on line 35
Sorry, only JPG, JPEG, PNG & GIF files are allowed. Sorry, your file was not uploaded.
I am using hostinger.com.
Please help,
Thanks in advance
Hi.
I just tried this great tutorial on a raspberry pi zero w,
running a lamp server.
It runs amazingly well!!
Hi.
That’s great!
Thanks for sharing your feedback.
Regards,
Sara
Hi.
WinSCP is really good if you want access,
to the files on the Raspberry Pi local server.
To access the files
In WinSCP from the launch window select your connection then Edit>Advanced>SCP Shell>and change it to sudo -s then save. This will give you root access to the Pi file system
Great.
Thanks for sharing.
Regards,
Sara
Hi is there a way to make this go into deep sleep for say 30 seconds to save power?
Take a look at our deep sleep tutorial: https://randomnerdtutorials.com/esp32-timer-wake-up-deep-sleep/
I hope this helps.
Regards.
Sara
Hi There, Thanks for this awesome tutorial! I noticed that if I increase the resolution anything larger, say SXGA, the POST seems to time out. Any suggestions on how to deal with this?
Sara / Rui – Thanks for an excellent tutorial. After much battling I thought I had things working — it worked for about a day of uploading pics every 30 min or so to my Bluehost site. Gallery worked, etc. Then it just stopped. So I decreased the resolution and set the FB count to one. I tried that comment above about — config.grab_mode = CAMERA_GRAB_LATEST; — but after some errors and investigating the header I saw that was not supported as a config in the library that I have (running the latest IDE 2.1.0). So I double checked the certificate, etc. It kept failing when it got to the “connect to the server” serial print. So I dug a second new ESP32-CAM out that I have, uploaded the code and — it worked first go. So my question — is the first ESP32-CAM toast — or can I somehow re-initialize it? I had uploaded the same code multiple times — and it mostly was working — connecting to wifi, getting the camera info, then failing on the server connect. I did notice that the new one was assigned a new IP local address (but going out to the web by Xfinity). I also couldn’t find any errors or clues up on Bluehost (I wonder if they sometimes block devices?) Thanks for any ideas.
Hi.
Did that same ESP32-CAM worked when uploading the code a second time?
Or did it always fail the same way? Like after one day or something?
Regards,
Sara
The new one also stopped after I moved from the USB on the PC (programing) over to the wall plug USB power supply I had the other one running on. So I decided to use a different USB power supply and then it took off and has been uploading a pic every 10 minutes since this AM. So I am going to try to test the first one on the new supply — but I will first see if reducing the Hz on the camera config. helps — since the first one was also failing to connect even at the PC. It seems like the ESP32-CAM can be a little touchy about power and also where the antenna sits in relation to the CPU (from some additional research).
Yes, that’s true.
It can also be the case that the board gets too hot if running “heavy” code non-stop.
Regards,
Sara
I reduced the Hz the old one with the new power supply and it had been working fine since. Some other notes —
config.xclk_freq_hz = 10000000; <– seemed to help
client.setInsecure(); //skip certificate validation <– couldn’t get to work had to use the root cert
config.grab_mode = CAMERA_GRAB_LATEST; <– this was also not supported in my ESP32-CAM library (esp_camera.h)
Added code to turn port 4 (LED “flash”) on right before a grab and off after
Code snippet to add a text stamp to the JPG in gallery.php (down at the bottom) —
(had to save a true type font in an accessible place).
// Add for Graphic ———————-
$filedata = $_FILES[‘photo’][‘tmp_name’];
….
$jpg_image = imagecreatefromjpeg($filedata);
// Allocate A Color For The Text
$white = imagecolorallocate($jpg_image, 255, 255, 255);
$blue = imagecolorallocate($jpg_image, 0, 0, 255);
//$font_path = ‘http://www.dexterglass.com/fonts/DejaVuSans-Bold.ttf’;
$font_path = ‘/fonts/DejaVuSans-Bold.ttf’;
//$img_date = date(“m-d-Y H:i:s”);
$img_date = new DateTime(‘now’, new DateTimeZone(‘America/New_York’));
$imdt2 = $img_date->format(‘Y-m-d H:i:s’);
imagefilledrectangle($jpg_image, 0, 0, 285, 30, $white);
imagettftext($jpg_image, 16, 0, 10, 20, $blue, $font_path, $imdt2);
// imagejpeg($jpg_image); //– output to browser
imagejpeg($jpg_image,$target_file);
//if (move_uploaded_file($_FILES[“photo”][“tmp_name”], $target_file)) {
echo “The file “. basename($_FILES[“photo”][“name”]). ” has been uploaded.”;
// Clear Memory
imagedestroy($jpg_image);
…
Thanks again for a nice project.
Hi.
Thanks for sharing yout findings.
The problem with CAMERA_GRAB_LATEST is probably because you don’t have the latest version of the ESP32 installed.
Go to Tools > Board > Boards Manager, search for ESP32 and check the version. You probably need to update.
Regards,
Sara
Sara – Looks like the latest ESP Library. I am on Arduino 2.1.0 — ESP Arduino board library 1.0.4 — board = AI Thinker ESP32-CAM
Hi.
You need to update the link on the Preferences menu to be able to update to the latest version.
Go to this tutorial: https://randomnerdtutorials.com/installing-the-esp32-board-in-arduino-ide-windows-instructions/
and follow the section called “Installing ESP32 Add-on in Arduino IDE”. It uses an updated link, that will allow you to update to most recent versions.
Regards,
Sara
Thanks for that. I guess I forgot to check when I updated to Arduino 2.0 — maybe it wiped out the repositories (I will bet there was a note I neglected to read).
Then, let me know if that solves the issue.
Regards,
Sara
It has been grabbing clips steady now for 2 days. So all set. The board(s) I have seem to be a little picky on the start-up — needed to do it a few times before it connected up and started running (tried the boot/reset – and also the power on/off — so ?? don’t know which worked. You were correct about the update to the ESP library — I checked esp_camera.h and the “config.grab_mode = CAMERA_GRAB_LATEST” is there now. Have not tried to add it yet — but will soon.
Great!
I’m glad everything is working fine now.
Regards,
Sara
Hi Sara & Rui: thank you for this great tutorial. I Got it up and running with some modifications. I swapped out the timer for a PIR sensor. I’d like to set an extra level of security with an API key in the post data as in this tutorial: https://randomnerdtutorials.com/esp32-esp8266-mysql-database-php/
I hacked around for a while and couldn’t implement it. Thanks again
Sorry to take up so much of your time. One more question — so the ESP-CAM was working fine on the one wifi I use for development. When I moved it to another wifi it seemed to fail at the point it needs to upload the image. The serial monitor on the second wifi shows a good connection to the local wifi and also connection to the Bluehost server — it appears to upload, but I never get the message that the JPG has been uploaded. And on the server side I see a PHP error where the watermark code I added says there is no image. I can hit the web site from the second location. When I moved the same EPS-CAM back to the development wifi — it works great (even when the rest button had fallen completely off the board — which was what I thought might have been the issue) … (grrr) … Maybe I need to write a Perl program to see if I can upload a JPG (and see what errors get thrown). Any ideas about what might be going on? Thanks.
Thanks, was running great for me until server upgraded php to 8.1. Uploads.php no longer works. Could you tell me what version of php was used in the tutorial — so I can try downgrading my php to that version.
Thanks so much for your tutorials!
curt_wells
Hello Sara, hello Rui,
I like your project and it worked for me right away. The ESP32-Cam module is taking a pic every 30s and sending it to the Pi. perfect 🙂
Is there a possibility to have more than just one camera connecting to the pi and sending the pictures? I would need at least two better three Cam modules which are observering a larger object.
Thanks a lot
BR
Ralf
Hi.
Yes.
I think you just need to copy the same code for all boards.
On the server side you may want to have a folder for each camera or have each picture with a name that identifies the camera so that you know from which camera the pictures are from.
Regards,
Sara
Hi,
I have seen some users said about getting the error
“2e
Sorry, there was an error uploading your file.”
And also that they solved.
I am using hostgator server.
What is the way to solve this error?
Thanks, regards
that esp32cam code not sending current photo on every 30 sec its sending old pics like buffer image each time that not good why its happening even google has no answer
Hi Sara.
ESP32 Cam works with a 5Vdc 1A power supply and external antenna, everything works very well, it sends photos every 5 minutes to the altervista site, this for 3-4 days then it doesn’t send any more photos, I have to turn the camera off and on again and everything starts working again for 3-4 days. I am using Arduino IDE 1.8.19 and ESP32 by Expressif ver. 1.0.6.
Do you have any suggestions to solve this problem??
Thanks in advance and regards
Roby
Hi Sara,
thanks for your website and code.
It worked for me first, but suddenly i can’t connect to the webserver any more.
ESP32-CAM IP Address: 192.168.0.126
Connecting to server: xxx.de
Connection to xxx.de failed.
Any idea where i can look at?
Can it be my webserver(Managed Server) blocking for any (sercurity) reason?
thanks in advance and regards
Stefan
Hi Sara, Hi Rui,
I like your work and it worked for me right away.
The ESP32-Cam module takes a picture every 30 seconds and sends it to my web server, perfect.
I can’t modify this project for my own needs because very simply
I’m a beekeeper and I only know about bees.
For those of you who know programming very well and provide us with all these nice sketches (thanks a lot for that) I think it would be easy to make a modification so that the images are uploaded to the server when motion detection (without PIR) occurs on the camera
Thank you very much
Alexander Greece
Hi.
Thanks for your suggestion.
Unfortuantely, I don’t have a sketch to detect motion based on video/pictures.
Regards,
Sara
You could use a raspberry pi with a program called “motion” or MotionEye OS , with a minor mod to count detected Bee motion events. I use a pi 3b to watch my driveway. A PiZero would probably work.
Hi Sara, Rui
Thank you for this code example. It works just great.
I have a question regarding the upload.php. There is this section which checks the submit- value:
// Check if image file is a actual image or fake image
if(isset($_POST[“submit”])) {
To me it looks that there is no such value in the sending part of the example, as none of the echoed values regarding image type are shown. So is this section totally unnecessary?
I also would like to know if there is any method to add a parameter to the sent post message, like the number or name of the sending camera (1, 2 etc.)
Thanks again and keep up the good work.
Petri
Hello – I was able to add a section to the PHP to insert a tag in the image — here is a code clip (you need to have a font available to the script) —
// 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 {
$jpg_image = imagecreatefromjpeg($filedata);
// Allocate A Color For The Text
$white = imagecolorallocate($jpg_image, 255, 255, 255);
$blue = imagecolorallocate($jpg_image, 0, 0, 255);
//$font_path = ‘http://your_web_host_url/fonts/DejaVuSans-Bold.ttf’;
$font_path = ‘/fonts/DejaVuSans-Bold.ttf’;
//$img_date = date(“m-d-Y H:i:s”);
$img_date = new DateTime(‘now’, new DateTimeZone(‘America/New_York’));
$imdt2 = $img_date->format(‘Y-m-d H:i:s’);
imagefilledrectangle($jpg_image, 0, 0, 285, 30, $white);
imagettftext($jpg_image, 16, 0, 10, 20, $blue, $font_path, $imdt2);
// imagejpeg($jpg_image); //– output to browser
imagejpeg($jpg_image,$target_file);
//if (move_uploaded_file($_FILES[“photo”][“tmp_name”], $target_file)) {
echo “The file “. basename($_FILES[“photo”][“name”]). ” has been uploaded.”;
// Clear Memory
imagedestroy($jpg_image);
}
Did you ever get this worked out?
I cannot figure out how to add anything to the form data to go along with the image.
Seems like it would be common and simple, but I am not finding any information RE “client.write” to populate form fields or otherwise get data to the receiver php file.
Hi Sara or anybody else who might be reading this lines,
you might be aware the TimerCam-F is not often specifically referenced in randomnerdtutorials. I try to adapt as far as possible the nice sample provided for the Typ F Cam. But even with simplest
example ‘capture.ino’ accessible at ‘https://github.com/m5stack/TimerCam-arduino/tree/master’
it fails for larger pic size configurations as denoted below. Could you probably give me a hint
how that might be addressed to be solved?
I would like to increase pix size of the picture as denoted below, but up on the size and higher resolution than:
FRAMESIZE_SVGA, // 800×600
the function ‘TimerCAM.Camera.get()’ gives any no response at all.
Remark: I have the latest TimerCam-arduino-master.zip 1.0.0 installed, but
I don’t have much experience with the right memory settings/management (that’s all taken by default in my case).
I expect the size FRAMESIZE_UXGA, // 1600×1200 should also work as max. resolution.
Many thanks for your help and answer in advance!
Minu
: )