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 


🔥 구현 목표

  1. OV5640에서 HD(1280x720) 해상도로 크롭하여 캡처
  2. ESP32에서 JPEG 압축
  3. 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;
    }
}

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); // 필요 시 좌우 반전
    }
}

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!");
}

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

🔥 전체 펌웨어 코드

위의 모든 기능을 통합한 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() {}

 

🚀 최종 요약

✅ OV5640에서 HD(1280x720) 해상도 크롭
✅ ESP32가 JPEG로 변환 후 Wi-Fi로 10FPS 전송
✅ 초당 10프레임 유지하며 지속적으로 전송

 

이 코드를 ESP32-S3에 업로드하면 HD 영상이 10FPS로 전송됩니다. 🚀✨