/**
* Ejemplo de servidor de cámara web con ESP32-S3 + módulo de cámara.
* Configura la cámara, se conecta a la red WiFi y sirve un stream MJPEG.
* URL de acceso: http://<IP_local> tras la conexión.
*/
/* ───────── KODE | docs.kode.diy ───────── */
#include "esp_camera.h"
#include <WiFi.h>
/* ===========================
Credenciales WiFi
=========================== */
const char *ssid = "**********"; /* Nombre de la red WiFi */
const char *password = "**********"; /* Contraseña de la red WiFi */
/* Declaración de funciones externas (implementadas en otros archivos) */
void startCameraServer();
void setupLedFlash();
void setup() {
Serial.begin(115200);
Serial.setDebugOutput(true);
Serial.println();
/* ─── Configuración de pines y parámetros de la cámara ─── */
camera_config_t config;
config.ledc_channel = LEDC_CHANNEL_0;
config.ledc_timer = LEDC_TIMER_0;
config.pin_d0 = 12;
config.pin_d1 = 11;
config.pin_d2 = 1;
config.pin_d3 = 2;
config.pin_d4 = 3;
config.pin_d5 = 39;
config.pin_d6 = 40;
config.pin_d7 = 41;
config.pin_xclk = -1;
config.pin_pclk = 13;
config.pin_vsync = 42;
config.pin_href = 43;
config.pin_sccb_sda = 48;
config.pin_sccb_scl = 47;
config.pin_pwdn = -1;
config.pin_reset = 44;
config.xclk_freq_hz = 20000000; /* Frecuencia XCLK */
config.frame_size = FRAMESIZE_UXGA; /* Resolución inicial */
config.pixel_format = PIXFORMAT_JPEG; /* Formato para streaming */
//config.pixel_format = PIXFORMAT_RGB565; // Opción para detección facial
config.grab_mode = CAMERA_GRAB_WHEN_EMPTY;
config.fb_location = CAMERA_FB_IN_PSRAM;
config.jpeg_quality = 12; /* Calidad JPEG (menor número = mejor calidad) */
config.fb_count = 1;
/* Ajustar configuración si hay PSRAM disponible */
if (config.pixel_format == PIXFORMAT_JPEG) {
if (psramFound()) {
config.jpeg_quality = 10;
config.fb_count = 2;
config.grab_mode = CAMERA_GRAB_LATEST;
} else {
/* Si no hay PSRAM, reducir resolución para no agotar RAM */
config.frame_size = FRAMESIZE_SVGA;
config.fb_location = CAMERA_FB_IN_DRAM;
}
} else {
/* Ajuste para detección/ reconocimiento facial */
config.frame_size = FRAMESIZE_240X240;
#if CONFIG_IDF_TARGET_ESP32S3
config.fb_count = 2;
#endif
}
#if defined(CAMERA_MODEL_ESP_EYE)
pinMode(13, INPUT_PULLUP);
pinMode(14, INPUT_PULLUP);
#endif
/* ─── Inicialización de la cámara ─── */
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
Serial.printf("Error al iniciar la cámara: 0x%x", err);
return;
}
/* Obtener acceso al sensor para ajustes adicionales */
sensor_t *s = esp_camera_sensor_get();
/* Reducir tamaño de frame para aumentar la velocidad inicial */
if (config.pixel_format == PIXFORMAT_JPEG) {
s->set_framesize(s, FRAMESIZE_QVGA);
}
/* Voltear imagen verticalmente */
s->set_vflip(s, 1);
/* ─── Conexión WiFi ─── */
WiFi.begin(ssid, password);
WiFi.setSleep(false); /* Evitar suspensión de WiFi */
Serial.print("Conectando a WiFi");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi conectado");
/* ─── Iniciar servidor de cámara ─── */
startCameraServer();
Serial.print("Cámara lista. Accede a: http://");
Serial.println(WiFi.localIP());
}
void loop() {
/* El servidor web gestiona el streaming; bucle vacío */
delay(10000);
}