はじめに — 背景とねらい
Pico W は Wi-Fi を内蔵した廉価で強力な IoT MCU ですが、単に接続するだけでなく、RTOS を活用した高信頼・高効率な実装方法 が求められます。本記事では RP2040 のデュアルコア設計 を活かし、core0 でベアメタル lwIP による TCP/IP スタック処理、core1 でITRON系 ベースの RTOSを組み合わせた IoTデモを行いました。
pico_wのwifiを使って、センサデータをホストへ送信するデモを作成します。
環境構築はこちら
githubで公開しています
今回のセンシング+wifiでのiot例を公開しています
picow搭載の無線チップ CYW43439について
-
Infineon CYW43439 は 2.4GHz IEEE 802.11 b/g/n 仕様の Wi‑Fi 4 チップ
→ SDIO v2.0(4bit 50MHz)で最大 200Mbps のデータ転送が可能です - Bluetooth 5.x も統合
- 内部に ARM Cortex‑M3、LNA/PA、iTR RF スイッチなど無線処理回路を搭載
→ ホスト MCU(RP2040)の負荷を軽減。 - Pico W の公式ハード構成は「Pico W Datasheet」に記載されています
Pico W のネットワークスタック構成
Pico SDK 1.5.1でも、extensionで以下の階層のネットワーク機能が提供されています
-
cyw43_driver
- CYW43439 の下位ドライバ(SPI/SDIO 通信)
- Pico SDK 版では RP2040 の PIO を用いた SPI 実装になっています
-
pico_cyw43_arch
- cyw43_driver と lwIP を統合する “アーキテクチャ層”
- Wi‑Fi 初期化、STA/AP モード切替、LED 制御
- lwIP をスレッドセーフに扱うための begin/end ラッパを提供しています
(cyw43_arch_lwip_begin()/cyw43_arch_lwip_end())
-
pico_lwip(TCP/IP スタック lwIP)
- pico_lwip_core(TCP/UDP 基本機能)
- pico_lwip_http(HTTP/HTTPS)
- pico_lwip_mqtt、pico_lwip_sntp、pico_lwip_mdns 等
- FreeRTOS 連携モジュールも存在(NO_SYS=0)
-
pico_mbedtls(TLS/暗号)
- TLS1.2/1.3、X.509、暗号(AES/ECC/SHA 等)
- lwIP の altcp_tls と組み合わせて HTTPS 通信を実現しています
lwIP の動作モード
-
NO_SYS=1(ベアメタル)
- コールバックで lwIP を駆動します
- pico_lwip_nosys を利用可能します
- 今回はcore0をこっち(ベアメタル)で使用します
-
NO_SYS=0(FreeRTOS 等)
- Socket API が利用可能 です
- マルチタスクで安定した実装が可能です
- pico_lwip_freertos を使用できます
注意点
-
Thread-Safe Background(TSBG)
- Pico W で頻繁に使われる割り込み駆動方式です
- 通常コードから lwIP を使う際は下記を挟むほうが無難です:
cyw43_arch_lwip_begin()cyw43_arch_lwip_end()
-
理由として、lwIP はスレッドセーフではないため必須の操作です
使用API
- 以下を使用。最低限しか使っていません
cyw43_arch_init();
cyw43_arch_enable_sta_mode();
cyw43_arch_wifi_connect_timeout_ms("SSID", "PASS", CYW43_AUTH_WPA2_AES_PSK, 30000);
cyw43_arch_lwip_begin();
// → lwIP で DNS / TCP 接続など
cyw43_arch_lwip_end();
cyw43_arch_deinit();
以下に各APIの意味を整理します。
1. cyw43_arch_init();
役割:Wi-Fiスタック全体の初期化
- CYW43439無線チップの初期化
- SPI通信のセットアップ
- lwIPスタックの初期化
- 割り込みや内部タスクの起動
- 内部同期機構(mutex等)の初期化
ポイント
- Wi-Fiを使う前に必ず呼ぶ
- 失敗時はエラーコードが返る(0なら成功)
- これを呼ばないと他のcyw43系APIは使用不可
2. cyw43_arch_enable_sta_mode();
役割:Station(子機)モードに設定
- Pico WをWi-Fiアクセスポイントへ接続する「子機モード」に設定する
- APモードではなくSTAモードに切り替える
補足
- APモードを使う場合は
cyw43_arch_enable_ap_mode()を使用する - この関数は「モード設定のみ」で、まだ接続はしない
3. cyw43_arch_wifi_connect_timeout_ms
cyw43_arch_wifi_connect_timeout_ms(
"SSID",
"PASS",
CYW43_AUTH_WPA2_AES_PSK,
30000
);
役割:Wi-Fiアクセスポイントへ接続
| 引数 | 意味 |
|---|---|
| SSID | 接続先アクセスポイント名 |
| PASS | パスワード |
| CYW43_AUTH_WPA2_AES_PSK | 認証方式 |
| 30000 | タイムアウト(ms) |
動作内容
- 指定SSIDへ接続試行
- DHCPでIP取得
- 指定時間内に接続できなければ失敗
認証方式の例
CYW43_AUTH_OPENCYW43_AUTH_WPA2_AES_PSK
戻り値
- 0:成功
- 負値:失敗
4. cyw43_arch_lwip_begin();
役割:lwIPの排他制御開始
- lwIPスタックに安全にアクセスするためのロック取得
- マルチスレッド/割り込み環境で必要
使う場面
- TCP/UDP APIを直接操作する前
- pbuf操作などlwIP内部構造へ触る場合
5. cyw43_arch_lwip_end();
役割:lwIP排他制御終了
-
cyw43_arch_lwip_begin()で取得したロックを解放する
注意
- begin/endは必ずペアで使用
- 忘れるとデッドロックの原因になる
6. cyw43_arch_deinit();
役割:Wi-Fiスタックの終了処理
- 無線チップ停止
- lwIP停止
- リソース解放
使う場面
- プログラム終了時
- Wi-Fi機能を完全停止したい場合
全体の流れ(典型例)
cyw43_arch_init(); // 初期化
cyw43_arch_enable_sta_mode(); // STAモード設定
cyw43_arch_wifi_connect_timeout_ms(
"SSID",
"PASS",
CYW43_AUTH_WPA2_AES_PSK,
30000
); // 接続
// 通信処理
cyw43_arch_deinit(); // 終了処理
センサ基板について
ここからはデモに使用した温度湿度気圧センサを紹介します。
aliexpressで100円以下で売っている、BMP280+AHT20基板を使います。
amazonなんかでも売っています。
この格安モジュール自体は、かなり出回ってますが、センサ自体は生産中止のようです
アドレスは、BMPが「0x76」AHTが「0x38」でした
ベースボードについて
ブレッドボード上やユニバーサル基板上などでも作れますが、ずいぶん前に作成したpico用のベースボードを使いました。githubで公開しています。液晶やデバッグボタンをつけただけです。
デモの構成 pinアサイン
- 液晶(ACM1602)
I2C1を使用
GPIO6 (SDA) / GPIO7 (SCL)
- センサ(上記のBMP280+AHT20)
I2C0を使用
GPIO8(SDA) GPIO9(SCL)
両方I2Cです。運よく?両モジュールとも10Kのプルアップがついていましたが、他を使用する場合外付が必要です
- キーSWも基板につけていました。以下を使用
SW1 GP20 SW2 GP21 SW3 GP14 SW4 GP15
| 用途 | インターフェイス | ピン |
|---|---|---|
| 液晶(ACM1602) | I2C1 | GPIO6 (SDA) |
| I2C1 | GPIO7 (SCL) | |
| センサ(BMP280 + AHT20) | I2C0 | GPIO8 (SDA) |
| I2C0 | GPIO9 (SCL) |
デモの様子
まとめ
本記事では以下のポイントを実装とともに紹介しました:
- cyw43_arch を中心とした Wi-Fi 接続 API の整理と実装例
- lwIP を安全に扱うための排他制御手法 cyw43_arch_lwip_begin/end
実装から得られた知見
- 単純なループ処理だけでなく、RTOSベースでタスクを整理することで処理分担が明確になる
- cyw43_arch は lwIP との融合が深く、排他制御を適切に扱うことが安定動作の鍵 となる
- dual-core の設計を活かし、無線処理とアプリ処理を分離 することで保守性・拡張性が向上
今後の展望
- HTTPS や MQTT などの上位プロトコル統合
- core1 側 RTOS タスクの増強(今はセンサとSW割り込みしか使ってない)
最後に
PicoWのWi-Fi+RTOS 実装は一見敷居が高いですが、デュアルコアで仕事を分けることで、実用的な IoT 基盤になると感じました。この記事が読者の開発の一助になれば幸いです!


