WLAN Commander  /  sensor image  /  v1.0.7

NanoPi Zero2Wi-Fi 7 capture sensor

An Armbian image that turns a FriendlyElec NanoPi Zero2 and an M.2 Wi-Fi card into a headless scanning and packet-capture sensor. It runs mainline Linux 7.3, so the Intel BE200 uses the kernel's own iwlmld driver rather than an out-of-tree backport, and four other Wi-Fi 6E and Wi-Fi 7 chipsets work without a driver being built per card.

Kernel7.3.0-rc1-bleedingedge-rockchip64
BoardNanoPi Zero2 · Rockchip RK3528
BaseArmbian · Debian trixie
Image419 MB compressed
Built7 September 2026
Download v1.0.7 .img.xz · 419 MB
sha256 6e3c08ac97cc4e71ec6bacdedeeb43fef7dd0d196a85e383e3a5d1ca1931a494

Band coverage by card

US domain · 2400–7125 MHz
2.4 GHz 5 GHz 6 GHz ISM U-NII-1 2A U-NII-2C U-NII-3 U-NII-5 6 U-NII-7 U-NII-8 2400 5150 5895 5925 7125 Intel BE200 M.2 Key-E · iwlmld 160 MHz 160 MHz MediaTek MT7925U USB · mt7925u 160 MHz 160 MHz MediaTek MT7921U USB · mt7921u 80 MHz 160 MHz Qualcomm WCN7850 M.2 · ath12k 160 MHz 320 MHz Realtek RTL8922AU USB · rtw89 160 MHz 160 MHz One linear scale throughout, 0.373 px per MHz. Only the unallocated spectrum between bands is removed.
40 MHz 80 MHz 160 MHz 320 MHz Driver ships, not run on hardware here

Widths are the documented maxima for 5 and 6 GHz capture. The 2.4 GHz segment is only 83.5 MHz wide at this scale, so it carries no label. No USB card here reaches 320 MHz; on this image that width exists only on the PCIe Qualcomm part.

What was measured on hardware

3 September 2026
Subject Result Evidence Status
Intel BE200 Binds iwlmld with firmware core 106 6 GHz capture on channel 165, an AP at −32 dBm Verified
MediaTek MT7921U Capture on all three bands, first attempt 91, 114 and 108 beacons on 2.4, 5 and 6 GHz Verified
MediaTek MT7925U Capture to 160 MHz 136 beacons on 6 GHz once the domain was set Verified
Ethernet Gigabit link through the RTL8211F PHY Link negotiated at 1000 Mb/s, DHCP lease taken Verified
USB-C gadget NCM ethernet, MACs pinned to the board serial Host reaches the sensor at 198.18.42.1 Verified
Capture without sudo dumpcap holds its own capabilities cap_net_admin,cap_net_raw=eip Verified
Qualcomm WCN7850 Driver and firmware ship in the image No card on hand; 320 MHz unproven Not tested
Realtek RTL8922AU Driver and firmware ship in the image No card on hand Not tested

Set the country, or lose 6 GHz

/etc/modprobe.d/cfg80211-regdom.conf

The kernel starts in the world domain, and the world domain has no 6 GHz allocation at all. Intel cards are self-managed and learn their own domain from a scan, so a BE200 never notices. Every other card follows the global domain and silently loses the band.

Measured here with both cards in the same sensor: the MT7925U refused to tune 6775 MHz and scanned zero 6 GHz access points, while the BE200 beside it found 21. After the domain was set the same adapter tuned 6775 MHz and captured 136 beacons, and the Intel radio stayed self-managed with no firmware errors. The image ships ieee80211_regdom=US. It is a regulatory setting, so change it to match where the sensor physically is.

What is in the image

Debian trixie · minimal

It behaves like a WLANPi

Account wlanpi, blanket passwordless sudo, and the same mDNS advertisement, so WLAN Commander's Add Device screen finds it with nothing retyped.

Capture without sudo

dumpcap carries its own capabilities and wlanpi is in the wireshark group, which is what third-party survey apps expect.

USB-C is a whole sensor link

One cable to a laptop gives an ethernet interface at 198.18.42.1, so a unit in a case is reachable when the network is not. That is WLANPi's own addressing, on reserved space that cannot collide with the host's network. Both gadget MAC addresses are derived from the board serial, so two sensors on one laptop cannot collide and neither exhausts the DHCP pool. It is an NCM ethernet gadget only, so the console is the UART header.

6 GHz stays unlocked

The image brings up mon0 at boot and then leaves the radio alone. That is what keeps all 110 frequencies available on a clean boot, to 7115 MHz; scanning for regulatory at boot instead costs 69 of them, 6 GHz among them.

Named for the board, not the card

Each unit comes up as WC-nanopi-<last 3> from the SoC serial, so a reflashed sensor keeps the name it had. The _wlanpi._tcp mDNS record is what WLAN Commander's Add Device screen matches on.

It measures its own SD card

wc-storage-check times a 32 MiB write once per boot and publishes a verdict to /run/wlan-commander/storage.json. Idle I/O priority, and it will not run while tcpdump is alive.

Losing power is not an event

A sensor is switched off by pulling its cable, so the filesystem comes up dirty routinely. fsck.repair=yes means that is repaired at boot rather than dropping a headless unit into an emergency shell with no way in.

Orb Sensor, unclaimed

Orb 1.5.5 starts on first boot and appears in the Orb app on the same network. Every flashed card is a distinct sensor, never a clone of the build host.

The build refuses to ship broken

Two gates fail the build outright: one on drivers, firmware, the device tree and boot glue, one on the finished filesystem. A missing M.2 slot cannot reach a card.

Provenance travels with it

Each image carries a .build-info naming the source commit, the Armbian commit, the kernel branch and whether the tree was clean.

Flash it and boot it

microSD · 8 GB or larger
01

Write the card

Any standard imaging tool reads the .img.xz directly. From a shell:

# Replace /dev/sdX with the card. The wrong device loses its data.
xz -dc wlan-commander-nanopi-zero2-v1.0.7-bleedingedge.img.xz \
  | sudo dd of=/dev/sdX bs=4M status=progress conv=fsync
02

First boot takes about two minutes

The root filesystem resizes and the board reboots once on its own. Look for it on mDNS after that, not before. The hostname comes from the SoC serial rather than the card, so a reflashed sensor keeps the name it had.

03

Log in

User wlanpi, password wlanpi, over the network or straight down the USB-C cable at ssh wlanpi@198.18.42.1. No SSH key is installed.

A reflash resets the password and removes any key you added by hand. Change the password before putting a unit on a network you do not control.

04

The monitor interface is already there

mon0 is created at boot and nothing else happens to it. The image runs no regulatory scan of its own — that was the fault, not the fix, and WLAN Commander does the scan correctly with the target frequency known. To tune one by hand:

sudo wc-monitor up 6775 160

Why the move off 6.1 was hard

Six builds to a working image

Mainline is not missing this board. It is missing exactly the pieces a sensor needs, and the old image was welded to the vendor kernel at every joint.

The M.2 slot does not exist upstream

PCIe on the Zero2 comes only from an out-of-tree Armbian patch. If that patch fails to apply the card silently is not there, and a failed patch is only a warning. The build now decompiles the device tree and fails unless the PCIe node reads okay.

No Armbian config enables the BE200 driver

CONFIG_IWLMLD has no default, and from 6.18 the BE200 sits behind it. Without the symbol the log says no config was found for the PCI device, which reads like a broken card rather than a missing kernel option.

Firmware has a narrow accepted range

The 7.3 driver loads core-named files from c102 to c107. The 6.18 kernel tops out at c99, so no amount of firmware makes that branch work, which is why the build refuses it outright instead of producing a dead image.

This kernel branch is not one the board supports

The board file only recognises two branches, so a 7.3 image inherits the vendor device-tree name and a console on the wrong UART. That is a board that boots to silence. The image supplies its own boot glue and then checks the result.

User patches do not override core patches

The patcher keys on filename and reads the core directory last, so core wins. An Armbian patch for an unrelated Orange Pi board, space-indented against a tab-indented file, killed the kernel build until a corrected copy could be forced over it.

Nothing upstream watches the temperature

The vendor kernel throttles at 95 °C and cuts power at 120 °C. Mainline has no thermal zone for this SoC at all and runs the top operating point regardless, so case temperature under sustained capture is measured by hand.