아두이노/아두이노 일반

초간단 wifi 카메라 ESP32-CAM 사용하기

아크리엑터 2020. 5. 10. 18:43
반응형





작년에 충동 구매한 부품들을 뒤적이다가 카메라 모듈을 찾게 되어서, 정리차원에서 간단 사용기를 적는다.

홈서버로 사용하는 라즈베리파이에 카메라를 연결하여 사용하려고도 해봤는데, 아두이노를 이용해서도 아주 간단하게 카메라를 사용한다. 동영상까지는 얼마나 잘 작동할지 모르겠지만... WIFI카메라를 만들어보자.

아래에 설명하게 되는 카메라 모듈은 ESP32를 같이 장착하고 있는 모듈로, 전원만 공급하면 WIFI카메라 역할을 하게 된다. MicroSD카드 슬롯도 장착되어있어서, 필요한 것은 저장할 수 있는 기능도 있다.

안테나 까지 포함해서 가격이 5달러를 조금 넘을 뿐이다. 세상 정말 좋아진것 같다. 중국이 있어서 행복해요 라는 말이 헛소리는 아닌 것 같다.

 
한번의 광고 클릭이 저에게 도움을 줍니다. 감사합니다.

필요부품

    이 모듈도 다양한 곳에서 살수 있지만, 알리 익스프레스에서 간단히 조회를 하니, 안테나까지 포함된 것으로 배송비도 없이 싸게 판매를 하고있다.

  - https://www.aliexpress.com/item/33027303390.html

  - 제품 스펙은 이렇다고 한다. 쇼핑몰에 안내되어있는 글을 구글번역하여 붙여넣기 하였다.  카메라는 200M화소를 지원한다.

 

[ESP32-CAM]

모델 : ESP32-CAM

작동 전압 : 5V

SPI 플래시 : 32Mbit

RAM : Inter 520KB +, 외부 4M PSRAM

블루투스 : BLuetooth 4.2 BR / EDR & BLE 표준

와이파이 : 802.11 / b / g / n / e / i

포트 : UART, SPI, I2C, PWM

IO 포트 : 9

직렬 포트 속도 : 115200bps

사진 형식 : JPEG (OV2640 만 지원), BMP, GRAYSCALE

스펙트럼 범위 : 2412-2484MHz

Antanna : 온보드 PCB Antanna 2dBi

보안 : WPA / WPA2 / WPA2-Enterprise / WPS

작용 온도 : -20 -85 ℃

보관 온도 : -40 -90 ℃, <90 % RH

 

송신 전력 : 

802.11b : 17 +/- 2dBm (@ 11Mbps)

802.11g : 14 +/- 2dBm (@ 54Mbps)

802.11n : 13 +/- 2dBm (@ MSC7)

 

안테나 감도

CCK, 1Mbps : -90dBm

CCK, 11Mbps : -85dBm

6Mbps (1/2 BPSK) : -88dBm

54Mbps (3/4 64-QAM) : -70dBm

MCS7 (65Mbps, 72.2Mbps) : -67dBm

 

[ESP32-S]

메인 칩은 최대 240MHz의 주파수와 최대 600DMIPS의 컴퓨팅 성능을 가진 저전력 듀얼 코어 32 비트 CPU를 사용합니다.

기본 32Mbit SPI 플래시, 520KB SRAM

SoftAP 및 스테이션 모드 지원

초소형 802.11b / g / n Wi-Fi + BT / BLE SoC 모듈

UART / SPI / I2C / I2S / PWM / ADC / DAC 등 지원

펌웨어 업그레이드 지원 (FOTA)

안테나는 온보드 안테나 또는 IPEX 블록 출력을 지원합니다

 

[OV2640 카메라 모듈]

특색:

OV2640 이미지 센서는 2 메가 픽셀 (1632x1232 픽셀)

작은 크기, 낮은 작동 전압 및 단일 칩 UXGA 카메라 및 이미지 프로세서의 모든 기능을 제공합니다.

SCCB 컨트롤을 통해 전체 프레임을 출력하고 서브 샘플링을 수행하며 창을 열고 다양한 해상도 10 비트 샘플링 데이터를 얻을 수 있습니다.

제품 UXGA는 초당 최대 15 프레임을 이미지화합니다.

사용자는 이미지 품질, 데이터 형식 및 전송 모드를 완전히 제어 할 수 있습니다.

 

사양:

저조도 애플리케이션을위한 고감도

임베디드 애플리케이션을위한 저전압

I2C 인터페이스와 호환되는 표준 SCCB 인터페이스

RawRGB, RGB (GRB4 : 2 : 2, RGB565 / 555 / 444), YUV (4 : 2 : 2) 및 YCbCr (4 : 2 : 2) 출력 형식

UXGA, SXGA, VGA, QVGA, QQVGA, CIF, QCIF 및 최대 40x30 크기 지원

Vario Pixel 하위 샘플링 모드 지원

자동 충격 제어 기능에는 자동 노출 제어, 자동 게인 제어, 자동 화이트 밸런스, 자동 줄 제거, 블랙 레벨 자동 교정이 포함됩니다. 채도, 색조, 감마, 선명도를 포함한 이미지 품질 관리 ANTI_BLOOM

노이즈 캔슬링 및 데드 픽셀 보상 기능이있는 ISP

이미지 스케일링 지원

렌즈 손실 보정

채도 자동 조정

가장자리 향상 자동 조정

노이즈 감소 자동 조정

감지 배열 1632 x 1232

최대 형식 UXGA IO

전압 1.7V -3.3V

아날로그 전압 2.5 -3.0V (내부 LDO-전원 공급 장치 1.2V)

소비 전력 TBD 절전 <20uA

온도 작동 -30 -70 ℃

섭씨 0 ~ 50 도의 안정적인 작업

출력 형식 (8 비트)

YUV / YCbCr4 : 2 : 2 RGB565 / 555 / 444

GRB4 : 2 : 2 원시 RGB 데이터

광학 크기 1/4 "

시야각 25 °

최대 속도 15fps

SXGA 감도 1.3V / (Lux-sec)

신호 대 잡음비 40dB

다이나믹 레인지 50 dB

뷰 모드 프로그레시브 전자 노출 1 라인 ~ 1247 라인

픽셀 영역 2.2 um x 2.2 um

60 ℃에서 암전류 15mV / s

 

스펙에는 무엇인지 모르겠지만, 많은 것들이 적혀있다. 내가 이해를 한 것은 200M픽셀의 카메라가 설치되어있다. 15프레임을 지원한다. ESP32모듈은 BLE도 지원한다. 수준으로만 주요한 것을 뽑아봤다.

 

ESP32-S 모듈 PIN정보

 

 

 

 

 

 

 

 

 

환경설정(개발)

아두이노의 개발 환경을 설정하자. 기본적인 아두이노에는 이 보드를 지원하지 못하기 때문에, 새로운 보드 정보를 등록해야 한다. 등록 방법은 다음과 같다.

아두이노를 실행한 후, 환경설정 메뉴를 선택하여 나타난 아래 화면에서 추가적인 보드 매니저 URLs로  표시된 맨 오른쪽의 1번 아이콘을 선택한다. 내 경우에는 기존에 ESP8266 보드를 추가하여 사용하였기에, 이 주소가 추가되어있는데, 이것은 사용자에 따라서 없을 수도 있고 다르다.

그런 후에, 아래 그림과 같이 URL을 추가한다. ( https://dl.espressif.com/dl/package_esp32_index.json )

 

 

 

 

 

 

 

 

 

그 다음은 아두이노 메뉴(툴 -> 보드 -> 보드매니저)를 선택한 후,  "esp32"로 보드를 검색하여 설치하도록 한다. 설치할 파일을 다운로드 할 때 꽤 시간이 오래 걸린다.

 

 

 

 

 

 

 

 

 

위의 ESP32 보드가 설치가 된 되에 아래와 같이 메뉴를 선택하면, 수많은 ESP32 보드가 설치된 것을 확인할 수 있다. 너무 많아서 놀랐다. 언젠가 이 모든 보드를 사용해볼 수 있을까... 이것을 사용해야 지만 하나? 등 다양한 생각이 든다. 엄청 많은 보드가 있나 보다. 그중에 눈에 띄는 TTGO보드가 있다. 얼마전에 알리에서 본 모양이 깔끔한 보드였던 것으로 기억한다.

보드를 ESP32 Wrover Module로 설정한다.  포트는 나중에 FTDI 모듈을 연결했을 때 COM포트 인식되면 그것을 선택한다.

 

 

 

 

 

 

 

 

 

 

예제

예제를 선택해보자. 아래와 같이 등록되어 있는 예제를 선택한다. 맥에서 설치했을 때 예제가 안보여서 아두이노를 종료했다가 재실행하니, 정상적으로 표시가 되었다.  

 

 

 

 

 

 

 

 

 

Camera 메뉴에 있는 "Camera Web Server" 예제를 선택하였다.

#include "esp_camera.h"
#include <WiFi.h>

//
// WARNING!!! Make sure that you have either selected ESP32 Wrover Module,
//            or another board which has PSRAM enabled
//

// Select camera model
#define CAMERA_MODEL_WROVER_KIT
//#define CAMERA_MODEL_ESP_EYE
//#define CAMERA_MODEL_M5STACK_PSRAM
//#define CAMERA_MODEL_M5STACK_WIDE
//#define CAMERA_MODEL_AI_THINKER

#include "camera_pins.h"

const char* ssid = "*********";       // WIFI SID 이름을 입력한다.
const char* password = "*********";   // WIFI 비밀번호를 입력한다.

void startCameraServer();

void setup() {
  Serial.begin(115200);
  Serial.setDebugOutput(true);
  Serial.println();

  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;
  //init with high specs to pre-allocate larger buffers
  if(psramFound()){
    config.frame_size = FRAMESIZE_UXGA;
    config.jpeg_quality = 10;
    config.fb_count = 2;
  } else {
    config.frame_size = FRAMESIZE_SVGA;
    config.jpeg_quality = 12;
    config.fb_count = 1;
  }

#if defined(CAMERA_MODEL_ESP_EYE)
  pinMode(13, INPUT_PULLUP);
  pinMode(14, INPUT_PULLUP);
#endif

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

  sensor_t * s = esp_camera_sensor_get();
  //initial sensors are flipped vertically and colors are a bit saturated
  if (s->id.PID == OV3660_PID) {
    s->set_vflip(s, 1);//flip it back
    s->set_brightness(s, 1);//up the blightness just a bit
    s->set_saturation(s, -2);//lower the saturation
  }
  //drop down frame size for higher initial frame rate
  s->set_framesize(s, FRAMESIZE_QVGA);

#if defined(CAMERA_MODEL_M5STACK_WIDE)
  s->set_vflip(s, 1);
  s->set_hmirror(s, 1);
#endif

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");

  startCameraServer();

  Serial.print("Camera Ready! Use 'http://");
  Serial.print(WiFi.localIP());
  Serial.println("' to connect");
}

void loop() {
  // put your main code here, to run repeatedly:
  delay(10000);
}

 

컴파일

 

보드를 "ESP32 Wrover  Module"을 선택하고, 아두이노 IDE화면의 맨 왼쪽의 Check모양의 버튼인 컴파일을 해보자. 컴파일이 완료되면 이상없지만, 내 경우에는 "스케치가 너무 크다"는 메시지 "Sketch is too big" 메시지가 출력되고 컴파일 오류가 난다.

이것을 해결하기 위한 방법은 "툴 --> Partition Scheme"를 "Huge APP..."을 선택한 후 컴파일을 하면 오류없이 완료된다.

 

업로드

FTDI 모듈을 아래 그림과 같이 연결한다. 아래 그림과 같이 U0R은 FTDI의 TX로, U0T 는 FTDI의 RX로 연결한다. 

그리고, 코드 업로드를 위해서, ESP32-S의 IO0(GPIO 0) 를 GND에 연결한다. 

 

 

 

 

 

 

 

 

 

아두이노의 업로드 버튼을 누른다. 컴파일이 된 후에, 아래와 같이 나온 후, 업로드가 진행된다.

스케치는 프로그램 저장 공간 2100647 바이트(66%)를 사용. 최대 3145728 바이트.
전역 변수는 동적 메모리 53544바이트(16%)를 사용, 274136바이트의 지역변수가 남음.  최대는 327680 바이트. 
esptool.py v2.6
Serial port /dev/cu.usbserial-A700f65C
Connecting........_____....._____....._____....._____....._____..

 

 아래의 코드가 나오면서 업로드가 완료된다.

Writing at 0x0019c000... (98 %)
Writing at 0x001a0000... (99 %)
Writing at 0x001a4000... (100 %)
Wrote 2100768 bytes (1661725 compressed) at 0x00010000 in 74.6 seconds (effective 225.3 kbit/s)...
Hash of data verified.
Compressed 3072 bytes to 119...

Writing at 0x00008000... (100 %)
Wrote 3072 bytes (119 compressed) at 0x00008000 in 0.0 seconds (effective 1555.3 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...

 

ESP32-S의 IO0과 GND를 연결한 Jumper를 제거한다. 그 후 아두이노의 시리얼 디버깅 창을 열고 전송속도를 115200 으로 설정한 후, ESP32-S의 RESET버튼을 누른다. 다음과 같은 화면이 나오는데, 하드웨어 리셋이 된 후에 WIFI접속(AP설정한)하고 카메라가 준비되었다는 메시지가 나타난다. 

 

 

 

 

 

 

 

 

 

이제 정상적으로 작동되는 것 같으니, 휴대폰으로 위의 카메라 주소로 접속해보자. 최초 접속한 화면에서 Resolution을 변경하고, 맨 아래에 있는 Start Steam을 선택한다.

 

 

 

 

 

 

카메라 촬영이 되고 있는 것을 보려면, 선택한 메뉴 아래에 동영상이 출력되고 있다.  또한, 위 화면의 왼쪽 상단에 있는 3선의 줄로된 메뉴를 선택해도 된다.

 

 

 

 

 

디버그 창에 출력되는 정보를 보니, 10프레임 이상 나오지 않는 것 같다. 그렇지만, 여기에 히스토그램을 이용하여 이미지 변화를 탐지하여 방법용으로 사용할 수 있을 것 같다.  Enroll Face라는 메뉴는 무엇인지도 좀 찾아봐야 겠다.

MJPG: 87462B 327ms (3.1fps), AVG: 237ms (4.2fps), 0+0+0+0=0 0
MJPG: 87086B 150ms (6.7fps), AVG: 234ms (4.3fps), 0+0+0+0=0 0
MJPG: 87066B 322ms (3.1fps), AVG: 237ms (4.2fps), 0+0+0+0=0 0
MJPG: 87279B 133ms (7.5fps), AVG: 236ms (4.2fps), 0+0+0+0=0 0
MJPG: 87522B 337ms (3.0fps), AVG: 238ms (4.2fps), 0+0+0+0=0 0
MJPG: 87701B 155ms (6.5fps), AVG: 238ms (4.2fps), 0+0+0+0=0 0
MJPG: 87556B 159ms (6.3fps), AVG: 230ms (4.3fps), 0+0+0+0=0 0
MJPG: 87693B 226ms (4.4fps), AVG: 234ms (4.3fps), 0+0+0+0=0 0
MJPG: 87713B 154ms (6.5fps), AVG: 224ms (4.5fps), 0+0+0+0=0 0
MJPG: 87793B 339ms (2.9fps), AVG: 232ms (4.3fps), 0+0+0+0=0 0
MJPG: 87754B 159ms (6.3fps), AVG: 225ms (4.4fps), 0+0+0+0=0 0
MJPG: 87963B 297ms (3.4fps), AVG: 232ms (4.3fps), 0+0+0+0=0 0
MJPG: 87985B 203ms (4.9fps), AVG: 226ms (4.4fps), 0+0+0+0=0 0
MJPG: 87525B 443ms (2.3fps), AVG: 240ms (4.2fps), 0+0+0+0=0 0
MJPG: 86480B 165ms (6.1fps), AVG: 233ms (4.3fps), 0+0+0+0=0 0
MJPG: 87762B 323ms (3.1fps), AVG: 242ms (4.1fps), 0+0+0+0=0 0
MJPG: 87107B 194ms (5.2fps), AVG: 235ms (4.3fps), 0+0+0+0=0 0
MJPG: 87802B 228ms (4.4fps), AVG: 238ms (4.2fps), 0+0+0+0=0 0
MJPG: 87437B 216ms (4.6fps), AVG: 234ms (4.3fps), 0+0+0+0=0 0
MJPG: 88145B 275ms (3.6fps), AVG: 240ms (4.2fps), 0+0+0+0=0 0
MJPG: 88106B 190ms (5.3fps), AVG: 233ms (4.3fps), 0+0+0+0=0 0
MJPG: 87836B 302ms (3.3fps), AVG: 241ms (4.1fps), 0+0+0+0=0 0
MJPG: 87984B 170ms (5.9fps), AVG: 233ms (4.3fps), 0+0+0+0=0 0
MJPG: 87555B 292ms (3.4fps), AVG: 241ms (4.1fps), 0+0+0+0=0 0

 

Troubleshooting  정보는 아래의 사이트에서 찾을 수 있다.

www.randomnerdtutorials.com/esp32-cam-troubleshooting-guide/

 

ESP32-CAM Troubleshooting Guide: Most Common Problems Fixed | Random Nerd Tutorials

This guide is a compilation with the most common errors when using the ESP32-CAM and how to fix them. The ESP32-CAM can be a bit tricky to setup, follow this guide.

randomnerdtutorials.com

 

반응형