Serveur de diffusion vidéo ESP32-CAM connectant des écrans I2C et SPI

Module CAM ESP-32 avec caméra de Diymore

Serveur de diffusion vidéo ESP32-CAM


Un exemple d'utilisation est ici .

Vous devez d'abord installer les bibliothèques: Carte Esp32 sous Arduino Ide Windows / Carte Esp32 sous Arduino Ide Linux et Mac

Les paramètres détaillés sont dans l'article.

Dans mon cas, j'ai utilisé le module AI-THINKER donc sans commentaire
#define CAMERA_MODEL_AI_THINKER

La fonctionnalité de reconnaissance faciale ne fonctionnait pas pour moi. Le commentaire dans l'article a été utile.

Il semble que la reconnaissance faciale ne fonctionne plus (du moins avec l'exemple de programme) lors de l'utilisation du noyau ESP 1.02. Revenir au noyau 1.01 et utiliser l'exemple de programme appartenant à ce noyau le «corrigera»

Après être revenu à la version précédente de la bibliothèque 1.01, tout fonctionnait.


J'ai une paire d'écrans I2C 128x64 et TFT SPI 128x128

Article OV7670 avec FIFO comment connecter la caméra à l'écran si vous n'avez pas de module CAM. Prise en charge des caméras OV2640 et OV7670

Au moment de la rédaction, les éléments suivants ont fonctionné pour moi

Caméra ESP32 + serveur Wifi + écran I2C (AdaFruit)
Caméra ESP32 + écran SPI 1,44 "TFT 128x128 v1.1 (AdaFruit)
Caméra ESP32 + écran SPI 1,8 "TFT 128 * 160 (bibliothèque Espressif)

Le pilote WiFi est en conflit avec le bus SPI. Solution possible pour utiliser une bibliothèque différente. Le problème est survenu lors de l'initialisation du module WiFi.

Le principal problème est que le module ESP32-CAM a un nombre limité de jambes libres. Une partie des ports est utilisée pour la caméra, une partie en parallèle avec la carte SD. Le connecteur de la carte SD est installé sur la carte. Une autre conclusion (IO4) est la lampe de poche LED.

L'affichage I2C N / B n'est pas particulièrement intéressant pour une utilisation réelle avec l'image reçue de la caméra. Couleur TFT et haute résolution. Sur celui-ci, vous pouvez déjà voir le visage. Sur un tel écran ou une résolution un peu plus élevée, vous pouvez faire

Je dirai tout de suite que la bibliothèque AdaFruit n'est pas la plus rapide. J'ai réussi à afficher quelques images par seconde. Il est plus prometteur d'utiliser des bibliothèques qui fonctionnent à un faible niveau. Mais je n'ai pas pu obtenir une ESP32_TFT_library avec mon écran 1,44 "128x128 SPI V1.1. Peut-être qu'ILI9163 n'est pas pris en charge. J'ai pris 1,8" 128 * 160 SPI TFT et j'ai réussi à serrer environ 12 FPS! Lien

Il existe quelques bibliothèques qui fonctionnent plus rapidement. Mais certains ne sont pas portés pour esp-32 ( lien ):

4.98 sec Adafruit_ST7735
1,71 s ST7735X_kbv
1,30 sec PDQ_ST7735

La vidéo est impressionnante:



Lorsque vous utilisez deux ports, l' un des ports matériels HSPI ou VSPI sur le microcontrôleur et l'affichage avec le pilote ILI9341 peut recevoir 30 images par seconde ( lien ).



Mais comme je l'ai dit plus tôt dans le module ESP32-CAM, un seul SPI est gratuit. Il est affiché sur les PINS suivants:

IO2 - DC (A0)
IO14 - CLK
IO15 - CS
IO13 - MOSI (SDA)
IO12 - MISO (entrée. Non utilisée)

IO0 - BCKL (rétroéclairage. Non utilisé)
IO16 - RST





La première bibliothèque que j'ai essayée était AdaFruit SSD1306

Écran OLED bleu I2C 128x64



#include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels // Declaration for an SSD1306 display connected to I2C (SDA, SCL pins) #define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin) Adafruit_SSD1306 display; void init_display(){ pinMode(14,INPUT_PULLUP); pinMode(15,INPUT_PULLUP); Wire.begin(14,15); display = Adafruit_SSD1306(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64 Serial.println(F("SSD1306 allocation failed")); for(;;); // Don't proceed, loop forever } .... 

camera_capture ()
 #define BACKCOLOR 0x0000 // Black #define PIXELCOLOR 0xFFFF // White #define FRAME_WIDTH 320 #define FRAME_HEIGHT 240 uint16_t pixel_color = 0; esp_err_t camera_capture(){ //acquire a frame camera_fb_t * fb = esp_camera_fb_get(); if (!fb) { ESP_LOGE(TAG, "Camera Capture Failed"); return ESP_FAIL; } int i = 0; for(int y = 0; y < SCREEN_HEIGHT; y++){ for(int x = 0; x < SCREEN_WIDTH; x++){ i = y * FRAME_WIDTH + x; // FRAMESIZE_QVGA // 320x240 char ch = (char)fb->buf[i]; if (ch > 128) pixel_color = WHITE; else pixel_color = BLACK; // Draw a single pixel in white display.drawPixel(x, y, pixel_color); } } display.display(); //return the frame buffer back to the driver for reuse esp_camera_fb_return(fb); Serial.println("Capture frame ok."); return ESP_OK; } 


Lorsque vous travaillez dans esp32, l'émulation Software I2C est utilisée. Impliqué IO14 et IO15. Presque tous les ports libres peuvent être utilisés, pas le bus H / W.

Comment connecter un écran OLED monochrome 0.96 "i2c . Vous devez faire attention à l'adresse d'affichage sur le bus I2C. Dans ce cas, 0x3C

Affichage SPI 1,8 "TFT 128 * 160 Bibliothèque Espressif




Schéma de câblage:

IO2 - A0
IO14 - SCK
IO15 - CS
IO13 - SDA
IO16 - RESET


Il y a aussi un lecteur de carte SD sur la carte

Configuration d'E / S:

 // Configuration for other boards, set the correct values for the display used //---------------------------------------------------------------------------- #define DISP_COLOR_BITS_24 0x66 //#define DISP_COLOR_BITS_16 0x55 // Do not use! // ############################################# // ### Set to 1 for some displays, ### // for example the one on ESP-WROWER-KIT ### // ############################################# #define TFT_INVERT_ROTATION 0 #define TFT_INVERT_ROTATION1 0 // ################################################ // ### SET TO 0X00 FOR DISPLAYS WITH RGB MATRIX ### // ### SET TO 0X08 FOR DISPLAYS WITH BGR MATRIX ### // ### For ESP-WROWER-KIT set to 0x00 ### // ################################################ #define TFT_RGB_BGR 0x08 // ############################################################## // ### Define ESP32 SPI pins to which the display is attached ### // ############################################################## // The pins configured here are the native spi pins for HSPI interface // Any other valid pin combination can be used #define PIN_NUM_MISO 12 // SPI MISO #define PIN_NUM_MOSI 13 // SPI MOSI #define PIN_NUM_CLK 14 // SPI CLOCK pin #define PIN_NUM_CS 15 // Display CS pin #define PIN_NUM_DC 2 // Display command/data pin #define PIN_NUM_TCS 0 // Touch screen CS pin (NOT used if USE_TOUCH=0) // -------------------------------------------------------------- // ** Set Reset and Backlight pins to 0 if not used ! // ** If you want to use them, set them to some valid GPIO number #define PIN_NUM_RST 0 // GPIO used for RESET control #define PIN_NUM_BCKL 0 // GPIO used for backlight control #define PIN_BCKL_ON 0 // GPIO value for backlight ON #define PIN_BCKL_OFF 1 // GPIO value for backlight OFF // -------------------------------------------------------------- // ####################################################### // Set this to 1 if you want to use touch screen functions // ####################################################### #define USE_TOUCH TOUCH_TYPE_NONE // ####################################################### // ####################################################################### // Default display width (smaller dimension) and height (larger dimension) // ####################################################################### #define DEFAULT_TFT_DISPLAY_WIDTH 128 #define DEFAULT_TFT_DISPLAY_HEIGHT 160 // ####################################################################### #define DEFAULT_GAMMA_CURVE 0 #define DEFAULT_SPI_CLOCK 32000000 #define DEFAULT_DISP_TYPE DISP_TYPE_ST7735B //---------------------------------------------------------------------------- #define TFT_INVERT_ROTATION 0 #define TFT_INVERT_ROTATION1 1 #define TFT_INVERT_ROTATION2 0 

Installez l'environnement et l'environnement de développement d' Espressif . Des instructions détaillées sur la façon de procéder .

Installez la bibliothèque . Deux corrections doivent être apportées pour assembler la bibliothèque.

Makefile:

 + CFLAGS += -Wno-error=tautological-compare \ + -Wno-implicit-fallthrough \ + -Wno-implicit-function-declaration 

composants / tft / tftspi.c:

 + #include "driver/gpio.h 

Patch

Installez ensuite le pilote de la caméra ESP32 .

Configurer:

#. $ HOME / esp / esp-idf / export.sh
# idf.py menuconfig




Autorisez l'accès au port USB pour le micrologiciel et la surveillance:

#sudo chmod 777 / dev / ttyUSB0

Nous collectons et remplissons:

#make -j4 && faire flash

12FPS est atteint par l'écriture de paquets en utilisant la méthode send_data. L'enregistrement n'est pas pixel par pixel, mais une ligne entière égale à la largeur de l'écran:

 esp_err_t camera_capture(){ uint32_t tstart, t1, t2; tstart = clock(); //acquire a frame camera_fb_t * fb = esp_camera_fb_get(); if (!fb) { printf("Camera Capture Failed\n"); return ESP_FAIL; } t1 = clock() - tstart; printf("Capture camera time: %u ms\r\n", t1); int i = 0, bufPos = 0; uint8_t hb, lb; color_t color; color_t *color_line = heap_caps_malloc(_width*3, MALLOC_CAP_DMA); tstart = clock(); for(int y = 0; y < _height; y++) { bufPos = 0; for(int x = 0; x < _width; x++) { i = (y * FRAME_WIDTH + x) << 1; hb = fb->buf[i] ; lb = fb->buf[i + 1]; color.r = (lb & 0x1F) << 3; color.g = (hb & 0x07) << 5 | (lb & 0xE0) >> 3; color.b = hb & 0xF8; color_line[bufPos] = color; bufPos++; // TFT_drawPixel(0, 0, color, 1); } disp_select(); send_data(0, y, _width-1, y, _width, color_line); wait_trans_finish(1); disp_deselect(); } free(color_line); t1 = clock() - tstart; printf("Send buffer time: %u ms\r\n", t1); esp_camera_fb_return(fb); printf("Capture frame ok.\n"); return ESP_OK; } 

Configuration de la caméra
 // #if defined(CAMERA_MODEL_AI_THINKER) #define PWDN_GPIO_NUM 32 #define RESET_GPIO_NUM -1 #define XCLK_GPIO_NUM 0 #define SIOD_GPIO_NUM 26 #define SIOC_GPIO_NUM 27 #define Y9_GPIO_NUM 35 #define Y8_GPIO_NUM 34 #define Y7_GPIO_NUM 39 #define Y6_GPIO_NUM 36 #define Y5_GPIO_NUM 21 #define Y4_GPIO_NUM 19 #define Y3_GPIO_NUM 18 #define Y2_GPIO_NUM 5 #define VSYNC_GPIO_NUM 25 #define HREF_GPIO_NUM 23 #define PCLK_GPIO_NUM 22 void camera_init_(){ camera_config_t config; 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.fb_count = 2; // for display config.frame_size = FRAMESIZE_QVGA; config.pixel_format = PIXFORMAT_RGB565; // camera init esp_err_t err = esp_camera_init(&config); if (err != ESP_OK) { printf("Camera init failed with error 0x%x", err); return; } printf("Camera init OK\n"); } 


Gist

FRAME_WIDTH est la largeur d'image de 320 pixels pour QVGA

 config.frame_size = FRAMESIZE_QVGA; // 320x240 

En fait, nous voyons sur la fenêtre d'affichage 128 * 160 à partir du cadre complet

Journal pour la configuration avec un tampon de caméra vidéo (config.fb_count = 1)
Temps de capture de la caméra: 32 ms
Temps de tampon d'envoi: 47 ms
Cadre de capture ok.

Résultat
1000 / (32 + 47) = 12,65 FPS

Journal pour la configuration avec deux tampons de caméscope (config.fb_count = 2)
Temps de capture de la caméra: 39 ms

Temps de tampon d'envoi: 63 ms

Cadre de capture ok.
Temps de capture de la caméra: 0 ms

Temps de tampon d'envoi: 59 ms

Cadre de capture ok.
Temps de capture de la caméra: 0 ms

Temps de tampon d'envoi: 34 ms

Cadre de capture ok.
Temps de capture de la caméra: 40 ms

Temps de tampon d'envoi: 64 ms

Cadre de capture ok.
Temps de capture de la caméra: 0 ms

Temps de tampon d'envoi: 59 ms

Cadre de capture ok.
Temps de capture de la caméra: 0 ms

Temps de tampon d'envoi: 34 ms

Cadre de capture ok.
Temps de capture de la caméra: 40 ms

Temps de tampon d'envoi: 63 ms

Cadre de capture ok.
Temps de capture de la caméra: 0 ms

Temps de tampon d'envoi: 60 ms

Cadre de capture ok.
Temps de capture de la caméra: 0 ms

Temps de tampon d'envoi: 34 ms

Cadre de capture ok.
Temps de capture de la caméra: 39 ms

Temps de tampon d'envoi: 63 ms

Cadre de capture ok.
Temps de capture de la caméra: 0 ms

Temps de tampon d'envoi: 60 ms

Cadre de capture ok.
Capturez le temps de la caméra: 1 ms

Temps de tampon d'envoi: 34 ms

Cadre de capture ok.
Temps de capture de la caméra: 40 ms

Temps de tampon d'envoi: 63 ms

Cadre de capture ok.
Temps de capture de la caméra: 0 ms

Temps de tampon d'envoi: 60 ms

Cadre de capture ok.
Temps de capture de la caméra: 0 ms

Temps de tampon d'envoi: 34 ms

Cadre de capture ok.
Temps de capture de la caméra: 40 ms

Temps de tampon d'envoi: 63 ms

Cadre de capture ok.
Temps de capture de la caméra: 0 ms

Temps de tampon d'envoi: 59 ms

Cadre de capture ok.
Temps de capture de la caméra: 0 ms

Temps de tampon d'envoi: 35 ms

Cadre de capture ok.

En raison de l'utilisation du deuxième tampon du caméscope, le tampon de certains cycles est obtenu instantanément. Dans un premier temps, le cycle complet est obtenu en moins que d'utiliser un seul tampon, mais cette fois "continue". L'intervalle entre les cycles est flottant.

Plusieurs fois, j'ai attrapé dans les journaux "Le détecteur de panne de courant s'est déclenché", j'ai donc éteint le détecteur. Parce qu'au début, j'ai alimenté l'affichage du rétroéclairage à partir de la broche ESP32-CAM de 3,3 V

 #include "soc/rtc_cntl_reg.h" ... WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector 

Conclusion


Module fonctionnel ESP32 à faible coût. Il y a un manque catastrophique de conclusions pour les ports implémentés dans la version CAM de la carte, alors choisissez la version CAM si vous avez vraiment besoin d'une caméra.

Source: https://habr.com/ru/post/fr463157/


All Articles