第3回で Raspberry Pi (以下 Pi) を起動して SSH で入れる状態にしました。今回は Pi に USB WiFi ドングルを 1 個追加 して、ESP センサー専用の無線 アクセスポイント (AP) を立てます。
Pi にはオンボードで WiFi (wlan0) が既に付いていますが、これは第5回で 「インターネット出口」として家や現場のルーターに繋ぐために使います。 今回追加する USB ドングル (wlan1) は ESP 側からの接続だけを受ける 独立した無線 として動かします。
- なぜ WiFi を 2 系統に分けるのか
- 全体像
- 用意するもの
- 【最重要】ドライバ選択の落とし穴 — 8821au と 8812au を間違えると発狂する
- この記事で決めておくアドレス設計
- 手順の流れ
- 1. USB ドングルの認識確認
- 2. ドライバのインストール
- 3. wlan1 を NetworkManager から切り離す
- 4. hostapd (AP 提供サービス) の設定
- 5. dnsmasq (DHCP サーバー) の設定
- 6. wlan1 に固定 IP 192.168.4.1 を設定
- 7. 再起動で自動立ち上げを確認
- 8. スマホから接続確認
- 3 層分離アーキテクチャの予告
- よくある失敗
- AI との会話例
- 補足: ヘッダ導入のフォールバック連鎖 (見やすい版)
- 次回予告
なぜ WiFi を 2 系統に分けるのか
1 系統 (オンボード WiFi のみ) でも技術的には可能ですが、実用上以下の 問題があります。
- ビル管理業務先など、勝手にネットワーク機器を挿せない環境で使えない: センサーを 1 台追加するために現場ネットワーク管理者に IP 予約を依頼する 運用は現実的ではありません。特に自社ビルでなく請負であればなおさらです。Pi 自身が AP を提供すれば、ビル所有者の ネットワークから完全独立して動きます
- ビル所有者側のセキュリティポリシーに引っかからない: ESP は WPA3 未対応など WiFi 認証方式が古く、企業ネットワークが受け付けない ことがあります。独立 AP なら Pi 側で認証設定を自由にできます
- 障害切り分けが楽: 「センサーが繋がらない」が起きたとき、Pi 内部の 問題か外部ネットワークの問題かが即判別できます
- アドレス設計を自分で決められる: 現場ネットワークの DHCP に介入できなくても、Pi が管理する
192.168.4.xの中で ESP のアドレスを自由に配置できます
全体像
構築後は以下の構成になります。

wlan0 と wlan1 は別の IP セグメント (192.168.11.x と 192.168.4.x) なので混線しません。ESP は 192.168.4.x の世界だけを見ます。
用意するもの
| 部品 | 型番 | 目安価格 | 入手先 |
|---|---|---|---|
| USB WiFi ドングル | TP-Link Archer T2U Plus (RTL8821AU 搭載) | 2,000〜2,500 円 | Amazon、ヨドバシ |
なぜ Archer T2U Plus か:
- チップ (RTL8821AU) が AP モード対応 で、有志ドライバの動作実績が 豊富
- 長いアンテナ が付いている (機械室・機械置場のように設備が林立して見通しの悪い場所では、この差がそのまま到達距離に出ます)
- 3,000 円以下で入手可能
- 本連載の手順で 動作確認済み (筆者が新規 SD で通し実行して検証)
注意: 他の USB WiFi ドングルを使うと、そもそも AP モードに対応していない、Raspberry Pi 用のドライバが存在しない、といった問題が高確率で発生します。「安いから」で無名メーカー品を選ばず、本連載と同じ Archer T2U Plus を入手するのが結局は近道です。
買う前に確認: Amazon の商品ページで「Archer T2U Plus」と表記されているものを選んでください。「Archer T2U」(Plus なし) は RTL8811AU 搭載で、実は同じ 8821au-20210708 ドライバで動きます。ただし本連載で実機検証したのは Plus 版だけなので、余計な変数を増やしたくなければ Plus を選んでください。
【最重要】ドライバ選択の落とし穴 — 8821au と 8812au を間違えると発狂する
本連載で 一番ハマる箇所 がここです。以下 1 点だけ必ず守ってください。
- ✅ 正解:
morrownr/8821au-20210708(v5.12.5.2) を使う - ❌ 不正解:
morrownr/8812au-20210820を使う (見た目そっくり、名前も似ている)
Archer T2U Plus のチップは RTL8821AU です。名前が似た RTL8812AU ではありません。
間違ったドライバ (8812au) を入れると起きること:
wlan1は認識される (ip linkで見える)- しかし hostapd (AP 起動サービス) を実行すると
Operation not permitted(EPERM) エラーで起動しない - ネットで検索すると「大抵の RTL8812AU 系は 8812au ドライバで動く」と 出てくるので、余計に沼にハマる
- 実機で試すまで気付かない (
lsmodは正常に見える)
これで時間を浪費した人が多数いるようです。私も AI に任せきりでハマりました。実績が有ると文字で伝えてもできないので止めましょうと返してくる。
旧・現場出動版は AI にコードを作ってもらい、USB ドングルを試行錯誤しながらも使えていたのですが、この記事用に検証用のガイドとコードを再生成してもらったら一向にドライバが通らず、挙句に AI が何度か「諦めます」と言い出しました。原因は結局これでした。
まず PowerShell で Pi にログインします。 ssh ユーザー名@IPアドレス (ホスト名でも構いません。例: ssh pi@takemetothehospital.local)

判別方法: USB ドングルを Pi に挿して以下を実行。
lsusb
以下のように表示されれば RTL8821AU です:
Bus 001 Device 004: ID 2357:0120 TP-Link Archer T2U PLUS [RTL8821AU]
[RTL8821AU] の表記があれば 8821au リポジトリを使います。似た型番の [RTL8812AU] が出た場合は本連載と別のドングルを掴んでいます。
この記事で決めておくアドレス設計
先に結論を出しておきます。ここを曖昧にしたまま進めると、第6回で ESP を繋いだときに IP がぶつかります。
| 範囲 | 用途 | 誰が決めるか |
|---|---|---|
192.168.4.1 | Pi 自身 (wlan1、ゲートウェイ) | 固定 |
192.168.4.100 〜 192.168.4.227 | ESP センサーの静的 IP | ESP が自分の MAC アドレスから自動生成 (第6回) |
192.168.4.228 〜 192.168.4.254 | DHCP 動的プール | dnsmasq (スマホでの動作確認など一時接続用) |
ESP 側は「MAC アドレスの下位 1 バイトから IP の第 4 オクテットを作る」方式にします。スケッチは全チップ共通のまま、書換えなしでコピペ書込みできて、しかも IP は重複しません。電池運用では DHCP の折衝時間 (1 回あたり 3〜5 秒) がそのまま電池寿命に効いてくるので、静的宣言にする意味があります。この話は第6回で詳しくやります。
今回の dnsmasq は「ESP 以外がたまたま繋いできたとき用」に残り 27 個を配るだけの役目になります。
手順の流れ
作業は以下の順序で進めます。
- USB ドングルを Pi に挿して認識確認
- ドライバ (
8821au-20210708) を DKMS でインストール wlan1を NetworkManager から切り離すhostapd(AP 提供サービス) を設定dnsmasq(DHCP サーバー) を設定wlan1に固定 IP192.168.4.1を設定- 再起動して自動起動を確認
作業は全て Pi の SSH セッション内で行います。ここからは PowerShell でコピペを繰り返すだけです。エラーが出たら、その出力をそのまま AI に食わせてください。何度も同じコマンドを要求されるようなら「同じことを繰り返しているので、しっかりネットで最新情報を調べて解説して」とでもプロンプトを入れてください。
1. USB ドングルの認識確認
USB ドングルを Pi に挿してから以下を実行:
lsusb
TP-Link Archer T2U PLUS [RTL8821AU] の行が出れば認識成功です。

出ない場合:
- USB ドングルを別の USB ポートに挿し替える (青い USB 3.0 ポートは 2.4GHz 帯にノイズを出すことが知られているので、黒い USB 2.0 ポートの方が無難です)
- USB 延長ケーブルを介している場合は直挿しに切替える
- Pi の電源を疑う (第3回で触れたとおり Pi 4B は 5.1V/3A、Pi 5 は 27W が推奨)
この段階では ip link に wlan1 はまだ表示されません。ドライバが 入っていないためです。次のステップで解決します。
2. ドライバのインストール
2.1 ビルドツールとカーネルヘッダの導入
まずビルドに必要な共通パッケージを入れます。2 行をそのまま順に実行:
sudo apt update
sudo apt install -y git build-essential bc dkms

次にカーネルヘッダを入れます。機種に合わせて 1 行だけ 実行して ください。
Pi 4B (64-bit Trixie) の場合:
sudo apt install -y linux-headers-rpi-v8

Pi 5 の場合:
sudo apt install -y linux-headers-rpi-2712
Pi 3B+ / 32-bit 版の場合:
sudo apt install -y linux-headers-rpi-v7l
自分の機種が分からない場合: 以下の 1 行で自動判定できます。5 つの 候補パッケージ名を順に試して、どれかが入れば成功します。上級者向けの 書き方です:
sudo apt install -y linux-headers-$(uname -r) || sudo apt install -y linux-headers-rpi-v8 || sudo apt install -y linux-headers-rpi-2712 || sudo apt install -y linux-headers-rpi-v7l || sudo apt install -y raspberrypi-kernel-headers
このコマンドは長いですが 1 行として貼付けてください (途中で改行 すると動きません)。改行入りで見やすくしたバージョンは記事末尾の 「補足」に載せています。
2.2 ドライバソースの取得と DKMS 登録
mkdir -p ~/src
cd ~/src
git clone https://github.com/morrownr/8821au-20210708.git
cd 8821au-20210708
sudo ./install-driver.sh
対話プロンプトが 2 回出ます。
- ドライバオプションファイルを編集するか →
n(デフォルトのまま) - 再起動するか →
y
Pi が自動で再起動し、SSH セッションは切れます。1〜2 分待って再度 SSH で入り直してください。うっかり編集の方に y と答えて nano エディタに入ってしまっても、Ctrl + X で抜けられます。

再起動します。

もう一度ログインしてください。

2.3 ドライバ認識の確認
# 1) ドライバがロードされているか
lsmod | grep 8821au
# → 8821au xxxxxxx 0 のような行が出れば OK
# 末尾の 0 は「これに依存する他モジュールが無い」の意味で、正常です
# 2) wlan1 が認識されているか
ip link show wlan1
# → wlan1: <BROADCAST,MULTICAST> ... のような行が出れば OK
# 3) 正しいドライバが割当てられているか (最重要)
readlink /sys/class/net/wlan1/device/driver
# → 末尾が rtl8821au なら正解
# 末尾が rtl8812au だったら間違ったリポジトリを入れています。
# 誤ったソースディレクトリで sudo ./remove-driver.sh を実行し、
# ソースを消してから §2.2 をやり直してください
3 つの確認が全て通れば、ドライバ導入は完了です。

3. wlan1 を NetworkManager から切り離す
デフォルトでは NetworkManager (Pi の WiFi 管理サービス) が wlan1 も 管理しようとします。これを放置すると次ステップの hostapd と競合して AP が立ち上がりません。以下で wlan1 を管理対象から外します。
3.1 設定ファイルを作成 (nano エディタを使う方法)
手順 1: nano エディタで新規ファイルを開く
sudo nano /etc/NetworkManager/conf.d/99-unmanaged-wlan1.conf
真っ黒な画面 (nano エディタ) が開きます。画面下部に ^X 終了 ^O 書き込み 等のメニューが出ています (^ は Ctrl キー)。

手順 2: 以下の 2 行を貼り付ける
[keyfile]
unmanaged-devices=interface-name:wlan1
貼付は SSH の場合は右クリック (または Ctrl+Shift+V)、Pi 上の LXTerminal ならマウスで選択 → 中クリック貼付、または Ctrl+Shift+V。

手順 3: 保存して閉じる
Ctrl + O(書き込み) → Enter (ファイル名確認、そのまま Enter)Ctrl + X(nano を終了)
手順 4: NetworkManager に設定を再読み込みさせる
sudo systemctl reload NetworkManager
確認:
sleep 1
nmcli device status
# wlan1 の行が unmanaged になっていれば OK

4. hostapd (AP 提供サービス) の設定
4.1 パッケージ導入
sudo apt install -y hostapd
sudo systemctl unmask hostapd
hostapd is already the newest version と表示されることがありますが、既に入っているだけなので問題ありません。
4.2 hostapd 設定ファイル
sudo tee /etc/hostapd/hostapd.conf > /dev/null << 'EOF'
interface=wlan1
driver=nl80211
ssid=YOUR_AP_SSID_HERE
country_code=JP
hw_mode=g
channel=6
wmm_enabled=1
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_passphrase=YOUR_AP_PASSWORD_HERE
wpa_key_mgmt=WPA-PSK
wpa_pairwise=CCMP
EOF
# パスフレーズが平文で入っているので他ユーザーから隠す
sudo chmod 600 /etc/hostapd/hostapd.conf
YOUR_AP_SSID_HERE と YOUR_AP_PASSWORD_HERE を実際の値に書換えてください。SSID は任意 (例: SensorNet-Bldg1)、パスワードは 8 文字以上の任意文字列にします。この SSID/パスワードは後で ESP スケッチにも書きます (第6回で扱います)。

| キー | 値 | 意味 |
|---|---|---|
country_code | JP | 日本の電波法に合わせて使えるチャンネルと出力が決まる。無くても 2.4GHz の ch1〜11 なら起動してしまうことがあるが、国内で電波を出す以上は必ず書く。ドライバによっては未設定だと Could not initialise hostapd interface で起動に失敗する |
hw_mode=g + channel=6 | 2.4GHz 11g | ESP-WROOM-02 は 2.4GHz のみ対応のため |
wpa=2 | WPA2-PSK | ESP 側と一致させる |
wpa_pairwise=CCMP | AES/CCMP のみ | TKIP は非推奨。wpa=2 では実際に効くのは CCMP 側なので、TKIP の行を混ぜても動きはするが紛らわしいので書かない |
macaddr_acl=0 | MAC 制限なし | 全 MAC 接続許容 |
4.3 デフォルト設定ファイルへのパス指定
sudo sed -i 's|^#DAEMON_CONF=.*|DAEMON_CONF="/etc/hostapd/hostapd.conf"|' /etc/default/hostapd
4.4 サービス有効化と起動
sudo systemctl enable hostapd
sudo systemctl start hostapd
sudo systemctl status hostapd --no-pager
期待する出力:
Active: active (running)の緑文字- ログの中に
AP-ENABLEDの行 - ログの中に
UNINITIALIZED->COUNTRY_UPDATEとCOUNTRY_UPDATE->ENABLEDの 2 行

COUNTRY_UPDATE という状態遷移は、country_code が設定されているときにだけ現れます。この行が無く UNINITIALIZED->ENABLED と一段で飛んでいる場合は、国コードが読まれていません。hostapd.conf に country_code=JP の行があるか、sudo systemctl restart hostapd で設定を読み直したか (start は既に動いているサービスには効きません) を確認してください。
Active: failed の場合: ここまでの手順のどこかで問題があります。 まず以下を確認してください。
sudo journalctl -u hostapd -n 50 --no-pager
エラー文言を確認します。Operation not permitted が出ていれば ドライバが 8812au になっている可能性が濃厚 です。§2.3 の確認 3 に戻ってください。Could not initialise hostapd interface が出ていれば country_code=JP の行が抜けていないか確認してください。
5. dnsmasq (DHCP サーバー) の設定
5.1 パッケージ導入
sudo apt install -y dnsmasq

5.2 dnsmasq 設定ファイル
sudo tee /etc/dnsmasq.d/wlan1.conf > /dev/null << 'EOF'
interface=wlan1
domain-needed
bogus-priv
# 動的プールは .228〜.254 だけ。
# .100〜.227 は ESP が MAC から自動生成して自己宣言する静的 IP 用に空けておく
dhcp-range=192.168.4.228,192.168.4.254,255.255.255.0,24h
dhcp-option=option:router,192.168.4.1
dhcp-option=option:dns-server,8.8.8.8,8.8.4.4
EOF
設計方針の背景:
192.168.4.100〜227は ESP 用に空けておく。ESP は自分の MAC アドレスから IP を自動生成して名乗るので、スケッチは全チップ共通のままで重複しません (第6回で扱います)192.168.4.228〜254だけを DHCP の動的プールにする。スマホでの動作確認など、一時的に何かを繋ぐとき用ですbind-interfacesは書きません。付けると dnsmasq が起動時点でwlan1が上がっていることを要求し、systemd の起動順序に依存して不安定になります。interface=wlan1があるので、指定しなくても DHCP はwlan1側にしか出ませんdhcp-optionの 2 行が無いと、クライアントにゲートウェイと DNS が渡りません。スマホが「インターネットに接続されていません」と判断して勝手に切断することがあるので、動作確認のためにも入れておきます
5.3 サービス有効化と起動
sudo systemctl enable dnsmasq
sudo systemctl start dnsmasq
sudo systemctl status dnsmasq --no-pager
Active: active (running) が出れば OK。

6. wlan1 に固定 IP 192.168.4.1 を設定
wlan1 (AP 側インターフェース) は自分自身が「ゲートウェイ」なので、 192.168.4.1 という固定 IP を持たせます。systemd unit で起動時に自動 設定するようにします。
sudo tee /etc/systemd/system/wlan1-static-ip.service > /dev/null << 'EOF'
[Unit]
Description=Assign static IP to wlan1 for AP
After=NetworkManager.service
Before=hostapd.service dnsmasq.service
[Service]
Type=oneshot
ExecStart=/usr/sbin/ip addr flush dev wlan1
ExecStart=/usr/sbin/ip addr add 192.168.4.1/24 dev wlan1
ExecStart=/usr/sbin/ip link set wlan1 up
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable wlan1-static-ip.service
sudo systemctl start wlan1-static-ip.service
確認:
ip addr show wlan1
# inet 192.168.4.1/24 の行があれば OK

7. 再起動で自動立ち上げを確認
sudo reboot
再度 SSH で入り直して、以下を全て確認します。
# wlan1 に静的 IP が付いているか
ip addr show wlan1 | grep 'inet '
# hostapd が動いているか
systemctl is-active hostapd
# dnsmasq が動いているか
systemctl is-active dnsmasq
3 つとも active または inet 192.168.4.1/24 が出れば、電源を入れる だけで AP が自動で立ち上がる状態が完成しています。

8. スマホから接続確認
ご自身のスマホの WiFi 設定で SSID YOUR_AP_SSID_HERE (書換えた値) が見えるはずです。パスワードを入れて接続してください。
- 接続が成功する
- スマホの WiFi 詳細で IP アドレスが
192.168.4.228〜192.168.4.254の範囲で割当てられている
の 2 点が確認できれば、AP は完成です。この時点でスマホ側からインターネットには出られません。DNS だけは配っているので「インターネットなし」の警告は出にくいはずですが、実際の外向き通信はまだ通りません。次回 (第5回) で wlan0 (オンボード WiFi) をインターネット出口として設定します。
3 層分離アーキテクチャの予告
ここで決めたアドレス設計は、本連載で「3 層分離アーキテクチャ」と呼んでいる考え方の一部です。
| レイヤー | 何を決めるか | 誰が決めるか |
|---|---|---|
| 識別 | このチップは物理的にどれか | ESP 自身 (MAC から ESP-A1B2C3 のような ID を自動生成) |
| ネットワーク | どの IP で繋がるか | ESP 自身 (MAC から 192.168.4.100〜227 を自動生成) |
| 表示 | 人間が何と呼ぶか | Pi 上のダッシュボード (「冷却塔1」などの表示名を後から付ける) |
この 3 つを分けておくと、ESP のスケッチは全チップ共通で、1 文字も書換えずにコピペ書込みできます。チップを増やすときも、壊れて交換するときも、Pi 側の作業だけで済みます。詳細は第6回 (ESP 側) と第8回 (Flask サーバー側) で扱います。
よくある失敗
| 症状 | 原因 | 対処 |
|---|---|---|
lsusb に Archer T2U Plus が出ない | USB 電力不足 or ケーブル不良 | 別の USB ポート、直挿し、電源を疑う |
ip link に wlan1 が出ない | ドライバ未インストール、または自動ロード前 | §2 を実行。それでも出なければ sudo modprobe 8821au |
wlan1 は出るが hostapd が起動しない (Operation not permitted) | 8812au ドライバを誤って入れた | §2.3 の確認 3 で rtl8821au を指しているか確認、必要なら入替え |
hostapd 起動時に Could not initialise hostapd interface | country_code=JP が無い | §4.2 の設定を再確認 |
| hostapd 起動時に “could not configure driver mode” | wlan1 が NetworkManager 管理下のまま | §3 の unmanaged 設定を確認 |
| スマホから SSID が見えない | hostapd 未起動 or channel/hw_mode 設定不整合 | systemctl status hostapd でエラー確認 |
| スマホは SSID に繋がるが IP が付かない | dnsmasq 未起動、または wlan1 に IP が無い | sudo systemctl status dnsmasq と ip -4 addr show wlan1 を確認 |
| スマホが繋がってすぐ切れる | DHCP でゲートウェイ/DNS を配っていない | §5.2 の dhcp-option 2 行があるか確認 |
| 再起動後に AP が立ち上がらない | サービスの enable 忘れ | systemctl is-enabled wlan1-static-ip hostapd dnsmasq で確認 |
AI との会話例
このセットアップは工程が多く、途中で詰まりやすいです。詰まったら AI にはこう聞くと通じます。
Raspberry Pi 4B (Trixie 64-bit Desktop) に TP-Link Archer T2U Plus (RTL8821AU) を挿して独立 AP を立てたい。morrownr/8821au-20210708 を DKMS でインストール済み。lsmod | grep 8821au で
8821auが 表示される。ip link show wlan1 は出る。しかしsudo systemctl start hostapdすると status が failed になる。 journalctl -u hostapd -n 20 の出力は以下: [ここにテキストを貼る] 原因は何が考えられる?
「チップ名」「使ったドライバのリポジトリ名」「エラーメッセージ (スクショではなくテキスト)」の 3 つを揃えて聞くのがコツです。
補足: ヘッダ導入のフォールバック連鎖 (見やすい版)
§2.1 で紹介した「機種が分からない人向け」の 1 行コマンドは、bash の \ (行継続) 記法を使うと以下のように改行して見やすく書けます。ただし 貼付け時に \ の直後が改行のみ (半角スペース混入なし) である必要があり、貼付け方式によっては壊れることがあります。仕組みを理解している方向けです。
sudo apt install -y linux-headers-$(uname -r) || \
sudo apt install -y linux-headers-rpi-v8 || \
sudo apt install -y linux-headers-rpi-2712 || \
sudo apt install -y linux-headers-rpi-v7l || \
sudo apt install -y raspberrypi-kernel-headers
|| の意味: 前のコマンドが失敗したら次を試す。5 つ全部失敗した場合のみ、最終的にエラーになります。うち 1 つでも成功すれば、それ以降は実行されません。
次回予告
第5回は今回作った AP 側 (wlan1) はそのままで、もう片方の wlan0 (オンボード WiFi) を家/現場のルーターに繋いでインターネット出口として 設定 します。実は第3回の Imager 設定で既にほぼ済んでいますが、静的 IP 化と現場での SSID 切替え運用について整理します。


コメント