ESP-IDFを使ってみる

esp32_nat_router


こちら
にESP-IDFを使ったRouterアプリが公開されています。
Console Componentを使って、コマンドラインで設定を行うことができます。
ファームを書き込むと、シリアルポートに以下が表示されます。
ESP32 NAT ROUTER
Type 'help' to get the list of commands.
Use UP/DOWN arrows to navigate through command history.
Press TAB when typing command name to auto-complete.

Unconfigured WiFi
Configure using 'set_sta' and 'set_ap' and restart.
esp32>

show configコマンドで現在の設定を確認することができます。
esp32> show config
Router Configuration:
====================
STA Settings:
  SSID: <undef>
  Password: <undef>
  Enterprise: <not active>
  Static IP: <not configured>
  Hostname: esp32-nat-router

AP Settings:
  SSID: <undef>
  Password: <undef>
  IP Address: 192.168.4.1
  DNS Server: (upstream)
  Security: WPA2/WPA3

Web Interface: enabled (port 80)
TX Power: 20.0 dBm

helpコマンドで使用できるコマンドの一覧を表示します。
esp32> help
help  [<string>] [-v <0|1>]
  Print the summary of all registered commands if no arguments are given,
  otherwise print summary of given command.
      <string>  Name of command
  -v, --verbose=<0|1>  If specified, list console commands with given verbose level

free
  Get the current size of free heap memory

heap
  Get minimum size of free heap memory that was available during program
  execution

version
  Get version of chip and SDK

restart
  Software reset of the chip

deep_sleep  [-t <t>] [--io=<n>] [--io_level=<0|1>]
  Enter deep sleep mode. Two wakeup modes are supported: timer and GPIO. If no
  wakeup option is specified, will sleep indefinitely.
  -t, --time=<t>  Wake up time, ms
      --io=<n>  If specified, wakeup using GPIO with given number
  --io_level=<0|1>  GPIO level to trigger wakeup

light_sleep  [-t <t>] [--io=<n>]... [--io_level=<0|1>]...
  Enter light sleep mode. Two wakeup modes are supported: timer and GPIO.
  Multiple GPIO pins can be specified using pairs of 'io' and 'io_level'
  arguments. Will also wake up on UART input.
  -t, --time=<t>  Wake up time, ms
      --io=<n>  If specified, wakeup using GPIO with given number
  --io_level=<0|1>  GPIO level to trigger wakeup

tasks
  Get information about running tasks

nvs_set  <key> <type> -v <value>
  Set key-value pair in selected namespace.
  Examples:
  nvs_set VarName i32 -v 123
  nvs_set VarName str -v YourString
  nvs_set VarName blob -v 0123456789abcdef
         <key>  key of the value to be set
        <type>  type can be: i8, u8, i16, u16 i32, u32 i64, u64, str, blob
  -v, --value=<value>  value to be stored

nvs_get  <key> <type>
  Get key-value pair from selected namespace.
Example: nvs_get VarName i32
         <key>  key of the value to be read
        <type>  type can be: i8, u8, i16, u16 i32, u32 i64, u64, str, blob

nvs_erase  <key>
  Erase key-value pair from current namespace
         <key>  key of the value to be erased

nvs_namespace  <namespace>
  Set current namespace
   <namespace>  namespace of the partition to be selected

nvs_list  <partition> [-n <namespace>] [-t <type>]
  List stored key-value pairs stored in NVS.Namespace and type can be specified
  to print only those key-value pairs.
  Following command list variables stored inside 'nvs' partition, under
  namespace 'storage' with type uint32_tExample: nvs_list nvs -n storage -t u32

   <partition>  partition name
  -n, --namespace=<namespace>  namespace name
  -t, --type=<type>  type can be: i8, u8, i16, u16 i32, u32 i64, u64, str, blob

nvs_erase_namespace  <namespace>
  Erases specified namespace
   <namespace>  namespace to be erased

set_sta  <ssid> <passwd> [-- <ent_username>] [-- <ent_identity>]
  Set SSID and password of the STA interface
        <ssid>  SSID
      <passwd>  Password
  --, -u, ----username=<ent_username>  Enterprise username
  --, -a, ----anan=<ent_identity>  Enterprise identity

set_sta_static  <ip> <subnet> <gw>
  Set Static IP for the STA interface
          <ip>  IP
      <subnet>  Subnet Mask
          <gw>  Gateway Address

set_sta_mac  <octet> <octet> <octet> <octet> <octet> <octet>
  Set MAC address of the STA interface
       <octet>  First octet
       <octet>  Second octet
       <octet>  Third octet
       <octet>  Fourth octet
       <octet>  Fifth octet
       <octet>  Sixth octet

set_ap_mac  <octet> <octet> <octet> <octet> <octet> <octet>
  Set MAC address of the AP interface
       <octet>  First octet
       <octet>  Second octet
       <octet>  Third octet
       <octet>  Fourth octet
       <octet>  Fifth octet
       <octet>  Sixth octet

set_ap  <ssid> <passwd>
  Set SSID and password of the SoftAP
        <ssid>  SSID of AP
      <passwd>  Password of AP

set_ap_ip  <ip>
  Set IP for the AP interface
          <ip>  IP

portmap  [add|del] [TCP|UDP] <ext_portno> <int_ip> <int_portno>
  Add or delete a portmapping to the router
     [add|del]  add or delete portmapping
     [TCP|UDP]  TCP or UDP port
  <ext_portno>  external port number
      <int_ip>  internal IP
  <int_portno>  internal port number

show
  Get status and config of the router




最初に以下のコマンドでAPのSSIDとパスワードを設定します。
パスワードが8文字未満の時はオープン(パスワード無し)ルーターの設定となります。
コマンドで指定した内容は、NVS領域に記録されます。
restartコマンドで最新の設定が有効になります。
esp32> set_ap ESP32 ESP32
AP will be open (no passwd needed).
I (24305) cmd_router: AP settings ESP32/ESP32 stored.

esp32> set_ap ESP32 ESP32PASS
I (111554) cmd_router: AP settings ESP32/ESP32PASS stored.

esp32> restart

esp32> show config
I (590388) cmd_router: ap_ssid ESP32
I (590398) cmd_router: ap_passwd ESP32PASS
Router Configuration:
====================
STA Settings:
  SSID: <undef>
  Password: <undef>
  Enterprise: <not active>
  Static IP: <not configured>
  Hostname: esp32-nat-router

AP Settings:
  SSID: ESP32
  Password: ESP32PASS
  IP Address: 192.168.4.1
  DNS Server: (upstream)
  Security: WPA2/WPA3

Web Interface: enabled (port 80)
TX Power: 20.0 dBm

このアクセスポイントに接続すると、192.168.4.xのアドレスが払い出されます。
I (17068) wifi:new:<1,1>, old:<1,1>, ap:<1,1>, sta:<0,0>, prof:1, snd_ch_cfg:0x0
I (17068) wifi:station: 24:0a:c4:c5:46:fc join, AID=1, bgn, 40U
I (17098) ESP32 NAT router: Client connected: 24:0A:C4:C5:46:FC - 1 total
I (17128) esp_netif_lwip: DHCP server assigned IP to a client, IP is: 192.168.4.2

DHCPで払い出されるアドレスを変更する場合は、以下のコマンドを実行します。
esp32> set_ap_ip 192.168.0.1
I (633668) cmd_router: AP IP address 192.168.0.1 stored.
esp32> restart

esp32> show config
I (6398) cmd_router: ap_ssid ESP32
I (6408) cmd_router: ap_passwd ESP32PASS
Router Configuration:
====================
STA Settings:
  SSID: <undef>
  Password: <undef>
  Enterprise: <not active>
  Static IP: <not configured>
  Hostname: esp32-nat-router

AP Settings:
  SSID: ESP32
  Password: ESP32PASS
  IP Address: 192.168.0.1
  DNS Server: (upstream)
  Security: WPA2/WPA3

Web Interface: enabled (port 80)
TX Power: 20.0 dBm
esp32> I (8408) wifi:new:<6,1>, old:<6,1>, ap:<6,1>, sta:<6,1>, prof:1, snd_ch_cfg:0x0

これで、このアクセスポイントに接続したときのアドレスが、192.168.0.xのアドレスに変わります。
I (29698) wifi:new:<1,1>, old:<1,1>, ap:<1,1>, sta:<0,0>, prof:1, snd_ch_cfg:0x0
I (29698) wifi:station: 24:0a:c4:c5:46:fc join, AID=1, bgn, 40U
I (29738) ESP32 NAT router: Client connected: 24:0A:C4:C5:46:FC - 1 total
I (29758) esp_netif_lwip: DHCP server assigned IP to a client, IP is: 192.168.0.2



外部のサイトに接続するためには、以下のコマンドでUplink側のルーター(外部と接続しているルータ)を登録する必要が有ります。
Uplink側のルーターを登録するとesp_nat_routerは中継機として動作します。
esp32> set_sta UplinkルータのSSID Uplinkルータのパスワード
I (5346545) cmd_router: STA settings aterm-d5a4ee-g/xxxxxxxxxx stored.

esp32> restart

esp32> show config
I (6218) cmd_router: ap_ssid ESP32
I (6228) cmd_router: ap_passwd ESP32PASS
Router Configuration:
====================
I (6228) cmd_router: ssid aterm-d5a4ee-g
I (6228) cmd_router: ent_username
I (6228) cmd_router: ent_identity
I (6228) cmd_router: passwd xxxxxxxxxx
STA Settings:
  SSID: aterm-d5a4ee-g
  Password: xxxxxxxxxx
  Enterprise: <not active>
  Static IP: <not configured>
  Hostname: esp32-nat-router

AP Settings:
  SSID: ESP32
  Password: ESP32PASS
  IP Address: 192.168.0.1
  DNS Server: (upstream)
  Security: WPA2/WPA3

Web Interface: enabled (port 80)
TX Power: 20.0 dBm

Linuxマシンを使用してWiFiのパフォーマンスを調べてみました。
使用したLinuxマシンはOrangePi-PCで、MT7601UのUSB-WiFiとspeedtestツールを使いました。
どちらも親機にはAterm PA-WG2600HSを使っています。
こちらがNECのAterm WR8165N(300Mbps)経由で、親機に接続している状態でのパフォーマンスです。
orangepi@orangepipc:~$ speedtest --simple
Ping: 57.313 ms
Download: 13.38 Mbit/s
Upload: 6.26 Mbit/s
orangepi@orangepipc:~$ speedtest --simple
Ping: 55.69 ms
Download: 13.85 Mbit/s
Upload: 6.55 Mbit/s
orangepi@orangepipc:~$ speedtest --simple
Ping: 67.225 ms
Download: 13.87 Mbit/s
Upload: 5.69 Mbit/s

こちらがesp32_nat_router経由で、親機に接続したときのパフォーマンスです。
orangepi@orangepipc:~$ speedtest --simple
Ping: 54.381 ms
Download: 3.99 Mbit/s
Upload: 6.20 Mbit/s
orangepi@orangepipc:~$ speedtest --simple
Ping: 38.856 ms
Download: 5.88 Mbit/s
Upload: 6.07 Mbit/s
orangepi@orangepipc:~$ speedtest --simple
Ping: 52.458 ms
Download: 5.72 Mbit/s
Upload: 6.24 Mbit/s

こちらがesp_wifi_repeater(ESP8266のルーター)経由で、親機に接続したときのパフォーマンスです。
ESP32(240MHz 2Core)とESP8266(160MHz 1Core)では、CPU周波数は1.5倍の差ですが、Downloadスピードはそれ以上の差が出ています。
orangepi@orangepipc:~$ speedtest --simple
Ping: 55.979 ms
Download: 1.52 Mbit/s
Upload: 4.77 Mbit/s
orangepi@orangepipc:~$ speedtest --simple
Ping: 54.665 ms
Download: 1.20 Mbit/s
Upload: 4.20 Mbit/s
orangepi@orangepipc:~$ speedtest --simple
Ping: 48.133 ms
Download: 1.19 Mbit/s
Upload: 4.14 Mbit/s

esp_nat_routerのconfigデータはNVS領域に記録されるんので、以下のコマンドで初期値に戻すことができます。
$ idf.py erase-flash



ESP32はEthernet、WiFi-Station、WiFi-SoftAPの3つのNetwork Interfaceを持っているので、これらを使った ブリッジアプリケーションがいくつか公開されています。
こ ちらにはEthernetを外部へのInterface、WiFi-SoftAPを内部へのInterfaceとして使うアプリケー ションが公開されています。
このサンプルは特別なコンポーネントを使わずに、ESP-IDFの標準的な関数だけでEthernet<-->WiFiのパケット転 送を行ってい ます。


続く...