If you are trying to configure a raspberry pi wifi access point on modern Raspberry Pi OS (Bookworm or newer), the old tutorials using hostapd and dhcpcd will break your network stack. Raspberry Pi OS has migrated to NetworkManager as the default network configuration tool. To set up a reliable access point (AP) today, you must use the nmcli command-line interface. This guide walks through the exact hardware, the modern nmcli configuration, a Python GPIO status monitor, and the specific failure modes you will encounter on the bench.
Hardware Spec Sheet and Board Variant Target
This guide and the accompanying code specifically target the Raspberry Pi 5 (8GB variant) running Raspberry Pi OS Bookworm (64-bit). While the networking commands apply to the Pi 4 and Pi 3B+, the Pi 5’s power delivery and thermal profile require specific component choices for a 24/7 access point deployment.
Estimated Time: 45 minutes
Parts List
| Component | Exact Variant / Specification | Notes |
|---|---|---|
| Microcontroller | Raspberry Pi 5 (8GB RAM) | Target board for this guide. Infineon CYW43455 dual-band 802.11ac WiFi chip. |
| Power Supply | Official Raspberry Pi 27W USB-C PD | Required to prevent brownouts when WiFi TX spikes under load. |
| Cooling | Raspberry Pi Active Cooler | Mandatory for Pi 5 in enclosed AP deployments to prevent thermal throttling. |
| Storage | SanDisk 64GB Max Endurance MicroSD | Standard SD cards fail from constant DHCP lease logging. Use high-endurance. |
| Status LED | 5mm Green LED + 330Ω Resistor | For the Python GPIO monitoring script. |
| Debug Header | Standard 3-pin JST or dupont wires | For UART serial console access when headless WiFi fails. |
For deeper hardware specifications, refer to the official Raspberry Pi 5 documentation.
Pin Mapping for Debug UART and Status LED
When running a headless access point, losing SSH access means you need a hardware fallback. We map the primary UART for serial console debugging and a dedicated GPIO pin for an AP status LED. Wire these before sealing the Pi in its enclosure.
| Function | Pi 5 Physical Pin | BCM GPIO Number | Wiring Destination |
|---|---|---|---|
| UART TX (Debug) | Pin 8 | GPIO 14 | USB-to-TTL Adapter RX |
| UART RX (Debug) | Pin 10 | GPIO 15 | USB-to-TTL Adapter TX |
| Ground (UART) | Pin 6 | GND | USB-to-TTL Adapter GND |
| AP Status LED (+) | Pin 11 | GPIO 17 | 330Ω Resistor → LED Anode |
| AP Status LED (-) | Pin 9 | GND | LED Cathode |
Configuring the Access Point via NetworkManager
Forget editing /etc/dhcpcd.conf. In Bookworm, NetworkManager owns the interfaces. We will create a shared IPv4 connection profile that turns the wlan0 interface into a DHCP server and access point automatically.
Step-by-Step Setup
- Update the OS and enable predictable network interface names:
sudo apt update && sudo apt full-upgrade -y
sudo raspi-config(Navigate to Advanced Options → Network Interface Names → Enable predictable names. Reboot). - Create the AP connection profile using nmcli:
sudo nmcli connection add type wifi ifname wlan0 con-name PiAP autoconnect yes ssid "FluxNet_AP" - Set the connection to shared mode (this enables the built-in DHCP server):
sudo nmcli connection modify PiAP ipv4.method shared ipv4.addresses 192.168.4.1/24 - Configure WiFi security (WPA2-PSK):
sudo nmcli connection modify PiAP wifi-sec.key-mgmt wpa-psk wifi-sec.psk "SuperSecretPassword123" - Set the WiFi mode to AP and define the band:
sudo nmcli connection modify PiAP 802-11-wireless.mode ap 802-11-wireless.band bg - Bring the connection up:
sudo nmcli connection up PiAP
ipv4.method shared flag is the magic switch. It tells NetworkManager to automatically launch an internal dnsmasq instance to hand out IP addresses to connected clients. Do not install or configure dnsmasq manually, or you will create port 53 conflicts.
Python Status Monitor with Error Handling
Headless access points need physical feedback. This Python script uses the gpiozero library to monitor the PiAP connection state via nmcli and drives the LED on GPIO 17. It includes robust error handling for subprocess failures and GPIO cleanup.
#!/usr/bin/env python3
import subprocess
import time
import sys
from gpiozero import LED
from signal import pause
# --- PIN DEFINITIONS ---
AP_STATUS_LED_PIN = 17
# Initialize LED on GPIO 17
status_led = LED(AP_STATUS_LED_PIN)
def get_ap_status():
"""Queries NetworkManager for the active state of the PiAP connection."""
try:
result = subprocess.run(
['nmcli', '-g', 'GENERAL.STATE', 'connection', 'show', 'PiAP'],
capture_output=True, text=True, check=True
)
state = result.stdout.strip()
return 'activated' in state.lower()
except subprocess.CalledProcessError as e:
print(f"[ERROR] nmcli command failed: {e.stderr.strip()}")
return False
except FileNotFoundError:
print("[CRITICAL] nmcli not found. Is NetworkManager installed?")
sys.exit(1)
def main():
print(f"Starting AP Monitor on GPIO {AP_STATUS_LED_PIN}...")
try:
while True:
if get_ap_status():
status_led.on() # Solid ON = AP is broadcasting and active
else:
status_led.blink(on_time=0.2, off_time=0.2) # Fast blink = AP down
time.sleep(2)
except KeyboardInterrupt:
print("\nMonitor stopped by user.")
except RuntimeError as e:
print(f"[ERROR] GPIO hardware failure: {e}")
finally:
# Ensure GPIO resources are released safely
status_led.off()
status_led.close()
print("LED cleanup complete.")
if __name__ == '__main__':
main()
Save this as ap_monitor.py, make it executable (chmod +x ap_monitor.py), and add it to your systemd services or rc.local for boot persistence.
Debugging: "No Suitable Device Found" and Other Failures
The most common point of failure when building a raspberry pi wifi access point on Bookworm is interface management conflicts. If you run sudo nmcli connection up PiAP and receive this exact error string:
Error: Connection 'PiAP' activation failed: No suitable device found for this connection.
The First Three Things to Check
- Check for RF-Kill Blocks: The Broadcom/Infineon WiFi chip can be soft-blocked by the kernel. Run
rfkill list. If you seeSoft blocked: yesfor Wireless LAN, runsudo rfkill unblock wifi. - Verify NetworkManager Ownership: Run
nmcli device status. Ifwlan0shows asunmanaged, another service (like a leftoverdhcpcdorwpa_supplicantconfig) is holding the interface. Disable legacy services:sudo systemctl disable dhcpcdand reboot. - Check for Firmware Crashes: The CYW43455 chip occasionally drops off the SDIO bus under heavy thermal load. Run
dmesg | grep brcmfmac. If you seebrcmfmac: brcmf_sdio_htclk: HT Avail timeout, your Pi is overheating or your power supply is sagging. Check your Active Cooler seating and PSU wattage.
Extending and Simplifying the Build
To Simplify: If you don't need the Python GPIO monitor, you can delete the script and rely entirely on the nmcli commands. You can also drop the UART debug header if you have a micro-HDMI cable handy for emergency local access.
To Extend:
- Captive Portal: To force users to a landing page, install
NodogsplashorOpenNDSviaapt. Bind it to thewlan0interface. NetworkManager's shared mode works seamlessly with OpenNDS's NAT routing. - Dual-Band Routing: The Pi 5's internal WiFi is great for 2.4GHz/5GHz client connections, but if you need dedicated backhaul, plug in a USB WiFi adapter (like an Alfa AWUS036ACH), assign it as
wlan1, and route internet from an Etherneteth0connection out to the USB AP.
Frequently Asked Questions
Can I use a Raspberry Pi as a WiFi access point and connect to the internet at the same time?
Yes, but with a major caveat regarding the internal WiFi chip. The Raspberry Pi's internal Infineon/Broadcom chip cannot simultaneously act as an AP and a client (station mode) on different channels without severe latency and packet drops. If you need the Pi to connect to your home WiFi for internet while broadcasting its own AP, you must use the internal chip for the AP and plug in a USB WiFi dongle to connect to your home router as a client. Alternatively, use Ethernet (eth0) for the internet uplink, which is the most stable configuration.
Why is my Raspberry Pi WiFi access point dropping clients randomly?
Random client drops on a Pi AP are almost always caused by power management features putting the WiFi chip to sleep, or thermal throttling. First, disable WiFi power management by creating a NetworkManager dispatcher script or running sudo iw dev wlan0 set power_save off. Second, monitor the Pi's temperature using vcgencmd measure_temp. If it crosses 80°C, the SoC throttles, causing SDIO bus timeouts that drop the WiFi firmware. Ensure you are using the official Active Cooler.
How do I change the Raspberry Pi WiFi access point password without a monitor?
If you are locked out or headless, SSH into the Pi (or use the UART debug header mapped in the pin table) and run a single nmcli command to update the pre-shared key and restart the connection:
sudo nmcli connection modify PiAP wifi-sec.psk "NewPassword456" && sudo nmcli connection up PiAP.
This updates the NetworkManager profile on the fly without requiring a reboot or manual file editing.






