?How can you increase the speed of sending images from arduino to the server

.I use esp32 and send images to a python server that I created
.The esp32 camera captures images and sends to the server
The response times for sending the images to the server are done at different times each time, .once every 7 seconds and once every half a second
.I would like to know how to optimize the running time and make it uniform and faster

Here is my arduino code:

#include <Arduino.h>
#include <WiFi.h>
#include "soc/soc.h"
#include "soc/rtc_cntl_reg.h"
#include "esp_camera.h"
//#include "app_httpd.cpp"
#include "carMotor.h"

//String serverName = "192.168.43.61";   // REPLACE WITH YOUR Raspberry Pi IP ADDRESS
//String serverName = "192.168.164.104";
String serverName = "192.168.50.104";

//String serverName = "example.com";   // OR REPLACE WITH YOUR DOMAIN NAME

String serverPath = "/upload";     // The default serverPath should be upload.php

const int serverPort = 8000;

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

#define STOP_SIGN "stop"
#define SPEED_LIMIT_50 "limit50"
#define PEDESTRIAN "pedestrian"
#define KEEP_RIGHT "keepRight"
#define CROSSWALK "crossWalk"
#define SPEED_LIMIT_100 "limit100"

#define SPEED_50 40
#define SPEED_100 80
#define DEFAULT_SPEED 60

void WheelAct(int nLf, int nLb, int nRf, int nRb);
const int timerInterval = 30000;    // time between each HTTP POST image
unsigned long previousMillis = 0;   // last time image was sent

int carSpeed = DEFAULT_SPEED;
int cycle = 10;
void setup() {
  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); 
  Serial.begin(115200);

  pinMode(gpLb, OUTPUT); //Left Backward
  pinMode(gpLf, OUTPUT); //Left Forward
  pinMode(gpRb, OUTPUT); //Right Forward
  pinMode(gpRf, OUTPUT); //Right Backward
  pinMode(gpLed, OUTPUT); //Light

  //initialize
  digitalWrite(gpLb, LOW);
  digitalWrite(gpLf, LOW);
  digitalWrite(gpRb, LOW);
  digitalWrite(gpRf, LOW);
  digitalWrite(gpLed, LOW);


  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;
  //config.frame_size = FRAMESIZE_QQVGA; 
  config.frame_size = FRAMESIZE_96X96;
  // 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();
  }

  //establishConnection();
}
void handlePedestrian(){
  stop();
}
void handleStopSign(){
  //stop for 3 seconds
  stop();
  delay(3000);
}
void handleCrossWalk(){
  carSpeed = 35;
  moveForward(); 
}
void handleKeepRight(){
  int lastSpeed = carSpeed;
  carSpeed = 35;
  moveRight();
  carSpeed = lastSpeed;
}
void handleLimit50(){
  carSpeed = SPEED_50;
}
void handleLimit100(){
  carSpeed = SPEED_100;
}
void drive(String direction) {
  if (strcmp(direction.c_str(), PEDESTRIAN) == 0) {
    handlePedestrian();
  }
  else if (strcmp(direction.c_str(), STOP_SIGN) == 0) {
    handleStopSign();
  }
  else if (strcmp(direction.c_str(), CROSSWALK) == 0) {
    handleCrossWalk();
  }
  else if (strcmp(direction.c_str(), KEEP_RIGHT) == 0) {
    handleKeepRight();
  }
  else if (strcmp(direction.c_str(), SPEED_LIMIT_50) == 0) {
    handleLimit50();
  }
  else if (strcmp(direction.c_str(), SPEED_LIMIT_100) == 0) {
    handleLimit100();
  }
  else { //none
    moveForward();
  }
}
void lights(bool on) {
  if (on) {
      digitalWrite(gpLed, HIGH);
  }
  else {
      digitalWrite(gpLed, LOW);    
  }
}
int ControlSpeed() {
  int parton = cycle * carSpeed/100;
  return parton;
}

void moveForward() {
  int parton = ControlSpeed();
  for (int loop=0; loop<100; loop++) {
    WheelAct(HIGH, LOW, HIGH, LOW);
    delay(parton);
    WheelAct(LOW, LOW, LOW, LOW);
    delay(cycle-parton);
  }
}
void moveBackward() {
  int parton = ControlSpeed();
  for (int loop=0; loop<100; loop++) {
    WheelAct(LOW, HIGH, LOW, HIGH);
    delay(parton);
    WheelAct(LOW, LOW, LOW, LOW);
    delay(cycle-parton);
  }
}
void moveRight() {
  int parton = ControlSpeed();
  for (int loop=0; loop<100; loop++) {
    WheelAct(LOW, HIGH, HIGH, LOW);
    delay(parton);
    WheelAct(LOW, LOW, LOW, LOW);
    delay(cycle-parton);
  }
}
void moveLeft() {
  int parton = ControlSpeed();
  for (int loop=0; loop<100; loop++) {
    WheelAct(HIGH, LOW, LOW, HIGH);
    delay(parton);
    WheelAct(LOW, LOW, LOW, LOW);
    delay(cycle-parton);
  }
}
void loop() {
    String response = sendPhoto();
    response.trim();
    drive(response);
    delay(500);
}
void stop(){
  WheelAct(LOW, LOW, LOW, LOW);
}
void establishConnection() {
  // Establish the initial connection with the server
  if (client.connect(serverName.c_str(), serverPort)) {
    Serial.println("Connection successful!");
  } else {
    Serial.println("Connection to " + serverName + " failed.");
  }
}

void closeConnection() {
  // Close the connection with the server
  client.stop();
  Serial.println("Connection closed.");
}

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);
    Serial.print("head sent!");
    uint8_t *fbBuf = fb->buf;
    size_t fbLen = fb->len;

    for (size_t n = 0 ; n < fbLen; n=n+1024) {
      Serial.print(".");
      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);
    Serial.print("tail sent!");
    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);
    Serial.println("Photo sent");
  }
  else {
    getBody = "Connection to " + serverName +  " failed.";
    Serial.println(getBody);
  }
  return getBody;
}

Thank you

If I understand you correctly, you think that the transfer of an image needs from half a second to seven seconds.

I miss an analysis of where this time is spent. Is it the server that responds not fast enough? Is it the network that doesn't have the transfer speed you want? Are the images of more or less the same size? Do you really need the delay() calls?

I would like the operation of sending an image to the server to be around 0.5-1 second
Sometimes this process takes way longer (seconds) which is critical for system function
The question is if is there any alternative way (and faster) to capture an image from the camera and send it to the server.
Note: when I decrease the image resolution the process became faster obviously, but it comes at the expense of the image quality.

The delay is between every image transmition, which is not included in the time measurement of the process mentioned above, so it's not relevant.
Thanks

You didn't answer any of my questions. Did you read my answer?

Why do you rule out the server part completely? Did you use Wireshark to catch what's actually going on on the network? If yes, post the raw files!

Network problems. Unless you are willing to do the required full analysis, this method will not work.

Built a ESP32 bot with Cam few months back, plan on digging into some more soon..
Some points..
I found using one ESP32 for drive control and image streaming to be a bit ratchet..
and take in mind I was sending pics in a separate task and I noticed this..
waiting for drive commands coming back in response to sending an image probably not going to fly..
I myself will probably end up with a second dedicated esp32 cam just for streaming the images..

Bot source here..

try to separate the drive command from image transfers, then maybe try a separate task for the cam and see how it goes..
this way image transfers don't slow down the reception of drive parameters..

http has some overhead, just connecting a client may take some time, be best to raise and keep the connection..

good luck.. ~q

I guess it would depend on how large your images are. Just for comparison have you tried the
esp32 camera example code ? There is a option for image capture. The example sends the image to a client (browser) and the processing is done in javascript.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.