Dalam berbagai proyek Internet of Things (IoT), modul ESP32-CAM sering dimanfaatkan sebagai sistem pemantauan, kamera otomatis, hingga perangkat pengambilan gambar berbasis jaringan. Umumnya, foto hasil tangkapan disimpan pada kartu microSD agar dapat diakses kembali dengan mudah. Namun, bagaimana jika Anda tidak memiliki kartu microSD? Untungnya, ESP32-CAM tetap dapat menyimpan hasil foto menggunakan memori internal bawaan, yaitu SPIFFS (SPI Flash File System). Dengan metode ini, foto yang diambil dapat disimpan secara langsung ke memori flash internal tanpa memerlukan perangkat tambahan.
Pada tutorial ini, kita akan mempelajari cara mengambil foto menggunakan ESP32-CAM-MB dengan sensor kamera OV3660, kemudian menyimpannya ke memori internal menggunakan nama file yang disertai tanggal dan waktu (timestamp). Penggunaan timestamp pada nama file memiliki beberapa keuntungan, seperti mencegah file lama tertimpa oleh file baru, memudahkan identifikasi waktu pengambilan gambar, membantu pengelompokan dan pengelolaan file, dan mempermudah implementasi sistem monitoring atau CCTV sederhana.
ESP32-CAM dengan Sensor OV3660
ESP32-CAM-MB berfungsi sebagai modul pemrograman yang mempermudah proses upload program melalui USB. Sedangkan sensor OV3660 merupakan sensor kamera beresolusi tinggi yang memiliki kualitas cukup baik untuk berbagai kebutuhan pemantauan. Perlu diperhatikan bahwa sensor OV3660 memiliki kebutuhan memori yang lebih besar dibandingkan beberapa sensor lain seperti OV2640. Oleh karena itu, konfigurasi resolusi perlu disesuaikan agar sistem tetap stabil.
Mengapa Tidak Menggunakan MicroSD?
Pada umumnya, penyimpanan gambar pada ESP32-CAM menggunakan kartu microSD karena kapasitasnya lebih besar. Namun pada kondisi tertentu, penggunaan microSD tidak selalu diperlukan, misalnya tidak tersedia kartu microSD, hanya menyimpan beberapa gambar, dan digunakan untuk pengujian atau prototipe. Sebagai penggantinya, kita dapat memanfaatkan SPIFFS (SPI Flash File System). SPIFFS merupakan sistem file internal yang berjalan pada memori flash ESP32. Walaupun kapasitasnya tidak sebesar microSD, metode ini cukup untuk menyimpan beberapa file gambar berukuran kecil hingga menengah.
Cara Kerja Sistem
Pada tutorial ini, ESP32-CAM akan melakukan beberapa proses berikut:
1. ESP32-CAM terhubung ke jaringan Wi-Fi
2. Sistem mengambil waktu dari server NTP
3. Zona waktu disesuaikan dengan lokasi pengguna
4. Kamera diinisialisasi
5. Sistem mengambil foto
6. Foto disimpan ke SPIFFS
7. Nama file otomatis menggunakan tanggal dan waktu
8. Proses diulang setiap 10 detik
Format nama file yang dihasilkan:
picture_2026-06-16_14-25-10.jpg
Dengan format tersebut, setiap foto akan memiliki nama unik sehingga file lama tidak tertimpa.
Perangkat yang Dibutuhkan
Untuk mengikuti tutorial ini, siapkan beberapa komponen berikut:
- ESP32-CAM-MB
- Modul kamera OV3660
- Kabel USB
- Arduino IDE
- Jaringan Wi-Fi
Library yang Digunakan
Tambahkan beberapa library berikut pada program:
#include "esp_camera.h"
#include "SPIFFS.h"
#include "WiFi.h"
#include "time.h"
#include "soc/soc.h"
#include "soc/rtc_cntl_reg.h"
Masing-masing library memiliki fungsi sebagai berikut:
- esp_camera.h → Mengontrol modul kamera
- SPIFFS.h → Mengakses memori internal
- WiFi.h → Menghubungkan perangkat ke internet
- time.h → Mengambil waktu dari server NTP
- soc/soc.h → Mengatasi masalah brownout
Kode Lengkap Program
Salin seluruh kode berikut ke Arduino IDE. Program ini sudah disesuaikan untuk ESP32-CAM-MB dengan sensor OV3660 dan menggunakan SPIFFS sebagai pengganti microSD.
#include "esp_camera.h"
#include "SPIFFS.h"
#include "soc/soc.h"
#include "soc/rtc_cntl_reg.h"
#include <WiFi.h>
#include "time.h"
// Ganti dengan WiFi Anda
const char* ssid = "NAMA_WIFI";
const char* password = "PASSWORD_WIFI";
// Zona waktu Indonesia (WIB)
String myTimezone = "WIB-7";
// Pin ESP32-CAM 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
camera_config_t config;
// Inisialisasi kamera
void configInitCamera(){
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_sccb_sda = SIOD_GPIO_NUM;
config.pin_sccb_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;
config.grab_mode = CAMERA_GRAB_LATEST;
if(psramFound()){
config.frame_size=FRAMESIZE_SVGA;
config.jpeg_quality=12;
config.fb_count=1;
}
else{
config.frame_size=FRAMESIZE_VGA;
config.jpeg_quality=15;
config.fb_count=1;
}
esp_err_t err=esp_camera_init(&config);
if(err!=ESP_OK){
Serial.printf("Camera gagal:0x%x\n",err);
return;
}
}
// Koneksi WiFi
void initWiFi(){
WiFi.begin(ssid,password);
Serial.println("Menghubungkan WiFi");
while(WiFi.status()!=WL_CONNECTED){
Serial.print(".");
delay(500);
}
Serial.println("");
Serial.println("WiFi Terhubung");
}
// Atur zona waktu
void setTimezone(String timezone){
setenv("TZ",timezone.c_str(),1);
tzset();
}
// Ambil waktu dari NTP
void initTime(String timezone){
struct tm timeinfo;
configTime(0,0,"pool.ntp.org");
if(!getLocalTime(&timeinfo)){
Serial.println("Gagal mengambil waktu");
return;
}
setTimezone(timezone);
}
// Membuat nama file otomatis
String getPictureFilename(){
struct tm timeinfo;
if(!getLocalTime(&timeinfo)){
return "";
}
char timeString[20];
strftime(
timeString,
sizeof(timeString),
"%Y-%m-%d_%H-%M-%S",
&timeinfo
);
String filename="/picture_"+
String(timeString)+
".jpg";
return filename;
}
// Ambil dan simpan foto
void takeSavePhoto(){
camera_fb_t *fb=
esp_camera_fb_get();
if(!fb){
Serial.println("Capture gagal");
return;
}
String path=
getPictureFilename();
Serial.println(path);
File file=
SPIFFS.open(
path,
FILE_WRITE
);
if(!file){
Serial.println(
"Gagal menyimpan file"
);
}
else{
file.write(
fb->buf,
fb->len
);
Serial.println(
"Foto berhasil disimpan"
);
}
file.close();
esp_camera_fb_return(fb);
}
void setup(){
WRITE_PERI_REG(
RTC_CNTL_BROWN_OUT_REG,
0
);
Serial.begin(115200);
delay(2000);
initWiFi();
initTime(myTimezone);
if(!SPIFFS.begin(true)){
Serial.println(
"Gagal memulai SPIFFS"
);
return;
}
Serial.println(
"Memulai kamera..."
);
configInitCamera();
Serial.println(
"Kamera siap"
);
}
void loop(){
takeSavePhoto();
delay(10000);
}
Mengatur Kredensial Wi-Fi
Masukkan nama Wi-Fi dan password yang digunakan.
const char* ssid = "xxxxxx";
const char* password = "xxxxxxxx";
Pastikan jaringan stabil karena proses sinkronisasi waktu membutuhkan koneksi internet.
Mengatur Zona Waktu Indonesia
Untuk pengguna di wilayah Indonesia bagian barat (WIB), gunakan konfigurasi berikut:
String myTimezone = "WIB-7";
Konfigurasi ini akan memastikan nama file mengikuti waktu lokal Indonesia.
Konfigurasi Pin Kamera
Karena menggunakan modul ESP32-CAM AI Thinker, konfigurasi pin yang digunakan adalah:
#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
Inisialisasi Kamera
Sistem kemudian melakukan konfigurasi kamera. Untuk sensor OV3660, disarankan menggunakan ukuran gambar yang tidak terlalu besar agar sistem berjalan stabil.
if(psramFound()){
config.frame_size = FRAMESIZE_SVGA;
config.jpeg_quality = 12;
config.fb_count = 1;
}
Penjelasan konfigurasi:
- FRAMESIZE_SVGA → Resolusi 800×600
- jpeg_quality = 12 → Kualitas gambar menengah
- fb_count = 1 → Mengurangi penggunaan RAM
Pengaturan ini cukup seimbang antara kualitas gambar dan performa sistem.
Menghubungkan ESP32 ke Wi-Fi
ESP32 harus terhubung ke internet agar dapat mengambil data waktu dari server NTP.
void initWiFi(){
WiFi.begin(ssid,password);
while(WiFi.status()!=WL_CONNECTED){
delay(500);
Serial.print(".");
}
}
Saat proses berhasil, ESP32 akan terhubung secara otomatis.
Mengambil Waktu dari Server NTP
Setelah terhubung ke internet, sistem akan meminta data waktu.
configTime(0,0,"pool.ntp.org");
Server NTP berfungsi memberikan informasi waktu secara akurat.
Membuat Nama File Otomatis Berdasarkan Timestamp
Program akan menghasilkan nama file secara otomatis menggunakan waktu saat foto diambil.
Contoh:
picture_2026-06-16_14-25-10.jpg
Dengan metode ini, file lama tidak tertimpa, waktu pengambilan foto mudah diketahui, dan manajemen file menjadi lebih rapi.
Menyimpan Foto ke SPIFFS
Berikut fungsi yang digunakan untuk menyimpan gambar ke memori internal:
void takeSavePhoto(){
camera_fb_t *fb = esp_camera_fb_get();
if(!fb){
Serial.println("Capture gagal");
return;
}
String path=getPictureFilename();
File file=SPIFFS.open(path,FILE_WRITE);
if(!file){
Serial.println("Gagal menyimpan");
}
else{
file.write(fb->buf,fb->len);
Serial.println("Foto tersimpan");
}
file.close();
esp_camera_fb_return(fb);
}
Fungsi tersebut akan mengambil gambar dari kamera, membuat nama file otomatis, menyimpan file ke SPIFFS, membersihkan buffer memori.
Cara Kerja Program Secara Keseluruhan
Ketika sistem dijalankan:
1. ESP32 terhubung ke Wi-Fi
2. Waktu disinkronkan melalui NTP
3. Kamera diinisialisasi
4. SPIFFS diaktifkan
5. Kamera mengambil foto
6. Foto disimpan
7. Proses diulang setiap 10 detik
Hasil Pengujian
1. Setelah program berhasil diunggah, buka Serial Monitor dengan baud rate 115200.
2. Tekan tombol RST pada modul ESP32-CAM.
3. Apabila berhasil, Serial Monitor akan menampilkan informasi seperti berikut:
Contoh hasil:
Saved:
/picture_2026-06-16_14-25-10.jpg
Hal tersebut menunjukkan bahwa gambar telah tersimpan pada memori internal.







0 Komentar