Hello, I'm still new to the process of managing char array data types.
I have a project that uses esp32cam - arduino mega. the flow is esp32cam takes a picture then it is converted to base64 and then base64 data is sent to arduino mega via serial communication.
i have tried the way from here but the problem is the arduino mega is not enough memory due to the large size of the char array variable. Is there any other solution or method I can use to solve this problem? Thanks in advance
https://forum.arduino.cc/t/transfer-pictures-from-esp32-cam-to-esp32-via-serial/647488
Here is my code:
Esp32Cam (Sender) based on fustyles Base64 lib
#include "soc/soc.h"
#include "soc/rtc_cntl_reg.h"
#include "Base64.h"
#include "esp_camera.h"
#include "SerialTransfer.h"
SerialTransfer myTransfer;
// WARNING!!! Make sure that you have either selected ESP32 Wrover Module,
// or another board which has PSRAM enabled
//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
String command, phrase;
char chara;
char img_64[20000];
void setup() {
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);
Serial.begin(115200);
Serial.println("Wellcam");
myTransfer.begin(Serial);
Serial.setDebugOutput(true);
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_UXGA;
config.jpeg_quality = 10; //0-63 lower number means higher quality
config.fb_count = 2;
} else {
config.frame_size = FRAMESIZE_SVGA;
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();
}
//drop down frame size for higher initial frame rate
sensor_t * s = esp_camera_sensor_get();
s->set_framesize(s, FRAMESIZE_QVGA); // VGA|CIF|QVGA|HQVGA|QQVGA
}
void loop() {
while(Serial.available()){
delay(10);
chara = Serial.read();
if(chara == '\n'){break;}
phrase += chara;
}
if(phrase.length()>0){
Serial.println(phrase);
if (phrase == "Data"){
CapaturedPhoto64();
delay(200);
}
else{
Serial.println("Data Palsu");
}
phrase ="";
}
}
void CapaturedPhoto64() {
Serial.println("Take Photo -----");
uint16_t sendSize = 0;
//capture 1
for (int i = 0; i <= 3; i++) {
camera_fb_t * fb = NULL;
fb = esp_camera_fb_get();
if(!fb) {
Serial.println("Camera capture failed");
delay(1000);
ESP.restart();
return;
}
esp_camera_fb_return(fb);
delay(200);
}
camera_fb_t * fb = NULL;
fb = esp_camera_fb_get();
char *input = (char *)fb->buf;
char output[base64_enc_len(3)];
String imageFile = "data:image/jpeg;base64,";
for (int i=0;i<fb->len;i++) {
base64_encode(output, (input++), 3);
if (i%3==0) imageFile += urlencode(String(output));
}
esp_camera_fb_return(fb);
int file_len = imageFile.length()+1;
imageFile.toCharArray(img_64, file_len);
sendSize = myTransfer.txObj(img_64, sendSize);
///////////////////////////////////////// Send buffer
myTransfer.sendData(sendSize);
delay(500);
//Serial.println(imageFile);
//Serial.println("####Image size = " + String(imageFile.length()));
}
//https://github.com/zenmanenergy/ESP8266-Arduino-Examples/
String urlencode(String str)
{
String encodedString="";
char c;
char code0;
char code1;
char code2;
for (int i =0; i < str.length(); i++){
c=str.charAt(i);
if (c == ' '){
encodedString+= '+';
} else if (isalnum(c)){
encodedString+=c;
} else{
code1=(c & 0xf)+'0';
if ((c & 0xf) >9){
code1=(c & 0xf) - 10 + 'A';
}
c=(c>>4)&0xf;
code0=c+'0';
if (c > 9){
code0=c - 10 + 'A';
}
code2='\0';
encodedString+='%';
encodedString+=code0;
encodedString+=code1;
//encodedString+=code2;
}
yield();
}
return encodedString;
}
Arduino mega (Receiver)
#include "SerialTransfer.h"
SerialTransfer myTransfer;
String command, data_read;
char img_64[20000];
void setup() {
Serial.begin(115200);
Serial2.begin(115200);
Serial.println("Wellcam .... ");
myTransfer.begin(Serial2);
}
void loop() {
if(Serial.available()){
command = Serial.readStringUntil('\n');
if(command.equals("Data")){
Serial.println(F("Req data...."));
Serial2.print(F("Data\n"));
}
else{
Serial.println(F("Invalid command"));
}
}
if(myTransfer.available()>0){
uint16_t recSize = 0;
recSize = myTransfer.rxObj(img_64, recSize);
Serial.println(F("#######"));
Serial.println(img_64);
Serial.print(F("Total size:"));
Serial.println(sizeof(img_64));
}
}