Sending Picture from ESP32-CAM to Arduino via UART & LoRa

Hi, I want to send a picture from ESP32-CAM to Arduino Uno via UART and then want to send the same picture that I received, from Uno to another Uno with LoRa. The way that I’m planning to use is taking encrypted codes of picture from Serial Monitor. If there's a better way, I'm open to new ones.

First of all, the thing is format of the payload, the way how it encrypted. In my code I got two different outputs from the picture, JPEG (I'm not sure about that) and HEX (And that one is weird too, you'll see). When I'm trying to read these encrypted codes, couldn't decode and open the picture.

So I want to find a better way to send. Actually haven't decided yet that which way will I use. It can be Base64 or HEX as well.

So my questions are :

1-) Is taking the picture from serial monitor a good way? Which way can you prefer to sending picture between things that I mention?

2-) Which encoding way is the easiest one to transferring picture?

3-) In my code that I’ll add below, I can get JPEG & HEX. When I record the last part with CoolTerm software, I’m can reach to picture. But If I send it with UART to Uno, I cannot decode it. It’s probably cuz of comm problems. What is the safest and easiest way to send?

4-) In code, I cannot use the HEX output. It’s kind of different from other HEX encrypted pictures. Why and how can I use it?

5-) What are the exactly my outputs from this code?

Here's my code :

#include "esp_camera.h"
#include "soc/soc.h"
#include "soc/rtc_cntl_reg.h"
#include "driver/rtc_io.h"
#include "img_converters.h" // https://github.com/espressif/esp32-camera/blob/master/conversions/include/img_converters.h

#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


size_t jpgCallBack(void * arg, size_t index, const void* data, size_t len)
{
  uint8_t* basePtr = (uint8_t*) data;
  for (size_t i = 0; i < len; i++) {
    Serial.write(basePtr[i]);
  }
  return 0;
}

void setup() {

  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);

  Serial.begin(115200);

  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_GRAYSCALE;

  if (psramFound()) {
    config.frame_size = FRAMESIZE_QQVGA; // Boyut degistirmek icin QQVGA|QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA
    config.fb_count = 2;
  } else {
    Serial.println(F("PSRAM NOT FOUND"));
    return;
  }

  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.printf("CAMERA ERROR 0x%x", err);
    return;
  }

  camera_fb_t * fb = NULL;
  
  Serial.print("5 SEC TO PHOTO");
  delay(5000);
  
  fb = esp_camera_fb_get();

  if (!fb) {
  Serial.print("ERROR WHILE TAKING PHOTO");
    return;
  }

  Serial.printf("\nWidht = %u, Height=%u\n", fb->width, fb->height);
  
    for (size_t i = 0; i < fb->len; i++)
    {
    if (i % 16 == 0) Serial.printf("\n%06u\t", i);
    if (fb->buf[i] < 0x10) Serial.write('0');
    Serial.print(fb->buf[i], HEX);
    }
  
  Serial.print("\n\nSTART RECORDING\n\n");
  delay(5000);

  frame2jpg_cb(fb, 10, jpgCallBack, NULL); // https://github.com/espressif/esp32-camera/blob/b02992a5b88571bdad0660ee652a620aaabc994a/conversions/include/img_converters.h#L54

  esp_camera_fb_return(fb);
}

void loop() {}

Here are my outputs from the serial monitors, both of are from Arduino Uno. Datas are taken from ESP32-CAM via UART.

Could any problem exist in the Uno code that you didn't post?

Here's the Uno code:

#include <SoftwareSerial.h>

SoftwareSerial mySerial(2, 3); // RX, TX

void setup()
{
  Serial.begin(115200);
  
  mySerial.begin(115200);
  
}

void loop()
{  
  
  if (mySerial.available() > 0)
  {
    char c = mySerial.read();
    Serial.print(c);
  }
}

I wouldn't count on SoftwareSerial to run at 115200 on an Uno.

By the way, why are you doing this? What is the purpose of the intermediate Uno between the ESP32 and the destination Uno? Why can't you just send it directly from the ESP32 to the destination Uno? And why do you want to send it anyway?