Page 1 of 1

Assistance with Tranfer image from ESP32-Cam to ESP32 via serial

Posted: Wed Apr 08, 2020 8:54 pm
by Pcborges
Hi, I have run out of GPIO pins on my ESP32 project but still need to capture a picture.
For that I am trying to use an ESP32-Cam.
Cameras need a lot of pins and I just do not have them available.
The ESP-Cam takes the picture and sends to ESP32, I would like to get the image and send it to FTP but I am facing a lot of problems most related with the content of the image to arrive in a format that can be used by the FTP client to send it to the net.

That is the first time I am using serial to transfer a lot of data.
The picture is in its native format when it is written to the serial port of the ESP32-CAM but on the receiving side the only thing I could make work was Serial2.readString();
So things start to take a bad route from here because I did not find a way to convert String to const unsigned char that successfully compiles so I hope there is another way to accomplish it.

The code on the ESP32-Cam side is as below:

Code: Select all

/* Take picture when requested and sends via serial to Master ESP32*/

#include "esp_camera.h"
#include "Arduino.h"
#include "soc/soc.h"           // Disable brownour problems
#include "soc/rtc_cntl_reg.h"  // Disable brownour problems
#include "driver/rtc_io.h"

// Pin definition for 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

#include <HardwareSerial.h>
HardwareSerial Comm(1);

void setup() {
  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector
  Serial.begin(115200);                     // Define and start serial monitor
  Comm.begin(962100, SERIAL_8N1,12,13);     //, Comm_Txd_pin, Comm_Rxd_pin); // Define and start Comm serial port
  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; 
    config.jpeg_quality = 10;
    config.fb_count = 2;
  } else {
    config.frame_size = FRAMESIZE_SVGA;
    config.jpeg_quality = 12;
    config.fb_count = 1;
  // Init Camera
  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.printf("Camera init failed with error 0x%x", err);

void loop() {
  bool takePicture=0;
  while (Comm.available()) {                         // Wait for the Receiver to get the characters
    takePicture = Comm.parseInt();                // Display the Receivers characters  
    if(takePicture == 1){
      Serial.print("Received: ");
      camera_fb_t * fb = NULL;
      // Take Picture with Camera
      fb = esp_camera_fb_get(); 
      Comm.write(fb->buf, fb->len);               // payload (image), payload length   SENT Via Serial to ESP32
      Serial.print(" - Pic Size: ");   
The code that is to receive the image and forward it to the FTP server is as below:

Code: Select all

/*Receives picture via serial and saves to ftp*/

#include <WiFi.h>
// WiFi credentials.
char ssid[] = "myWiFi;
char pass[] = "myWFPass";

// Define NTP Client to get time
#include <NTPClient.h>
#include <WiFiUdp.h>
NTPClient timeClient(ntpUDP);

// Variables to save date and time
String formattedDate;
String dayStamp;
String timeStamp;

// FTP Client Lib
#include "ESP32_FTPClient.h"

// FTP Server credentials
char ftp_server[] = "";
char ftp_user[]   = "";
char ftp_pass[]   = "mypass";
ESP32_FTPClient ftp (ftp_server, ftp_user, ftp_pass);

// Camera, URL and picture name
String picPrefix ="";
String pic_name;  
String pic_url   = "";
String imageContent="";

// Connection timeout;
#define CON_TIMEOUT   10*1000                     // milliseconds

void setup(){
  //Serial.begin(Baud Rate, Data Protocol, Txd pin, Rxd pin);
  Serial.begin(115200);                                                     // Define and start serial monitor
  Serial2.begin(962100, SERIAL_8N1); //Receiver_Txd_pin, Receiver_Rxd_pin); // Define and start Receiver serial port

  WiFi.begin( ssid, pass );
  Serial.println("\nConnecting to WiFi");
  while ( WiFi.status() != WL_CONNECTED && millis() < CON_TIMEOUT )  {

void loop(){
  Serial.print("Requesting Pic: "); 
  while (Serial2.available()) {                         // Wait for the Receiver to get the characters
    imageContent = Serial2.readString();         // Saves the Received characters
      Serial.print("Recebida: ");
      Serial.println(imageContent);                  // Display the result on the serial monitor
      pic_name  = picPrefix;
      pic_name += getDateTime() + ".jpg";

void FTP_upload(){
  Serial.print("Uploading via FTP");
  //Create a file and write the image data to it;
  ftp.InitFile("Type I");
  const char *f_name = pic_name.c_str();
  ftp.NewFile( f_name );
  const char *buf = imageContent.c_str();
  //ftp.WriteData(buf, sizeof(buf));                     //***invalid conversion from 'const char*' to 'unsigned char*' [-fpermissive]
  // Breath, withouth delay URL failed to update.
  Serial.println("Done... Waiting next shot...");

String getDateTime(){
  String curDateTime="";

  while(!timeClient.update()) {
  // The formattedDate comes with the following format:
  // 2018-05-28T16:00:13Z
  // We need to extract date and time
  formattedDate = timeClient.getFormattedDate();

  #ifdef DEGUB_ESP
    // Extract date
    int splitT = formattedDate.indexOf("T");
    dayStamp = formattedDate.substring(0, splitT);
    // Extract time
    timeStamp = formattedDate.substring(splitT+1, formattedDate.length()-1);
    Serial.print("DATE: ");
    Serial.print("HOUR: ");
  curDateTime  = formattedDate.substring(8,10);  //day
  curDateTime += formattedDate.substring(5,7);   //month
  curDateTime += formattedDate.substring(2,4);   //year
  curDateTime += formattedDate.substring(11,13); //hour
  curDateTime += formattedDate.substring(14,16); //minute
  return curDateTime;

The idea is that when the ESP32 script needs a picture it will request to ESP32-Cam sending a true, otherwise the ESP32-Cam should stay idle waiting for a new request. In this test code ESP32 keeps requesting pictures for diagnostic purposes.
Please notice my main difficulty is to receive the picture in a format that can be accepted by the upload routine.
Compile error line is indicated on the code.

Thanks in Advance.