Skip to content

Jrodmac/asistenteIA

Repository files navigation

Carla — Asistente de voz con visión (ESP32-P4)

Asistente de voz conversacional para la placa Guition JC-ESP32P4-M3-DEV. Habla y escucha en tiempo real conectándose directamente a la Gemini Live API por WebSocket (sin servidor intermedio), y ve: cuando se lo pides, hace una foto con la cámara y se la manda al modelo para que describa lo que tiene delante.

  • 🎙️ Voz bidireccional en tiempo real (mic 16 kHz → Gemini, respuesta 24 kHz → altavoz).
  • 👁️ Visión bajo demanda: la foto se envía solo cuando lo pides ("mira", "¿qué ves?"…), para no gastar cuota. La cámara captura la imagen del instante en que lo pides.
  • 🔎 Búsqueda en Google (grounding) para datos actuales.
  • 📝 Recordatorios con fecha persistentes en flash (NVS) vía function calling.
  • ♻️ Sesión continua: compresión de ventana de contexto + reanudación tras cortes de red.

La persona del asistente ("Carla") y los datos del usuario se configuran en main/config.h (SYSTEM_INSTRUCTION).


Hardware

Componente Detalle
Placa Guition JC-ESP32P4-M3-DEV (ESP32-P4)
WiFi Vía ESP32-C6 como slave (esp-hosted / esp_wifi_remote)
Códec audio ES8311 + amplificador NS4150B
Cámara OV5647 (MIPI-CSI) → ISP → encoder JPEG por hardware

Pines (demo del fabricante, no el BSP de la EV board oficial):

I2S:  MCLK=13  BCLK=12  WS=10  DOUT=9  DIN=48
PA (amplificador) = GPIO 11        I2C (SDA=7, SCL=8, compartido códec + cámara)

⚠️ El BSP de la EV board oficial tiene DIN/PA intercambiados (DIN=11, PA=53). En esta placa es DIN=48, PA=11. Está documentado en main/config.h.


Estructura del proyecto

Código modular en main/, cada fichero con una responsabilidad (≤300 líneas):

main/
├── app_main.c            Orquestador: arranca wifi, SNTP, audio, cámara, notas, ws, tareas
├── config.h              Configuración (audio, pines, persona, modelo Gemini)
├── secrets.h             Credenciales — NO versionado (ver «Configuración»)
├── app_state.h/.c        Estado compartido entre tareas (banderas de sesión, colas…)
├── net/
│   └── wifi.c/.h         Conexión WiFi (modo estación)
├── audio/
│   ├── audio.c/.h        Códec ES8311 + I2S (init, read, write)
│   └── audio_tasks.c/.h  mic_task, spk_task y resampler 24→16 kHz
├── gemini/
│   ├── gemini.h          API del protocolo Gemini Live
│   ├── gemini_session.c  Handshake: setup + saludo de arranque
│   ├── gemini_send.c     Envíos: audio del mic, encolado de audio, toolResponse
│   ├── gemini_rx.c       Parseo de los mensajes entrantes
│   └── ws.c/.h           Transporte WebSocket (TLS) + watchdog de reconexión
├── vision/
│   └── vision.c/.h       Detección "mira", envío de foto y worker de recordatorios
├── camera/
│   └── camera.c/.h       Cámara: captura de foto JPEG bajo demanda + endpoint /pic
└── notes/
    └── notes.c/.h        Recordatorios con fecha en NVS

Cómo funciona la visión

La cámara queda en streaming (encendida) pero no codifica ni guarda nada entre peticiones. Cuando pides "mira", camera_capture_jpeg() vacía los frames viejos de la cola V4L2, coge el primer frame fresco (sensor a 50 fps ≈ 100 ms) y lo manda a Gemini como realtimeInput.video. Así la imagen es siempre la del momento y no se malgasta CPU ni cuota.


Requisitos

  • ESP-IDF v5.3 o superior con soporte para ESP32-P4 (esp_video, esp_cam_sensor, esp_wifi_remote/esp-hosted).
  • Toolchain de ESP32-P4 instalada por el install de ESP-IDF.
  • Las dependencias gestionadas se descargan solas (component manager) a partir de main/idf_component.yml y dependencies.lock.

Configuración

Las credenciales van en main/secrets.h, que no se sube al repo. Crea el tuyo a partir de la plantilla:

cp main/secrets.h.example main/secrets.h

y rellena:

#define WIFI_SSID       "TU_WIFI"
#define WIFI_PASSWORD   "TU_PASSWORD"
#define GEMINI_API_KEY  "TU_API_KEY"   // https://aistudio.google.com/apikey

El resto de ajustes (persona del asistente, voz, ganancia del mic, calidad JPEG, pines…) están en main/config.h.

🔒 Seguridad: la API key queda embebida en el binario; quien tenga el .bin puede leerla. Usa una key dedicada y revócala si se filtra.


Compilar y flashear

idf.py set-target esp32p4
idf.py build
idf.py -p <PUERTO> flash monitor

(<PUERTO> = COMx en Windows, /dev/ttyUSBx o /dev/ttyACMx en Linux/Mac.)

Al arrancar, en cuanto haya WiFi y se sincronice la hora, Carla saluda en voz alta: esa es la señal de que la sesión está lista y ya puedes hablar.


Depuración

Con la cámara activa, el firmware levanta un pequeño servidor HTTP (puerto 80):

  • http://<IP>/pic — una foto JPEG suelta.
  • http://<IP>/ — vista casi en vivo (auto-refresco) para enfocar.

La IP aparece en el log del monitor al conectar el WiFi.


Notas

  • main/_old/ y main/context/ no entran al build (código histórico / experimental).
  • server.py es el antiguo relay en Python, ya no se usa (la conexión es directa a Google).
  • En otra máquina, tras clonar, recuerda crear main/secrets.h o el build fallará con "no such file: secrets.h".

About

robot asistente para compañia

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors