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
Serial.println("Listening...");
camera_config_t config;
config.ledc_channel = LEDC_CHANNEL_0;
config.ledc_timer = LEDC_TIMER_0;
config.pin_d0 = Y2_GPIO_NUM;
config.pin_d1 = Y3_GPIO_NUM;
config.pin_d2 = Y4_GPIO_NUM;
config.pin_d3 = Y5_GPIO_NUM;
config.pin_d4 = Y6_GPIO_NUM;
config.pin_d5 = Y7_GPIO_NUM;
config.pin_d6 = Y8_GPIO_NUM;
config.pin_d7 = Y9_GPIO_NUM;
config.pin_xclk = XCLK_GPIO_NUM;
config.pin_pclk = PCLK_GPIO_NUM;
config.pin_vsync = VSYNC_GPIO_NUM;
config.pin_href = HREF_GPIO_NUM;
config.pin_sscb_sda = SIOD_GPIO_NUM;
config.pin_sscb_scl = SIOC_GPIO_NUM;
config.pin_pwdn = PWDN_GPIO_NUM;
config.pin_reset = RESET_GPIO_NUM;
config.xclk_freq_hz = 20000000;
config.pixel_format = PIXFORMAT_JPEG;
if(psramFound()){
config.frame_size = FRAMESIZE_UXGA; // FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA
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);
return;
}
}
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: ");
Serial.print(takePicture);
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: ");
Serial.println(fb->len);
esp_camera_fb_return(fb);
}
break;
}
}
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>
WiFiUDP ntpUDP;
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[] = "ftp.mysite.com";
char ftp_user[] = "esp32@mysite.com";
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 ) {
delay(500);
Serial.print(".");
}
}
void loop(){
Serial.print("Requesting Pic: ");
Serial.println(1);
Serial2.println(1);
delay(100);
while (Serial2.available()) { // Wait for the Receiver to get the characters
imageContent = Serial2.readString(); // Saves the Received characters
if(imageContent.length()>0){
Serial.print("Recebida: ");
Serial.println(imageContent); // Display the result on the serial monitor
pic_name = picPrefix;
pic_name += getDateTime() + ".jpg";
//FTP_upload();
break;
}
}
Serial.println("");
delay(10000);
}
void FTP_upload(){
Serial.print("Uploading via FTP");
ftp.OpenConnection();
//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]
ftp.CloseFile();
// Breath, withouth delay URL failed to update.
Serial.println("Done... Waiting next shot...");
delay(100);
}
String getDateTime(){
String curDateTime="";
while(!timeClient.update()) {
timeClient.forceUpdate();
}
// 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.println(formattedDate);
Serial.print("DATE: ");
Serial.println(dayStamp);
Serial.print("HOUR: ");
Serial.println(timeStamp);
#endif
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.
Paulo