IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Arduino Discussion :

Comment utiliser l'image de la caméra ESP32-S3-N16R8 CAM development board


Sujet :

Arduino

  1. #1
    Candidat au Club
    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Janvier 2019
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes

    Informations forums :
    Inscription : Janvier 2019
    Messages : 10
    Par défaut Comment utiliser l'image de la caméra ESP32-S3-N16R8 CAM development board
    Bonjour :)
    Je cherche à démarrer le module ESP32-S3-N16R8 CAM Development Board WiFi + Bluetooth with OV2640 camera for Arduino (acheté sur AliExpress).
    Je n'arrive pas à obtenir la documentation de ce produit précis (j'ai la doc de ESP32-S3-N16R8 VROOM : ce n'est pas le bon module).
    Je programme en C++ et j'utilise VSCode pour développer (je ne suis pas un "pro").
    J'utilise un programme généré par Le CHAT qui doit lire la caméra et envoyer l'image sur l'écran de mon PC.
    J'ai réussi à compiler le programme et à le charger dans le module ... mais il ne se passe rien : ni image, ni message d'erreur :(
    Le programme demande de définir le PINOUT du module (je n'ai pas cette information).
    Il y a 16 paramètres à définir : PWDN, RESET, XCLK, SIOD, SIOC, Y9, Y8, Y7, Y6, Y5, Y4, Y3, Y2, VSYNC, HREF et PCLK.
    J'ai testé 6 combinaisons de PINOUT extraites de divers programmes ESP32 CAM (ESP32 EYE, Espressif, XIAO CAM, AI thinker, WROOM, ...) sans succès.
    Aujourd'hui, je ne sais plus quoi tenter pour démarrer mon module ...
    Et j'aimerais beaucoup obtenir un peu d'aide ! Merci !!!

    platforIO.ini
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    [env:esp32-s3-devkitc1-n16r8]
    platform = espressif32
    board = esp32-s3-devkitc1-n16r8
    framework = arduino
    monitor_speed = 115200
    Programme C++
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    #include "Arduino.h"
    #include "esp_camera.h"
     
    // Définition des broches pour ESP32 S3 WROOM (China)
    #define PWDN_GPIO_NUM     -1
    #define RESET_GPIO_NUM    -1
    #define XCLK_GPIO_NUM     15
    #define SIOD_GPIO_NUM      4
    #define SIOC_GPIO_NUM      5
    #define Y9_GPIO_NUM       16
    #define Y8_GPIO_NUM       17
    #define Y7_GPIO_NUM       18
    #define Y6_GPIO_NUM       12
    #define Y5_GPIO_NUM       10
    #define Y4_GPIO_NUM        8
    #define Y3_GPIO_NUM        9
    #define Y2_GPIO_NUM       11
    #define VSYNC_GPIO_NUM     6
    #define HREF_GPIO_NUM      7
    #define PCLK_GPIO_NUM     13
     
    void setup() {
      Serial.begin(115200);
      Serial.setDebugOutput(true);
      Serial.println();
     
      // Initialisation de la caméra
      camera_config_t config;
      esp_camera_init(&config);
    if (esp_camera_init(&config) != ESP_OK) {
      Serial.println("Erreur d'initialisation de la caméra !");
      ESP.restart();
    } else {
      Serial.println("Caméra initialisée avec succès !");
    }
      config.ledc_channel = LEDC_CHANNEL_0;
      config.ledc_timer = LEDC_TIMER_0;
      config.pin_d0 = Y2_GPIO_NUM;
      config.pin_d1 = Y3_GPIO_NUM;
      config.pin_d2 = Y4_GPIO_NUM;
      config.pin_d3 = Y5_GPIO_NUM;
      config.pin_d4 = Y6_GPIO_NUM;
      config.pin_d5 = Y7_GPIO_NUM;
      config.pin_d6 = Y8_GPIO_NUM;
      config.pin_d7 = Y9_GPIO_NUM;
      config.pin_xclk = XCLK_GPIO_NUM;
      config.pin_pclk = PCLK_GPIO_NUM;
      config.pin_vsync = VSYNC_GPIO_NUM;
      config.pin_href = HREF_GPIO_NUM;
      config.pin_sscb_sda = SIOD_GPIO_NUM;
      config.pin_sscb_scl = SIOC_GPIO_NUM;
      config.pin_pwdn = PWDN_GPIO_NUM;
      config.pin_reset = RESET_GPIO_NUM;
      config.xclk_freq_hz = 20000000;
      config.pixel_format = PIXFORMAT_JPEG;
     
      // Initialisation avec PSRAM
      config.fb_count = 2;
      config.grab_mode = CAMERA_GRAB_WHEN_EMPTY;
     
      // Initialisation de la caméra
      esp_err_t err = esp_camera_init(&config);
      if (err != ESP_OK) {
        Serial.printf("Erreur d'initialisation de la caméra : 0x%x", err);
        return;
      }
     
      // Configuration de la résolution
      sensor_t *s = esp_camera_sensor_get();
      s->set_framesize(s, FRAMESIZE_QVGA); // 320x240
    }
     
    void loop() {
      // Capture d'une image
      camera_fb_t *fb = esp_camera_fb_get();
      if (!fb) {
        Serial.println("Échec de la capture d'image");
        return;
      }
     
      // Affichage de la taille de l'image
      Serial.printf("Image capturée : %u octets\n", fb->len);
     
      // Retour de l'image au pool
      esp_camera_fb_return(fb);
     
      delay(1000);
    }

    Photo du module "development board vs Wroom"
    Nom : Photo-ESP32-S3-N16R8-CAM.jpeg
Affichages : 186
Taille : 1,23 Mo

  2. #2
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 754
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 754
    Par défaut
    Hello,

    Vous auriez pu mettre le lien où vous l'avez acheté, bref je l'ai retrouvé... Apparemment le vendeur de ce module est Baishundianzi, et je me suis renseigné dessus... Apparemment ils sont spécialisés dans la vente de clone de ce type de module. Il faut donc trouver un équivalent, qui n'est même pas sûr d'être un équivalent niveau spécifications.

    Je dirai que le module le plus proche serait le ESP32-S3-WROOM-1-N16R8. L'ESP32-S3 prend en charge deux types d'interfaces pour la mémoire externe : Quad SPI (4 lignes de données) et Octal SPI (8 lignes de données). Les modules dotés de 2 Mo de PSRAM utilisent généralement le QSPI. Cependant, les modules R8 (8 Mo) utilisent quasi exclusivement l'interface OPI pour maximiser la bande passante, nécessaire au transfert rapide des données d'image.

    Je connais pas ce module mais je pense qu'il y a une erreur dans la configuration.

    Voir ici : https://www.reddit.com/r/esp32/comme...s3_n16r2_with/

    EDIT : J'ai trouvé une config à tester

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    ; Définition de l'environnement pour ESP32-S3 N16R8 OPI
    [env:esp32-s3-n16r8-cam]
    platform = espressif32
    board = esp32-s3-devkitc-1
    framework = arduino
     
    ; --- Configuration Mémoire Critique (N16R8) ---
    ; Force l'utilisation du mode Octal (OPI) pour la PSRAM 8Mo
    board_build.arduino.memory_type = qio_opi 
    ; Mode Quad I/O pour la Flash
    board_build.flash_mode = qio
    ; Type de PSRAM défini explicitement sur OPI
    board_build.psram_type = opi
    ; Taille de la Flash 16Mo
    board_upload.flash_size = 16MB
    board_upload.maximum_size = 16777216
    ; Table de partition adaptée aux grandes applications (16MB)
    board_build.partitions = default_16MB.csv
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  3. #3
    Candidat au Club
    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Janvier 2019
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes

    Informations forums :
    Inscription : Janvier 2019
    Messages : 10
    Par défaut
    Merci beaucoup pour votre message ; même si je n'ai pas pu appliquer tout ce que vous m'avez proposé :
    * je ne trouve pas l'environnement "esp32-s3-n16r8-cam" pour le tester à la place de celui que j'ai utilisé "esp32-s3-devkitc1-n16r8"
    * le lien ALIEXPRESS est le suivant :
    Carte de développement de caméra ESP32-S3-N16R8, Module WiFi + Bluetooth avec caméra OV2640/OV3660 pour arduino - AliExpress
    * le fabricant est bien :
    Shenzhen Baishun Ming core Electronics Co. , LTD
    12H-1. City 100 Building, No. 4 Zhonghang Road. Huahang Community.
    Huaqiang North Street, Futian District, Shenzhen.
    * j'avais déjà testé le PINOUT de :
    --- ESP32-CAM AI thinker
    --- ESP32-S3-WROOM-1-N16R8 (j'ai la documentation)
    --- et 4 autres brochages trouvé par Le CHAT sur internet (EYE ... , XIAO ...)
    mais aucun brochage ne me permet de démarrer la caméra
    * pour démarrer ESP32-S3-ZERO, j'ai utilisé la recommandation de sivar2311
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    [env:esp32-s3-fh4r2]
    platform = espressif32
    framework = arduino
    board = esp32-s3-fh4r2
    Merci pour votre aide

  4. #4
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 754
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 754
    Par défaut
    Pour l'environnement introuvable,

    C'est la source principale de votre confusion. L'environnement [env:esp32-s3-n16r8-cam] n'existe pas dans la liste officielle de PlatformIO. C'est un nom personnalisé que vous devez créer vous-même.

    Vous ne pouvez pas le "sélectionner" dans une liste. Vous devez copier-coller le bloc de configuration ci-dessous directement dans votre fichier platformio.ini (en écrasant ou modifiant votre bloc [env:esp32-s3-devkitc1-n16r8] actuel).

    C'est cette configuration manuelle qui active la mémoire OPI (Octal). Sans elle, aucun brochage de caméra ne fonctionnera car l'ESP32 n'aura pas de mémoire pour stocker l'image.

    Remplacez tout le contenu de votre fichier platformio.ini par ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    [env:esp32-s3-n16r8-cam]
    ; On utilise la base "devkitc-1" car c'est la plus générique pour les puces S3
    platform = espressif32
    board = esp32-s3-devkitc-1
    framework = arduino
    monitor_speed = 115200
     
    ; --- CONFIGURATION MEMOIRE OBLIGATOIRE POUR N16R8 ---
    ; Sans ces 3 lignes, la caméra ne démarrera jamais (écran noir)
    board_build.arduino.memory_type = qio_opi
    board_build.flash_mode = qio
    board_build.psram_type = opi
     
    ; Taille mémoire
    board_upload.flash_size = 16MB
    board_build.partitions = default_16MB.csv
     
    ; --- DRAPEAUX DE COMPILATION ---
    build_flags = 
        -DBOARD_HAS_PSRAM
        ; Cette ligne active le port série sur l'USB natif (celui marqué USB/OTG)
        ; Si vous utilisez le port marqué "COM" ou "UART", mettez cette ligne à 0
        -DARDUINO_USB_CDC_ON_BOOT=1
    Essayez ce brochage

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    // PINOUT SPÉCIFIQUE POUR "BAISHUN / DUAL USB N16R8"
    #define PWDN_GPIO_NUM     -1
    #define RESET_GPIO_NUM    -1
    #define XCLK_GPIO_NUM     15  // Attention: C'est souvent 15 sur ces clones
    #define SIOD_GPIO_NUM     4   // SDA
    #define SIOC_GPIO_NUM     5   // SCL
     
    #define Y9_GPIO_NUM       16
    #define Y8_GPIO_NUM       17
    #define Y7_GPIO_NUM       18
    #define Y6_GPIO_NUM       12
    #define Y5_GPIO_NUM       10
    #define Y4_GPIO_NUM       8
    #define Y3_GPIO_NUM       9
    #define Y2_GPIO_NUM       11
     
    #define VSYNC_GPIO_NUM    6
    #define HREF_GPIO_NUM     7
    #define PCLK_GPIO_NUM     13
    Puisque votre carte est une "Baishun Dual USB", elle suit le design de référence qui évite les broches 33 à 37 (utilisées par la RAM Octal). C'est pourquoi le brochage "AI Thinker" (votre premier test) ou "WROOM Standard" ne fonctionnent pas : ils essaient d'utiliser des broches occupées par la mémoire RAM.
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  5. #5
    Candidat au Club
    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Janvier 2019
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes

    Informations forums :
    Inscription : Janvier 2019
    Messages : 10
    Par défaut Test du soir ...
    Bonjour
    * J’ai utilisé le PINOUT que vous m’avez proposé (issu du design de référence)
    * J’ai remplacé le PlatformIO.INI par la nouvelle version
    * Build : OK → Upload : OK – Serial Monitor → il ne se passe rien (ni message positif, ni message d’erreur)

    Noter que le design de référence s’appuie sur la carte ESP32-S3-N16R8 avec Dual USB : ce doit être la grande carte avec 44 broches …

    Ma carte est composée de 2 petits PCB : ESP32-S3-CAM et ESP32-CAM-MB (module burner) …

    Ma carte ressemble à la carte ESP32-CAM AI thinker, qui ne porte pas la mention « S3 »
    * J’ai ré-essayé avec le PINOUT de AI thinker (malgé l’utilisation de broches entre 33 et 37)
    * Build + Upload : OK – Mais rien avec le moniteur série (aucun message) …

    * Encore plus grave : j’ai essayé un programme basique de communication série … ne fonctionne pas
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #include <Arduino.h>
     
    void setup() {
     Serial.begin(115200);
     while (!Serial); // attend que le port série soit prêt
     Serial.println("ESP32-S3-CAM démarré !");
    }
     
    void loop() {
     Serial.println("Hello World !!!");
     delay(1000);
    }
    * J’ai changé le paramètre DARDUINO → pas d’effet visible avec 0 ou 1
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    [env:esp32-s3-n16r8-cam]
    ; On utilise la base "devkitc-1" car c'est la plus générique pour les puces S3
    platform = espressif32
    board = esp32-s3-devkitc-1
    framework = arduino
    monitor_speed = 115200
     
    ; --- CONFIGURATION MEMOIRE OBLIGATOIRE POUR N16R8 ---
    ; Sans ces 3 lignes, la caméra ne démarrera jamais (écran noir)
    board_build.arduino.memory_type = qio_opi
    board_build.flash_mode = qio
    board_build.psram_type = opi
     
    ; Taille mémoire
    board_upload.flash_size = 16MB
    board_build.partitions = default_16MB.csv
     
    ; --- DRAPEAUX DE COMPILATION ---
    build_flags = 
        -DBOARD_HAS_PSRAM
        ; Cette ligne active le port série sur l'USB natif (celui marqué USB/OTG)
        ; Si vous utilisez le port marqué "COM" ou "UART", mettez cette ligne à 0
        -DARDUINO_USB_CDC_ON_BOOT=1

    Merci infiniment pour votre aide

  6. #6
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 754
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 754
    Par défaut
    Ok, on va ignorer les schémas AI-Thinker et utiliser exclusivement le mappage.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    [env:esp32-s3-cam-n16r8]
    platform = espressif32
    board = esp32-s3-devkitc-1
    framework = arduino
     
    ; --- Configuration Mémoire Matérielle (CRITIQUE) ---
    ; Définit le mode de communication avec la Flash et la PSRAM.
    ; "qio_opi" signifie Quad I/O pour la Flash et Octal I/O pour la PSRAM.
    ; Sans cela, la PSRAM n'est pas vue et la caméra échoue (pas de buffer).
    board_build.arduino.memory_type = qio_opi 
    board_upload.flash_size = 16MB
    board_build.partitions = default_16MB.csv
     
    ; --- Définitions des Broches Caméra (Injection Macro) ---
    ; Ces drapeaux remplacent les définitions par défaut au moment de la compilation.
    build_flags = 
        -D BOARD_HAS_PSRAM
        -D CAM_PIN_D0=11
        -D CAM_PIN_D1=9
        -D CAM_PIN_D2=8
        -D CAM_PIN_D3=10
        -D CAM_PIN_D4=12
        -D CAM_PIN_D5=18
        -D CAM_PIN_D6=17
        -D CAM_PIN_D7=16
        -D CAM_PIN_XCLK=15
        -D CAM_PIN_PCLK=13
        -D CAM_PIN_VSYNC=6
        -D CAM_PIN_HREF=7
        -D CAM_PIN_SIOD=4
        -D CAM_PIN_SIOC=5
        -D CAM_PIN_PWDN=-1
        -D CAM_PIN_RESET=-1
     
        ; --- Configuration de la Console Série (Correction "Écran Noir") ---
        ; Option A : Si vous utilisez le port USB-C natif (petit connecteur sur la carte)
        ; L'USB agit comme un port série virtuel (CDC).
        -D ARDUINO_USB_CDC_ON_BOOT=1 
        -D ARDUINO_USB_MODE=1
     
        ; Option B (Alternative) : Si vous utilisez le Shield "MB" externe sur les pins UART
        ; Commentez les lignes ci-dessus et décommentez :
        ; -D ARDUINO_USB_CDC_ON_BOOT=0
    L'utilisation de PlatformIO (extension pour VSCode) est fortement recommandée, car elle permet une gestion explicite des drapeaux de compilation et des versions de bibliothèques.

    Code d'initialisation de la caméra

    L'initialisation doit tirer parti de la PSRAM Octale. Contrairement à l'ESP32-CAM standard qui peine au-delà du SVGA, le S3 N16R8 peut gérer le UXGA (1600x1200) avec fluidité grâce au double buffering en PSRAM.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    #include "esp_camera.h"
    #include <Arduino.h>
     
    void setup() {
      Serial.begin(115200);
      Serial.setDebugOutput(true);
      Serial.println();
     
      camera_config_t config;
      config.ledc_channel = LEDC_CHANNEL_0;
      config.ledc_timer = LEDC_TIMER_0;
     
      // Mappage explicite (correspond aux build_flags, mais utile de réaffirmer)
      config.pin_d0 = 11;
      config.pin_d1 = 9;
      config.pin_d2 = 8;
      config.pin_d3 = 10;
      config.pin_d4 = 12;
      config.pin_d5 = 18;
      config.pin_d6 = 17;
      config.pin_d7 = 16;
      config.pin_xclk = 15;
      config.pin_pclk = 13;
      config.pin_vsync = 6;
      config.pin_href = 7;
      config.pin_sscb_sda = 4;
      config.pin_sscb_scl = 5;
      config.pin_pwdn = -1;
      config.pin_reset = -1;
     
      config.xclk_freq_hz = 20000000; // 20MHz est un bon compromis stabilité/vitesse
      config.pixel_format = PIXFORMAT_JPEG;
     
      // Optimisation Mémoire N16R8
      if(psramFound()){
        config.frame_size = FRAMESIZE_UXGA; // 1600x1200
        config.jpeg_quality = 10; // 0-63, plus bas est meilleur
        config.fb_count = 2; // Double buffering pour fluidité
        config.grab_mode = CAMERA_GRAB_WHEN_EMPTY;
        config.fb_location = CAMERA_FB_IN_PSRAM; // INDISPENSABLE
        Serial.println("PSRAM détectée et activée.");
      } else {
        config.frame_size = FRAMESIZE_SVGA;
        config.jpeg_quality = 12;
        config.fb_count = 1;
        config.fb_location = CAMERA_FB_IN_DRAM;
        Serial.println("AVERTISSEMENT: PSRAM non détectée! Vérifiez le mode OPI.");
      }
     
      // Initialisation
      esp_err_t err = esp_camera_init(&config);
      if (err!= ESP_OK) {
        Serial.printf("Échec init caméra: 0x%x", err);
        return;
      }
      Serial.println("Caméra prête!");
    }
     
    void loop() {
      // Votre code de capture...
    }
    Intégration Applicative : ESPHome et Home Assistant

    Cette carte est extrêmement populaire pour créer des caméras IP intelligentes dans Home Assistant. L'utilisation d'ESPHome simplifie grandement la gestion en abstrayant le code C++. Basé sur l'analyse des configurations fonctionnelles , voici le bloc YAML

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    esp32:
      board: esp32-s3-devkitc-1
      framework:
        type: arduino
     
    # Configuration Mémoire Critique
    psram:
      mode: octal  # OBLIGATOIRE pour le module R8. 'quad' causera un échec.
      speed: 80MHz
     
    esp32_camera:
      name: "Caméra S3 Salon"
      external_clock:
        pin: GPIO15
        frequency: 20MHz
      i2c_pins:
        sda: GPIO4
        scl: GPIO5
      data_pins: [GPIO11, GPIO9, GPIO8, GPIO10, GPIO12, GPIO18, GPIO17, GPIO16]
      vsync_pin: GPIO6
      href_pin: GPIO7
      pixel_clock_pin: GPIO13
      resolution: 1280x1024
      jpeg_quality: 10
      max_framerate: 15 fps
    https://community.home-assistant.io/...express/731795
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  7. #7
    Candidat au Club
    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Janvier 2019
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes

    Informations forums :
    Inscription : Janvier 2019
    Messages : 10
    Par défaut
    Bonjour
    Merci beaucoup de passer du temps pour m’aider à résoudre cette question !!!

    1. Nouveaux programmes
    Ce soir, j’ai testé les 2 nouveaux programmes que vous m’avez proposés :
    - platformIO.ini
    - camera : main.cpp
    La configuration matérielle que j’utilise :
    - micro PC sous windoxs11
    - programmation : VSCode + platformIO
    - connecteur PC : port USB qui se définit automatiquement « COM8 »
    - câble USB entre PC et l’usb-C de la carte ESP32-CAM-MB
    - les 2 cartes : Esp32-cam-MB & Esp32-s3-CAM enfichées l’une sur l’autre
    Dans tous les tests que j’ai réalisé :
    - la compilation est faite sans connexion avec l’ESP : … build OK
    - je connecte le câble sur l’usb-C de Esp-cam-MB en appuyant simultanément sur le switch I00, jusqu’à la fin du chargement : … upload OK
    - je relache le switch I00
    - je sélectionne « Serial Monitor » et il apparaît 4 lignes :
    --- Terminal on COM8 | 115200 8-N-1
    --- Available filters and text transformations: colorize, debug, default, direct, esp32_exception_decoder, hexlify, log2file, nocontrol, printable, send_on_enter, time
    --- More details at https://bit.ly/pio-monitor-filters
    --- Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H
    - le processus continue à tourner, mais il ne se passe plus rien à l’écran : aucun des commentaires « Serial.println("... bla bla bla ..."); » n’apparaît lorsque le processus tourne

    2. Communication USB
    Il me semble que la première priorité serait d’arriver à faire écrire l’ESP32 sur l’écran du PC, avant même de résoudre la question de l’utilisation de la caméra. Car il est possible que la caméra fonctionne normalement ...

    3. Programme LED
    J’ai réussi à faire fonctionner le programme de colorisation de la LED : WS2812
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    [env:esp32-s3-cam-n16r8]
    platform = espressif32
    board = esp32-s3-devkitc-1
    framework = arduino
    monitor_speed = 115200
    lib_deps = adafruit/Adafruit NeoPixel @^1.12.0
    Mais il n’utilise pas la communication série ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    #include <Arduino.h>
    #include <Adafruit_NeoPixel.h>
     
    #define LED_PIN    48    // Broche où la LED est connectée
    #define LED_COUNT  1     // Nombre de LEDs (ici, une seule)
     
    Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
     
    void setup() {
      Serial.begin(115200);
      // while (!Serial); // Attend que le port série soit prêt
      delay(1000);
     
      strip.begin();           // Initialise la bibliothèque NeoPixel
      strip.show();            // Éteint toutes les LEDs
      strip.setBrightness(50); // Règle la luminosité (0-255)
     
      Serial.println("ESP32-S3-ZERO démarré avec LED WS2812 !");
    }
     
    void loop() {
      // Allume la LED en rouge
      strip.setPixelColor(0, strip.Color(255, 0, 0));
      strip.show();
      delay(1000);
     
      // Allume la LED en vert
      strip.setPixelColor(0, strip.Color(0, 255, 0));
      strip.show();
      delay(1000);
     
      // Allume la LED en bleu
      strip.setPixelColor(0, strip.Color(0, 0, 255));
      strip.show();
      delay(1000);
    }
    Merci beaucoup pour votre aide

  8. #8
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 754
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 754
    Par défaut
    Avez vous installé l'extension PlatformIO sur VSCode ?


    Vous devez forcer le microcontrôleur à utiliser ses broches UART physiques au lieu de l'USB interne.

    Désactiver l'USB CDC : Il faut impérativement régler le drapeau ARDUINO_USB_CDC_ON_BOOT sur 0 (Disabled).
    • Si réglé sur 1 (par défaut), les données vont vers un port USB interne déconnecté, rendant la carte "muette".
    • Si réglé sur 0, les données sont dirigées vers l'UART matériel, permettant au programmeur externe (CH340) de les relayer au PC.


    Selon votre outil, appliquez ces paramètres pour gérer la mémoire spécifique "N16R8" (16Mo Flash / 8Mo PSRAM OPI) et éviter les crashs au démarrage.

    Configuration du fichier platformio.ini


    Ce fichier se trouve à la racine de votre projet VSCode. Remplacez ou adaptez son contenu avec les lignes suivantes. Cette configuration force l'usage de l'UART matériel (pour que votre carte "MB" fonctionne) et configure correctement la mémoire OPI pour éviter les plantages.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    [env:esp32s3-cam-n16r8]
    platform = espressif32
    board = esp32-s3-devkitc-1
    framework = arduino
     
    ; --- Configuration des Drapeaux de Compilation ---
    build_flags = 
        ; Force la sortie Série sur les broches UART physiques (TX/RX)
        ; Indispensable pour voir les logs via le programmateur externe (MB)
        -D ARDUINO_USB_CDC_ON_BOOT=0 
        -D ARDUINO_USB_MODE=0
     
        ; Indique au système que la carte possède de la PSRAM
        -D BOARD_HAS_PSRAM
     
        ; Désactive les modes USB inutiles qui pourraient bloquer le démarrage
        -D ARDUINO_USB_MSC_ON_BOOT=0 
        -D ARDUINO_USB_DFU_ON_BOOT=0
     
        ; Définit explicitement les broches UART pour l'ESP32-S3
        -D RX1=44
        -D TX1=43
     
    ; --- Configuration Mémoire Critique (N16R8) ---
    ; Ces lignes empêchent le crash "écran noir" dû à la mémoire OPI
    board_build.arduino.memory_type = qio_opi
    board_build.flash_mode = qio
    board_build.psram_type = opi
    board_upload.flash_size = 16MB
    board_upload.maximum_size = 16777216
     
    ; --- Configuration du Moniteur Série ---
    monitor_speed = 115200
    monitor_rts = 0
    monitor_dtr = 0
    Adaptation du code

    Dans votre code source, assurez-vous d'initialiser le port série sur les bonnes broches lors du setup(), car la définition par défaut de la carte peut être incorrecte pour ce modèle spécifique .

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    #include <Arduino.h>
     
    void setup() {
        // Initialisation explicite sur les broches matérielles 44 (RX) et 43 (TX)
        // Cela correspond au câblage physique de la carte ESP32-CAM-MB
        Serial.begin(115200, SERIAL_8N1, 44, 43);
     
        // Petite pause pour laisser le temps au convertisseur USB de s'initialiser
        delay(2000); 
     
        Serial.println("Démarrage réussi : Sortie UART active sur ESP32-S3 !");
    }
     
    void loop() {
        // Votre code ici
    }
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  9. #9
    Candidat au Club
    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Janvier 2019
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes

    Informations forums :
    Inscription : Janvier 2019
    Messages : 10
    Par défaut ça marche !!!!
    1. PlatformIO
    Oui, j’ai installé l’extension PlatformIO sur VSCode
    PlatformIO IDE v3.3.4
    Les autres extensions : C/C++ ; CMake Tools
    Par contre, je n’utilise pas : GitHub Copilot ; markdownlint

    2. Application des nouvelles recommandations
    Remplacement du contenu de « platformio.ini » avec drapeau à 0 pour utiliser la carte MB
    Remplacement du contenu de « main.cpp » avec le nouveau programme
    Ajoute une instruction dans la boucle loop (affichage toutes les secondes)

    Build → success
    Upload → success
    Serial monitor → CA MARCHE !!!!!!!!!!!!!!!!!!!
    Vous êtes un Champion ++++++++

  10. #10
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 754
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 754
    Par défaut
    Au vue de la carte j'aurais pas parié cher sur la réussite de ce problème

    Du coup vous pouvez sans doute changer quelques remarques sur le produit sur le site d'achat

    Bonne continuation...
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  11. #11
    Candidat au Club
    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Janvier 2019
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes

    Informations forums :
    Inscription : Janvier 2019
    Messages : 10
    Par défaut merci !!!!
    Merci infiniment !!! Sans votre aide, je ne sais pas ce que serait devenu mon projet ALITA !
    J’avais déjà avancé la partie mécanique et prévu d’installer précisément 3 caméras comme celle-ci.
    Je vais pouvoir tester l’affichage et l’enregistrement des images : l’aventure continue …
    Si cela vous intéresse, je vous tiendrai au courant de l’avancement du projet.
    Encore merci

  12. #12
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 754
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 754
    Par défaut
    Si cela vous intéresse, je vous tiendrai au courant de l’avancement du projet.
    Avec plaisir
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  13. #13
    Candidat au Club
    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Janvier 2019
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes

    Informations forums :
    Inscription : Janvier 2019
    Messages : 10
    Par défaut Est-ce que quelque chose a bougé entre 2 photos ?
    Bonjour
    Depuis un long moment, je cherche à déterminer si quelque chose bouge entre 2 photos successives.
    Sur ordre (bouton GO), mon programme prend une rafale de 5 photos toutes les 175 ms
    Il élimine les 2 premières images pour la stabilisation du capteur et enregistre les images 2, 3 et 4 sur la carte SD.
    A partir de l'image 2, il analyse si quelque chose a changé pour repérer un mouvement sur un décor fixe
    Il y a en ensemble de filtres et de prétraitements des images pour arriver à extraire le résultat "mouvement ou "image fixe"
    La camera prend des image en JPEG UXGA 1600x1200 avec la meilleures qualité possible (compression 60)
    Chaque test est composé de 4 cas de figure pour tenter de valider routines et paramètres
    - FP : prise de vue fixe avec peu d'objets dans le champ de vision
    - FC : prise de vue fixe avec des couleurs et des crayons de couleur
    - TF : ma tête immobile
    - TM : ma tête en mouvement
    Je n'arrive pas à construire un indicateur plaçant : FP, FC, TF ->image FIXE - TM -> MOUVEMENT
    et pourtant "à l'œil" il n'y a aucune d'ambigüité

    Les annexes
    ESP32-S3-N16R8 CAM ->

    platformio.ini ->
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    [env:esp32s3-cam-n16r8]
    platform        = espressif32
    board           = esp32-s3-devkitc-1
    framework       = arduino
     
    ; --- Configuration mémoire ---
    board_build.arduino.memory_type = qio_opi
    board_build.flash_mode          = qio
    board_build.psram_type          = opi
    board_upload.flash_size         = 16MB
    board_upload.maximum_size       = 16777216
    board_build.f_heap              = 65536   ; Taille du heap 64k
    board_build.f_stack             = 8192    ; Augmente la pile
     
    ; --- Configuration du moniteur série ---
    monitor_speed                   = 115200
    monitor_rts                     = 0
    monitor_dtr                     = 0
     
    ; --- Désactive les modes USB inutiles ---
    build_flags =
        -D ARDUINO_USB_CDC_ON_BOOT=0
        -D ARDUINO_USB_MODE=0
        -D ARDUINO_USB_MSC_ON_BOOT=0
        -D ARDUINO_USB_DFU_ON_BOOT=0
    Programme C++ ->
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    // --------------------------------------------------------
    //       ***     Programme ALITA     ***
    // --------------------------------------------------------
    // Historique ...
     
    // 2025-12-11 - Rédaction structurée du programme
    //              détection de contours SOBEL sur image 80x60
    //              analyse sur 4 bloc centraux / 16 blocs
    //              référence calculée APRES appui bouton GO
    // 2025-12-10 - redimensionnement image 80x60
    // 2025-12-09 - blockSize 256->64 - seuilBlock 1000->300 - seuil 50->450
    //              résolution UXGA -> SVGA (800x600) 64 200 200
    // 2025-12-08 - 1 seule rafale de 5 images - 175 ms -> cycle 1 seconde
    // 2025-12-05 - Optimisation rafale
    // 2025-12-04 - Codification des images par rafale
    // 2025-12-02 - Reprise caméra seule, ajout sd_read_write : OK !!!
    // 2025-12-01 - Suppression LED et LED couleur
    // 2025-11-25 - Test de la librairie SD_READ_WRITE
    // 2025-11-24 - Test des 9 pin GPIO (avec LED simple)
    // 2025-11-23 - aide de FRED1599 : le programme USB fonctionne !
    // 2025-11-22 - le programme 3 couleurs OK (pas de retour / moniteur série)
    // 2025-10-24 - solution GitHub -> SIVAR2311 pour ESP32-S3 FH4R2 (non CAM)
    // --------------------------------------------------------
    // --------------------------------------------------------
    //       ***     Programme ALITA     ***
    //       ESP32-S3-n16r8 CAM Development Board
    //       Détection de mouvement par contours (Sobel) sur images 80x60
    //       Référence calculée APRES appui bouton GO
    // --------------------------------------------------------
    #include <Arduino.h>
    #include "esp_camera.h"
    #include "sd_read_write.h"
     
    // ========== CONSTANTES GLOBALES ==========
    // Entrées/Sorties
    #define LED_SIMPLE       2       // LED on-board
    #define BOUTON_GO        0       // Bouton on-board
    #define INTERVALLE_PHOTO 175     // Temps entre images (ms)
    #define NB_IMAGES_RAFALE 5       // Nombre d'images par rafale
    #define DELai_DEMARRAGE  10      // Délai avant démarrage (s)
     
    // Caméra
    #define PWDN_GPIO_NUM    -1
    #define RESET_GPIO_NUM   -1
    #define XCLK_GPIO_NUM    15
    #define SIOD_GPIO_NUM     4
    #define SIOC_GPIO_NUM     5
    #define Y9_GPIO_NUM      16
    #define Y8_GPIO_NUM      17
    #define Y7_GPIO_NUM      18
    #define Y6_GPIO_NUM      12
    #define Y5_GPIO_NUM      10
    #define Y4_GPIO_NUM       8
    #define Y3_GPIO_NUM       9
    #define Y2_GPIO_NUM      11
    #define VSYNC_GPIO_NUM    6
    #define HREF_GPIO_NUM     7
    #define PCLK_GPIO_NUM    13
     
    // Traitement d'image
    #define SMALL_WIDTH      80      // Largeur image réduite
    #define SMALL_HEIGHT     60      // Hauteur image réduite
    #define ZONE_SIZE        10      // Taille des zones d'analyse
    #define NUM_ZONES        16      // Nombre de zones (4x4)
    #define ABSOLUTE_THRESHOLD 5000   // Seuil absolu pour détection
     
    // ========== VARIABLES GLOBALES ==========
    // Gestion des images
    uint8_t *previousFrame = nullptr;      // Image précédente (pleine résolution)
    size_t previousFrameSize = 0;
    const size_t MAX_FRAME_SIZE = 1600 * 1200 * 2;  // Taille max image
     
    // Buffers pour traitement 80x60
    uint8_t referenceEdges[SMALL_WIDTH * SMALL_HEIGHT];  // Référence stable
    uint8_t prevEdges[SMALL_WIDTH * SMALL_HEIGHT];       // Contours image précédente
    uint8_t currentSmallImg[SMALL_WIDTH * SMALL_HEIGHT]; // Image réduite courante
    uint8_t smoothedImg[SMALL_WIDTH * SMALL_HEIGHT];     // Image lissée
    uint8_t laplacianImg[SMALL_WIDTH * SMALL_HEIGHT];    // Image après Laplacien
    uint8_t currentEdges[SMALL_WIDTH * SMALL_HEIGHT];    // Contours courants
     
    // Gestion rafale
    int imageCount = 0;
    int nbImage = NB_IMAGES_RAFALE;
    char filename[64];
    unsigned long debutPhoto, dureePhoto;
    unsigned long debutRafale, dureeRafale;
     
    // ========== ROUTINES ==========
    void allume_LED_OK() {                          // Signal visuel OK
        digitalWrite(LED_SIMPLE, HIGH);
        delay(25);
        digitalWrite(LED_SIMPLE, LOW);
    }
     
    void allume_LED() {                            // Allume LED
        digitalWrite(LED_SIMPLE, HIGH);
    }
     
    void eteint_LED() {                            // Éteint LED
        digitalWrite(LED_SIMPLE, LOW);
    }
     
    void allume_LED_NOK() {                        // Signal visuel ERREUR
        digitalWrite(LED_SIMPLE, HIGH);
        delay(50);
        digitalWrite(LED_SIMPLE, LOW);
        delay(100);
        digitalWrite(LED_SIMPLE, HIGH);
        delay(50);
        digitalWrite(LED_SIMPLE, LOW);
    }
     
    // --------------------------------------------------------
    void applySmoothing(uint8_t *src, uint8_t *dst) {
        // Lissage 5x5 pour réduire le bruit JPEG
        for (uint16_t y = 2; y < SMALL_HEIGHT - 2; y++) {
            for (uint16_t x = 2; x < SMALL_WIDTH - 2; x++) {
                int sum = 0;
                for (int dy = -2; dy <= 2; dy++) {
                    for (int dx = -2; dx <= 2; dx++) {
                        sum += src[(y + dy) * SMALL_WIDTH + (x + dx)];
                    }
                }
                dst[y * SMALL_WIDTH + x] = sum / 25;  // 5x5 = 25 pixels
            }
        }
    }
     
    // --------------------------------------------------------
    void applyLaplacian(uint8_t *src, uint8_t *dst) {
        // Filtre Laplacien pour renforcer les contours
        for (uint16_t y = 1; y < SMALL_HEIGHT - 1; y++) {
            for (uint16_t x = 1; x < SMALL_WIDTH - 1; x++) {
                int laplacian = -4 * src[y*SMALL_WIDTH + x]
                              + src[(y-1)*SMALL_WIDTH + x] + src[(y+1)*SMALL_WIDTH + x]
                              + src[y*SMALL_WIDTH + (x-1)] + src[y*SMALL_WIDTH + (x+1)];
                dst[y*SMALL_WIDTH + x] = min(255, abs(laplacian));
            }
        }
    }
     
    // --------------------------------------------------------
    void applySobel(uint8_t *src, uint8_t *dst) {
        // Détection contours avec binarisation
        const uint8_t threshold = 30;  // Seuil de binarisation
        for (uint16_t y = 1; y < SMALL_HEIGHT - 1; y++) {
            for (uint16_t x = 1; x < SMALL_WIDTH - 1; x++) {
                int gx = -src[(y-1)*SMALL_WIDTH + (x-1)] - 2*src[(y-1)*SMALL_WIDTH + x]
                         - src[(y-1)*SMALL_WIDTH + (x+1)]
                         + src[(y+1)*SMALL_WIDTH + (x-1)] + 2*src[(y+1)*SMALL_WIDTH + x]
                         + src[(y+1)*SMALL_WIDTH + (x+1)];
                int gy = -src[(y-1)*SMALL_WIDTH + (x-1)] - 2*src[y*SMALL_WIDTH + (x-1)]
                         - src[(y+1)*SMALL_WIDTH + (x-1)]
                         + src[(y-1)*SMALL_WIDTH + (x+1)] + 2*src[y*SMALL_WIDTH + (x+1)]
                         + src[(y+1)*SMALL_WIDTH + (x+1)];
                int magnitude = (abs(gx) + abs(gy)) / 2;
                dst[y*SMALL_WIDTH + x] = (magnitude > threshold) ? 255 : 0;
            }
        }
    }
     
    // --------------------------------------------------------
    void resizeJpegApprox(uint8_t *srcBuf, size_t srcLen, uint8_t *dstBuf) {
        // Redimensionnement par échantillonnage
        size_t blockSize = srcLen / (SMALL_WIDTH * SMALL_HEIGHT);
        for (size_t i = 0; i < SMALL_WIDTH * SMALL_HEIGHT; i++) {
            size_t srcIndex = i * blockSize;
            if (srcIndex < srcLen) {
                dstBuf[i] = srcBuf[srcIndex];
            }
        }
    }
     
    // --------------------------------------------------------
    bool detectMotion(camera_fb_t *currentFrame) {
        // 1. Redimensionnement
        resizeJpegApprox(currentFrame->buf, currentFrame->len, currentSmallImg);
     
        // 2. Lissage agressif (5x5)
        applySmoothing(currentSmallImg, smoothedImg);
     
        // 3. Contours (Laplacien + Sobel)
        applyLaplacian(smoothedImg, laplacianImg);
        applySobel(laplacianImg, currentEdges);
     
        // 4. Détection multi-zones (16 zones de 10x10)
        int zoneDiffs[NUM_ZONES] = {0};
        for (int z = 0; z < NUM_ZONES; z++) {
            int startX = (z % 4) * ZONE_SIZE;
            int startY = (z / 4) * ZONE_SIZE;
            for (int y = 0; y < ZONE_SIZE; y++) {
                for (int x = 0; x < ZONE_SIZE; x++) {
                    int i = (startY + y) * SMALL_WIDTH + (startX + x);
                    zoneDiffs[z] += abs(currentEdges[i] - prevEdges[i]);
                }
            }
        }
     
        // 5. Vérification des seuils absolus
        bool movementDetected = false;
        for (int z = 0; z < NUM_ZONES; z++) {
            if (zoneDiffs[z] > ABSOLUTE_THRESHOLD) {
                Serial.printf("Mouvement zone %d (diff=%d)\n", z, zoneDiffs[z]);
                movementDetected = true;
            }
        }
     
        // 6. Mise à jour conditionnelle de prevEdges
        if (!movementDetected) {
            memcpy(prevEdges, currentEdges, SMALL_WIDTH * SMALL_HEIGHT);
        }
     
        return movementDetected;
    }
     
    // ========== SETUP ==========
    void setup() {
        // Initialisation série et GPIO
        Serial.begin(115200);
        pinMode(LED_SIMPLE, OUTPUT);
        pinMode(BOUTON_GO, INPUT_PULLUP);
     
        // Initialisation SD
        sdmmcInit();
     
        // Allocation mémoire
        previousFrame = (uint8_t *)malloc(MAX_FRAME_SIZE);
     
        // Configuration caméra
        camera_config_t config = {
            .pin_pwdn = PWDN_GPIO_NUM,
            .pin_reset = RESET_GPIO_NUM,
            .pin_xclk = XCLK_GPIO_NUM,
            .pin_sscb_sda = SIOD_GPIO_NUM,
            .pin_sscb_scl = SIOC_GPIO_NUM,
            .pin_d7 = Y9_GPIO_NUM,
            .pin_d6 = Y8_GPIO_NUM,
            .pin_d5 = Y7_GPIO_NUM,
            .pin_d4 = Y6_GPIO_NUM,
            .pin_d3 = Y5_GPIO_NUM,
            .pin_d2 = Y4_GPIO_NUM,
            .pin_d1 = Y3_GPIO_NUM,
            .pin_d0 = Y2_GPIO_NUM,
            .pin_vsync = VSYNC_GPIO_NUM,
            .pin_href = HREF_GPIO_NUM,
            .pin_pclk = PCLK_GPIO_NUM,
            .xclk_freq_hz = 20000000,
            .ledc_timer = LEDC_TIMER_0,
            .ledc_channel = LEDC_CHANNEL_0,
            .pixel_format = PIXFORMAT_JPEG,
            .frame_size = FRAMESIZE_UXGA,           // 1600x1200
            .jpeg_quality = 60,                     // compression
            .fb_count = 2,
            .grab_mode = CAMERA_GRAB_WHEN_EMPTY,
        };
     
        // Initialisation caméra
        esp_err_t err = esp_camera_init(&config);
        if (err != ESP_OK) {
            allume_LED_NOK();
            Serial.printf("Erreur caméra: 0x%x\n", err);
            while(1);
        }
        Serial.println("Caméra initialisée");
     
        // Réglages caméra
        sensor_t *s = esp_camera_sensor_get();
        s->set_brightness(s, 0);
        s->set_contrast(s, 0);
        s->set_saturation(s, 0);
        s->set_sharpness(s, 0);
        s->set_denoise(s, 1);
    }
     
    // ========== LOOP ==========
    void loop() {
        // Attente bouton GO
        Serial.println("Appuyez sur le bouton GO pour démarrer");
        while (digitalRead(BOUTON_GO) == HIGH) delay(25);
        delay(50);  // Anti-rebond
        while (digitalRead(BOUTON_GO) == LOW) delay(25);
     
        // Délai de préparation (10s pour positionner la scène)
        Serial.print("Préparez la scène. Départ dans ");
        for (int i = 0; i < DELai_DEMARRAGE; i++) {
            Serial.print(".");
            allume_LED_OK();
            delay(1000);
        }
        Serial.println(" GO!");
     
        // ===== CALCUL DE LA RÉFÉRENCE APRES APPUI BOUTON =====
        Serial.println("Calcul de la référence stable (5 images)...");
        memset(referenceEdges, 0, SMALL_WIDTH * SMALL_HEIGHT);  // Réinitialise
     
        for (int i = 0; i < 5; i++) {
            camera_fb_t *fb = esp_camera_fb_get();
            if (!fb) continue;
     
            resizeJpegApprox(fb->buf, fb->len, currentSmallImg);
            applySmoothing(currentSmallImg, smoothedImg);
            applyLaplacian(smoothedImg, laplacianImg);
            applySobel(laplacianImg, currentEdges);
     
            for (int j = 0; j < SMALL_WIDTH * SMALL_HEIGHT; j++) {
                referenceEdges[j] += currentEdges[j];
            }
            esp_camera_fb_return(fb);
            delay(100);
        }
     
        // Normalisation de la référence
        for (int j = 0; j < SMALL_WIDTH * SMALL_HEIGHT; j++) {
            referenceEdges[j] /= 5;
        }
        memcpy(prevEdges, referenceEdges, SMALL_WIDTH * SMALL_HEIGHT);
        Serial.println("Référence calculée. Rafale en cours...");
        // =======================================================
     
        // Rafale de photos
        debutRafale = millis();
        allume_LED();
        for (imageCount = 0; imageCount < nbImage; imageCount++) {
            snprintf(filename, sizeof(filename), "/_image_%d.jpg", imageCount);
            camera_fb_t *fb = esp_camera_fb_get();
            if (!fb) {
                allume_LED_NOK();
                Serial.println("Échec capture");
                continue;
            }
     
            if (imageCount <= 1) {  // Images 0-1 éliminées
                esp_camera_fb_return(fb);
                continue;
            }
     
            // Détection mouvement
            bool mouvement = detectMotion(fb);
     
            // Sauvegarde image
            writejpg(SD_MMC, filename, fb->buf, fb->len);
            if (imageCount == 2) {  // Initialisation référence pleine résolution
                memcpy(previousFrame, fb->buf, fb->len);
                previousFrameSize = fb->len;
            }
     
            Serial.printf("Image %d: %s\n", imageCount,
                         mouvement ? "MOUVEMENT" : "FIXE");
            esp_camera_fb_return(fb);
     
            // Intervalle entre images
            dureePhoto = millis();
            if (millis() - debutPhoto < INTERVALLE_PHOTO) {
                delay(INTERVALLE_PHOTO - (millis() - debutPhoto));
            }
            debutPhoto = millis();
        }
     
        eteint_LED();
        dureeRafale = millis() - debutRafale;
        Serial.printf("Rafale terminée en %lu ms\n", dureeRafale);
     
        // Attente
        Serial.print("Attente");
        while(1) {
            for (int i = 0; i < 10; i++) {
                delay(1000);
                Serial.print(".");
            }
        }
    }
    Synthèse des derniers résultats -> TableauResultats.pdfNom : 1FP_image_2.jpg
Affichages : 19
Taille : 39,9 KoNom : 1FP_image_3.jpg
Affichages : 18
Taille : 39,9 KoNom : 1FP_image_4.jpg
Affichages : 18
Taille : 39,9 KoNom : 2FC_image_2.jpg
Affichages : 18
Taille : 51,2 KoNom : 2FC_image_3.jpg
Affichages : 18
Taille : 51,2 KoNom : 2FC_image_4.jpg
Affichages : 18
Taille : 51,2 KoNom : 3TF_image_2.jpg
Affichages : 18
Taille : 46,2 KoNom : 3TF_image_3.jpg
Affichages : 18
Taille : 46,2 KoNom : 3TF_image_4.jpg
Affichages : 18
Taille : 46,3 KoNom : 4TM_image_2.jpg
Affichages : 18
Taille : 44,6 KoNom : 4TM_image_3.jpg
Affichages : 18
Taille : 44,7 Ko

Discussions similaires

  1. [JAR] Utiliser des images
    Par Seiya dans le forum Général Java
    Réponses: 2
    Dernier message: 26/08/2005, 18h59
  2. [MFC] Utilisation d'image en couleur 32 bits
    Par vanitom dans le forum MFC
    Réponses: 1
    Dernier message: 03/08/2005, 12h13
  3. Droit d'utilisation des images clipart
    Par Civodul4 dans le forum Autres Logiciels
    Réponses: 2
    Dernier message: 23/05/2005, 09h30
  4. Utilisation d'images au format png
    Par chtiot dans le forum Langage
    Réponses: 2
    Dernier message: 24/10/2003, 16h56

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo