How to Integrate ESP32 Cam with Particle Boron?

Hi,

I have an ESP32 cam and Particle Boron, I want to transfer images serially from ESP32 to Particle and then to the sever. I would be very grateful If someone can guide me.

Thanks

Hi-

Sending images with the Boron is very difficult since it’s a pretty low bandwidth device. Some users have been successful but it’s an arduous process.

@rickkas7 have you done something similar to this?

As Colleen pointed out, there are bandwidth and size issues. From the Pi, however, if you have a not too large image and JPEG compress it (easy on the Pi), you can get it to a reasonable size.

Then you need to get it by serial (or I2C or SPI) to the Boron. This will require software on both sides of the connection. If you use serial, it’s kind of like the Aruino to Particle example, except you need to write the other side as a Linux app using sockets.
https://docs.particle.io/tutorials/learn-more/about-serial/#communicating-with-an-arduino

Then the next part is what to do with the image. The TrackerCamera is intended for the Tracker, but it would be easy to adapt to other devices.
https://github.com/rickkas7/TrackerCamera

Here is what I am doing. Capturing an image every 2 minutes and storing it in the buffer.

// ESP32 cam code

void loop() {
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= timerInterval) {
    if(!captured_image)
    capture_image();
    previousMillis = currentMillis;
  }
  while(Serial.available())
  {
    // S0 means start packet 0 
    if(captured_image && Serial.readString().equals("S0"))
     send_next_packet=true;
    //   SN means Send Next packet   
    else if(captured_image && Serial.readString().equals("SN"))
     send_next_packet=true;
      
  }
  if(send_next_packet)
   Send_serial_packet();
} 


void capture_image(){
 
  fb_global = esp_camera_fb_get();
  if(!fb_global) {
    // indicate serially that image capture failed
    Serial.print("0000");
    delay(1000);
    ESP.restart();
    return;
  }
   image_length = fb_global->len;
   fbBuf_global = fb_global->buf; 
   captured_image=true;

   packets_of_buffer=image_length/buffer_length;
//    if (fbLen%1024>buffer_length)
//      reminder_lenght=    
   current_packet=0; 
  
  }

void Send_serial_packet(){
      
       if(!captured_image)
           return   
       // if current packet number is more then max packets then look for reminder of image data
        if(current_packet>packets_of_buffer)
          { 
            // if there is a reaminder data
             if (image_length%buffer_length>0) {
              size_t remainder = image_length%1024;
              Serial.write(fbBuf_global, remainder);
            }
            // all packets are sent clear the camera buffer and end of transmission
            esp_camera_fb_return(fb_global);
            Serial.print("EOT");
            // make it availble to capture new image
            captured_image=false; 
            current_packet=0;
           
          }
          else
          {
            // send the next packet
             Serial.write(fbBuf_global, buffer_length);
             // increment the buffer for next transmission
             fbBuf_global += buffer_length;
             current_packet++;
          }
            
       send_next_packet=false;
     
  }

The image is only 15kb JPEG compressed. On the Particle side, I am going to use store image in a buffer, and when complete I am going to transfer it via TCP client.

void  sendPhoto() {
  String getAll;
  String getBody;
  
  if (client.connect(serverName.c_str(), serverPort)) {
    Serial.println("Connection successful!");    
    String head = "Content-Disposition: "
                  "form-data; name=\"imageFile\"; filename=\"esp32-cam.jpg\"\r\n"
                  "Content-Type: image/jpeg\r\n\r\n";
    uint32_t imageLen =image_length;
    uint32_t extraLen = head.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;");
    client.println();
    client.print(head);
    
    for (size_t n=0; n<imageLen ; n=n+1024) {
      if (n+1024 < imageLen ) {
        client.write(image_buf, 1024); 
        Serial.write(image_buf, 1024);
        image_buf+= 1024;
      }
      else if (imageLen %1024>0) {
        size_t remainder = imageLen %1024;
        client.write(image_buf, remainder);
         Serial.write(image_buf, remainder);
      }
}

Hi,

Yes, it is done thanks @rickkas7 and everybody for making my code more readable. The image file size is about 10kb that I sent via TCP client.

From the Particle website
In a Free plan, there are 100k Data Operations per month and up to 100 devices.

Each Particle Publish, Subscribe, Function or Variable consumes one Data Operation regardless of size (currently limited to 622 bytes per operation). In the Console, the user-initiated Ping and Signal buttons are metered as well.

My question is what about the TCP client data. How it is measured?

Thanks

TCP does not use data operations and does not count against that limit. However, there is a 45 MB limit on cellular data, across your entire fleet of free plan cellular devices (up to 100 devices), so you are limited to that.

For Wi-Fi devices (Argon, Photon), TCP and UDP data do not have a limit.

Oh, thanks for the information.