Multiple ESP32 cams using one as a Soft Access point

Hi! I'm trying to have a multiple ESP-32 camera setup (just 2). I'm trying to have one camera act as a soft access point creating its own wifi server basically. And the second one just connecting to that same wifi that cam 1 created and sending its feed. Does anyone have an example of a 2 camera setup but with one camera acting as a soft access point, not where they both connect to a wifi signal like in a home. Thank you!

@Idahowalker might have some info.
Wait for them to weigh in.

My initial thought is that the ESP32 cam would be busy processing images and that the ESP32 CAM may be RAM challenged to store images from other ESP32 cams as well as doing the AP thing.

I do not have an example.

My ESP32CAM's FTP's their images to a Raspberry Pi for processing.

That's the setup I was hoping you'd bring up. Seems like the best option for OP.

and if the OP is interested

#include "sdkconfig.h" // used for log printing
#include "esp_system.h"
#include "freertos/FreeRTOS.h" //freeRTOS items to be used
#include "freertos/task.h"
#include "certs.h"
#include "esp_camera.h"
#include "soc/soc.h"           // Disable brownout problems
#include "soc/rtc_cntl_reg.h"  // Disable brownout problems
#include "driver/rtc_io.h"
#include <WiFi.h>
#include <WiFiClient.h>
#include "ESP32_FTPClient.h"
//
WiFiClient wifiClient; // do the WiFi instantiation thing
ESP32_FTPClient ftp (ftp_server, ftp_user, ftp_pass, 5000, 2);
////
void IRAM_ATTR WiFiEvent(WiFiEvent_t event)
{
  switch (event) {
    case SYSTEM_EVENT_STA_CONNECTED:
      log_i("Connected to WiFi access point");
      break;
    case SYSTEM_EVENT_STA_DISCONNECTED:
      log_i("Disconnected from WiFi access point");
      break;
    case SYSTEM_EVENT_AP_STADISCONNECTED:
      log_i("WiFi client disconnected");
      break;
    default: break;
  }
} // void IRAM_ATTR WiFiEvent(WiFiEvent_t event)
////
void setup()
{
  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector
  ////
  if ( configInitCamera() )
  {
    xTaskCreatePinnedToCore( capturePhoto_sendFTP, "capturePhoto_sendFTP", 20000, NULL, 3, NULL, 1 );
  } else {
    log_i( "camera failed to initilize. Quitting programed operations." );
  }
} // void setup()
////
void capturePhoto_sendFTP( void *pvParameters )
{
  TickType_t xLastWakeTime    = xTaskGetTickCount();
  const TickType_t xFrequency = 100; //delay for mS
  for (;;)
  {
    log_i( "tick");
    if ( WiFi.status() == WL_CONNECTED )
    {
      camera_fb_t * fb = NULL; // pointer
      fb = esp_camera_fb_get();
      if (!fb)
      {
        log_i( "Camera capture failed" );
      } else {
        ftp.OpenConnection(); // try open FTP
        if ( ftp.isConnected() )
        {
          //try send file ftp
          ftp.ChangeWorkDir( ftp_path );
          // Delete existing file, create the new file, and send the image to the file
          ftp.DeleteFile( ftp_file_name );
          ftp.InitFile( ftp_file_type ); //"Type I"
          ftp.NewFile( ftp_file_name );
          ftp.WriteData( (unsigned char *)fb->buf, fb->len );
          ftp.CloseFile();
          ftp.CloseConnection();
        }
        esp_camera_fb_return(fb); //return the frame buffer back to the driver for reuse
      }
    } else {
      log_i( "In capturePhoto_sendFTP found WiFi not connected ");
      connectToWiFi();
    }
    xLastWakeTime = xTaskGetTickCount();
    vTaskDelayUntil( &xLastWakeTime, xFrequency );
  }
  vTaskDelete( NULL );
} //void capturePhoto_sendFTP( void *pvParameters )
////
void configureCameraSettings()
{
  sensor_t * s = esp_camera_sensor_get(); //see certs.h for more info
  s->set_brightness(s, -1);     // -2 to 2 **************************
  s->set_contrast(s, 0);       // -2 to 2
  s->set_saturation(s, 0);     // -2 to 2
  s->set_special_effect(s, 0); // 0 to 6 (0 - No Effect, 1 - Negative, 2 - Grayscale, 3 - Red Tint, 4 - Green Tint, 5 - Blue Tint, 6 - Sepia)
  s->set_whitebal(s, 1);       // 0 = disable , 1 = enable
  s->set_awb_gain(s, 1);       // 0 = disable , 1 = enable
  s->set_wb_mode(s, 0);        // 0 to 4 - if awb_gain enabled (0 - Auto, 1 - Sunny, 2 - Cloudy, 3 - Office, 4 - Home)
  s->set_exposure_ctrl(s, 1);  // 0 = disable , 1 = enable
  s->set_aec2(s, 0);           // 0 = disable , 1 = enable
  s->set_ae_level(s, 0);       // -2 to 2
  s->set_aec_value(s, 300);    // 0 to 1200
  s->set_gain_ctrl(s, 1);      // 0 = disable , 1 = enable
  s->set_agc_gain(s, 0);       // 0 to 30
  s->set_gainceiling(s, (gainceiling_t)0);  // 0 to 6
  s->set_bpc(s, 0);            // 0 = disable , 1 = enable
  s->set_wpc(s, 1);            // 0 = disable , 1 = enable
  s->set_raw_gma(s, 1);        // 0 = disable , 1 = enable
  s->set_lenc(s, 1);           // 0 = disable , 1 = enable
  s->set_hmirror(s, 0);        // 0 = disable , 1 = enable
  s->set_vflip(s, 0);          // 0 = disable , 1 = enable
  s->set_dcw(s, 1);            // 0 = disable , 1 = enable
  s->set_colorbar(s, 0);       // 0 = disable , 1 = enable
} //void configureCameraSettings()
////
bool configInitCamera()
{
  camera_config_t config = {}; // Stores the camera configuration parameters
  config.ledc_channel = LEDC_CHANNEL_0;
  config.ledc_timer   = LEDC_TIMER_0;
  config.pin_d0       = GPIO_NUM_5; //Y2
  config.pin_d1       = GPIO_NUM_18; //Y3
  config.pin_d2       = GPIO_NUM_19; //Y4
  config.pin_d3       = GPIO_NUM_21; //Y5
  config.pin_d4       = GPIO_NUM_36; //Y6
  config.pin_d5       = GPIO_NUM_39; //Y7
  config.pin_d6       = GPIO_NUM_34; //Y8
  config.pin_d7       = GPIO_NUM_35; // Y9
  config.pin_xclk     = GPIO_NUM_0; //XCLK
  config.pin_pclk     = GPIO_NUM_22; //PCLK
  config.pin_vsync    = GPIO_NUM_25; //VSSYNC
  config.pin_href     = GPIO_NUM_23; // HREF
  config.pin_sscb_sda = GPIO_NUM_26; //SIOD
  config.pin_sscb_scl = GPIO_NUM_27; //SIOC
  config.pin_pwdn     = GPIO_NUM_32; //PWDN
  config.pin_reset    = -1; //RESET
  config.xclk_freq_hz = 20000000;
  config.pixel_format = PIXFORMAT_JPEG; //assuming default is has PSRAM
  config.frame_size = FRAMESIZE_UXGA; // FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA
  config.jpeg_quality = 10; //0-63 lower number means higher quality
  config.fb_count = 2;
  // Initialize the Camera
  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    log_i("Camera init failed with error 0x%x", err);
    return false;
  } else {
    configureCameraSettings();
    return true;
  }
} //void configInitCamera()
////
void connectToWiFi()
{
  int TryCount = 0;
  while ( WiFi.status() != WL_CONNECTED )
  {
    TryCount++;
    WiFi.disconnect();
    WiFi.begin( SSID, PASSWORD );
    vTaskDelay( 4000 );
    if ( TryCount == 10 )
    {
      ESP.restart();
    }
  }
  WiFi.onEvent( WiFiEvent );
}
////
void loop() {}

the FTP code I use.

1 Like

@Idahowalker Thank you for that! now on terms of the raspberry pi side thats capable of setting up its own wifi to connect to with a smartphone? sorry if thats a simple question, not a lot of experience with raspberry Pis! Would node red be an option or would that require connection to the internet?

Many questions about the RPi can asked on the https://forums.raspberrypi.com/ site.

hmm you should try to connect the cameras by ESPnow and send the information through that, but the ESP32CAMs do a lot of work just processing his own stuff maybe its going to work but very slow. If you want to "stream video" you can create a webserver on each camera and then connect that with external apps. Or if you want to just take photos, you can connect both to a same server (for example firebase) and trigger the photos at the same time. The best answer really depends of your final goal

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