800円くらいだったESP32-CAMを衝動買いしてたらしいのでつかってみる

[これ](https://m.banggood.com/Geekcreit-ESP32-CAM-WiFi-+-Bluetooth-Camera-Module-Development-Board-ESP32-With-Camera-Module-OV2640--p-1394679.html)

1000円以下でESP32とカメラ（ov2640）なんて反則だと思うんだ。

で、なんかサンプルないかと探したら、、
[ESP32-CAM | ESP32 Camera Module with Face Recognition](https://robotzero.one/esp32-camera-module/)

さらにrecognitionまで絡めるとか、反則だと思うんだ。
ESP32はサーバーになる感じなのかな。

そんなわけでこれ、やりましょう。

##環境

- win10Pro 64bit (構築用)
- ESP32-CAM
- USBでシリアル通信できるモジュール(FTDI)

最後のはこういうやつかな。
https://www.amazon.co.jp/dp/B00YMJVSIS/
たしか200円くらいで買ったやつでよくわかんないとこからドライバ落として入れた気がする。

##なにはともあれやってみる

### msys2
windowsでやるのですが、msys2というのが必要らしい。書き込みに使うんだろうか。
http://www.msys2.org/
まずはmsys2-i686-20180531.exeというのをDLしてダブルクリックしてみます。
そしてウィーザードの通りに進めていきますが、
見本のページに```uncheck the “Run MSYS2 32-bit now” checkbox at the end.```ってあったのでそれに倣う。日本語になってたけど。
で、

1. C:\msys32\mingw32.exeをダブルクリック
2. https://raw.githubusercontent.com/espressif/esp-idf/master/tools/windows/windows_install_prerequisites.shをc:\msys32に置く
3. C:/msys32/windows_install_prerequisites.shする。msys32の黒いウインドウが開いてたのでcd /c/msys32して./windows_install_prerequisites.shしました。
4. なんか見本の通りにerrorで終了したのでもっかいmingw32.exe起動して再実行。いろんなパッケージを入れ始めて15分くらいかかったものの完了です。
5. source /etc/profileを叩いておく
6. c:\msys32\home\user\.bashrcの末尾に```export IDF_PATH=/c/msys32/home/user/esp/esp-idf```を追記

というかこれ、git-bash入れた時に入ってたな。。無駄に容量消費しただけだった。

### esp-idf

こっちが書き込み用のツールでした。msys32はwindow上にlinux風の環境作るやつだった。見本通り、mingw32使ったけどたぶんmingw64で良かったな。

下記はmingw32のウインドウ上で行います。
実際、ディレクトリはどこでもいいと思う。例だとホームディレクトリ直下にesp。

```
cd ~
mkdir esp
cd ~/esp
git clone --recursive https://github.com/espressif/esp-idf.git
```

ちなみに見本のように``` cannot fork() type...```みたいなエラーが出たけど開いてたgit bashの方でgit clone打ったら正常に終わりました。10分くらいかかったけど。
```c:/msys32/autorebase.bat```実行してからもっかいやれ、って書いてあったけども。

あとexport_idf_path.shってとこはスルーです。homeの.bashrcに書いてしまった。
実行も問題なし。

``` bash
user@user-PC MINGW64 ~
$ printenv IDF_PATH
/c/msys32/home/user/esp/esp-idf
```

## ESP-WHO Face Detection and Recognition Libraries

### esp-who

**ESP-WHO is a face detection and recognition platform that is currently based on Espressif Systems' ESP32 chip.**
らしいです。
今回のプログラムのソースですね。C言語でゴリゴリでソースでかい。また10分くらいかかる。今回待ちが多いなー。

```
cd ~
git clone --recursive https://github.com/espressif/esp-who.git
```

### esp32繋ぎます

見本のサイトの通りに繋ぐ。
画像付きでわかりやすくかかれてるし説明省きます。
USB経由でESP32に電流が回って、TXとRXで通信できるようになって、IO0がGNDに落ちてESP32が書き込みモードになるって感じでしょうか。

![IMG_20190203_160252.jpg](https://qiita-image-store.s3.amazonaws.com/0/308709/7b17fe16-ef57-e887-d081-fcb36952119c.jpeg)
なお、直繋ぎでいいんだけど、メス-メスのケーブルが足りなかったのでブレッドボード挟んでます。

で、ソースをmakeしてesp32にflash

```
cd ~/esp-who/examples/single_chip/camera_web_server/
make menuconfig
make flash
make monitor
```

menuconfigではCOMポートの番号以外は見本通りにしました。あとIPアドレスも192.168.4.1とかになったので自分の環境に合わせて192.168.0.60に変更しました（←実は192.168.4.1のままで良かった。あくまでAPのIPですし。)。なお、これは10分くらいかかる。


>Serial flasher config —> Default serial port (Change to the port number shown in Device Manager – ~~ie COM3~~ **ie COM9**)
Camera Web Server —> WiFi Settings —> (Add your WiFi SSID and Password)
Camera Web Server —> Camera Pins —> Select Camera Pinout —> (Select ESP32-CAM by AI-Thinker)
Component config —> ESP32-specific —> SPI Ram config —> Type of SPI RAM chip (Select Auto-detect)

で、make flashは少し躓いた。
pyserialがみつからないって言われたので```pip install pyserial```したのと、```NOTE: You may need to run "pacman -Syu" ```って言われたから```pacman -Syu```してみたのと。
あと```C:/msys32/mingw32/bin/python.exe -m pip install --user -r C:/msys32/home/user/esp/esp-idf/requirements.txt```もやれって言われたから実行。
いくつかパッケージが入ったみたいなので、改めてmake flashで進みました。
このあたりの手順書いてなかったけどな。ちなみに20分くらいかかったような気がした。

・・しかし、、make moniterを実行してみるも

```
....
I (1314) spiram: Adding pool of 4096K of external SPI memory to heap allocator

Brownout detector was triggered

ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:6724
load:0x40078000,len:11972
ho 0 tail 12 room 4
load:0x40080400,len:7400
entry 0x40080780
I (31) boot: ESP-IDF v3.3-beta1-328-gabea9e4c0 2nd stage bootloader
I (31) boot: compile time 17:43:05
.....
```

となんかrebootを繰り返してる模様。
仕方ないのでmake menuconfigまで戻ります。
そしてなんか必要そうなパラメータを確認していく・・あ、ここ設定し忘れてた。。またやり直しか。。

>Camera Web Server —> Camera Pins —> Select Camera Pinout —> (Select ESP32-CAM by AI-Thinker)

(で、EXAMPLE_ESP_WIFI_AP_PASSを5文字([^1])とかにしててまたやり直したりしたけども・・。。）
なんとかできたみたいです！

## 動作確認

```
$ make monitor
Toolchain path: /opt/xtensa-esp32-elf/bin/xtensa-esp32-elf-gcc
Toolchain version: crosstool-ng-1.22.0-80-g6c4433a5
Compiler version: 5.2.0
Python requirements from C:/msys32/home/user/esp/esp-idf/requirements.txt are satisfied.
MONITOR
--- idf_monitor on COM9 115200 ---
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
I (135327) wifi: new:<7,0>, old:<7,0>, ap:<7,2>, sta:<7,0>, prof:7
I (135327) wifi: station: 08:11:96:71:6c:40 join, AID=1, bgn, 20
I (135347) camera wifi: station:08:11:96:71:6c:40 join, AID=1
dhcps: send_offer>>udp_sendto result 0
I (135417) tcpip_adapter: softAP assign IP to station,IP is: 192.168.0.61
```

アクセスポイントになってるのでそちらに繋いでからブラウザで192.168.0.60開きます。DHCPでIP振られてるはずだからたぶん、そっち繋いでも見れると思うけど。

で、見れたことは見れたのですが・・
USBとの接続を外して別電源で動作させてカメを映してる所でも撮ろうと思ったのですが・・

つい逆に電流を流してしまい、、どっか死んだっぽいです。。
書き込みが2%までしかできなくなった。ミスったー。どっかショートしたんでしょうね。

とまあ、一応ゴールはしました。
ゴールと同時に昇天しました。
せめてウイニングランくらいさせてほしかったー。
なんにせよもっかい買いますわ。ESP32は他にあるからカメラの基盤付きのやつだけ買うのもありだけど。
これで静止画をとりつつ、Tensorflow Object Detection APIでリクガメの位置を認識しつつ、カメラの角度を調整ってのをやりたいのです。


でもってしばらくして・・
なんか書き込めるようにはなったものの、やっぱりおかしくままだ。

```
22:51:35.006 -> [0;32mI (30) boot: ESP-IDF v3.3-beta1-328-gabea9e$B
22:51:43.201 -> ⸮⸮I⸮0⸮UP*Uz⸮%⸮_FQRe=⸮V2JJH腥ti⸮for⸮⸮⸮nl⸮XVH⸮
```

ぐちゃっと文字化け。APもネットワークに出てこないし、Wifiにもつながってないっぽい。

##もうちょっとだけ続く

諦めかけたけど、もうちょいトライ。なんかEXAMPLE_ESP_WIFI_AP_SSIDが空でEXAMPLE_ESP_WIFI_SSIDだとSTATIONモードになるっぽいですね。というかEXAMPLE_ESP_WIFI_AP_SSIDもEXAMPLE_ESP_WIFI_AP_SSIDも両方書かれてる時の動作がなくない？

``` c:app_wifi.c
    if (strlen(EXAMPLE_ESP_WIFI_AP_SSID) && strlen(EXAMPLE_ESP_WIFI_SSID)) {
        mode = WIFI_MODE_APSTA;
    } else if (strlen(EXAMPLE_ESP_WIFI_AP_SSID)) {
        mode = WIFI_MODE_AP;
    } else if (strlen(EXAMPLE_ESP_WIFI_SSID)) {
        mode = WIFI_MODE_STA;
    }
```

WIFI_MODE_STAになるようにしてみよう。

ってやったけどやっぱりダメ。壊れたかー。変になる前はちゃんと見れたし、撮影もできたしな。
というかWIFI_MODE_APSTAとかはビット演算で見てるやつかも。なのでいいのか。
残念。これ関連は発展形でぜひまた。

## その後

また購入し、やり直した結果ちゃんと使えてます。

![IMG_20190501_112127.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308709/4777a36e-f2aa-8665-4c2c-e38511291543.jpeg)

精度は低いけど、いちおうfacerecognitionも。
せっかくSDカードのスロットついてるし、カードに画像収めてどっかにPOSTするとかしたいすね。

[^1]: camera_web_server/main/app_wifi.cに```wifi_config.ap.authmode = WIFI_AUTH_WPA_WPA2_PSK;```って書かれてる。固定でWPA2/PSKなんですね。8文字以上じゃないとダメだ。そしてパスなしだとOPEN Wifiになっちゃうみたいなのでそれは避けておきました。