Kernel Porting/Linux
[딥네트워크 펌웨어 설계 노하우 소개][ESP32 에서 OV5640 을 사용하여 HD 해상도로 크롭된 이미지를 초당 10프레임(FPS)으로 Wi-Fi를 통해 전송하는 펌웨어 설계 노하우]
파란새
2025. 2. 27. 18:57
ESP32 에서 OV5640 을 사용하여 HD 해상도로 크롭된 이미지를 초당 10프레임(FPS)으로 Wi-Fi를 통해 전송하는 펌웨어를 다음과 같이 설명 드립니다 .... 참고하셔서 펌웨어 개발 진행에 도움 되셨으면 합니다 ...
일인 AI 스타트업 딥네트워크 CEO / CTO 장석원 HP : 010 3350 6509 sayhi7@daum.net
🔥 구현 목표
- OV5640에서 HD(1280x720) 해상도로 크롭하여 캡처
- ESP32에서 JPEG 압축
- Wi-Fi를 통해 초당 10프레임(FPS)으로 전송
🚀 핵심 기능별 코드
1️⃣ OV5640 초기화 및 HD 해상도 설정
OV5640 센서를 HD(1280x720)로 크롭하여 설정합니다.
c
복사편집
#include "esp_camera.h"
#include "ov5640.h"
#include <WiFi.h>
#include <HTTPClient.h>
// Wi-Fi 정보 설정
const char* ssid = "your_SSID";
const char* password = "your_PASSWORD";
const char* serverUrl = "http://yourserver.com/upload";
// 카메라 설정
camera_config_t config;
void setupCamera() {
config.ledc_channel = LEDC_CHANNEL_0;
config.ledc_timer = LEDC_TIMER_0;
config.pin_d0 = 5;
config.pin_d1 = 18;
config.pin_d2 = 19;
config.pin_d3 = 21;
config.pin_d4 = 36;
config.pin_d5 = 39;
config.pin_d6 = 34;
config.pin_d7 = 35;
config.pin_xclk = 0;
config.pin_pclk = 22;
config.pin_vsync = 25;
config.pin_href = 23;
config.pin_sscb_sda = 26;
config.pin_sscb_scl = 27;
config.pin_pwdn = -1;
config.pin_reset = -1;
config.xclk_freq_hz = 20000000;
config.pixel_format = PIXFORMAT_JPEG;
config.frame_size = FRAMESIZE_HD; // 1280x720 해상도 설정
config.jpeg_quality = 12; // JPEG 압축 품질 (값이 낮을수록 고화질)
config.fb_count = 2;
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
Serial.println("Camera Init Failed");
return;
}
}
#include "ov5640.h"
#include <WiFi.h>
#include <HTTPClient.h>
// Wi-Fi 정보 설정
const char* ssid = "your_SSID";
const char* password = "your_PASSWORD";
const char* serverUrl = "http://yourserver.com/upload";
// 카메라 설정
camera_config_t config;
void setupCamera() {
config.ledc_channel = LEDC_CHANNEL_0;
config.ledc_timer = LEDC_TIMER_0;
config.pin_d0 = 5;
config.pin_d1 = 18;
config.pin_d2 = 19;
config.pin_d3 = 21;
config.pin_d4 = 36;
config.pin_d5 = 39;
config.pin_d6 = 34;
config.pin_d7 = 35;
config.pin_xclk = 0;
config.pin_pclk = 22;
config.pin_vsync = 25;
config.pin_href = 23;
config.pin_sscb_sda = 26;
config.pin_sscb_scl = 27;
config.pin_pwdn = -1;
config.pin_reset = -1;
config.xclk_freq_hz = 20000000;
config.pixel_format = PIXFORMAT_JPEG;
config.frame_size = FRAMESIZE_HD; // 1280x720 해상도 설정
config.jpeg_quality = 12; // JPEG 압축 품질 (값이 낮을수록 고화질)
config.fb_count = 2;
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
Serial.println("Camera Init Failed");
return;
}
}
2️⃣ OV5640 해상도 크롭 적용
OV5640의 해상도를 1280x720(HD)로 설정하고, 중앙 부분을 크롭합니다.
c
복사편집
void setCropRegion() {
sensor_t *s = esp_camera_sensor_get();
if (s) {
s->set_framesize(s, FRAMESIZE_HD); // HD 해상도로 설정 (1280x720)
s->set_vflip(s, 1); // 필요 시 이미지 반전
s->set_hmirror(s, 1); // 필요 시 좌우 반전
}
}
sensor_t *s = esp_camera_sensor_get();
if (s) {
s->set_framesize(s, FRAMESIZE_HD); // HD 해상도로 설정 (1280x720)
s->set_vflip(s, 1); // 필요 시 이미지 반전
s->set_hmirror(s, 1); // 필요 시 좌우 반전
}
}
3️⃣ Wi-Fi 초기화 및 연결
ESP32를 Wi-Fi 네트워크에 연결합니다.
c
복사편집
void connectWiFi() {
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
}
Serial.println("WiFi Connected!");
}
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
}
Serial.println("WiFi Connected!");
}
4️⃣ JPEG 캡처 및 Wi-Fi 전송 (초당 10프레임)
10FPS를 유지하면서 캡처 및 Wi-Fi 전송을 수행합니다.
c
복사편집
void sendImage(camera_fb_t *fb) {
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
http.begin(serverUrl);
http.addHeader("Content-Type", "image/jpeg");
int httpResponseCode = http.POST(fb->buf, fb->len);
if (httpResponseCode > 0) {
Serial.printf("Image sent successfully: %d\n", httpResponseCode);
} else {
Serial.printf("Failed to send image: %d\n", httpResponseCode);
}
http.end();
}
}
void captureAndSend() {
const int target_fps = 10;
const int delay_per_frame = 1000 / target_fps;
while (true) {
unsigned long start_time = millis();
camera_fb_t *fb = esp_camera_fb_get();
if (!fb) {
Serial.println("Camera capture failed");
continue;
}
sendImage(fb);
esp_camera_fb_return(fb);
unsigned long process_time = millis() - start_time;
int delay_time = delay_per_frame - process_time;
if (delay_time > 0) {
delay(delay_time);
}
}
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
http.begin(serverUrl);
http.addHeader("Content-Type", "image/jpeg");
int httpResponseCode = http.POST(fb->buf, fb->len);
if (httpResponseCode > 0) {
Serial.printf("Image sent successfully: %d\n", httpResponseCode);
} else {
Serial.printf("Failed to send image: %d\n", httpResponseCode);
}
http.end();
}
}
void captureAndSend() {
const int target_fps = 10;
const int delay_per_frame = 1000 / target_fps;
while (true) {
unsigned long start_time = millis();
camera_fb_t *fb = esp_camera_fb_get();
if (!fb) {
Serial.println("Camera capture failed");
continue;
}
sendImage(fb);
esp_camera_fb_return(fb);
unsigned long process_time = millis() - start_time;
int delay_time = delay_per_frame - process_time;
if (delay_time > 0) {
delay(delay_time);
}
}
🔥 전체 펌웨어 코드
위의 모든 기능을 통합한 ESP32 펌웨어 전체 코드입니다.
c
복사편집
#include "esp_camera.h"
#include "ov5640.h"
#include <WiFi.h>
#include <HTTPClient.h>
const char* ssid = "your_SSID";
const char* password = "your_PASSWORD";
const char* serverUrl = "http://yourserver.com/upload";
camera_config_t config;
void setupCamera() {
config.ledc_channel = LEDC_CHANNEL_0;
config.ledc_timer = LEDC_TIMER_0;
config.pin_d0 = 5;
config.pin_d1 = 18;
config.pin_d2 = 19;
config.pin_d3 = 21;
config.pin_d4 = 36;
config.pin_d5 = 39;
config.pin_d6 = 34;
config.pin_d7 = 35;
config.pin_xclk = 0;
config.pin_pclk = 22;
config.pin_vsync = 25;
config.pin_href = 23;
config.pin_sscb_sda = 26;
config.pin_sscb_scl = 27;
config.pin_pwdn = -1;
config.pin_reset = -1;
config.xclk_freq_hz = 20000000;
config.pixel_format = PIXFORMAT_JPEG;
config.frame_size = FRAMESIZE_HD; // 1280x720 해상도 설정
config.jpeg_quality = 12;
config.fb_count = 2;
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
Serial.println("Camera Init Failed");
return;
}
}
void setCropRegion() {
sensor_t *s = esp_camera_sensor_get();
if (s) {
s->set_framesize(s, FRAMESIZE_HD);
s->set_vflip(s, 1);
s->set_hmirror(s, 1);
}
}
void connectWiFi() {
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
}
Serial.println("WiFi Connected!");
}
void sendImage(camera_fb_t *fb) {
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
http.begin(serverUrl);
http.addHeader("Content-Type", "image/jpeg");
int httpResponseCode = http.POST(fb->buf, fb->len);
if (httpResponseCode > 0) {
Serial.printf("Image sent successfully: %d\n", httpResponseCode);
} else {
Serial.printf("Failed to send image: %d\n", httpResponseCode);
}
http.end();
}
}
void captureAndSend() {
const int target_fps = 10;
const int delay_per_frame = 1000 / target_fps;
while (true) {
unsigned long start_time = millis();
camera_fb_t *fb = esp_camera_fb_get();
if (!fb) {
Serial.println("Camera capture failed");
continue;
}
sendImage(fb);
esp_camera_fb_return(fb);
unsigned long process_time = millis() - start_time;
int delay_time = delay_per_frame - process_time;
if (delay_time > 0) {
delay(delay_time);
}
}
}
void setup() {
Serial.begin(115200);
connectWiFi();
setupCamera();
setCropRegion();
captureAndSend();
}
void loop() {}
#include "ov5640.h"
#include <WiFi.h>
#include <HTTPClient.h>
const char* ssid = "your_SSID";
const char* password = "your_PASSWORD";
const char* serverUrl = "http://yourserver.com/upload";
camera_config_t config;
void setupCamera() {
config.ledc_channel = LEDC_CHANNEL_0;
config.ledc_timer = LEDC_TIMER_0;
config.pin_d0 = 5;
config.pin_d1 = 18;
config.pin_d2 = 19;
config.pin_d3 = 21;
config.pin_d4 = 36;
config.pin_d5 = 39;
config.pin_d6 = 34;
config.pin_d7 = 35;
config.pin_xclk = 0;
config.pin_pclk = 22;
config.pin_vsync = 25;
config.pin_href = 23;
config.pin_sscb_sda = 26;
config.pin_sscb_scl = 27;
config.pin_pwdn = -1;
config.pin_reset = -1;
config.xclk_freq_hz = 20000000;
config.pixel_format = PIXFORMAT_JPEG;
config.frame_size = FRAMESIZE_HD; // 1280x720 해상도 설정
config.jpeg_quality = 12;
config.fb_count = 2;
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
Serial.println("Camera Init Failed");
return;
}
}
void setCropRegion() {
sensor_t *s = esp_camera_sensor_get();
if (s) {
s->set_framesize(s, FRAMESIZE_HD);
s->set_vflip(s, 1);
s->set_hmirror(s, 1);
}
}
void connectWiFi() {
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
}
Serial.println("WiFi Connected!");
}
void sendImage(camera_fb_t *fb) {
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
http.begin(serverUrl);
http.addHeader("Content-Type", "image/jpeg");
int httpResponseCode = http.POST(fb->buf, fb->len);
if (httpResponseCode > 0) {
Serial.printf("Image sent successfully: %d\n", httpResponseCode);
} else {
Serial.printf("Failed to send image: %d\n", httpResponseCode);
}
http.end();
}
}
void captureAndSend() {
const int target_fps = 10;
const int delay_per_frame = 1000 / target_fps;
while (true) {
unsigned long start_time = millis();
camera_fb_t *fb = esp_camera_fb_get();
if (!fb) {
Serial.println("Camera capture failed");
continue;
}
sendImage(fb);
esp_camera_fb_return(fb);
unsigned long process_time = millis() - start_time;
int delay_time = delay_per_frame - process_time;
if (delay_time > 0) {
delay(delay_time);
}
}
}
void setup() {
Serial.begin(115200);
connectWiFi();
setupCamera();
setCropRegion();
captureAndSend();
}
void loop() {}
🚀 최종 요약
✅ OV5640에서 HD(1280x720) 해상도 크롭
✅ ESP32가 JPEG로 변환 후 Wi-Fi로 10FPS 전송
✅ 초당 10프레임 유지하며 지속적으로 전송
이 코드를 ESP32-S3에 업로드하면 HD 영상이 10FPS로 전송됩니다. 🚀✨