If you are asking does the Raspberry Pi have WiFi, the short answer is yes—every mainstream model released since 2016 includes onboard wireless networking. However, the type of WiFi (single-band vs. dual-band), the antenna architecture, and the underlying OS network stack have changed drastically. If you are following a tutorial from 2021 that tells you to edit wpa_supplicant.conf or use the RPi.GPIO library on a modern board, your project will fail before it starts.

This guide breaks down exactly which boards have what WiFi capabilities, provides a decision framework to pick your hardware, and walks through a complete, modern Python build with real-world debugging for the current Raspberry Pi OS network stack.

The Short Answer: Which Raspberry Pi Models Have WiFi?

Not all WiFi is created equal. A Pi Zero 2 W trying to stream a camera feed over 2.4GHz WiFi will bottleneck, while a Pi 5 on a 5GHz network will handle it easily. Here is the exact hardware spec sheet for modern boards.

Board Variant WiFi Standard Bands Supported Antenna Type Best Use Case
Raspberry Pi 5 (4GB/8GB) WiFi 5 (802.11ac) 2.4 GHz & 5 GHz Onboard PCB trace + external U.FL pad High-bandwidth IoT, local servers, camera streaming
Raspberry Pi 4 Model B WiFi 5 (802.11ac) 2.4 GHz & 5 GHz Onboard PCB trace Desktop replacement, media centers, moderate IoT
Raspberry Pi Zero 2 W WiFi 4 (802.11n) 2.4 GHz ONLY Onboard PCB trace Battery-powered sensors, low-profile embedded nodes
Raspberry Pi 3 B+ WiFi 5 (802.11ac) 2.4 GHz & 5 GHz Onboard PCB trace Legacy projects (discontinued but widely available)
Raspberry Pi 1, 2, Zero 1 None N/A N/A Requires external USB WiFi dongle

Decision Path: Picking the Right Board for Your WiFi Project

Don't just grab the cheapest board. Use this decision tree to lock in your hardware choice based on your project's network and power requirements.

  • IF your project requires streaming video, hosting a local web dashboard, or transferring large CSV logs THEN you need dual-band 5GHz to avoid 2.4GHz congestion. Pick: Raspberry Pi 5 (8GB) or Pi 4 Model B.
  • IF your project is a remote environmental sensor running on a LiPo battery via a UPS HAT THEN you need minimal quiescent current draw, and 2.4GHz is fine for small JSON payloads. Pick: Raspberry Pi Zero 2 W.
  • IF your project is in a metal enclosure or a location with weak signal THEN you need an external antenna port. Pick: Raspberry Pi 5 (and solder a U.FL connector to the unpopulated pad, or use a PoE+ HAT for wired fallback).
Concrete Default Pick: If you are building a general-purpose embedded WiFi project and want the fewest hardware headaches, buy the Raspberry Pi 5 (8GB). It has the best WiFi silicon, handles modern NetworkManager configurations natively, and won't bottleneck on CPU when encrypting TLS traffic.

Project Build: WiFi-Connected GPIO Status Beacon

To prove your WiFi is working and debug connection drops without needing a monitor attached, we will build a hardware status beacon. This script pings a reliable external endpoint over your WiFi connection and drives a physical LED based on the network health.

Parts List

  • Board: Raspberry Pi 5 (8GB) running Raspberry Pi OS 64-bit (Bookworm or newer)
  • Storage: SanDisk Extreme 64GB microSD (A2 rating for OS responsiveness)
  • Component: Standard 5mm Red LED
  • Component: 330Ω through-hole resistor (1/4W)
  • Hardware: Half-size breadboard, 2x male-to-female jumper wires

Pin Mapping Table

We are using BCM (Broadcom) pin numbering, which is the default for modern Python libraries. Physical pin numbers are provided for your wiring reference.

Component BCM GPIO Physical Pin Connection Notes
LED Anode (Long Leg) GPIO 17 Pin 11 Connect via 330Ω resistor to limit current to ~10mA
LED Cathode (Short Leg) GND Pin 9 Direct connection to Pi ground plane
Difficulty Rating: Beginner (Hardware) / Intermediate (Software). Time: 15 minutes.

The Code: Python Network Monitor with Error Handling

Target Board: This code is explicitly written for the Raspberry Pi 5 using the gpiozero library. Do not use the legacy RPi.GPIO library; it is incompatible with the Pi 5's RP1 southbridge chip and will throw runtime errors.

First, ensure your environment has the required packages: sudo apt install python3-gpiozero python3-requests.

import time
import requests
from gpiozero import LED
from requests.exceptions import ConnectionError, Timeout, SSLError

# --- PIN DEFINITIONS ---
# BCM GPIO 17 (Physical Pin 11)
STATUS_LED = LED(17)

# --- CONFIGURATION ---
TARGET_URL = "https://1.1.1.1"  # Cloudflare DNS, highly reliable
CHECK_INTERVAL = 5  # Seconds between pings
TIMEOUT_SEC = 3     # Max wait for HTTP response

def check_wifi_health():
    """Pings target URL and updates LED state based on network health."""
    try:
        # We use a fast, lightweight GET request
        response = requests.get(TARGET_URL, timeout=TIMEOUT_SEC)
        
        if response.status_code == 200:
            STATUS_LED.on()
            print("[OK] WiFi and internet routing healthy.")
        else:
            # Connected to router, but upstream is failing or blocking
            STATUS_LED.blink(on_time=0.5, off_time=0.5)
            print(f"[WARN] WiFi connected, but HTTP returned {response.status_code}")
            
    except (ConnectionError, Timeout) as e:
        # Fast blink indicates total local network failure or DNS timeout
        STATUS_LED.blink(on_time=0.1, off_time=0.1)
        print(f"[FAIL] Network Drop: {type(e).__name__}")
        
    except SSLError as e:
        # Captive portal or MITM interference
        STATUS_LED.blink(on_time=1.0, off_time=0.2)
        print(f"[FAIL] TLS/SSL Handshake failed: {e}")
        
    except Exception as e:
        STATUS_LED.off()
        print(f"[FATAL] Unexpected error: {e}")

if __name__ == "__main__":
    print("Starting WiFi Health Monitor... Press Ctrl+C to exit.")
    try:
        while True:
            check_wifi_health()
            time.sleep(CHECK_INTERVAL)
    except KeyboardInterrupt:
        STATUS_LED.off()
        print("\nMonitor stopped. LED off.")

Debugging: Exact Error Strings and Modern NetworkManager Fixes

When your Pi fails to connect or the script above throws errors, do not guess. Match your terminal output to these exact error strings and apply the ranked fixes.

Error 1: The Legacy Configuration Trap

Exact Error String: Error: wpa_supplicant.conf is no longer supported (or your Pi simply ignores the file you placed in /boot/).

Cause: As of Raspberry Pi OS Bookworm, the underlying network stack switched from wpa_supplicant to NetworkManager. The old wpa_supplicant.conf headless setup method is dead.

Fix: Use the modern CLI tool. Run sudo nmcli device wifi connect "YOUR_SSID" password "YOUR_PASSWORD". Alternatively, use sudo raspi-config -> System Options -> Wireless LAN.

Error 2: Python GPIO Incompatibility on Pi 5

Exact Error String: ModuleNotFoundError: No module named 'RPi' OR RuntimeError: This module can only be run on a Raspberry Pi.

Cause: You are trying to import RPi.GPIO on a Raspberry Pi 5. The Pi 5 uses the RP1 I/O controller, which the legacy library cannot address.

Fix: Rewrite your code to use gpiozero (as shown in the code block above) or install the compatibility shim via sudo apt install python3-rpi-lgpio. The gpiozero documentation is the authoritative source for Pi 5 pin control.

Error 3: DNS Resolution Failure in Python

Exact Error String: requests.exceptions.ConnectionError: HTTPSConnectionPool(host='1.1.1.1', port=443): Max retries exceeded... [Errno -3] Temporary failure in name resolution

Cause: Your Pi is connected to the router's WiFi (Layer 2 is up), but it has not received a valid DNS server via DHCP, or your router's DNS forwarding is broken.

Fix: Check your resolved DNS with resolvectl status. If it's empty, force a static DNS in NetworkManager: sudo nmcli con mod "YOUR_SSID" ipv4.dns "8.8.8.8 1.1.1.1" followed by sudo nmcli con up "YOUR_SSID".

The First Three Things to Check When WiFi Fails

  1. Verify the Interface State: Run nmcli device status. If wlan0 says disconnected, your credentials are wrong or the SSID is hidden. If it says unavailable, the WiFi radio is soft-blocked (run sudo rfkill unblock wifi).
  2. Check Band Steering (Pi Zero 2 W specific): If you are using a Pi Zero 2 W and your router combines 2.4GHz and 5GHz into a single SSID, the Pi will fail to connect because it physically lacks a 5GHz radio. You must separate your router's bands or create a dedicated 2.4GHz IoT SSID.
  3. Ping the Gateway, Not the Internet: Run ip route | grep default to find your router's IP, then ping -c 3 [ROUTER_IP]. If this fails, you have a local RF interference or password issue. If this succeeds but ping 8.8.8.8 fails, your router's WAN connection is down.

Extending and Simplifying the Build

Depending on your deployment environment, you may need to scale this project up or strip it down.

How to Simplify (No-Pip Environments)

If you are deploying this on a read-only filesystem or a stripped-down Raspberry Pi OS Lite image where you cannot use pip or apt to install requests, swap the HTTP library for Python's built-in urllib. Replace the requests.get() block with:

import urllib.request
import urllib.error

try:
    urllib.request.urlopen(TARGET_URL, timeout=TIMEOUT_SEC)
    STATUS_LED.on()
except urllib.error.URLError:
    STATUS_LED.blink(on_time=0.1, off_time=0.1)

This removes the external dependency entirely while maintaining basic connectivity checking.

How to Extend (MQTT Integration)

A blinking LED is great for local debugging, but for a fleet of embedded devices, you need telemetry. Extend this build by installing paho-mqtt and publishing the network latency (ping time) to a local Mosquitto broker. You can then wire the Pi's GPIO 17 to an optocoupler to trigger a hardware watchdog reset on your main microcontroller if the Pi's WiFi drops for more than 60 seconds.

For deeper reading on managing headless network configurations on modern Raspberry Pi OS, refer to the official Raspberry Pi NetworkManager documentation. Always verify your specific board's RF compliance and power requirements before sealing it in an enclosure.