こんにちは、あろっちです。
ESP32-WROVER CAMボードはESP32-WROVER-E(技適マーク付き)とカメラが搭載されたボードです。
こちらを入手したので情報をまとめてみました。
ESP32-WROVER CAMボードには、Freenoveのオリジナル品(FNK0060)とジェネリック品があります。
Freenove FNK0060は基板にFREENOVEの文字がシルク印刷されています。

参考サイト:
https://lang-ship.com/blog/work/esp32-cam-fnk0060/(Lang-ship)
上記にたなかさんの情報がありますので参考にしてください。
こちらによると、ジェネリック品のWROVER-Eモジュールはクローン品とのことで筆者の方でも挙動の違いを確認しました。
本記事では両方の情報を網羅しようと思いますが、国内ではオリジナル品であるFreenove FNK0060をお使いください。
本記事は以下を参考にしています。
本記事ではArduino(C/C++)で試してみます。
ESP32-S3-WROOM-1を搭載した最新モデルが販売開始され入手できましたので記事を書きました。ぜひご覧ください。
特徴
Freenove ESP32-WROVER Board FNK0060
Amazonで入手しました。



モジュール | ESP32-WROVER-E (技適マーク付き) ※1 | フラッシュメモリ 4MB PSRAM 8MB※2 |
カメラ | オンボードカメラ (コネクタ) | 付属カメラモジュール OV2640 66° |
USBシリアル | Micro USB | シリアル変換IC CH340※3 |
※2 Arduinoで使用可能な容量は4MBまでです。
※3 シリアルドライバをインストールしていない場合は別途インストールが必要です。
ESP32-S3-WROOM-1を搭載した最新モデルの記事を書きました。ぜひご覧ください。
ギャラリー
Freenove FNK0060とジェネリック品を並べてみました。
基板サイズに違いはないようです。


Freenove FNK0060とジェネリック品でボードのバージョンが異なっています
普通のブレッドボード(400穴)だと片側1ピン分の穴が確保できます。

ブレッドボード2枚を連結して設置すると左右どちらもピン穴が確保できました。

サンハヤトのニューブレッドボードでは、3ピン分(片側どちらか1ピン、他方2ピン)ピン穴が確保できました。
このボードを使うのにオススメのブレッドボードです。
※このボードの使用例を後述のサンプルプログラムに掲載しています。

カメラモジュール(OV2640)例
カメラモジュール(OV2640)には様々なバリエーションがあります。
こちらは別途購入したもの。

66° 21mm(付属カメラ) 120°21mm 160°21mm
68°75mm 160°75mm
カメラはコネクタ接続なので換装して使えます。

CameraWebServer動作例
Freenove FNK0060
Arduino IDEでスケッチ書き込みした動作例

PlatformIO IDEでスケッチ書き込みした動作例

ジェネリック品
PlatformIO IDEにてビルド&書き込んだものを動かしたサンプル画像です。
カメラ OV2640 120° 21mm

カメラ OV2640 160° 21mm

ピン配列

※画像のバー付きのピン(GPIO)はカメラ(コネクタ)に接続されています。
下表のボード表記は左上のピンから反時計回りに記載しています。
※3.3V、EN、VCC、GNDを除く
ボード表記 | GPIO | 主機能 | 備考 |
---|---|---|---|
VP | GPIO36 | ADC1_0 | Camera Y6 |
VN | GPIO39 | ADC1_3 | Camera Y7 |
34 | GPIO34 | ADC1_6 | Camera Y8 |
35 | GPIO35 | ADC1_7 | Camera Y9 |
32 | GPIO32 | TOUCH_9 | |
33 | GPIO33 | TOUCH_8 | |
25 | GPIO25 | DAC_1 | Camera VSYNC |
26 | GPIO26 | DAC_2 | Camera SIOD |
27 | GPIO27 | TOUCH_7 | Camera SIOC |
14 | GPIO14 | HSPI_CLK | |
12 | GPIO12 | HSPI_MISO | |
13 | GPIO13 | HSPI_MOSI | |
SD2 | GPIO9 | SPIHD | フラッシュメモリ接続用(使用不可) |
SD3 | GPIO10 | SPIWP | フラッシュメモリ接続用(使用不可) |
CMD | GPIO11 | SPICS0 | フラッシュメモリ接続用(使用不可) |
CLK | GPIO6 | SPICLK | フラッシュメモリ接続用(使用不可) |
SD0 | GPIO7 | SPIQ | フラッシュメモリ接続用(使用不可) |
SD1 | GPIO8 | SPID | フラッシュメモリ接続用(使用不可) |
15 | GPIO15 | HSPI_SS | |
2 | GPIO2 | LED | 内蔵LED |
0 | GPIO0 | TOUCH_1 | BOOTボタン GND短絡にて書き込みモード(Download Boot) |
4 | GPIO4 | TOUCH_0 | Camera Y2 |
5 | GPIO5 | VSPI_SS | Camera Y3 |
18 | GPIO18 | VSPI_CLK | Camera Y4 |
19 | GPIO19 | VSPI_MISO | Camera Y5 |
21 | GPIO21 | I2C_SDA | Camera XCLK |
RX | GPIO3 | RX0 | シリアル通信 |
TX | GPIO1 | TX0 | シリアル通信 |
22 | GPIO22 | I2C_SCL | Camera PCLK |
23 | GPIO23 | VSPI_MOSI | Camera HREF |
VP, VN, 34, 35は入力(Input)のみとなります。
カメラ使用時は備考の空欄のピン(以下参考)が外部ピンとして使用できるかと思います。
GPIO12〜GPIO15(HSPI対応)
GPIO32、GPIO33
※HSPIを使用したスケッチ例を後述のサンプルプログラムに掲載しました。※2022年10月22日
参考URL(pdf):
https://github.com/Freenove/Freenove_ESP32_WROVER_Board/blob/main/C/C_Tutorial.pdf
本ボードは普通にESP32開発ボードとして使用することもでき、スターターキットが販売されています。
基本スターターキット
スーパースターターキット
アルティメットスターターキット
参考サイト:
ESP32-S3-WROOM-1を搭載した最新モデルの記事を書きました。ぜひご覧ください。
Arduinoボード設定
Arduino IDEにESP32ボードを追加しておきます。
追加方法については、以下の記事をご参照ください。
- ボードインストール
[ツール] > [ボード] > [ボードマネージャ]からESP32ボードをインストールします。
※ジェネリック品の場合はバージョン2.0.3をインストールしてください。 2022年12月18日
- ボードの選択
[ツール] > [ボード] > [ESP32 Arduino] > [ESP32 Wrover Module]を選択します。
- シリアルポートの選択
ボードが接続されているポートを選択します。
環境 | ポート名 |
---|---|
Mac | /dev/cu.wchusbserial* |
Windows | COM* |
※シリアルポートが認識されない場合はCH340用シリアルドライバを以下からダウンロードしてインストールしてください。
GitHub
https://github.com/Freenove/Freenove_ESP32_WROVER_Board/tree/main/CH340
PlatformIO IDEを使用する場合
動作確認した内容を記載します。
PlatformIO IDE

開発環境
Platform | Espressif 32 | バージョン 5.1.1 |
ボード | Espressif ESP-WROVER-KIT | フレームワーク Arduino |
CameraWebServerの修正済みArduinoスケッチをインポートしてプロジェクトを作成
※スケッチ例の修正方法は後述のサンプルプログラムに掲載しています。

以下の設定で動作確認しました。
platformio.ini (例)
[env:esp-wrover-kit]
platform = espressif32
board = esp-wrover-kit
framework = arduino
;upload_port = /dev/cu.wchusbserial14110
upload_speed = 921600
monitor_speed = 115200
upload_port
上記パラメーターはコメントアウトしていますが、必要であれば設定してください。
こちらがPlatformIO IDEで書き込んだCameraWebServerの動作例です。

サンプルプログラム (Arduinoスケッチ)
開発環境
Arduino IDE バージョン | 1.8.19 (※1系) 2.0.3 (※2系) |
ESP32 Arduinoボード | 基本的に最新版でOK ※Freenove FNK0060の場合 2.0.3 ※ジェネリック品の場合 |
以下にpdfやサンプルスケッチがあります。
CameraWebServer (Arduino IDEスケッチ例を使用する場合)
GitHubのサンプルスケッチにSketch_05.1_CameraWebServerがありますが、Arduino IDEのスケッチ例([スケッチ例] > [ESP32] > [Camera] > [CameraWebServer])を使用する場合、次のように修正します。

- カメラモデルの指定
CAMERA_MODEL_WROVER_KITのコメントをはずし、CAMERA_MODEL_AI_THINKERをコメントアウトします。 - Wi-Fi設定
ssidとpasswordを接続先Wi-Fiのssidとpasswordに書き換えます。
スケッチを書き込んだのち、シリアルモニターを開きリセットボタンを押すとCameraWebServerのURL(画像赤枠参照)が確認できます。

ブラウザからシリアルモニターに表示されたURLにアクセスすると以下のような画面が表示されます。
動作例

映像を液晶ディスプレイに表示する(HSPI使用例)
ボタンを押すと映像が液晶ディスプレイに表示されるというスケッチ例です。
素材はこちら
液晶ディスプレイ
今回のスケッチ例ではST7789の液晶ディスプレイを使用します。
左: 1.54インチ 右: 1.3インチ

いずれも解像度は240×240です。
ちなみに1.3インチの方はCSピンがありません。そのためスケッチを動かす場合は修正が必要です。
製作例
1.54インチディスプレイの例

右の箱は今回の被写体に使っている素材で製作には無関係です。
1.3インチディスプレイの例

いずれのライブラリもArduino IDEのライブラリマネージャーから検索してインストールできます。
スケッチ
#include "esp_camera.h"
#include <SPI.h>
#include <Adafruit_GFX.h> // Core graphics library
#include <Adafruit_ST7789.h> // Hardware-specific library for ST7789
#include <TJpg_Decoder.h>
// Pin definition for CAMERA_MODEL_WROVER_KIT
#define PWDN_GPIO_NUM -1
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 21
#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 19
#define Y4_GPIO_NUM 18
#define Y3_GPIO_NUM 5
#define Y2_GPIO_NUM 4
#define VSYNC_GPIO_NUM 25
#define HREF_GPIO_NUM 23
#define PCLK_GPIO_NUM 22
// Pin definition for TFT HSPI
#define TFT_SCLK 14
#define TFT_MISO -1
#define TFT_MOSI 13
#define TFT_CS 15 // Chip select control pin
#define TFT_DC 32 // Data Command control pin
#define TFT_RST 33
// Pin button
#define PIN_BTN 12
Adafruit_ST7789 tft = Adafruit_ST7789(&SPI, TFT_CS, TFT_DC, TFT_RST);
bool tft_output(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t *bitmap)
{
// Stop further decoding as image is running off bottom of screen
if (y >= tft.height())
return 0;
tft.drawRGBBitmap(x, y, bitmap, w, h);
// Return 1 to decode next block
return 1;
}
void init_camera()
{
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.frame_size = FRAMESIZE_UXGA;
config.pixel_format = PIXFORMAT_JPEG; // for streaming
config.grab_mode = CAMERA_GRAB_WHEN_EMPTY;
config.fb_location = CAMERA_FB_IN_PSRAM;
config.jpeg_quality = 12;
config.fb_count = 1;
// if PSRAM IC present, init with UXGA resolution and higher JPEG quality
// for larger pre-allocated frame buffer.
if (config.pixel_format == PIXFORMAT_JPEG)
{
if (psramFound())
{
config.jpeg_quality = 10;
config.fb_count = 2;
config.grab_mode = CAMERA_GRAB_LATEST;
}
else
{
// Limit the frame size when PSRAM is not available
config.frame_size = FRAMESIZE_SVGA;
config.fb_location = CAMERA_FB_IN_DRAM;
}
}
else
{
// Best option for face detection/recognition
config.frame_size = FRAMESIZE_QVGA;
#if CONFIG_IDF_TARGET_ESP32S3
config.fb_count = 2;
#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);
for (;;)
;
}
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 brightness just a bit
s->set_saturation(s, -2); // lower the saturation
}
// drop down frame size for higher initial frame rate
if (config.pixel_format == PIXFORMAT_JPEG)
{
s->set_framesize(s, FRAMESIZE_QVGA);
}
}
void setup()
{
Serial.begin(115200);
Serial.println("ESP32-WROVER-CAM Picture");
init_camera();
// Use HSPI
SPI.begin(TFT_SCLK, TFT_MISO, TFT_MOSI);
// if the display has CS pin try with SPI_MODE0
tft.init(240, 240); // Init ST7789 display 240x240 pixel
tft.fillScreen(ST77XX_BLACK);
TJpgDec.setJpgScale(1);
// The decoder must be given the exact name of the rendering function above
TJpgDec.setCallback(tft_output);
pinMode(PIN_BTN, INPUT);
}
void take_picture()
{
Serial.println("Taking picture..");
camera_fb_t *fb = NULL;
fb = esp_camera_fb_get();
if (!fb)
{
Serial.println("Camera capture failed");
return;
}
static uint16_t w = 0, h = 0;
TJpgDec.getJpgSize(&w, &h, fb->buf, fb->len);
Serial.print("- Width = ");
Serial.print(fb->width);
Serial.print(", height = ");
Serial.println(fb->height);
// Draw the image, top left at 0,0
TJpgDec.drawJpg(0, 0, fb->buf, fb->len);
// Free buffer
esp_camera_fb_return(fb);
}
void loop()
{
static int state = LOW;
if (digitalRead(PIN_BTN) == HIGH)
{
Serial.println("Button pressed");
take_picture();
state = HIGH;
}
else if (digitalRead(PIN_BTN) == LOW && state == HIGH)
{
tft.fillScreen(ST77XX_BLACK);
state = LOW;
}
delay(500);
}
ピン接続は次のようになっています。
項目 | GPIO | 備考 |
---|---|---|
TFT SCLK | 14 | HSPI SCLK |
TFT MOSI | 13 | HSPI MOSI |
TFT CS | 15 | HSPI CS |
TFT DC | 32 | |
TFT RST | 33 | |
BUTTON(スイッチ) | 12 | ボタン(トグルスイッチ) INPUT |
液晶ディスプレイはHSPIで接続するようにしています。
スイッチに割り当てるGPIOが不足したため、GPIO12(HSPI MISO)を入力ピンに割り当てています。
スケッチの修正について
1.3インチディスプレイを使用する場合、CSピンがないためSPIをMODE 2に設定します。
tft.init
の箇所を以下のように修正します。
tft.init(240, 240, SPI_MODE2); // Init ST7789 display 240x240 pixel
スライドスイッチを使用する場合
以下のようにON側に3.3V(赤ワイヤー)、OFF側にGND(黒ワイヤー)、入力(青ワイヤー)をGPIO12に接続すればON/OFFを実現できます。

今回の製作例のようにON側の3.3V(赤)のみ配線する場合、以下のようにOFF側にスイッチを入れているとき入力ピン(青)の状態が不安定になります。

そこで、setup関数内のボタン入力ピンの設定を以下のようにINPUT_PULLDOWNにするとスイッチがOFF側(入力ピン(青)が開放された状態)の時に内部プルダウンされるようになるのでGNDの配線をしなくても動作するようになるかと思います。
pinMode(PIN_BTN, INPUT_PULLDOWN);
1.3インチディスプレイ動作例

プリズムを使ってみました
見た目は透明なブロックみたいな感じです。1辺25.4mmの正方形です。


このプリズムを液晶ディスプレイに乗せるとプリズムに映像が投影されます。

投影している様子がこちら
関連記事
当ブログのマイコン記事です。ぜひご覧ください。
コメント