U různých pokusů a projektů se mi občas hodí udělat časosběrné video. Může jít o růst krystalů, stavbu nějakého zařízení, schnutí, pohyb počasí za oknem nebo prostě jen záznam delšího děje zrychlený do krátkého videa. Mobil nebo běžná kamera to samozřejmě zvládne také, ale chtěl jsem si postavit malé samostatné zařízení, které jen nastavím, zapnu a nechám fotit.
Jako základ jsem použil modul AI-Thinker ESP32-CAM s kamerou OV2640 a slotem pro microSD kartu. Výhoda je jednoduchost. Modul umí fotit do JPG, ukládat snímky na kartu a zároveň má Wi-Fi, takže se dá pohodlně nastavit přes webové rozhraní.

Základní myšlenka
Zařízení po zapnutí vytvoří vlastní Wi-Fi síť. Po připojení k této síti se v prohlížeči otevře jednoduchá nastavovací stránka, kde je vidět náhled z kamery. Na stránce lze nastavit:
- interval mezi fotkami,
- rozlišení snímků,
- kvalitu JPG.
Po uložení nastavení se Wi-Fi vypne a kamera začne fotit na microSD kartu. Po každém úspěšném uložení krátce blikne vestavěná LED. To se hodí hlavně proto, abych zařízení nevypnul zrovna ve chvíli, kdy zapisuje fotku na kartu.
Použitý hardware
- AI-Thinker ESP32-CAM
- kamerový modul OV2640
- microSD kartu
- USB-UART převodník pro nahrání programu
Připojení USB-UART převodníku a nahrání programu
Modul ESP32-CAM nemá na desce vlastní USB převodník, takže pro nahrání programu je potřeba použít externí USB-UART převodník. Převodník musí pracovat s logickými úrovněmi 3,3 V, ale samotný modul ESP32-CAM je vhodné napájet přes pin 5 V. Pro programování může stačit napájení 3,3 V z převodníku.
Pokud použijete převodník od Laskakitu jako já, je potřeba ho nastavit na 3V3 a VCC OUT na ON.

Zapojení pro nahrávání programu je následující:
USB-UART převodník ESP32-CAM
--------------------------------
Vcc → 3V3
GND → GND
TX → U0R
RX → U0T
Piny TX a RX se kříží, takže výstup TX z převodníku vede na vstup U0R na ESP32-CAM a výstup U0T z ESP32-CAM vede na RX převodníku.
Aby se ESP32-CAM přepnula do programovacího režimu, je potřeba před připojením napájení propojit pin GPIO0 s GND.
Postup nahrání programu:
- Připojit USB-UART převodník k ESP32-CAM.
- Propojit GPIO0 s GND.
- Připojit napájení nebo stisknout reset.
- V Arduino IDE spustit nahrávání programu.
- Po dokončení nahrávání odpojit GPIO0 od GND.
- Znovu resetovat ESP32-CAM.
V Arduino IDE jsem použil obecnější desku ESP32 Dev Module, hlavně kvůli nastavení rychlosti nahrávání a PSRAM.

Důležité je mít zapnutou PSRAM, protože bez ní vyšší rozlišení, například UXGA 1600 × 1200, nebude spolehlivě fungovat.
Při problémech s nahráváním se mi osvědčilo snížit rychlost nahrávání na 115200 baud. ESP32-CAM je také poměrně citlivá na napájení, takže pokud se nahrávání rozpadá nebo modul přestává odpovídat, je dobré použít stabilní 5V napájení a co nejkratší vodiče mezi převodníkem a modulem.
Po správném nahrání programu už GPIO0 nesmí zůstat připojené na GND, jinak se modul bude po resetu znovu spouštět do programovacího režimu místo běžného běhu programu.
Zjistil jsem, že ne všechny GND piny na desce jsou vzájemně propojené. Pokud se objeví problémy, je dobré je mezi sebou nejdřív propípnout. Hlavní GND pin je ten vedle napájecího pinu 5 V.
Nastavovací režim přes Wi-Fi
Po zapnutí modul vytvoří vlastní přístupový bod:
ESP32-CAM-Timelapse
Po připojení k této síti stačí v prohlížeči otevřít adresu:
192.168.4.1
Na stránce je jednoduchý náhled z kamery a formulář pro nastavení parametrů časosběru. Náhled není řešený jako plnohodnotný video stream, ale jako pravidelně obnovovaný JPG obrázek. Pro nastavení záběru to úplně stačí a zároveň je to jednodušší a stabilnější.

Po kliknutí na spuštění se nastavení uloží do proměnných, Wi-Fi se vypne a začne samotné focení. Další změna nastavení je možná po restartu zařízení.
Ukládání fotek
Fotky se ukládají na microSD kartu jako číslovaná série JPG souborů. Po každém spuštění se vytvoří nová složka, například:
/TL001/
/TL002/
/TL003/
Uvnitř jsou ještě podsložky, aby nebylo příliš mnoho souborů v jednom adresáři:
/TL003/P000/000001.jpg
/TL003/P000/000002.jpg
/TL003/P000/000003.jpg
To se hodí hlavně při delších časosběrech. Při intervalu jedna fotka za sekundu vznikne za 24 hodin 86 400 fotek, což už je docela hodně.
Po každém úspěšném uložení fotky krátce blikne vestavěná LED. Bliknutí nastane až po zavření souboru, takže slouží jako jednoduchá kontrola, že je snímek bezpečně uložený.
První testy
První test jsem dělal s delším odpoledním snímáním, s frekvencí 5 s. Kamera za několik hodin vytvořila přibližně 2200 fotek. Po počátečním ladění se jako funkční ukázalo i rozlišení UXGA 1600 × 1200 při kvalitě JPG 12.
První dvě fotky po startu bývaly přesvětlené, protože si kamera teprve dorovnávala expozici. Při skládání videa jsem je proto jednoduše přeskočil a video začal až od souboru 000003.jpg.
Složení videa z fotek
Kamera sama nevytváří hotové video. Ukládá pouze jednotlivé JPG snímky na microSD kartu. To je záměr, protože ukládání samostatných fotek je pro ESP32-CAM jednodušší a spolehlivější než přímé nahrávání videa. Výsledné časosběrné video se potom složí až v počítači.
K tomu jsem použil program FFmpeg. Je to nástroj pro práci s videem a zvukem, který umí mimo jiné vzít očíslovanou sérii obrázků a vytvořit z nich video soubor.
Instalace FFmpeg ve Windows
Pokud FFmpeg v počítači není nainstalovaný, PowerShell po zadání příkazu ffmpeg vypíše chybu, že příkaz nebyl nalezen. V tom případě je potřeba ho nejdřív nainstalovat.
Nejjednodušší možnost ve Windows je instalace přes winget. Stačí otevřít PowerShell a zadat:
winget install --id Gyan.FFmpeg -e
Po dokončení instalace je potřeba PowerShell zavřít a znovu otevřít. Tím se načte nová systémová cesta k programu.
Funkčnost instalace lze ověřit příkazem:
ffmpeg -version
Pokud se zobrazí informace o verzi FFmpeg, je vše připravené.
Příprava složky s fotkami
Fotky z ESP32-CAM jsou uložené na microSD kartě v očíslované sérii, například:
000001.jpg
000002.jpg
000003.jpg
000004.jpg
...
Pro složení videa je nejlepší zkopírovat celou složku s fotkami do počítače. V mém případě byla cesta například:
C:\Users\micha\Desktop\TL002\P000
Ve Windows je možné složku otevřít v Průzkumníku, kliknout do adresního řádku, napsat:
powershell
a potvrdit klávesou Enter. Tím se otevře PowerShell rovnou v dané složce.
Základní složení videa
Pokud jsou fotky pojmenované ve tvaru 000001.jpg, 000002.jpg, 000003.jpg a tak dále, lze z nich vytvořit video tímto příkazem:
ffmpeg -framerate 30 -start_number 1 -i '%06d.jpg' -c:v libx264 -pix_fmt yuv420p -crf 18 timelapse.mp4
Význam jednotlivých částí příkazu:
-framerate 30
určuje, kolik fotek se použije na jednu sekundu videa. Hodnota 30 znamená 30 snímků za sekundu.
-start_number 1
říká, že se má začít od souboru 000001.jpg.
-i '%06d.jpg'
určuje název vstupních souborů. Zápis %06d znamená šestimístné číslo doplněné nulami zleva. FFmpeg tedy hledá soubory jako 000001.jpg, 000002.jpg, 000003.jpg a podobně.
-c:v libx264
nastaví použití běžného kodeku H.264.
-pix_fmt yuv420p
zajistí dobrou kompatibilitu výsledného videa s běžnými přehrávači, mobily i webem.
-crf 18
nastavuje kvalitu výsledného videa. Nižší číslo znamená vyšší kvalitu a větší soubor. Hodnota 18 je dobrý kompromis mezi kvalitou a velikostí souboru.
timelapse.mp4
je název výsledného videa.
Přeskočení prvních fotek
Při testu se ukázalo, že první dvě fotky po spuštění byly přesvětlené. Kamera si po startu teprve dorovnávala expozici. Proto jsem video skládal až od třetí fotky.
Stačí změnit parametr -start_number z hodnoty 1 na 3:
ffmpeg -framerate 30 -start_number 3 -i '%06d.jpg' -c:v libx264 -pix_fmt yuv420p -crf 18 timelapse.mp4
Tím FFmpeg začne až od souboru:
000003.jpg
a první dvě fotky přeskočí.
Změna rychlosti videa
Rychlost výsledného časosběru se nastavuje hodnotou -framerate.
Pokud mám například 2200 fotek, výsledná délka videa bude přibližně:
2200 fotek / 30 FPS = 73 sekund
Při 30 snímcích za sekundu bude tedy video dlouhé asi 1 minutu a 13 sekund.
Pokud je video moc rychlé, stačí použít menší hodnotu:
ffmpeg -framerate 20 -start_number 3 -i '%06d.jpg' -c:v libx264 -pix_fmt yuv420p -crf 18 timelapse_20fps.mp4
Nebo ještě pomalejší variantu:
ffmpeg -framerate 15 -start_number 3 -i '%06d.jpg' -c:v libx264 -pix_fmt yuv420p -crf 18 timelapse_15fps.mp4
Čím menší hodnota -framerate, tím delší a pomalejší bude výsledné video.
Zmenšení videa na vhodné rozlišení
Fotky z kamery v rozlišení UXGA mají velikost 1600 × 1200 pixelů. To je poměr stran 4:3. Pro výsledné video jsem zvolil rozlišení 1440 × 1080, které zachová stejný poměr stran a zároveň je dobře použitelné pro přehrávání i nahrání na web nebo YouTube.
Příkaz potom vypadá takto:
ffmpeg -framerate 30 -start_number 3 -i '%06d.jpg' -vf "scale=1440:1080" -c:v libx264 -pix_fmt yuv420p -crf 18 timelapse_1080p.mp4
Část:
-vf "scale=1440:1080"
znamená, že se každá fotka před uložením do videa zmenší na 1440 × 1080 pixelů.
Příkaz použitý pro moje video
Pro moje první časosběrné video jsem nakonec použil tento příkaz:
ffmpeg -framerate 30 -start_number 3 -i '%06d.jpg' -vf "scale=1440:1080" -c:v libx264 -pix_fmt yuv420p -crf 18 timelapse_1080p.mp4
Tím se vzaly fotky od 000003.jpg, složily se rychlostí 30 snímků za sekundu, zmenšily se na 1440 × 1080 a uložily jako soubor:
timelapse_1080p.mp4
Výsledkem je klasické MP4 video, které lze přehrát v běžném přehrávači, nahrát na YouTube nebo vložit do článku.
Co když v číslované sérii chybí některé fotky
Při dalším testu jsem narazil na drobný problém. Měl jsem připravených dalších několik tisíc fotek, ale pár snímků jsem musel smazat. Tím už ale číslovaná řada nebyla souvislá.
FFmpeg při použití vstupu:
-i '%06d.jpg'
očekává soubory v souvislé řadě:
000001.jpg
000002.jpg
000003.jpg
000004.jpg
...
Jakmile narazí na chybějící číslo, například chybí 001237.jpg, zpracování v tom místě skončí. Video se tedy vytvoří jen z fotek před chybějícím souborem.
Nejjednodušší a nejbezpečnější řešení je udělat si kopii fotek do nové složky a tu znovu přečíslovat od začátku. Originální fotky tím zůstanou beze změny.
Ve složce s fotkami stačí otevřít PowerShell a spustit:
mkdir renumbered
$i = 1
Get-ChildItem -Filter *.jpg | Sort-Object Name | ForEach-Object {
Copy-Item $_.FullName ("renumbered\{0:D6}.jpg" -f $i)
$i++
}
Tím vznikne nová složka:
renumbered
a v ní nová souvislá řada souborů:
000001.jpg
000002.jpg
000003.jpg
000004.jpg
...
Potom stačí do nové složky přejít:
cd renumbered
a znovu spustit FFmpeg:
ffmpeg -framerate 30 -i '%06d.jpg' -vf "scale=1440:1080" -c:v libx264 -pix_fmt yuv420p -crf 18 timelapse_1080p.mp4
Tahle metoda je sice o něco náročnější na místo na disku, protože se fotky zkopírují, ale je bezpečná. Původní soubory se nepřejmenovávají ani nemažou, takže pokud se něco nepovede, pořád zůstane původní sada fotek zachovaná.
Přečíslování originálních fotek by také šlo, ale u větší série snímků bych to nedoporučoval. Kopie do nové složky je jistější postup.
Závěr
Výsledkem je jednoduchá samostatná časosběrná kamera. Po zapnutí se nastaví přes Wi-Fi, potom Wi-Fi vypne a dál už jen ukládá fotky na kartu. Díky tomu je provoz jednoduchý a zařízení není zbytečně zatížené webserverem nebo streamováním obrazu během samotného focení.
Pro základní ochranu jsem ESP desku uzavřel do plastové krabičky. Kvůli pohodlnému napájení jsem navíc připojil USB kabel přímo na napájecí piny 5V a GND. Díky tomu můžu kameru jednoduše napájet z powerbanky.
Další úpravy by mohly být například:
- automatické zahození prvních několika snímků
- uložení posledního nastavení do paměti
- jednoduché tlačítko pro spuštění bez webového rozhraní
- externí stavová LED
Už v této podobě je to ale použitelné zařízení, které se bude hodit i u dalších pokusů. Stačí ho namířit, nastavit interval, spustit focení a po skončení složit z fotek video.
Použité moduly zakoupíte na Laskakit.cz. Přímý odkaz na ESP32-CAM je ZDE a UART převodník ZDE.
