{"id":15354641,"url":"https://github.com/kikuomax/esp32-playground","last_synced_at":"2025-09-05T16:08:02.838Z","repository":{"id":85896956,"uuid":"244092946","full_name":"kikuomax/esp32-playground","owner":"kikuomax","description":"Play with ESP32","archived":false,"fork":false,"pushed_at":"2020-03-12T15:49:21.000Z","size":493,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-01T18:45:19.959Z","etag":null,"topics":["adxl345","e-paper","esp32","spi"],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kikuomax.png","metadata":{"files":{"readme":"README-ja.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-03-01T05:30:31.000Z","updated_at":"2020-03-12T15:49:20.000Z","dependencies_parsed_at":"2023-03-04T11:45:27.847Z","dependency_job_id":null,"html_url":"https://github.com/kikuomax/esp32-playground","commit_stats":{"total_commits":16,"total_committers":1,"mean_commits":16.0,"dds":0.0,"last_synced_commit":"eddd1b8c70e5e284288aa9a13a2f270515eb207c"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kikuomax%2Fesp32-playground","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kikuomax%2Fesp32-playground/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kikuomax%2Fesp32-playground/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kikuomax%2Fesp32-playground/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kikuomax","download_url":"https://codeload.github.com/kikuomax/esp32-playground/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245864935,"owners_count":20685133,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["adxl345","e-paper","esp32","spi"],"created_at":"2024-10-01T12:20:16.437Z","updated_at":"2025-03-27T14:46:59.382Z","avatar_url":"https://github.com/kikuomax.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ESP32\n\n言語: [English](README.md)/日本語\n\n[ESP32](https://www.espressif.com/en/products/hardware/esp32/overview)で遊んでみよう。\n\n## 準備\n\n私は[ESP32 Feather](https://www.adafruit.com/product/3405)をゲットしました。Adafruit提供の開発ボード(ピンヘッダはんだ済)です。\n\n私はMacOS (10.14.6)で作業しています。\n\n## ESP-IDF\n\nGitHubレポジトリ: https://github.com/espressif/esp-idf\n\nESP-IDFはESP32のプログラムをビルドしたりフラッシュに書き込んだりするためのツール群です。\nFreeRTOSとAPIも含んでいます。\n\nこのレポジトリに[`esp-idf`](/esp-idf)としてESP-IDFのサブモジュールを作りました。\n\n### ESP-IDFをインストールする\n\n[マニュアル](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html)に従って、以下のステップを実施しました。\n\n1. `esp-idf`ディレクトリに移動します。\n\n    ```\n    cd esp-idf\n    ```\n\n2. ESP-IDFをインストールします。\n\n    ```\n    ./install.sh\n    ```\n\n#### SSLエラー\n\nすると次のファイルをダウンロードする際にSSLエラーが出ました。\n\n```\nhttps://github.com/espressif/openocd-esp32/releases/download/v0.10.0-esp32-20190313/openocd-esp32-macos-0.10.0-esp32-20190313.tar.gz\n```\n\n警告メッセージは\n\n```\nWARNING: Download failure [Errno socket error] [SSL: TLSV1_ALERT_PROTOCOL_VERSION] tlsv1 alert protocol version (_ssl.c:581)\n```\n\nこれはPythonがTLS v1.0を使っており、GitHubサーバから拒絶されたことを意味します。\n`install.sh`スクリプトはPython2をデフォルトで実施しますが、私は最近Python2を使っておらずアップデートもしていません。\nということで、[こちらのIssue](https://github.com/espressif/esp-idf/issues/4629)のようにPython3を使いたいと思いました。\n\n(直接`idf_tools.py`を実行するような)侵襲性の高いアプローチはとりたくなかったので、virtual environmentを使うことにしました。\n下記のステップを実施しました。\n\n1. virtual environmentをPython3で作成します。\n\n    ```\n    python3 -m venv ./venv\n    ```\n\n2. virtual environmentをアクティベートします。\n\n    ```\n    source ./venv/bin/activate\n    ```\n\n3. `install.sh`を実行します。\n\n    ```\n    ./install.sh\n    ```\n\n#### 次のSSLエラー\n\n今度は別のエラーが出ました。\n\n```\nWARNING: Download failure \u003curlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1076)\u003e\n```\n\nこちらはPythonディストリビューションに付属の`Install Certificates`スクリプトを実行して証明書をインストールすることで解決しました。\nこの前に私のPython3を[公式のディストリビューション](https://www.python.org/downloads/release/python-376/)でアップデートしていました。\n\n#### virtualenvモジュールエラー\n\nさらに問題が発生しました。\n\n[`virtualenv`](https://virtualenv.pypa.io/en/latest/)のインストールに失敗したのです。\n\n最初は`idf_tools.py`の`virtualenv`を`venv`で置き換えて対応しました。\nしかし、`venv`に対して[`virtualenv`には付加機能がある](https://virtualenv.pypa.io/en/latest/)ことに気づきました。\nということで元々の実装を尊重して`install.sh`を実行する前に`virtualenv`をインストールすることにしました。\n\n```\npip install virtualenv\n```\n\n#### Python2\n\nん？Python2じゃないといけないのか？\nとりあえずPython3で動いています。\n\n## USB Driverをダウンロードする\n\nESP32 FeatherはUSB経由でPCと接続できます。\n\nESP32は適切なドライバをインストールするまで検出されませんでした。\n`ls /dev/cu.*`コマンドを実行してもESP32はリストされません。\n\nひとつの疑問はどのUSBドライバをインストールすべきかということでした。\n[このページ](https://learn.adafruit.com/adafruit-huzzah32-esp32-feather/using-with-arduino-ide)によると、ESP32 Featherには[CP210Xドライバ](https://www.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers)が必要ということが分かりました。\n\nドライバをインストールすると、`ls /dev/cu.*`コマンドは`/dev/cu.SLAB_USBtoUART`をリストしました。\n\n## Ninjaをインストールする\n\n私は[Ninja](https://ninja-build.org)をbrewでインストールしました。\n\n```\nbrew install ninja\n```\n\nNinjaなしでも[hello-worldサンプル](https://github.com/espressif/esp-idf/tree/master/examples/get-started/hello_world)のビルドに成功したので、Ninjaのインストールはオプションかもしれません。\n\n## プロジェクトを記述する\n\n[サンプル構造](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html#example-project)。\n\nプロジェクトをビルドする前に、以下のコマンドを実行しなければなりません。\n\n```\nsource ./export.sh\n```\n\n## ESP-IDF 準備のまとめ\n\n一度ESP-IDFをインストールした後は、ESP-IDFを使う際には次のステップを実施してください。\n\n1. `eps-idf`ディレクトリに移動します。\n\n    ```\n    cd eps-idf\n    ```\n\n2. virtual environmentをアクティベートします。\n\n    ```\n    source ./venv/bin/activate\n    ```\n\n3. ESP-IDFコマンドをエクスポートします。\n\n    ```\n    source ./export.sh\n    ```\n\n## SPI\n\n[このページ](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/spi_master.html)はESP32のSPIマスタドライバについて解説しています。\n[こちら](https://github.com/espressif/esp-idf/tree/master/examples/peripherals/spi_master)にSPIマスタのサンプルもあります。\n\n### ESP32 Featherピンアウト\n\n最初にESP32 Featherのピンアウトを理解する必要がありました。\n[ESP32 Featherの配線図](https://learn.adafruit.com/assets/41630)と[このセクション](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/spi_master.html#gpio-matrix-and-io-mux)によると、SPI関連のピンアウトは以下の通りです。\n\n| Featherのラベル | GPIO# | SPI機能        |\n|----------------|-------|---------------|\n| SCK            | 5     | VSPICS0       |\n| MO             | 18    | VSPICLK       |\n| MI             | 19    | VSPIQ = MISO  |\n| SDA            | 23    | VSPID = MOSI  |\n| SCL            | 22    | VSPIWP (QSPI) |\n| 21             | 21    | VSPIHD (QSPI) |\n\nESP32には4つのSPIバスがありますが我々が使えるのは、HSPI (SPI2)とVSPI (SPI3)の2つだけです。\n上のテーブルはVSPIバス用のピンアウトを示しています。\n\n#### HSPI接続\n\nドキュメントによると、HSPIバスには以下のピンが使えそうです。\n\n| Featherのラベル | GPIO# | SPI機能        |\n|----------------|-------|---------------|\n| 15             | 15    | HSPICS0       |\n| 14             | 14    | HSPICLK       |\n| 12             | 12    | HSPIMISO      |\n| 13 (LED点灯用?) | 13    | HSPIMOSI      |\n| 不在 (GPIO2?)   | 2     | HSPIWP (QSPI) |\n| A5             | 4     | HSPIHD (QSPI) |\n\nADXL345を上記の接続で試しましたが、GPIO12が接続されていると奇妙なフラッシュ書き込みエラーが出ました。\n\n```\nA fatal error occurred: Timed out waiting for packet content\nCMake Error at run_cmd.cmake:14 (message):\n  esptool.py failed\nCall Stack (most recent call first):\n  run_esptool.cmake:21 (include)\n```\n\nESP32をモニタしようとすると、以下のメッセージが出ました。\n\n```\nrst:0x10 (RTCWDT_RTC_RESET),boot:0x33 (SPI_FAST_FLASH_BOOT)\nflash read err, 1000\nets_main.c 371\n```\n\n[このページ](https://randomnerdtutorials.com/esp32-pinout-reference-gpios/)(ページでGPIO12を検索)に関連するコメントを見つけました。\nコメントによると[このページ](https://github.com/espressif/esptool/wiki/ESP32-Boot-Mode-Selection)が説明しているとのことです。\n\n以下、分かったことです。\n\nGPIO12ピンはStrapping Pin (MTDI)と呼ばれています。\n5つのStrapping Pinがあって、その電圧がブートモードとその他システムの設定に影響します。\n\n私がESP32をモニタしようとした時に出くわしたエラーメッセージは[このセクション](https://github.com/espressif/esptool/wiki/ESP32-Boot-Mode-Selection#early-flash-read-error)に解説されています。\n\nメッセージの`boot:0xXY`部分は以下のビットの組み合わせを表しており、どのStrapping PinがHighになっているかを示しています。\n- `0x01`: GPIO5\n- `0x02`: MTDO (GPIO15)\n- `0x04`: GPIO4 (Strapping Pinとしてはリストされていない)\n- `0x08`: GPIO2\n- `0x10`: GPIO0\n- `0x20`: MTDI (GPIO12)\n\n`boot:0x33`は`GPIO5 | MTDO | GPIO0 | MTDI`を意味します。\n\nVSPI接続の際は`boot:0x13`でした。つまり`GPIO5 | MTDO | GPIO0`です。\n\n[解決策は面倒くさそう](https://esp32.com/viewtopic.php?t=5970)なので、とりあえずVSPIで行くことにしました。\n\n#### GPIOマッピング\n\nESP32のGPIO番号は[GPIOマトリクス](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/spi_master.html#gpio-matrix-and-io-mux)で仮想的にどの番号にでもマップできるようです。\nしかしIO_MUXの定義によると、GPIOマトリクスを使わずにデフォルトのマッピングを使うとより効率的です。\n\n以下は私が少しほじくった詳細です。\n- [このコード](https://github.com/espressif/esp-idf/blob/c1d0daf36d0dca81c23c226001560edfa51c30ea/components/soc/soc/esp32s2/spi_periph.c)はデフォルトのSPIのマッピングを定義しています。\n- [この関数](https://github.com/espressif/esp-idf/blob/4bfd0b961bea502a3bd2b0f64a933fbf87dc7349/components/driver/spi_common.c#L178-L192)は指定したGPIO番号がデフォルトとマッチするかをチェックしています。\n\n### キーAPIs\n\n[spi_bus_initialize](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/spi_master.html#_CPPv418spi_bus_initialize17spi_host_device_tPK16spi_bus_config_ti)\n\nこの関数を最初に呼びます。\n\n[spi_bus_add_device](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/spi_master.html#_CPPv418spi_bus_add_device17spi_host_device_tPK29spi_device_interface_config_tP19spi_device_handle_t)\n\nこの関数でSPIデバイスを登録します。\n\n[spi_device_polling_transmit](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/spi_master.html#_CPPv427spi_device_polling_transmit19spi_device_handle_tP17spi_transaction_t)\n\nこの関数はデータの転送と受信を行う便利な関数です。\n\n### SPIの初期化\n\n以下はVSPIバスを使う際の[`spi_bus_config_t`](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/spi_master.html#_CPPv416spi_bus_config_t)の共通の設定です。\n- `sclk_io_num`: `18`\n- `mosi_io_num`: `23`\n- `miso_io_num`: `19`\n- `quadwp_io_num`: `-1` (無効)\n- `quadhd_io_num`: `-1` (無効)\n\n### ADXL345\n\n[こちら](./adxl345)にADXL345と通信するサンプルコードがあります。\n\n### 電子ペーパーディスプレイ\n\n[こちら](./epd)に電子ペーパーディスプレイと通信するサンプルコードがあります。","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkikuomax%2Fesp32-playground","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkikuomax%2Fesp32-playground","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkikuomax%2Fesp32-playground/lists"}