ESP32 Web Cam

Cele

Celem projektu jest opracowanie rozwiązania udostępniającego obraz z kamery w formie pojedynczej klatki w formacie JPG. Dostęp do kamery realizowany ma być za pośrednictwem sieci WiFi i protokołu HTTP.

Podzespoły urządzenia

Urządzenie oparte jest o moduł którego sercem jest ESP32-S. Ten bogaty w peryferia układ posiada między innymi WiFi 802.11 b/g/n, Bluetooth v4.2 BR/EDR BLE, EthernetCAN bus 2.0, SD host, PWM, I2CSPI i inne. Wyposażony jest w 32 bitowy mikroprocesor o wydajności 600 DMIPS i częstotliwości pracy 240MHz. Pojemność pamięci SRAM wynosi 520 kB a pamięć Flash to 4MB. Układ zawiera również sprzętową akcelerację szyfrowania AES, SHA-2, RSAECC oraz generator liczb losowych.
Producentem układu ESP32-S jest Ai-Thinker, zachowuje on kompatybilność z ESP-WROOM-32 wytwarzanym przez Espressif.

esp32-s-ai_pinout-300x254 ESP32 Web Cam
Wyprowadzenia układu ESP32-S Ai-Thinker

ESP32-S można kupić na płytkach które zawierają np. zintegrowany wyświetlacz, konwerter pozwalający na bezpośrednią komunikację z komputerem przez USB i inne. Jedną z gotowych płytek oferuje gniazdo do którego podłącza się kamerę, układ ten dostępny jest pod nazwą ESP32-CAM.

esp32-cam-dev-300x226 ESP32 Web Cam
ESP32 zamontowane na płytce z gniazdem kamery

Kamerą wchodzącą w skład tego zestawu jest zwykle OV2640. Na płytce obok ESP32-S znajduje się również przycisk reset, gniazdo kart SD oraz LED które założeniem jest oświetlanie w przypadku niedoboru światła (jednak w rzeczywistości jest on niewystarczający).

Kamera OV2640 zasilana jest napięciem 3,3V (ESO32-CAM posiada na płytce stabilizator napięcia). Rozdzielczość otrzymanego obrazu może wynosić maksymalnie 1622 x 1200 px (2Mpx).  Rozmiar obiektywu to 1/4″ a czułość wynosi 0,6 V/(lux*s). Kąt widzenia 25 stopni (nieliniowy). Przy rozdzielczości CIF (352 x 288 px) osiąga się do 60 klatek na sekundę, natomiast w UXGA (1600 x 1200 px) 15 klatek na sekundę. Dostępne są również rozdzielczości pośrednie; SXGA, SVGA.

esp32_cam-300x138 ESP32 Web Cam

Wyprowadzenia płytki ESP32-CAM

Porty niewykorzystane przez elektronikę na płytce wyprowadzone są goldpinami dając możliwość podłączenia dodatkowych układów. Płytka niestety nie zawiera konwertera UART-USB dlatego należy podłączyć go oddzielnie (w celu wgrania oprogramowania, bądź komunikacji na drodze USB-UART z urządzeniem).

Przygotowanie Arduino IDE do programowania ESP32

Mając zainstalowane na komputerze Arduino IDE należy doinstalować obsługę ESP32 i najpopularniejszych płytek na których jest on montowany. Po uruchomieniu tego środowiska (w wersji nowszej od 1.6.4) klikamy Plik->Preferencje.
Następnie w polu “dodatkowe adresy URL do menedżera płytek” doklejamy do już istniejących adresów: “https://dl.espressif.com/dl/package_esp32_index.json“.
Po wejściu w “Narzędzia->Płytka->Menedżer płytek” wyszukujemy i instalujemy “ESP32 by Espressif Systems“.

Program ESP32-CAM

//podłączenie bibliotek
#include “esp_camera.h”
#include “Arduino.h”
#include “WiFi.h”

//deginicja pinów dla 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

//zmienna zawierająca obraz pobrany z kamery
camera_fb_t * fb = NULL;

//ustawienia sieci wifi
const char* ssid = “foo”;
const char* password = “bar”;

//konfiguracja serwera www i portu
WiFiServer server(80);

/////////Setup//////////
void setup() {

//komunikacja po uart w celu debugowania
Serial.begin(115200);

//podłaczenie do sieci wifi
WiFi.begin(ssid, password);
Serial.print(“Connecting to WiFi.”);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(“.”);
}

//informacja o podłączeniu do sieci wifi
Serial.println(” Connected!”);
Serial.println(WiFi.localIP());

//uruchomienie serwera www
server.begin();

//——–konfiguracja kamery————
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.pixel_format = PIXFORMAT_JPEG;

if (psramFound()) {
config.frame_size = FRAMESIZE_UXGA;
config.jpeg_quality = 10;
config.fb_count = 2;
} else {
config.frame_size = FRAMESIZE_SVGA;
config.jpeg_quality = 10;
config.fb_count = 2;
}
//———-koniec konfiguracji kamery———-

//inicjacja kamery
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
Serial.printf(“Camera init failed with error 0x%x”, err);
return;
}

}

/////////Loop//////////
void loop() {

WiFiClient client = server.available();

//jeśli podłączył się do serwera klient
if (client) {

Serial.println(“New Client”);

//gdy klient jest podłaczony
while (client.connected()) {

//pobranie obrazu z kamery
fb = esp_camera_fb_get();
if(!fb) {
Serial.println(“Camera capture failed”);
} else {
Serial.println(“Camera capture succesfull!”);
}

//wysłanie do przeglądarki klienta nagłówka informującego i obrazie jpeg
client.printf(“HTTP/1.1 200 OK Content-Type: image/jpeg Content-Length: %u “, fb->len);
//wysłanie obrazu
client.write(fb->buf, fb->len);
client.flush();
esp_camera_fb_return(fb);

Serial.println(“Image send”);
break;
}
}
}

Programowanie ESP32-CAM

Wgranie programu odbywa się po podłączeniu ESP23-CAM przez konwerter UART-USB i wprowadzenie układu w stan programowania. Dokonuje się tego przez zwarcie pinu IO0 z GND i wciśnięcie przycisku “reset”.
Układ w trakcie programowania może być podłączony do napięcia 3,3V jednak testowany urządzenie testowane przez autora bez problemu pracowało przy zasilaniu 5V. Pin UOR należypodłączyć, do TX konwertera, a UOT do RX konwertera.
Po zakończeniu wczytywania programu należy rozłączyć połączenie IO0 z GND i zresetować układ.
Należy zwrócić uwagę na wydajność prądową zasilania, niewystarczające może prowadzić do resetowania układu. Testowane urządzenie zasilane było z kowertera UART-USB napięciem 5V.

Odnośniki