Server Streaming Video ESP32-CAM Menghubungkan Layar I2C dan SPI

Modul ESP-32 CAM dengan kamera dari Diymore

Server Streaming Video ESP32-CAM


Contoh penggunaan ada di sini .

Pertama-tama Anda harus menginstal perpustakaan: Papan Esp32 di Arduino Ide Windows / Papan Esp32 di Arduino Ide Linux dan Mac

Pengaturan detail ada di artikel.

Dalam kasus saya, saya menggunakan modul AI-THINKER yang tidak diomentari
#define CAMERA_MODEL_AI_THINKER

Fungsi pengenalan wajah tidak berfungsi untuk saya. Komentar dalam artikel itu sangat membantu.

Tampaknya pengenalan wajah tidak lagi berfungsi (setidaknya dengan program contoh) saat menggunakan inti ESP 1.02. Meluncur kembali ke inti 1.01 dan menggunakan contoh program milik inti itu, akan 'memperbaikinya'

Setelah memutar kembali ke versi 1.01 perpustakaan sebelumnya semuanya bekerja.


Saya memiliki sepasang layar I2C 128x64 dan TFT SPI 128x128

Artikel OV7670 dengan FIFO cara menghubungkan kamera ke layar jika Anda tidak memiliki modul CAM. Mendukung kamera OV2640 dan OV7670

Pada saat penulisan, berikut ini bekerja untuk saya

Kamera ESP32 + Wifi Server + Layar I2C (AdaFruit)
Kamera ESP32 + Tampilan SPI 1,44 "TFT 128x128 v1.1 (AdaFruit)
Kamera ESP32 + Tampilan SPI 1.8 "TFT 128 * 160 (Espressif library)

Driver WiFi bertentangan dengan bus SPI. Kemungkinan solusi untuk menggunakan perpustakaan yang berbeda. Masalah muncul pada saat inisialisasi modul WiFi.

Masalah utama adalah bahwa modul ESP32-CAM memiliki jumlah kaki bebas yang terbatas. Sebagian port digunakan untuk kamera, sebagian paralel dengan sd-card. Konektor sd-card dipasang di papan tulis. Kesimpulan lain (IO4) adalah senter LED.

Layar I2C B / W tidak begitu menarik untuk digunakan secara nyata dengan gambar yang diterima dari kamera. Warna TFT dan resolusi tinggi. Di atasnya Anda sudah bisa melihat wajahnya. Pada tampilan seperti itu atau sedikit resolusi yang lebih tinggi Anda dapat membuat Door Eye

Saya akan segera mengatakan bahwa perpustakaan AdaFruit bukanlah yang tercepat. Saya berhasil menampilkan beberapa bingkai per detik. Lebih menjanjikan untuk menggunakan perpustakaan yang berfungsi pada level rendah. Tapi saya tidak bisa mendapatkan ESP32_TFT_library dengan tampilan saya 1,44 "128x128 SPI V1.1. Mungkin ILI9163 tidak didukung. Saya mengambil 1,8" 128 * 160 SPI TFT dan saya berhasil memeras sekitar 12 FPS! Tautan

Ada beberapa perpustakaan yang bekerja lebih cepat. Tetapi beberapa tidak porting untuk esp-32 ( tautan ):

4,98 detik Adafruit_ST7735
1,71 detik ST7735X_kbv
1,30 detik PDQ_ST7735

Video ini terlihat mengesankan:



Saat menggunakan dua port, salah satu port perangkat keras HSPI atau VSPI pada mikrokontroler dan tampilan dengan driver ILI9341 dapat menerima 30 frame per detik ( tautan ).



Tetapi seperti yang saya katakan sebelumnya dalam modul ESP32-CAM, hanya satu SPI yang gratis. Ini ditampilkan pada PIN berikut:

IO2 - DC (A0)
IO14 - CLK
IO15 - CS
IO13 - MOSI (SDA)
IO12 - MISO (Input. Tidak Digunakan)

IO0 - BCKL (Lampu latar. Tidak digunakan)
IO16 - RST





Perpustakaan pertama yang saya coba adalah AdaFruit SSD1306

I2C 128x64 Layar OLED Biru



#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; } 


Saat bekerja di esp32, emulasi I2C Perangkat Lunak digunakan. Terlibat IO14 dan IO15. Hampir semua port gratis dapat digunakan, bukan bus H / W yang digunakan.

Bagaimana menghubungkan layar OLED Monochrome 0.96 "i2c . Anda perlu memperhatikan alamat tampilan pada bus I2C. Dalam hal ini, 0x3C

SPI Display 1,8 "TFT 128 * 160 Espressif Library




Diagram pengkabelan:

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


Ada juga pembaca kartu SD di papan tulis

Konfigurasi IO:

 // 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 

Instal lingkungan dan lingkungan pengembangan dari Espressif . Petunjuk terperinci tentang cara melakukan ini .

Instal perpustakaan . Dua koreksi perlu dilakukan untuk merakit perpustakaan.

Makefile:

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

komponen / tft / tftspi.c:

 + #include "driver/gpio.h 

Tempel

Kemudian instal Driver Kamera ESP32 .

Konfigurasikan:

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




Izinkan akses untuk port USB untuk firmware dan pemantauan:

#sudo chmod 777 / dev / ttyUSB0

Kami mengumpulkan dan mengisi:

#membuat -j4 && membuat flash

12FPS dicapai melalui penulisan paket menggunakan metode send_data. Rekaman bukan pixel demi pixel, tetapi seluruh baris sama dengan lebar layar:

 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; } 

Konfigurasi kamera
 // #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"); } 


Intisari

FRAME_WIDTH adalah lebar bingkai 320 piksel untuk QVGA

 config.frame_size = FRAMESIZE_QVGA; // 320x240 

Bahkan, kita melihat pada jendela tampilan 128 * 160 dari bingkai penuh

Log untuk konfigurasi dengan satu buffer kamera video (config.fb_count = 1)
Tangkap waktu kamera: 32 ms
Kirim waktu buffer: 47 ms
Ambil bingkai ok.

Hasil
1000 / (32 + 47) = 12,65 FPS

Log untuk konfigurasi dengan dua buffer camcorder (config.fb_count = 2)
Tangkap waktu kamera: 39 ms

Kirim waktu buffer: 63 ms

Ambil bingkai ok.
Tangkap waktu kamera: 0 ms

Kirim waktu buffer: 59 ms

Ambil bingkai ok.
Tangkap waktu kamera: 0 ms

Kirim waktu buffer: 34 ms

Ambil bingkai ok.
Tangkap waktu kamera: 40 ms

Kirim waktu buffer: 64 ms

Ambil bingkai ok.
Tangkap waktu kamera: 0 ms

Kirim waktu buffer: 59 ms

Ambil bingkai ok.
Tangkap waktu kamera: 0 ms

Kirim waktu buffer: 34 ms

Ambil bingkai ok.
Tangkap waktu kamera: 40 ms

Kirim waktu buffer: 63 ms

Ambil bingkai ok.
Tangkap waktu kamera: 0 ms

Kirim waktu buffer: 60 ms

Ambil bingkai ok.
Tangkap waktu kamera: 0 ms

Kirim waktu buffer: 34 ms

Ambil bingkai ok.
Tangkap waktu kamera: 39 ms

Kirim waktu buffer: 63 ms

Ambil bingkai ok.
Tangkap waktu kamera: 0 ms

Kirim waktu buffer: 60 ms

Ambil bingkai ok.
Tangkap waktu kamera: 1 ms

Kirim waktu buffer: 34 ms

Ambil bingkai ok.
Tangkap waktu kamera: 40 ms

Kirim waktu buffer: 63 ms

Ambil bingkai ok.
Tangkap waktu kamera: 0 ms

Kirim waktu buffer: 60 ms

Ambil bingkai ok.
Tangkap waktu kamera: 0 ms

Kirim waktu buffer: 34 ms

Ambil bingkai ok.
Tangkap waktu kamera: 40 ms

Kirim waktu buffer: 63 ms

Ambil bingkai ok.
Tangkap waktu kamera: 0 ms

Kirim waktu buffer: 59 ms

Ambil bingkai ok.
Tangkap waktu kamera: 0 ms

Kirim waktu buffer: 35 ms

Ambil bingkai ok.

Karena penggunaan buffer kedua camcorder, buffer dalam beberapa siklus diperoleh secara instan. Pada awalnya, siklus lengkap diperoleh dalam waktu kurang dari menggunakan satu buffer, tetapi kemudian kali ini "berjalan". Interval antara siklus mengambang.

Beberapa kali saya terjebak di log "Detektor Brownout dipicu" jadi saya mematikan detektor. Karena pada awalnya saya mengisi tampilan lampu latar dari pin 3.3V ESP32-CAM

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

Kesimpulan


Modul fungsional murah ESP32. Ada kekurangan kesimpulan besar untuk port yang diimplementasikan di papan CAM versi CAM, jadi pilih versi CAM jika Anda benar-benar membutuhkan kamera.

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


All Articles