热度 1 |


ESP8266(ESP-WROOM-02)を最近よく使っています。
ESP8266を使ったセンサを、Wi-Fiアクセスポイントから远い、直接电波の届きにくい场所に置きたかったため、ESP8266をもう一つ使ってWi-Fiの到达范囲を拡张する中継机にした(といってもブリッジではなくNAPTルータ)という话です。
とその前に軽くESP8266について绍介しておくと…(もう知ってる方は読み飞ばしてください)
ESP8266は无线LANモジュールです。购入した状态では外部のマイコンからATコマンドで制御できます。が、LX106という32bit MCUを搭载しており、このモジュール単体でArduino IDEからプログラミングして动作させることが可能です。この方が圧倒的に便利なので、私自身はATコマンドで使ったことはありません。
しかも安価(単体なら400円台)ですし、ESP-WROOM-02は技适も取得していて安心して使え、AVRと比べて高性能(CPUクロック80~160MHz, 4MBフラッシュ, 36KB RAM)。アナログ入力も1ch搭载していて、センサ・アクチュエータ等を简単にネットワーク接続できるので非常に便利です。
Arduinoとして利用する方法は下记などが参考になります。
技适済み格安高性能Wi-FiモジュールESP8266をArduinoIDEを使ってIoT开発する为の环境准备を10分でやる方法 - Qiita
なお开発时はモジュール単体よりも、下记のようなブレークアウトボード・开発ボードを购入するのが良いでしょう。特にESPr DeveloperはUSBを接続するだけでいきなり开発が始められ、シリアル変换や书き込みモード设定など気にしなくて済むので非常に楽です(お値段はしますが)。
ESP-WROOM-02ピッチ変换済みモジュール《フル版》 - スイッチサイエンス
ESPr Developer(ピンソケット実装済) - スイッチサイエンス
ちなみにシリアルでスケッチを书き込むと、ファームウェアが大きいため*1転送に少し时间がかかりますが、Wi-Fi経由で高速にアップロードすることも可能です。
ESP-WROOM-02 + ArduinoOTAでスケッチのWiFi経由アップロード - Qiita
他にもLua等でもプログラミングが可能なファームウェアもあります。
ESP8266(ESP-WROOM-02)自分的まとめ - 半空洞男女関系
ESP8266は、自身がWi-FiのアクセスポイントになるWIFI_APモード、既设のWi-Fiアクセスポイントに接続するWIFI_STAモードの両方をサポートしています。
しかしこれ以外にWIFI_AP_STAという、他のアクセスポイントに接続しつつ、同时に自分もアクセスポイントとして他のクライアントからのWi-Fi接続を受け付けるということができます。(ちなみにArduino化した直后のデフォルトではこのモードになっているため、明示的にモード指定していないと ESP_xxxxxx というSSIDが発信されています。APのON/OFFやSSID等の设定はフラッシュに不挥発に保存され、前回の値が电源ONに设定されます。)
モードの切り替えは以下のようにWiFi.mode()を使用します。
子端末になるESP8266では、上记のap_ssidに対してWiFi.begin()で接続することになります。こうすると以下のような接続状态になります。
なお、亲と子で别のサブネットのアドレスになっていないと(少なくとも亲ネットワーク侧からは)通信不能となるのでご注意を。
IPアドレスはDHCPで自动的に设定されます(静的に指定もできます)。
また、ESP8266WiFiMultiを使って复数の接続先SSIDを指定しておけば、接続できる方に自动接続するということも可能です。详しくはWiFiMultiというサンプルスケッチを见てください。
亲APとクライアントに同时接続できるということは、Wi-Fi中継机として使えるのでは?と思うわけですが、そのままでは中継机能(IP_FORWARD)は无効化されており、SDKに含まれるIPスタック(lwip)の设定を変更する必要があります。
参考: ESP8266 lwip IP_FORWARD/routing - ESP8266 Developer Zone
これにより、亲APのネットワークとESP8266 APのネットワークの间でパケットが転送されるようになります。しかし、これだけでは亲APやそのネットワーク内の各端末に「192.168.4.0/24 にアクセスするには 192.168.10.x をルータとして使う」というルーティング情报を设定しないと、通信が行えません(子端末からのパケットはESP8266がデフォルトゲートウェイになるので设定しなくとも亲APのネットワークに出て行けますが、その応答パケットが戻っていくためのルーティング情报を设定しないと応答が得られません)。
この设定を不要にする方法として、普通のルータで使われている方式としてNAT(正确にはNAPT)があります。子端末から亲ネットワークに出ていく际にソースアドレスをESP8266のもの(192.168.10.x)に书き换えておき、逆にこれに対する応答パケットが来た际には适切に子端末宛てに书き换えるというものです。(戻り先を特定するためにはセッション管理が必要になります。)
なお他にネットワークブリッジとして机能させることも考えられますが、こちらは色々ルーティングに改造を加えないと难しい気がして手を出していません。
esp8266のSDKのlwipをざっと眺めたところ、NATの机能はないようでしたので、自分で実装してみました。
変更の内容はGitHubに置いてあります。
https://github.com/NeoCat/esp8266-Arduino/commit/4108c8dbced7769c75bcbb9ed880f1d3f178bcbe
上记のバグ修正コミット
https://github.com/NeoCat/esp8266-Arduino/commit/634dfb5f60e902c681c95712bc7455e24773667d
ボードマネージャ等でESP8266のライブラリを导入している场合は、以下のパッチを当てることで対応できます。
https://gist.github.com/NeoCat/da3c141813980edaa256ad351cab3a2c (バグ修正コミットを含む差分)
上记からRaw(またはDownload ZIP)でパッチを适当な场所に保存し、Macであれば端末から
とすればパッチを适用できます。适用后、lwipを再コンパイルする必要があります。
パッチを适用したら、Arduinoのスケッチ内で以下のようにすることでNATを有効化できます。
これ以降、子端末からのTCP/UDP/ICMP(pingのみ)のパケットは亲ネットワークにアドレス変更の上で転送され、応答も対応付けてアドレス変换されます。
なおTCP, UDPの送信元ポート番号(1024以上)も重复を避けるために変换対象になります。
亲ネットワークから子端末のTCP/UDPサーバにアクセスするためには、ESP8266の特定ポートを子端末にマッピングする必要があります。このためにはスケッチから、
のように、対象プロトコル(TCPまたはUDP)、ESP8266上のマッピングするポート、転送先となる子端末のIPアドレス、ポートを指定します。
この例では、亲ネットワークから 192.168.10.x:8080 にアクセスすると、子端末192.168.4.3の80番ポート(Webサーバ)に接続できます。
なお実装上、1つの宛先(アドレス+ポート)に対しては1つのポートしかマッピングできず、同一の宛先を复数ポートにマップすると动作がおかしくなるのでご注意ください。
|Archiver|手机版|小黑屋|软路由
( 渝ICP备15001194号-1|
渝公网安备 50011602500124号 )
GMT+8, 2026-10-26 03:53 , Processed in 0.042353 second(s), 17 queries , Gzip On.
Powered by Discuz! X3.5 Licensed
© 2001-2026 Discuz! Team.