ESP32でLチカしてみる（できなかったのでpart1）


# Goal

- ESP32でLチカする
    - 4時間かけてたどり着けなかった…:angel:
- mruby/cで動かす
    - 完了

# 使用した開発ボード

ＥＳＰ３２－ＤｅｖＫｉｔＣ　ＥＳＰ－ＷＲＯＯＭ－３２開発ボード
http://akizukidenshi.com/catalog/g/gM-11819/

# 参考にしたサイト

利用したボードでもCP2102Nを使っていたので下記サイトを参考にさせていただきました。感謝！

**ESP32×mruby／c IoTハンズオン**
https://www.s-itoc.jp/activity/research/mrubyc/mrubyc_tutorial/ESP32/

# シリアルポートのドライバをインストール

おもむろにUSBでESP32をつないでみたのですが、Windowsのデバイスマネージャーでシリアルポートの表示すらでないので、ドライバをインストールします。

https://www.pololu.com/docs/0J7/all#2

上記サイトの「CP2102 drivers for Windows」をクリックしてインストーラをダウンロードしてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144344/69a18169-a89a-cfe4-95d2-8d0f5a0cc6e0.png)

ドライバのインストール後、デバイスマネージャーでみたところ…

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144344/f9deb1bf-1145-6c21-d72b-b6864979750c.png)

うん、よさげです。

# WSLでのESP-IDF SDKパッケージのインストールまで

WSLでインストールする場合は、公式の「Standard Setup of Toolchain for Linux (Legacy GNU Make)」を参考にして下さい。

**Standard Setup of Toolchain for Linux (Legacy GNU Make)**
https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started-legacy/linux-setup.html

 **==== ここから寄り道 ====**

[参考サイトの手順](https://www.s-itoc.jp/activity/research/mrubyc/mrubyc_tutorial/ESP32/865)をためしたのですが、現時点ではESP版Hello Worldがmakeできないようです。以下のエラーが発生してしまいました。

```
$ cd hello-mrubyc-world-esp32
$ make
...省略
At global scope:
cc1plus: warning: unrecognized command line option '-Wno-frame-address'
/home/xxx/esp/esp-idf/make/component_wrapper.mk:291: recipe for target 'asio/asio/src/asio.o' failed
make[1]: *** [asio/asio/src/asio.o] Error 1
/home/xxx/esp/esp-idf/make/project.mk:635: recipe for target 'component-asio-build' failed
make: *** [component-asio-build] Error 2
```

 **==== ここからまで ====**


まずは関連パッケージをインストールします。

```bash
sudo apt update
sudo apt install tree gcc git wget make libncurses-dev flex bison \
 gperf python python-pip python-setuptools python-serial \
 python-cryptography python-future python-pyparsing
```

ESP32 ToolChainをダウンロードします。なおパッケージが古い可能性もあるので、[公式サイト](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started-legacy/linux-setup.html)を確認してください！

```
mkdir $HOME/esp
cd $HOME/esp
wget https://dl.espressif.com/dl/xtensa-esp32-elf-gcc8_2_0-esp-2020r1-linux-amd64.tar.gz
tar -xzf xtensa-esp32-elf-gcc8_2_0-esp-2020r1-linux-amd64.tar.gz
```

あとは、環境変数をセットして…

```
echo 'export PATH="$HOME/esp/xtensa-esp32-elf/bin:$PATH"' >> $HOME/.profile
echo 'export IDF_PATH="$HOME/esp/esp-idf"' >> $HOME/.profile
source $HOME/.profile
```

ESP-IDF SDKをインストールすればOK。ちなみにこのgit cloneおよびpythonの依存ライブラリインストールはかなり時間がかかります:sweat:

```
git clone --recursive https://github.com/espressif/esp-idf.git
python -m pip install --user -r $IDF_PATH/requirements.txt
```

念のためシリアルポートへの権限のための設定をして作業完了です！

```
sudo usermod -a -G dialout $USER
```

# mrubyのインストール

 **==== ここから寄り道 ====**

このあとハンズオンまでやってみたいので、参考サイトどおり、mruby-1.4.1を入れてみました。

ちなみに `ruby 2.7.0p0 (2019-12-25 revision 647ee6f091) [x86_64-linux]` にインストールしました。

```bash
rbenv install mruby-1.4.1
```

:bangbang:上記駄目でした。rbenv rehashしてもだめだったので下記のとおりaptでインストールしてください！

 **==== ここからまで ====**

```bash:こちらでインストール
sudo apt install mruby
```

# WSL上でHello World!

[ハンズオン１](https://www.s-itoc.jp/activity/research/mrubyc/mrubyc_tutorial/ESP32/867)を参考にやってみました。

```
cd $HOME/esp
git clone https://github.com/hasumikin/hello-mrubyc-world-posix
cd hello-mrubyc-world-posix
```

プログラムもそのとおりに変更してみます。

```ruby:mrblib/loops/master.rb
while true
  puts "Hello World!"
  sleep 1
end
```

んで、makeします。

```
make
```

初回は `make menuconfig` がでますがいったんESCで閉じてください。
makeが成功すると完了です！

# ESP32との接続（シリアルポートの確認）

デバイスマネージャーでみると、`COM3` となっているのでUbuntu上では `/dev/ttyS3` でアクセスできるはずです。なお `COM3` の最後の数字は環境によって異なりますので実際にデバイスマネージャーで確認してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144344/f6b904e2-3888-e042-868d-7f2f08f11808.png)

# ESP-IDF SDKの設定

シリアルポートの設定を行います。

```
make menuconfig
```

「Serial flasher config」を選択し…

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144344/31494d64-c266-f34e-1ff1-c5d3faddc42f.png)

「(/dev/ttyUSB0) Default serial port」を選択し、私の場合は `/dev/ttyS3` に変更して保存、終了します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144344/11cf2a8e-b10e-26a2-575f-98af074924af.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144344/0e9fca08-8f09-393c-0ef8-00c7e02e8366.png)

# 書き込みと実行の確認

下記コマンドでESP32に書き込みます。

```
make flash
```

成功…と思ったら無慈悲なエラーが

```
Flashing binaries to serial port '/dev/ttyS3' (app at offset 0x10000)...
esptool.py v3.0-dev
Serial port /dev/ttyS3
Connecting........_____....._____....._____....._____....._____....._____....._____

A fatal error occurred: Failed to connect to ESP32: Timed out waiting for packet header
/home/xxx/esp/esp-idf/components/esptool_py/Makefile.projbuild:104: recipe for target 'flash' failed
make: *** [flash] Error 2

```

どうやらアップロード中はずっと `ESP32のbootボタン` を押さないといけないみたい。自動で切り替えてくれないのね…とりあえず成功した！

```
$ make flash
...省略...
Connecting........_
Chip is ESP32D0WDQ6 (revision 1)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
Crystal is 40MHz
MAC: fc:f5:c4:1a:5d:fc
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Auto-detected Flash size: 4MB
Flash params set to 0x0220
Compressed 25376 bytes to 15745...
Wrote 25376 bytes (15745 compressed) at 0x00001000 in 1.4 seconds (effective 146.2 kbit/s)...
Hash of data verified.
Compressed 223088 bytes to 114055...
Wrote 223088 bytes (114055 compressed) at 0x00010000 in 10.1 seconds (effective 177.4 kbit/s)...
Hash of data verified.
Compressed 3072 bytes to 103...
Wrote 3072 bytes (103 compressed) at 0x00008000 in 0.0 seconds (effective 1627.1 kbit/s)...
Hash of data verified.

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


書き込み後ESP32が再起動してプログラムが実行されますので下記コマンドで確認します。

```
make monitor
...省略...
I (0) cpu_start: App cpu up.
I (267) heap_init: Initializing. RAM available for dynamic allocation:
I (274) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (280) heap_init: At 3FFBD980 len 00022680 (137 KiB): DRAM
I (287) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (293) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (299) heap_init: At 40089E94 len 0001616C (88 KiB): IRAM
I (306) cpu_start: Pro cpu start user code
I (324) spi_flash: detected chip: generic
I (324) spi_flash: flash io: dio
I (325) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
Hello World!
Hello World!
Hello World!
Hello World!
```

`Hello World!` 何度も言いたくなる！！！

終わるときは `Ctrl + ]` で終了です

やっとここまでこれた:sob:

# 感想

ここまで厳しいHello Worldはプログラミングを始めた遠い昔を思い出させました…
次回こそはLチカを完了させます！