勉強しないとな~blog

ちゃんと勉強せねば…な電気設計エンジニアです。

M5Stampでhttpサーバー

M5Stampの続き。
今回もサンプルプロジェクトから。

やりたいこと

前にM5StampでWi-Fiが使えることが確認できたので、サーバー機能を入れたりして、子供のおもちゃをIoT化したときの機能の一つとして使いたい。

サンプルプロジェクト確認

サンプルプロジェクトの中に、http_serverがある。これを使ってみたい。

http_serverの中にもサンプルが色々あるが、simpleを使ってみる。

HTTP基本

その前にHTTPがよくわかっていないので調べる。

とりあえずこのあたりのサイトで、HTTPの簡単な中身。

HTTP の概要 - HTTP | MDN

HTTP

2つ目のサイトは、更新日不明だが、"1998年現在"とか書いてあったりしてかなり古めだが、Google検索で上のほうに来てたので、今でも参考になるということか。

プロジェクト作成、ビルド、実行

今までの手順通り。

  • "ESP-IDF: Set Espressif device target"でターゲットを"esp32c3"に設定。
  • "ESP-IDF: Select port to use (COM, tty, usbserial)"でデバイス接続したCOMポートを指定。(デバイス接続しておく必要がある)
  • "ESP-IDF: Select Flash Method"で、書き込み方法を"UART"に指定。
  • "ESP-IDF: SDK Configuration editor"でプロジェクト設定。
    Example Configurationを見ると、WiFi SSIDとパスワードの設定あり。
    "Get ssid and password from stdin"で、stdinからSSIDとパスワード設定もできるようなので、これを試してみる。
  • "Save"して、"ESP-IDF: Build, Flash and start a monitor on your device"でビルドと実行。

実行

実行すると、ターミナルウィンドウに、SSIDとパスワード入力を求める表示が出るので、入力。

なんだかうまくつながらなかったようで、"Wi-Fi disconnected, trying to reconnect..."が何回か出て、自分で再起動したよう。
最終的に、同じSSID、パスワード入力画面になった。

ここでのSSID、パスワードの入力のしかたがよくわからなかったが、結局SSIDの後にスペースを一度入力して、続けてパスワードを入力したらつながった。

接続後、IPを取得(192.168.1.11)してポート80にサーバーが立ち上がったよう。

クライアント側からテスト

テスト方法

READMEを見ると、pythonでscripts/client.pyを実行する、curlコマンドを使う、という2つのテスト方法が書かれている。

前者は、スクリプトで全部勝手にやると何が起こっているかわかりにくそうだし、そもそもscripts/client.pyがどこにいるかもよくわからない。

ので、後者のcurlコマンド実行するほうで。

curlコマンドでテスト

PowerShellcurlコマンド使えるのかよくわからないが、やってみる。

(base) PS C:\work\esp-idf_test\simple_httpd_server\simple> curl 192.168.1.11:80/hello                     


StatusCode        : 200
StatusDescription : OK
Content           : Hello World!
RawContent        : HTTP/1.1 200 OK
                    Custom-Header-1: Custom-Value-1
                    Custom-Header-2: Custom-Value-2
                    Content-Length: 12
                    Content-Type: text/html

                    Hello World!
Forms             : {}
Headers           : {[Custom-Header-1, Custom-Value-1], [Custom-Header-2, Custom-Value-2], [Content-Lengt 
                    h, 12], [Content-Type, text/html]}
Images            : {}
InputFields       : {}
Links             : {}
ParsedHtml        : System.__ComObject
RawContentLength  : 12



(base) PS C:\work\esp-idf_test\simple_httpd_server\simple>

できた。HTTPの中身が確認できる。

このときのM5Stamp側の出力はこんな感じ。

I (324197) example: Found header => Host: 192.168.1.11
I (324197) example: Request headers lost

ここでは、HTTPのGETメソッドを実行することができた。

その他試してみたり調べたりして分かったこと。

  • PowerShellでは、Invoke-WebRequestコマンドレットでHTTPリクエストを出せるとのこと
  • さっきやった感じ、PowerShellでもcurlコマンドが使えたっぽかったが、Invoke-WebRequestへのエイリアスとして設定されているだけとのこと。
    Invoke-webRequestとcurlコマンドでHTTPリクエスト | SugiBlog
    実際、PowerShellで、curlでのPOSTメソッドをやってみようとしたが、ダメだった。引数のフォーマットが違うからではないかと思われる
  • 今使ってるPCにgitをインストールしたときにbashもセットアップされていて、こっちでcurlコマンドを使うことはできた。
  • Invoke-WebRequestcurlでは実行結果の表示に違いあり。

色々実行結果

PowerShell(Invoke-WebRequest) or bash(curl)、GETメソッド or POSTメソッドの組み合わせで試してみた。

PowerShell、GETメソッド

PowerShellcurlコマンドを打ったときと同じ結果になった。

(base) PS C:\work\esp-idf_test\simple_httpd_server\simple> Invoke-WebRequest 192.168.1.11:80/hello        
                                 
   
StatusCode        : 200
StatusDescription : OK
Content           : Hello World!
RawContent        : HTTP/1.1 200 OK
                    Custom-Header-1: Custom-Value-1
                    Custom-Header-2: Custom-Value-2
                    Content-Length: 12
                    Content-Type: text/html

                    Hello World!
Forms             : {}
Headers           : {[Custom-Header-1, Custom-Value-1], [Custom-Header-2, Custom-Value-2], [Content-Lengt 
                    h, 12], [Content-Type, text/html]}
Images            : {}
InputFields       : {}
Links             : {}
ParsedHtml        : System.__ComObject
RawContentLength  : 12

M5Stamp側。当然こちらも同じ。

I (133427) example: Found header => Host: 192.168.1.11
I (133427) example: Request headers lost

PowerShell、POSTメソッド

curlコマンドだと、ファイルを送る例がプロジェクトのREADMEに書かれていたが、Invoke-WebRequestの場合のやり方がわからなかった。適当な文字列を送っている。

(base) PS C:\work\esp-idf_test\simple_httpd_server\simple> Invoke-WebRequest -Method POST -Body @{key="tekitou"} 192.168.1.11:80/echo                                                                               
                                                 
   
StatusCode        : 200
StatusDescription : OK
Content           : key=tekitou
RawContent        : HTTP/1.1 200 OK
                    Transfer-Encoding: chunked
                    Content-Type: text/html

                    key=tekitou
Forms             : {}
Headers           : {[Transfer-Encoding, chunked], [Content-Type, text/html]}
Images            : {}
InputFields       : {}
Links             : {}
ParsedHtml        : System.__ComObject
RawContentLength  : 11

M5Stamp側。

I (822307) example: =========== RECEIVED DATA ==========
I (822307) example: key=tekitou
I (822307) example: ====================================

bash、GETメソッド

a@dell MINGW64 /c/work/esp-idf_test/simple_httpd_server/simple
$ curl 192.168.1.11:80/hello
Hello World!

必要最小限の結果表示になった。
-vオプションで、もう少し経過が表示される。

知っておくとちょっと便利!curl コマンドの使い方をご紹介 | SIOS Tech. Lab

a@dell MINGW64 /c/work/esp-idf_test/simple_httpd_server/simple
$ curl 192.168.1.11:80/hello -v
*   Trying 192.168.1.11:80...
* Connected to 192.168.1.11 (192.168.1.11) port 80 (#0)
> GET /hello HTTP/1.1
> Host: 192.168.1.11
> User-Agent: curl/8.1.2
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: text/html
< Content-Length: 12
< Custom-Header-1: Custom-Value-1
< Custom-Header-2: Custom-Value-2
<
Hello World!* Connection #0 to host 192.168.1.11 left intact

Invoke-WebRequestの結果と似ているが、もう少し時系列的な情報が出ているよう。

M5Stamp側は特に表示は変わらない。

I (1053277) example: Found header => Host: 192.168.1.11
I (1053287) example: Request headers lost

bash、POSTメソッド

bashでは、ファイルの中身を送ることができた。
プロジェクト内の適当なファイル(main/CMakeLists.txt)を送ってみた。

a@dell MINGW64 /c/work/esp-idf_test/simple_httpd_server/simple
$ curl -X POST --data-binary @main/CMakeLists.txt 192.168.1.11:80/echo
set(requires "")
if(${IDF_TARGET} STREQUAL "linux")
    list(APPEND requires esp_stubs esp-tls esp_http_server protocol_examples_common nvs_flash)
endif()
idf_component_register(SRCS "main.c"
                    INCLUDE_DIRS "."
                    REQUIRES ${requires})

echoのところに送っているが、送った内容がそのまま返されている。今回はファイルの中身。

上と同様に、-vオプションで詳細が表示される。

a@dell MINGW64 /c/work/esp-idf_test/simple_httpd_server/simple
$ curl -X POST --data-binary @main/CMakeLists.txt 192.168.1.11:80/echo -v
Note: Unnecessary use of -X or --request, POST is already inferred.
*   Trying 192.168.1.11:80...
* Connected to 192.168.1.11 (192.168.1.11) port 80 (#0)
> POST /echo HTTP/1.1
> Host: 192.168.1.11
> User-Agent: curl/8.1.2
> Accept: */*
> Content-Length: 278
> Content-Type: application/x-www-form-urlencoded
>
< HTTP/1.1 200 OK
< Content-Type: text/html
< Transfer-Encoding: chunked
< 
set(requires "")
if(${IDF_TARGET} STREQUAL "linux")
    list(APPEND requires esp_stubs esp-tls esp_http_server protocol_examples_common nvs_flash)
endif()
idf_component_register(SRCS "main.c"
                    INCLUDE_DIRS "."
                    REQUIRES ${requires})
* Connection #0 to host 192.168.1.11 left intact

a@dell MINGW64 /c/work/esp-idf_test/simple_httpd_server/simple
$

M5Stamp側。

I (1376567) example: =========== RECEIVED DATA ==========
I (1376567) example: set(requires "")
if(${IDF_TARGET} STREQUAL "linux")
    list(APPEND requires esp_stubs esp-tls esp
I (1376577) example: ====================================
I (1376577) example: =========== RECEIVED DATA ==========
I (1376587) example: _http_server protocol_examples_common nvs_flash)
endif()
idf_component_register(SRCS "main.c"

I (1376597) example: ====================================
I (1376597) example: =========== RECEIVED DATA ==========
I (1376607) example:                  INCLUDE_DIRS "."
                    REQUIRES ${requires})

I (1376627) example: ====================================

いくつかにデータが区切られて送られている。

参考: M5Stamp出力全部

一応載せておく。
何度かM5Stamp上での実行をやり直していて、最終的にうまくできたときのログ出力になっている。

クリックで開く/閉じる


(base) PS C:\work\esp-idf_test\simple_httpd_server\simple> set IDF_PATH=C:\Users\a\esp\esp-idf
(base) PS C:\work\esp-idf_test\simple_httpd_server\simple> c:\work\esp-idf_env\.espressif\python_env\idf5.1_py3.11_env\Scripts\python.exe C:\Users\a\esp\esp-idf\tools\idf_monitor.py -p COM3 -b 115200 --toolchain-prefix riscv32-esp-elf- --target esp32c3 c:\work\esp-idf_test\simple_httpd_server\simple\build\simple.elf
--- WARNING: GDB cannot open serial ports accessed as COMx
--- Using \\.\COM3 instead...
--- esp-idf-monitor 1.3.3 on \\.\COM3 115200 ---
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
ESP-ROM:esp32c3-api1-20210207
Build:Feb  7 2021
rst:0x1 (POWERON),boot:0xc (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fcd5820,len:0x1704
load:0x403cc710,len:0x968
load:0x403ce710,len:0x2f68
entry 0x403cc710
I (30) boot: ESP-IDF v5.1.1 2nd stage bootloader
I (30) boot: compile time Nov 14 2023 06:54:17
I (30) boot: chip revision: v0.3
I (33) boot.esp32c3: SPI Speed      : 80MHz
I (38) boot.esp32c3: SPI Mode       : DIO
I (43) boot.esp32c3: SPI Flash Size : 2MB
I (47) boot: Enabling RNG early entropy source...
I (53) boot: Partition Table:
I (56) boot: ## Label            Usage          Type ST Offset   Length
I (64) boot:  0 nvs              WiFi data        01 02 00009000 00006000
I (71) boot:  1 phy_init         RF data          01 01 0000f000 00001000
I (79) boot:  2 factory          factory app      00 00 00010000 00100000
I (86) boot: End of partition table
I (90) esp_image: segment 0: paddr=00010020 vaddr=3c0a0020 size=237c8h (145352) map
I (122) esp_image: segment 1: paddr=000337f0 vaddr=3fc91600 size=02854h ( 10324) load
I (124) esp_image: segment 2: paddr=0003604c vaddr=40380000 size=09fcch ( 40908) load
I (135) esp_image: segment 3: paddr=00040020 vaddr=42000020 size=97adch (621276) map
I (235) esp_image: segment 4: paddr=000d7b04 vaddr=40389fcc size=07518h ( 29976) load
I (246) boot: Loaded app from partition at offset 0x10000
I (247) boot: Disabling RNG early entropy source...
I (258) cpu_start: Unicore app
I (258) cpu_start: Pro cpu up.
I (267) cpu_start: Pro cpu start user code
I (267) cpu_start: cpu freq: 160000000 Hz
I (267) cpu_start: Application information:
I (270) cpu_start: Project name:     simple
I (275) cpu_start: App version:      1
I (279) cpu_start: Compile time:     Nov 14 2023 06:53:57
I (285) cpu_start: ELF file SHA256:  3b03a5999661a97d...
I (291) cpu_start: ESP-IDF:          v5.1.1
I (296) cpu_start: Min chip rev:     v0.3
I (301) cpu_start: Max chip rev:     v0.99 
I (306) cpu_start: Chip rev:         v0.3
I (310) heap_init: Initializing. RAM available for dynamic allocation:
I (318) heap_init: At 3FC97F20 len 000447F0 (273 KiB): DRAM
I (324) heap_init: At 3FCDC710 len 00002950 (10 KiB): STACK/DRAM
I (331) heap_init: At 50000010 len 00001FD8 (7 KiB): RTCRAM
I (338) spi_flash: detected chip: generic
I (341) spi_flash: flash io: dio
W (345) spi_flash: Detected size(4096k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
I (359) sleep: Configure to isolate all GPIO pins in sleep state
I (365) sleep: Enable automatic switching of GPIO sleep configuration
I (373) app_start: Starting scheduler on CPU0
I (377) main_task: Started on CPU0
I (377) main_task: Calling app_main()
I (387) example_connect: Start example_connect.
I (387) pp: pp rom version: 9387209
I (387) net80211: net80211 rom version: 9387209
I (407) wifi:wifi driver task: 3fca08fc, prio:23, stack:6656, core=0
I (407) wifi:wifi firmware version: ce9244d
I (407) wifi:wifi certification version: v7.0
I (407) wifi:config NVS flash: enabled
I (417) wifi:config nano formating: disabled
I (417) wifi:Init data frame dynamic rx buffer num: 32
I (417) wifi:Init management frame dynamic rx buffer num: 32
I (427) wifi:Init management short buffer num: 32
I (427) wifi:Init dynamic tx buffer num: 32
I (437) wifi:Init static tx FG buffer num: 2
I (437) wifi:Init static rx buffer size: 1600
I (447) wifi:Init static rx buffer num: 10
I (447) wifi:Init dynamic rx buffer num: 32
I (447) wifi_init: rx ba win: 6
I (457) wifi_init: tcpip mbox: 32
I (457) wifi_init: udp mbox: 6
I (467) wifi_init: tcp mbox: 6
I (467) wifi_init: tcp tx win: 5744
I (467) wifi_init: tcp rx win: 5744
I (477) wifi_init: tcp mss: 1440
I (477) wifi_init: WiFi IRAM OP enabled
I (487) wifi_init: WiFi RX IRAM OP enabled
I (487) phy_init: phy_version 970,1856f88,May 10 2023,17:44:12
I (537) wifi:mode : sta (68:67:25:b2:53:44)
I (537) wifi:enable tsf
I (537) example_connect: Please input ssid password:
I (82457) example_connect: Connecting to XXXXXXXXXXXXX...
I (82457) example_connect: Waiting for IP(s)
I (84867) wifi:new:<5,0>, old:<1,0>, ap:<255,255>, sta:<5,0>, prof:1
I (85547) wifi:state: init -> auth (b0)
I (85547) wifi:state: auth -> assoc (0)
I (85557) wifi:state: assoc -> run (10)
I (85567) wifi:connected with XXXXXXXXXXXXX, aid = 12, channel 5, BW20, bssid = 48:3e:5e:7c:4a:53
I (85567) wifi:security: WPA2-PSK, phy: bgn, rssi: -63
I (85577) wifi:pm start, type: 1

I (85577) wifi:set rx beacon pti, rx_bcn_pti: 0, bcn_timeout: 25000, mt_pti: 0, mt_time: 10000
I (85587) wifi:AP's beacon interval = 102400 us, DTIM period = 1
I (86717) wifi:<ba-add>idx:0 (ifx:0, 48:3e:5e:7c:4a:53), tid:6, ssn:1, winSize:64
I (87387) example_connect: Got IPv6 event: Interface "example_netif_sta" address: fe80:0000:0000:0000:6a67:25ff:feb2:5344, type: ESP_IP6_ADDR_IS_LINK_LOCAL
I (87597) esp_netif_handlers: example_netif_sta ip: 192.168.1.11, mask: 255.255.255.0, gw: 192.168.1.1
I (87597) example_connect: Got IPv4 event: Interface "example_netif_sta" address: 192.168.1.11
I (87607) example_common: Connected to example_netif_sta
I (87617) example_common: - IPv4 address: 192.168.1.11,
I (87617) example_common: - IPv6 address: fe80:0000:0000:0000:6a67:25ff:feb2:5344, type: ESP_IP6_ADDR_IS_LINK_LOCAL
I (87627) example: Starting server on port: '80'
I (87637) example: Registering URI handlers
I (89487) wifi:<ba-add>idx:1 (ifx:0, 48:3e:5e:7c:4a:53), tid:0, ssn:1, winSize:64
I (133427) example: Found header => Host: 192.168.1.11
I (133427) example: Request headers lost
I (243947) example: =========== RECEIVED DATA ==========
I (243947) example: foo=main%2FCMakeLists.txt
I (243947) example: ====================================
I (822307) example: =========== RECEIVED DATA ==========
I (822307) example: key=tekitou
I (822307) example: ====================================
I (1053277) example: Found header => Host: 192.168.1.11
I (1053287) example: Request headers lost
I (1150567) example: Found header => Host: 192.168.1.11
I (1150567) example: Request headers lost
I (1376567) example: =========== RECEIVED DATA ==========
I (1376567) example: set(requires "")
if(${IDF_TARGET} STREQUAL "linux")
    list(APPEND requires esp_stubs esp-tls esp
I (1376577) example: ====================================
I (1376577) example: =========== RECEIVED DATA ==========
I (1376587) example: _http_server protocol_examples_common nvs_flash)
endif()
idf_component_register(SRCS "main.c"

I (1376597) example: ====================================
I (1376597) example: =========== RECEIVED DATA ==========
I (1376607) example:                  INCLUDE_DIRS "."
                    REQUIRES ${requires})

I (1376627) example: ====================================
I (1515027) example: =========== RECEIVED DATA ==========
I (1515027) example: set(requires "")
if(${IDF_TARGET} STREQUAL "linux")
    list(APPEND requires esp_stubs esp-tls esp
I (1515037) example: ====================================
I (1515047) example: =========== RECEIVED DATA ==========
I (1515057) example: _http_server protocol_examples_common nvs_flash)
endif()
idf_component_register(SRCS "main.c"

I (1515067) example: ====================================
I (1515067) example: =========== RECEIVED DATA ==========
I (1515077) example:                  INCLUDE_DIRS "."
                    REQUIRES ${requires})

I (1515087) example: ====================================

以上

サーバー機能使えそうなことは分かったが、HTTPとかもうちょっと勉強しないとできないかもしれない。

まだまだM5Stamp色々いじってみたい。

QsyncでPCデータバックアップ

2年前にQNAP製NASを自宅に導入して、特に大きな問題なく運用できている。

今までYOLOとかOpenPoseとかを動かしたときは、全てPC上でローカルで動かしてたが、PCがいかれてしまう心配があるのと、PCの前にいないと結果を見られないのがちょっと嫌なので、この辺りをNASに自動バックアップするようにする。

NASはそこそこ容量がある(ディスクは3TB)ので、そこは問題ないはず。

参考

この記事を参考に、PCにQsyncをインストールして動かす。
QNAPさん自身の記事だが。

note.com

Qsyncインストール

参考記事に書いてあるQNAP公式URLからインストーラをダウンロードする。

エッセンシャル | ユーティリティ | QNAP

後はインストーラを起動するだけ。

思ったよりサイズが大きい(300MBぐらい使う)ので少し躊躇するが、進める。

Qsync起動、設定

インストール後、Qsync起動。

QNAPでいつも出てくるリージョン選択。

クイックスタートで色々とガイドされる。

「容量節約モード」「スマート削除」についての理解を求められる。
チェックして進む。

まず最初の画面。
NAS検索と、NASユーザー指定。

NAS検索は、LAN上からと、QID(クラウド経由)の2パターンが可能。

LANから。検索すると、しばらくして検出される。

QIDからだと、まずブラウザでQNAP IDログイン画面が出て、その後、Qsyncでデバイス検出される。
おそらく事前にQNAP IDでNASの紐づけをしておく必要あり。

今回は、PCのバックアップは自宅内からしかしないと思うので、LANからの検索で。

この後、パスワードを入力すると、同期フォルダの選択画面になる。

右の鉛筆マークから設定を変更する。

NAS側の同期フォルダを変えようとしたが、"/home/.Qsync"しか選べない。

?をクリックしてみると、Qsync Centralで設定をしないといけないようなことが書かれている。

とりあえずこのまま進めてみる。
どんな感じで共有フォルダがNASにできるのか。

「適用」をクリックで元のウィンドウに戻る。
「終了」する。

デフォルトで同期対象外にされるファイル等あるらしい。

こんな感じの画面になった。

この後、エクスプローラからNASの中身をのぞいてみたが、"/home/.Qsync"なるフォルダは見つからない。

ブラウザでQNAP NASにアクセスして、File Stationを開いてみると、"Qsync"のところに同期元フォルダの中身が出てきていた。実体がどこにいるかよくわからない。

"Qsync"の直下に、同期元フォルダの中身が直置きされているので、ちょっと気持ち悪い。
もう1段フォルダをかましたい。

同期先フォルダの変更

"Qsync"下に"work"フォルダを作っておく。

QsyncPCアプリで、「ペアになっているフォルダーを表示し、管理する」で、前と同じような「管理フォルダーペア」画面が出てくる。

この後なんだかんだ設定したが、状況は以下の通りだった。

  • ペアリング済みの項目は、後から同期先のフォルダを変更できなかった。
  • 一度ペアリングを解除して、新しく設定すると、今度はNAS上のフォルダーとして、さっき作った"work"フォルダが出てきた。これを同期先に設定した。
  • しばらくして見ると、ブラウザでFile Stationから、"Qsync/work"下に、同期元フォルダの中身が見えた。
  • 最後に、"Qsync"直下に前に同期したものが残っていたので、削除。

    これですっきり。

その他状況

エクスプローラで同期元のフォルダを見ると、同期状態の表示が出るようになっていた。
データ量が多いのでちょっと時間がかかっているが、ちょっとずつ同期していっているよう。
しばらくPC起動した状態にせねば。

iPhoneのQfileアプリからも、"Qsync/work"フォルダが見えて、外出先からも確認できるようになった。

以上

ちょっと本筋でやってたことからは寄り道だったが以上で。
作業データの保存がちょっと安心になった。

M5Stamp LED制御動かす

M5Stamp続き。

やってみたこと

M5StampのLEDを動かしてみたいと思って、いくつかやってみた。

M5Stamp LEDについて

M5Stamp C3には、"programmable RGB LED (SK6812)"というのが付いている。

docs.m5stack.com

回路図を見ると、こんな感じで、電源とDOUT、DINの計4ピンだけが出ているシンプルなもの。
このDINが、ESP32-C3のGPIO2に接続されている。

SK6812を調べてみると、マイコン内蔵のRGB LEDとのこと。
NeoPixelというブランド名が付いている。

romly.com

秋月でも売られていて、データシートも確認できる。

マイコン内蔵RGBLED SK6812MINI(5個入): LED(発光ダイオード) 秋月電子通商-電子部品・ネット通販

サンプルプロジェクト

このLEDを動かせるサンプルがないか調べたが、2つ見つかった。

公式ドキュメントから

公式ドキュメントに、M5StackのGitHubリポジトリへのリンクがあった。

Arduino IDEから使うものと、ESP-IDFから使うものの2つがある。

github.com

ESP-IDF Examplesから

VSCodeでESP-IDF Examplesを見ると、前にも"blink"プロジェクトがあるのは見ていて、GPIOでHighLow制御するものだろうと思い込んでいたが、led_stripでの制御(WS2812(SK6812互換品)などが対象)を使うこともできるようだった。

プロジェクト設定のBlink LED typeで、単純なGPIOのものか、led_stripを使うタイプか、選択ができそう。

あと、ひとつ前の画像にあるが、"The led_strip is installed via component manager"と記載がある。自分でcomponent managerからのインストールが必要ということ?

ただ、このリンクからはどこにも飛べなかった。

led_stripのインストール?

"ESP-IDF Examples"ウィンドウの左上を見ると、"ID Component Registry"というリンクがあり、ここをクリックすると、同名のタブが開いた。

コンポーネントの検索ができて、とりあえずターゲットESP32-C3で検索すると、上のほうに"espressif/led_strip"というのが出てきた。

これを開いてみると、インストールできそうなボタンが見つかった。

"Install"ボタンを押してみたが、特に反応が見られない。

改めて上記ページを見ると、"To add this component to your project, "という文言があるので、コンポーネントの追加はプロジェクトごとになるよう。

ということは、サンプルプロジェクトを作ったら、そこに自動で入れてくれていそうな気がする。
ので、おそらくここでのインストールは不要と思う。

サンプルプロジェクト選択

公式ドキュメントからのサンプルのほうが、M5Stampに合わせた設定をやってくれていそうで、スムーズにいきそうな気がするが、ESP-IDF Examplesからのほうが、自分で設定が必要なので、理解が深まりそうに思う。

ので、後者のサンプルを使ってみる。

サンプルプロジェクト作成

今までと同様に進める。

作成直後はこんな感じ。

今度は、"component manager"のリンクをクリックすると、"idf_component.yml"のタブが開いて、"espressif/led_strip"の記述があった。
これをもとに自動でライブラリをダウンロードしてくれるのか?

サンプルプロジェクト設定

まず下記3点は今までと同様に設定する。

  • "ESP-IDF: Set Espressif device target"でターゲットを"esp32c3"に設定。
  • "ESP-IDF: Select port to use (COM, tty, usbserial)"でデバイス接続したCOMポートを指定。(デバイス接続しておく必要がある)
  • "ESP-IDF: Select Flash Method"で、書き込み方法を"UART"に指定。

最後のやつだけは、前回自分でコマンドを起動していなくて、書き込みの実行前にツールが出してきて設定待ち状態になった。
今回、あらかじめ設定しておいて、後のコマンド実行がスムーズになるようにする。

次、"ESP-IDF: SDK Configuration editor"コマンドで設定。
サンプルプロジェクトの設定を検索すると、LEDに関する設定が3つ出てきた。
ちなみに、設定項目の右の〇i をクリックすると、説明文が下に出てきた。

"Blink LED type"は、2通り出てきた。
デフォルトで"RMT-Addressable LED"になっていたので、そのままで。

それ以外、"Blink GPIO number"は、今回はGPIO2につながっているので、2にしておく。
"Blink period in ms"は、デフォルトの1000 (1秒周期で点滅)のままで。

これでSaveする。

ビルド、実行

"ESP-IDF: Build, Flash and start a monitor on your device"コマンドで。

ビルド成功、LEDも点滅した(^^)

コンソールにもメッセージ出てる。

以上

ちょっとずつM5Stampが分かるようになってるのでいい感じ。

M5StampでWi-Fi

前回に引き続き、M5Stampいじってみる。

やってみること

Example Projectが色々あったので、手あたり次第やってみる。
ぱぱっと色々試せそう。

Wi-Fiサンプル

M5Stampで興味あることの一つはWi-Fi機能。

試しに家のWi-Fiに接続できるか?

ESP-IDFでサンプルを調べると、"Wi-Fi Station Example"というのがある。
これはWi-Fiのアクセスポイントへの接続のサンプルのよう。

プロジェクト作成

前回の手順で。
こんな感じのプロジェクトが開いた。

下のコンソール出力がちょっと気になるが…

プロジェクト設定

まずはターゲットデバイスを設定。
コマンドパレットから、"ESP-IDF: Set Espressif device target"を実行。
これは前と違いなし。

次に、SDKの設定。
Example ProjectのREADME(↑の画像で開いている)を見ると、プロジェクトの設定メニューの中の"Example Configuration"でWi-FiSSID、パスワードを設定するように書かれている。

"ESP-IDF: SDK Configuration editor"コマンドで、SDK Configuration editorを開いて、設定項目を検索してみると、その項目が出てきた。

これを、家のWi-Fiのものに設定して、"Save"する。

ビルド、実行

今回は、ビルドから実行まで一気にやるコマンドを使ってみたい。

その前に、COMポートの設定が必要。
"ESP-IDF: Select port to use (COM, tty, usbserial)"を実行。使うCOMポートを選択する。

VSCodeの左下を見ると、設定されたCOMポートが表示されていた。

次に、"ESP-IDF: Build, Flash and start a monitor on your device"を実行。
どうなるか。

見てると、ビルドは完了して、自動でデバイスへの書き込みが行われているよう。

進まないなと思ってたら、VSCodeの上のほうで書き込み方法の選択をしろと出ていた。

"UART"を選択したら、書き込みが進んだ。

書き込みが終わると、自動でモニタ開始されていた。
表示を見ると、無事にWi-Fi接続されたよう。
DHCPIPアドレス割り当てされた旨書かれている。
Wi-Fi情報は伏せてます。

以上

ブログ書きながらでも1時間かからずにさくっとできたのでいい感じ。

ぱぱっとやれば10分かからずにできるのでは。

他にもいろいろ試してみたい。

M5Stampやってみる

スイッチサイエンスでOAK-D S2を買ったのと同時にM5Stampを買っていたので、これに手を付けてみる。

買ったもの

買ったのは、M5Stamp C3 (5個入り)。

M5Stamp C3 (5pcs)www.switch-science.com

写真。
M5Stampが5個と、シールが入っている。
1個取り出し済み。

M5Stamp本体にクローズアップ。
裏面にUSB Type Cコネクタと、アンテナらしき金属が見える。

こちらが公式ドキュメント。

m5-docs

M5Stampにも、いくつかシリーズがあるよう。

M5Stampとは?

スイッチサイエンスの紹介文によると、

Wi-FiおよびBluetooth 5(LE)の機能が利用可能な、IoTエッジデバイス向けのEspressif ESP32-C3 RISC-V MCUを搭載した切手サイズのモジュールです。

とのこと。

切手サイズでWi-Fiも使えるとのことで、子供のおもちゃに組み込んでみたいと思い、今回購入した。

ちなみに、切手のサイズは、2.6cm x 2.2cmが標準とのことで、M5Stamp C3では、長手方向に少し大きめ。
USBシリアル変換ICも載せているためと思われる。

M5Stamp S3、PICOでは、切手サイズに収まる。

動かす手順

公式ドキュメントからやってみる。

Get Started - ESP32 - — ESP-IDF Programming Guide v5.1.1 documentation

PCに環境構築

以下の3種類のソフトウェアをインストールしろと書いている。

  • Toolchain
    ESP32用のコンパイラ
  • Build tools
    ESP32のアプリケーションをビルド
  • ESP-IDF
    ESP32用のライブラリと、Toolchainを操作する用のスクリプト

ESP-IDFは、Espressif IoT Development Frameworkの略らしく、IDEとは別物だよと言いたいのか?

いくつかインストールのしかたが書かれている。

好みのIDEからのインストールが推奨されている。
今回は、VSCode拡張機能を使うやり方でやってみる。

だいたいこの手順通り。

github.com

VSCodeから環境構築

拡張機能インストール

VSCode拡張機能を検索すると、出てきて、これをインストールした。

2023/10/30時点で、467Kダウンロード、ただし、星3つ。

手順では、インストール後に"Install ESP-IDF Prerequisites"と書かれているが、リンク先を見てみると、

For Windows the C++ Build Tools might be required.

と書かれてた。
前のGPU使用環境構築時に、Visual StudioからC++ビルド環境を入れたので、不要かもしれない。
とりあえず何もせずに進める。

セットアップ実施

VSCodeで、コマンドパレットを開いて、"ESP-IDF: Configure ESP-IDF extension"を実行。

セットアップ画面が現れる。こんな形の拡張機能は初めてかもしれない。

セットアップのモードを選択するが、そんなに細かい設定をしたいわけではないので、"Express"にしておく。

"Express"をクリックすると、設定項目がいくつか出てくる。

  • download server : ドキュメントに特に何も書かれていなかった、"GitHub"か"Espressif"の2つの選択肢があったが、デフォルトの"GitHub"にしておく。
    ツールのダウンロード元を選択するだけと思うので、どこからダウンロードしても同じでは。
  • ダウンロードするESP-IDFのバージョン選択。
    以下の選択肢が出てくる。

    今回は最新のリリース版(v5.1.1)にする。
  • "ESP-IDF container directory"と"ESP-IDF Tools directory(IDF_TOOLS_PATH)"は、適当に新規作成しておいた。

これで、"Install"を実行。

Python環境を新しく構築したりしているらしく、結構重たいダウンロードが走っていたりする。

ダウンロード経過は色々出ていたが、完了すると、全部消えてしまった。

続きは、以下のチュートリアルページを参照する。

github.com

Example Projectやってみる

ESP-IDF拡張機能のほうで、Example Projectを持っているということなので、見てみる。

"Show Example Projects"を選択すると、使うフレームワークの選択がまず出てきた。

選択すると、VSCodeにタブが現れて、色々なExample Projectが出てきた。

blink(Lチカ)プロジェクトもあり、上記チュートリアルではこれを使っているが、今回のM5Stamp C3のボード情報を確認すると、単純なLEDは付いていなかったので、これは使えない。

その次にわかりやすそうなhello_worldプロジェクトをやってみる。

プロジェクト作成

"Create project using example hello_world"をクリック。
プロジェクト作成先フォルダを指定する。

こんな感じで、指定したフォルダ内に"hello_world"ができた。

VSCode上では、プロジェクトのフォルダをワークスペースとして開いた状態になる。

プロジェクト設定: ターゲットデバイス設定

まずはターゲットデバイス設定。

コマンドパレットから、"ESP-IDF: Set Espressif device target"を選択。

対象プロジェクトのワークスペースフォルダを指定。
今回は、さっき作ったhello_worldプロジェクトしか出てこない、これを指定。

少し時間がかかって、候補のリストが出てくる。

今回のM5Stamp C3では、ESP32-C3が使用されているので、"esp32c3"を指定。

m5-docs

もう少し設定があるよう。
"OpenOCD Configuration File Paths list"と書かれていて、おそらく書き込み、デバッグのインターフェースを指定するものと思われる。

M5Stamp C3では、上の2つ(ESP-PROGボード、builtin USB-JTAG)には該当せず、ESP32の外にUSBシリアル変換ICが載っているので、3つ目の設定を選べばいいかと思われる。

しばらくすると、ワークスペースにファイルが増えていて(sdkconfig、sdkconfig.old)、その中にさっき設定したものが入っているよう。

プロジェクト設定: SDK設定

"ESP-IDF: SDK Configuration editor"コマンドを実行。

少し時間がかかって、設定UIが出てきた。
結構設定項目は多い。スクロールバーの縦幅を見るとわかるか。

HTTPSサーバーやWi-Fi設定があるので、IoTやるときはこのあたりをいじるのか。

必要な設定があるのかよく分からないが、とりあえずこのままにして進める。
一応"Save"ボタンを押しておいて、"SDK Configuration editor"ウィンドウを閉じる。

C/C++ Configuration

を設定しろと書かれているが、リンクを見ると、

Why configure this file?
To enable Code Navigation, auto-complete and other language support features on ESP-IDF source files on Visual Studio Code.

https://github.com/espressif/vscode-esp-idf-extension/blob/master/docs/C_CPP_CONFIGURATION.md#why-configure-this-file

と書かれているので、特に設定しないでもビルドには影響しないか。

ということで、この手順は飛ばす。

ビルド実施

コマンドパレットで、"ESP-IDF: Build your project"を実行。

そうすると、ビルドが実行され、ターミナルに色々表示が出てくる。

最終的にできたっぽい表示になる。ターミナルは2つ出ている。

下のバーに、×2と書かれているが、シンタックスチェックのツールから defineマクロの定義箇所が見つからない、ということと思われる。

どちらもコード上から定義箇所にジャンプすることはできたので、おそらく問題はない。

バイナリサイズ確認

オプションの手順になるが、"ESP-IDF: Size analysis of the binaries"で、サイズ確認できる。
ビルドがきちんとできたかどうかの確認にもなるか。

49KB使っているよう。

シリアルポート設定

プログラミング前に指定が必要。

その前に、PCにドライバインストールしておく。

m5-docs

インストール済みだった?
実は先にPCにM5Stampを接続してしまっていたから?

とりあえず、M5StampをPCに接続。
接続してみると、LEDが水色に光った。

VSCodeで、使うポートの選択。

ポートが自動で出てきた。これで動かしてみる。

設定すると、やっぱりワークスペース選択になった。
これを設定したら準備完了。

書き込み実行

これはコマンド実行するだけか。
"ESP-IDF: Flash your project"をやる。

と思ったら、色々選択肢があった。接続方式など。

"ESP-IDF: Flash (UART) your project"を選択したら、すぐに下のコンソールに表示が現れて、書き込み完了したよう。

プログラム動作

"ESP-IDF: Monitor your device"コマンドを実行。
今更だけど、コマンド候補の上のほうに全コマンドまとめて実行のコマンドがある。。。

新しいターミナルが現れて、色々と表示が出てくる。
一部はブートローダーのログ、一部はアプリケーションが出している"Hello World!"の表示。
このHello Worldプロジェクトは、自分で再起動を繰り返している。 ブートローダーのログのところを見ると、どんな設定になっているのか分かったりする。

クリックで全出力を開く

ESP-ROM:esp32c3-api1-20210207
Build:Feb  7 2021
rst:0x3 (RTC_SW_SYS_RST),boot:0xc (SPI_FAST_FLASH_BOOT)
Saved PC:0x40048b82
0x40048b82: ets_secure_boot_verify_bootloader_with_keys in ROM

SPIWP:0xee
mode:DIO, clock div:1
load:0x3fcd5820,len:0x1704
load:0x403cc710,len:0x968
load:0x403ce710,len:0x2f68
entry 0x403cc710
I (35) boot: ESP-IDF v5.1.1 2nd stage bootloader
I (35) boot: compile time Oct 31 2023 02:06:15
I (35) boot: chip revision: v0.3
I (38) boot.esp32c3: SPI Speed      : 80MHz
I (43) boot.esp32c3: SPI Mode       : DIO
I (48) boot.esp32c3: SPI Flash Size : 2MB
I (52) boot: Enabling RNG early entropy source...
I (58) boot: Partition Table:
I (61) boot: ## Label            Usage          Type ST Offset   Length
I (69) boot:  0 nvs              WiFi data        01 02 00009000 00006000
I (76) boot:  1 phy_init         RF data          01 01 0000f000 00001000
I (83) boot:  2 factory          factory app      00 00 00010000 00100000
I (91) boot: End of partition table
I (95) esp_image: segment 0: paddr=00010020 vaddr=3c020020 size=08650h ( 34384) map
I (109) esp_image: segment 1: paddr=00018678 vaddr=3fc8a600 size=01120h (  4384) load
I (113) esp_image: segment 2: paddr=000197a0 vaddr=40380000 size=06878h ( 26744) load
I (126) esp_image: segment 3: paddr=00020020 vaddr=42000020 size=15690h ( 87696) map
I (143) esp_image: segment 4: paddr=000356b8 vaddr=40386878 size=03d30h ( 15664) load
I (149) boot: Loaded app from partition at offset 0x10000
I (149) boot: Disabling RNG early entropy source...
I (163) cpu_start: Unicore app
I (163) cpu_start: Pro cpu up.
I (172) cpu_start: Pro cpu start user code
I (172) cpu_start: cpu freq: 160000000 Hz
I (172) cpu_start: Application information:
I (175) cpu_start: Project name:     hello_world
I (180) cpu_start: App version:      1
I (184) cpu_start: Compile time:     Oct 31 2023 02:05:44
I (191) cpu_start: ELF file SHA256:  9e26fa748febbdc2...
I (197) cpu_start: ESP-IDF:          v5.1.1
I (201) cpu_start: Min chip rev:     v0.3
I (206) cpu_start: Max chip rev:     v0.99 
I (211) cpu_start: Chip rev:         v0.3
I (216) heap_init: Initializing. RAM available for dynamic allocation:
I (223) heap_init: At 3FC8C560 len 000501B0 (320 KiB): DRAM
I (229) heap_init: At 3FCDC710 len 00002950 (10 KiB): STACK/DRAM
I (236) heap_init: At 50000010 len 00001FD8 (7 KiB): RTCRAM
I (243) spi_flash: detected chip: generic
I (247) spi_flash: flash io: dio
W (251) spi_flash: Detected size(4096k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
I (264) sleep: Configure to isolate all GPIO pins in sleep state
I (271) sleep: Enable automatic switching of GPIO sleep configuration
I (278) app_start: Starting scheduler on CPU0
I (283) main_task: Started on CPU0
I (283) main_task: Calling app_main()
Hello world!
This is esp32c3 chip with 1 CPU core(s), WiFi/BLE, silicon revision v0.3, 2MB external flash
Minimum free heap size: 331264 bytes
Restarting in 10 seconds...
Restarting in 9 seconds...
Restarting in 8 seconds...
Restarting in 7 seconds...
Restarting in 6 seconds...
Restarting in 5 seconds...
Restarting in 4 seconds...
Restarting in 3 seconds...
Restarting in 2 seconds...
Restarting in 1 seconds...
Restarting in 0 seconds...
Restarting now.
ESP-ROM:esp32c3-api1-20210207
Build:Feb  7 2021
rst:0x3 (RTC_SW_SYS_RST),boot:0xc (SPI_FAST_FLASH_BOOT)
Saved PC:0x40048b82
0x40048b82: ets_secure_boot_verify_bootloader_with_keys in ROM

SPIWP:0xee
mode:DIO, clock div:1
load:0x3fcd5820,len:0x1704
load:0x403cc710,len:0x968
load:0x403ce710,len:0x2f68
entry 0x403cc710
I (35) boot: ESP-IDF v5.1.1 2nd stage bootloader
I (35) boot: compile time Oct 31 2023 02:06:15
I (35) boot: chip revision: v0.3
I (38) boot.esp32c3: SPI Speed      : 80MHz
I (43) boot.esp32c3: SPI Mode       : DIO
I (48) boot.esp32c3: SPI Flash Size : 2MB
I (52) boot: Enabling RNG early entropy source...
I (58) boot: Partition Table:
I (61) boot: ## Label            Usage          Type ST Offset   Length
I (69) boot:  0 nvs              WiFi data        01 02 00009000 00006000
I (76) boot:  1 phy_init         RF data          01 01 0000f000 00001000
I (83) boot:  2 factory          factory app      00 00 00010000 00100000
I (91) boot: End of partition table
I (95) esp_image: segment 0: paddr=00010020 vaddr=3c020020 size=08650h ( 34384) map
I (109) esp_image: segment 1: paddr=00018678 vaddr=3fc8a600 size=01120h (  4384) load
I (113) esp_image: segment 2: paddr=000197a0 vaddr=40380000 size=06878h ( 26744) load
I (126) esp_image: segment 3: paddr=00020020 vaddr=42000020 size=15690h ( 87696) map
I (143) esp_image: segment 4: paddr=000356b8 vaddr=40386878 size=03d30h ( 15664) load
I (149) boot: Loaded app from partition at offset 0x10000
I (149) boot: Disabling RNG early entropy source...
I (163) cpu_start: Unicore app
I (163) cpu_start: Pro cpu up.
I (172) cpu_start: Pro cpu start user code
I (172) cpu_start: cpu freq: 160000000 Hz
I (172) cpu_start: Application information:
I (175) cpu_start: Project name:     hello_world
I (180) cpu_start: App version:      1
I (184) cpu_start: Compile time:     Oct 31 2023 02:05:44
I (191) cpu_start: ELF file SHA256:  9e26fa748febbdc2...
I (197) cpu_start: ESP-IDF:          v5.1.1
I (201) cpu_start: Min chip rev:     v0.3
I (206) cpu_start: Max chip rev:     v0.99
I (211) cpu_start: Chip rev:         v0.3
I (216) heap_init: Initializing. RAM available for dynamic allocation:
I (223) heap_init: At 3FC8C560 len 000501B0 (320 KiB): DRAM
I (229) heap_init: At 3FCDC710 len 00002950 (10 KiB): STACK/DRAM
I (236) heap_init: At 50000010 len 00001FD8 (7 KiB): RTCRAM
I (243) spi_flash: detected chip: generic
I (247) spi_flash: flash io: dio
W (251) spi_flash: Detected size(4096k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
I (264) sleep: Configure to isolate all GPIO pins in sleep state
I (271) sleep: Enable automatic switching of GPIO sleep configuration
I (278) app_start: Starting scheduler on CPU0
I (283) main_task: Started on CPU0
I (283) main_task: Calling app_main()
Hello world!
This is esp32c3 chip with 1 CPU core(s), WiFi/BLE, silicon revision v0.3, 2MB external flash
Minimum free heap size: 331264 bytes
Restarting in 10 seconds...
Restarting in 9 seconds...
Restarting in 8 seconds...
Restarting in 7 seconds...
Restarting in 6 seconds...
Restarting in 5 seconds...
Restarting in 4 seconds...
Restarting in 3 seconds...
Restarting in 2 seconds...
Restarting in 1 seconds...
Restarting in 0 seconds...
Restarting now.

...

今回ここまで

今回、公式ドキュメントからのやり方でやったが、ほかにM5Stampを動かした例を見ると、だいたいArduino IDEを使ってる。
あえて茨の道を進んでしまったかもしれない。

一回Arduino IDEも使ってみるか…

M5Stamp-C3をとりあえず使ってみる | 松五郎ブログ

ESP32-C3搭載、小型の開発基板M5Stamp C3 MATE を使ってみる | たまねぎブログ

M5Stamp C3 Mateを試してみました【Arduino使用】 | あろしーど

USBケーブル選び

前回、まともにOAK-D S2を動かそうと思うと、USB TypeC - TypeCケーブルが必要ということがわかった。

ので、Amazonとかで選んでみる。

USB TypeC で検索

したら、色々出てくる。価格も1000円前後でお手頃。

と思ったら、「映像出力に対応していません」とか書いてある。

さらによく見ると、「480Mbpsで高速ファイル転送」とか書いてある。

いつの時代の話じゃ👨🏻‍🦳

OAK-D S2はUSB 3.0以上の通信レート必要そうだったので、これでは使えない。

検索条件変更

Amazonアプリの検索窓に入力してると、「usb 3.2 gen 2 type-c」と言うのが出てきた。

前回調べたところだと、USB 3.2から15W対応できそうだった。(通信規格と電源規格の組み合わせもあり一筋縄ではないが)

これで検索してみると、1000円弱のケーブルあり。スポンサー品になってるが。

詳細見てみると、確かに「USB 3.2 Gen2」とか、「20Gbps」とか、「4K 60Hz」とか書いてあるから、これならいけそうか?

とりあえず欲しいものリストに追加。

もっと高級なやつ(?)

さっきの検索結果の上に、コネクタに液晶がついてるぽい商品が見えた。

開いてみると、2980円と少しお高い。

これもよく見たら通信はUSB2.0だった。

480Mbpsって高速なのか…

Amazonおすすめ

1499円と少し高くなるが。

レビュー数がさっきの商品より一桁多い。

L字型もある

どれぐらい便利か?

どうしようか

最近お金使い過ぎなので、買うかどうか悩み中

OAK-D S2買った

買おうか悩んでいたOAK-D S2、前々回の記事書いた直後にポチッとして、H ZETTRIO見た帰りに受け取った。

ということで、さっそく開封、動かしてみる。

まず開封

外箱はしっかりしてる。
iPhoneぐらい、というと言い過ぎだが、そんな感じの質感。

開けると、まずカメラの表面が出てくる。
真ん中と、その左右にカメラのレンズが見える。
上下逆だった。

カメラの下には、USB (Type A - Type C)ケーブルと、お買い上げありがとうございますカード。

カメラ本体を触ってみると、しっかりした金属筐体で、表面はざらざらした感じ。
持つとずっしりした重みを感じる。

この写真は底面になるのかな?
USB TypeCコネクタと、固定用のねじ穴。

動かしてみる

公式ドキュメント見てみる

チュートリアルを動かしてみる

Windows環境でやってく。

まずWindowsインストーラをダウンロード、セットアップ実施。

インストール完了。

起動すると、しばらく"Installing Depthai Requirements ..."が表示されてる。

起動したが、OAK-DをPCに接続していなかったためか、エラーメッセージが出てしまった。

OAK-DをPCに接続して、"Apply and Restart"をクリックしてみる。

なぜか何度か失敗したが、USBポートを入れ替えたりしていると、カメラ画像が出るようになった。
※GIFのアップロード容量の限界からフレームレート下げてるが、実際はもっと更新レート高い。画面には30fpsぐらいと出ている。

ときどきこのエラー(RuntimeError: Communication exception)が出る。
これは何だろう。
なんとなく、USBの電源供給不足でカメラが落ちた、とかと予想。

電力確認

上のエラーが何度も出るので、USBの電力確認してみる。

PCのUSBポート仕様

Dell G15ゲーミング ノートパソコン:ゲーミング ノートパソコン | Dell 日本

USB規格の電源関連

USB の充電(給電)規格、多すぎ!! 混乱するのでまとめてみた

USB Type CとUSB 3.2 – 接続について理解する | CUI Devices

Thunderbolt 4がUSBの混乱を解決するか、多機能Type-Cの実装を予測(2ページ目) | 日経クロステック(xTECH)

  • USB 3.2 Gen1とはUSB 3.0のことだった… 電力は4.5W(電流0.9A)まで
  • Thunderbolt 4 は15Wは供給可能、最大100W供給可能

OAK-Dの消費電力

depthai-hardware/DM9098_OAK-D-S2/Datasheet/OAK-D-S2_Datasheet.pdf at master · luxonis/depthai-hardware · GitHub

  • 最大7.5Wの消費電力

結論

USB3.2 Gen1 (= USB 3.0)のポートでは電力足りなかった!

Thunderbolt 4のポートに接続すれば電力は足りそうだが、USB Type-C - Type-Cケーブルが必要。
ただし、OAK-Dに付属していたのはType-A - Type-Cケーブルで、自分でType-C - Type-Cケーブルを持っているわけでもない。

Type-C - Type-Cケーブル買うしかないか…

チュートリアル続き

なんとか今の状態で動いてくれることもあったので、チュートリアルを続行。

プレビュー変更

左上のメニューから、ライブ表示する内容を変更できる。
カラー画像、深度画像、深度画像(raw)、ステレオカメラの左(右)だけ、などなど。

"depth"を選択して、"Apply and Restart"すると、それらしいのが出た。

AIモデル変更

"AI"タブの中に、色々とモデルが入っている。
デフォルトでは、"mobilenet-ssd"になってる。

"openpose2"も入ってる。
人の絵を映してみたが、骨格推定されてた。

"human-pose-estimation-0001"というのもあり、こちらのほうが人物の足まで推定されていた。

ちなみにこれが元の画像。

顔検出もある。これは"face-detection-retail-0004"。
トーマスたちの顔が認識されている。

今回はここまで

今回見た中では、手の検出モデルが見つからなかった。
もう少し詳しい使い方を調べていこうと思う。