Skip to content

Recon Camera Module

Le module Camera permet le streaming vidéo en temps réel depuis un ESP32-CAM vers le serveur C2.

Hardware Requis

Ce module nécessite un ESP32-CAM avec module caméra OV2640.

Configuration

Activer dans menuconfig:

Epsilon Bot Configuration → Modules → Recon Commands
Epsilon Bot Configuration → Recon Settings → Enable Camera Reconnaissance


Vue d'Ensemble

┌────────────────────────────────────────────────────────────────────┐
│                      CAMERA MODULE                                  │
├────────────────────────────────────────────────────────────────────┤
│                                                                     │
│   ┌─────────────────────────────────────────────────────────────┐  │
│   │                    ESP32-CAM                                 │  │
│   │                                                              │  │
│   │   ┌──────────┐    ┌──────────────┐    ┌─────────────────┐   │  │
│   │   │ OV2640   │───►│ JPEG Encoder │───►│ UDP Packetizer  │   │  │
│   │   │ Sensor   │    │ (hardware)   │    │                 │   │  │
│   │   └──────────┘    └──────────────┘    └────────┬────────┘   │  │
│   │                                                 │            │  │
│   └─────────────────────────────────────────────────│────────────┘  │
│                                                     │               │
│                                                     ▼               │
│   ┌─────────────────────────────────────────────────────────────┐  │
│   │                    UDP STREAM                                │  │
│   │                                                              │  │
│   │   ┌─────────┐   ┌─────────┐   ┌─────────┐   ┌─────────┐     │  │
│   │   │ TOKEN + │   │ TOKEN + │   │ TOKEN + │   │ TOKEN + │     │  │
│   │   │ "START" │──►│ Chunk 1 │──►│ Chunk 2 │──►│  "END"  │     │  │
│   │   └─────────┘   └─────────┘   └─────────┘   └─────────┘     │  │
│   │                                                              │  │
│   └─────────────────────────────────────────────────────────────┘  │
│                                                     │               │
│                                                     ▼               │
│   ┌─────────────────────────────────────────────────────────────┐  │
│   │                    C3PO SERVER                               │  │
│   │                                                              │  │
│   │   UDP Receiver ──► Frame Assembly ──► Web Dashboard         │  │
│   │                                    ──► Video Recording      │  │
│   │                                                              │  │
│   └─────────────────────────────────────────────────────────────┘  │
│                                                                     │
└────────────────────────────────────────────────────────────────────┘

Spécifications Techniques

Hardware

Composant Spécification
Module ESP32-CAM (AI-Thinker)
Capteur OV2640
Résolution max 1600x1200
Interface DVP (Digital Video Port)
PSRAM 4MB (requis pour haute résolution)

Configuration Caméra (Firmware)

camera_config_t cfg = {
    .pixel_format   = PIXFORMAT_JPEG,
    .frame_size     = FRAMESIZE_QQVGA,  // 160x120
    .jpeg_quality   = 20,                // 0-63, plus bas = meilleur
    .fb_count       = 2,                 // Double buffer
    .fb_location    = CAMERA_FB_IN_PSRAM,
    .grab_mode      = CAMERA_GRAB_LATEST
};

Performance du Stream

Métrique Valeur
Résolution 160x120 (QQVGA)
Format JPEG
Qualité 20 (bon compromis taille/qualité)
FPS ~7 images/seconde
Bande passante ~50 KB/s
Taille frame ~5-10 KB
Latence ~200-500ms

Protocole UDP

Structure des Paquets

Chaque paquet UDP commence par un token d'authentification suivi des données.

┌─────────────────────────────────────────────────────────┐
│                    Paquet UDP                            │
├─────────────────┬───────────────────────────────────────┤
│  TOKEN (16B)    │           PAYLOAD                      │
│                 │                                        │
│ Sup3rS3cretT0k3n│  START | JPEG_CHUNK | END             │
└─────────────────┴───────────────────────────────────────┘

Séquence de Frame

Frame N:
  [1] TOKEN + "START"           ─► Début de frame
  [2] TOKEN + JPEG_CHUNK_1      ─► Données (max 2034 bytes)
  [3] TOKEN + JPEG_CHUNK_2      ─► Données
  [4] TOKEN + JPEG_CHUNK_3      ─► Données
  [5] TOKEN + "END"             ─► Fin de frame

Frame N+1:
  [1] TOKEN + "START"           ─► Début de frame suivante
  ...

Configuration du Token

Le token est configurable dans menuconfig:

Epsilon Bot Configuration
└── Recon Settings
    └── Camera UDP Token: "Sup3rS3cretT0k3n"

Sécurité

Changez le token par défaut en production. Il doit correspondre à CAMERA_SECRET_TOKEN dans le fichier .env du C2.


Commandes

cam_start

Démarre le streaming UDP vers le serveur C2.

Syntaxe:

c2:> send <device_id> cam_start <ip> <port>

Paramètres:

Paramètre Type Description
ip string Adresse IP du serveur C2
port int Port UDP (défaut: 5000)

Séquence de démarrage:

  1. Initialisation de la caméra (si premier appel)
  2. Création du socket UDP
  3. Validation de l'adresse IP
  4. Démarrage de la task de streaming
  5. Envoi des frames en continu

Exemple:

c2:> send espilon-cam cam_start 192.168.1.50 5000
[espilon-cam] INFO: stream started target=192.168.1.50:5000

Logs ESP32 (debug):

I (12345) CAMERA: camera initialized
I (12546) CAMERA: socket created: fd=54
I (12547) CAMERA: target: 192.168.1.50:5000 (addr=0x3201a8c0)
I (12548) CAMERA: stream started
I (12648) CAMERA: frame #1: 8234 bytes, 5 chunks, sock=54

cam_start Gauche: Output ESP32 | Droite: Web Dashboard avec flux vidéo


cam_stop

Arrête le streaming vidéo.

Syntaxe:

c2:> send <device_id> cam_stop

Comportement:

  1. Signal d'arrêt à la task de streaming
  2. Fermeture du socket UDP
  3. Libération des ressources

Exemple:

c2:> send espilon-cam cam_stop
[espilon-cam] INFO: stream stopped

# Log ESP32:
I (98765) CAMERA: stream stopped after 1234 frames

cam_stop Gauche: Output ESP32 | Droite: Réponse dans C3PO


Configuration C2

Démarrer le Récepteur

Dans le C3PO, lancez le récepteur UDP avant de démarrer le stream:

c2:> camera
[SYSTEM] Camera UDP receiver started on 0.0.0.0:5000

Démarrer le Web Dashboard

Pour visualiser le flux:

c2:> web
[SYSTEM] Web server started on http://0.0.0.0:8000

Accéder à http://localhost:8000 et naviguer vers la section Camera.

Enregistrement Vidéo

Enregistrer le flux en fichier AVI:

c2:> record start
[SYSTEM] Recording started: static/streams/record.avi

# ... streaming ...

c2:> record stop
[SYSTEM] Recording stopped (1234 frames saved)

Wiring ESP32-CAM

Pinout Standard (AI-Thinker)

ESP32-CAM Pinout:
                    ┌─────────────────┐
              3V3   │ ●             ● │   5V
              GND   │ ●             ● │   GND
             IO12   │ ●             ● │   IO13 (U0RXD)
             IO15   │ ●             ● │   IO14
             IO14   │ ●             ● │   IO2
             IO13   │ ●             ● │   IO4 (FLASH LED)
                    │                 │
                    │   ┌─────────┐   │
                    │   │         │   │
                    │   │  CAM    │   │
                    │   │  OV2640 │   │
                    │   │         │   │
                    │   └─────────┘   │
                    │                 │
                    └─────────────────┘

Pins Utilisés par la Caméra

Fonction GPIO Description
PWDN 32 Power down (actif bas)
RESET -1 Non utilisé
XCLK 0 Horloge caméra
SIOD 26 I2C Data (SCCB)
SIOC 27 I2C Clock (SCCB)
D7-D0 35,34,39,36,21,19,18,5 Données parallèles
VSYNC 25 Sync verticale
HREF 23 Sync horizontale
PCLK 22 Pixel clock

Dépannage

Problèmes Courants

Symptôme Cause Probable Solution
"camera init failed" Mauvais wiring Vérifier les connexions
Pas de réception C2 Firewall UDP Ouvrir le port 5000
Image noire PWDN non géré Vérifier GPIO 32
Stream saccadé Réseau saturé Réduire la qualité
Crash après démarrage Pas de PSRAM Utiliser ESP32-CAM avec PSRAM

Debug Avancé

Activer les logs verbose dans menuconfig:

Component config → Log output → Default log verbosity → Debug

Logs utiles:

I (12345) CAMERA: frame #100: 8234 bytes, 5 chunks, sock=54
E (12445) CAMERA: chunk 3/5 send failed: errno=11 (EAGAIN)
E (12545) CAMERA: too many errors, stopping stream

Vérifier la Réception

Côté C2, les logs indiquent la réception:

[CAMERA] Receiving from 192.168.1.100
[CAMERA] Frame complete: 8234 bytes
[CAMERA] FPS: 7.2


Optimisation

Améliorer le FPS

  1. Réduire la résolution: QQVGA (160x120) est optimal
  2. Augmenter la qualité JPEG: 20-30 est un bon compromis
  3. Réduire le délai inter-frame: Modifier vTaskDelay(pdMS_TO_TICKS(140))

Réduire la Latence

  1. Utiliser un réseau WiFi 5GHz si disponible
  2. Réduire la distance ESP32 ↔ AP
  3. Éviter les interférences WiFi

Économiser la Bande Passante

  1. Réduire la résolution
  2. Augmenter le numéro de qualité JPEG (plus de compression)
  3. Réduire le FPS cible

Cas d'Usage

Surveillance Discrète

# ESP32-CAM caché avec batterie USB
c2:> send hidden-cam cam_start 192.168.1.50 5000

# Monitoring depuis le C2
c2:> web
# Ouvrir http://localhost:8000/camera

Enregistrement Automatique

# Script Python pour enregistrement automatisé
import schedule

def start_recording():
    c2.send("hidden-cam", "cam_start", "192.168.1.50", "5000")
    c2.execute("record start")

def stop_recording():
    c2.execute("record stop")
    c2.send("hidden-cam", "cam_stop")

# Enregistrer de 9h à 18h
schedule.every().day.at("09:00").do(start_recording)
schedule.every().day.at("18:00").do(stop_recording)

Sécurité

Token d'Authentification

Le token empêche les injections de frames malveillantes:

  • Changez le token par défaut
  • Utilisez un token long et aléatoire
  • Synchronisez entre ESP32 et C2

Chiffrement

Le stream UDP n'est pas chiffré par défaut. Pour les environnements sensibles:

  • Utilisez un VPN entre ESP32 et C2
  • Ou implémentez un chiffrement au niveau applicatif

Précédent: FakeAP Module | Suivant: Recon MLAT