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.

Difficulty Rating: Intermediate (Requires comfort with Linux CLI and basic GPIO wiring)
Estimated Time: 45 minutes

Parts List

ComponentExact Variant / SpecificationNotes
MicrocontrollerRaspberry Pi 5 (8GB RAM)Target board for this guide. Infineon CYW43455 dual-band 802.11ac WiFi chip.
Power SupplyOfficial Raspberry Pi 27W USB-C PDRequired to prevent brownouts when WiFi TX spikes under load.
CoolingRaspberry Pi Active CoolerMandatory for Pi 5 in enclosed AP deployments to prevent thermal throttling.
StorageSanDisk 64GB Max Endurance MicroSDStandard SD cards fail from constant DHCP lease logging. Use high-endurance.
Status LED5mm Green LED + 330Ω ResistorFor the Python GPIO monitoring script.
Debug HeaderStandard 3-pin JST or dupont wiresFor 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.

FunctionPi 5 Physical PinBCM GPIO NumberWiring Destination
UART TX (Debug)Pin 8GPIO 14USB-to-TTL Adapter RX
UART RX (Debug)Pin 10GPIO 15USB-to-TTL Adapter TX
Ground (UART)Pin 6GNDUSB-to-TTL Adapter GND
AP Status LED (+)Pin 11GPIO 17330Ω Resistor → LED Anode
AP Status LED (-)Pin 9GNDLED 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

  1. 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).
  2. Create the AP connection profile using nmcli:
    sudo nmcli connection add type wifi ifname wlan0 con-name PiAP autoconnect yes ssid "FluxNet_AP"
  3. 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
  4. Configure WiFi security (WPA2-PSK):
    sudo nmcli connection modify PiAP wifi-sec.key-mgmt wpa-psk wifi-sec.psk "SuperSecretPassword123"
  5. 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
  6. Bring the connection up:
    sudo nmcli connection up PiAP
Callout Tip: The 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

  1. Check for RF-Kill Blocks: The Broadcom/Infineon WiFi chip can be soft-blocked by the kernel. Run rfkill list. If you see Soft blocked: yes for Wireless LAN, run sudo rfkill unblock wifi.
  2. Verify NetworkManager Ownership: Run nmcli device status. If wlan0 shows as unmanaged, another service (like a leftover dhcpcd or wpa_supplicant config) is holding the interface. Disable legacy services: sudo systemctl disable dhcpcd and reboot.
  3. Check for Firmware Crashes: The CYW43455 chip occasionally drops off the SDIO bus under heavy thermal load. Run dmesg | grep brcmfmac. If you see brcmfmac: 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 Nodogsplash or OpenNDS via apt. Bind it to the wlan0 interface. 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 Ethernet eth0 connection out to the USB AP.
For advanced network routing configurations, consult the Raspberry Pi NetworkManager documentation.

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.