Yes, you can run Windows on a Raspberry Pi, specifically Windows 11 on ARM (WoA) via custom UEFI firmware, but it requires a Pi 4 or Pi 5 with at least 8GB of RAM and an NVMe drive to be practically usable. You cannot install standard x86/x64 Windows because the Broadcom BCM2711 and BCM2712 system-on-chips (SoCs) use ARM64 architecture. Instead, you rely on the Windows on Raspberry (WoR) project to flash an EDK2 UEFI bootloader that tricks the Windows 11 ARM64 installer into recognizing the Pi as a standard UEFI-compliant PC.
While WoA on a Pi 5 is viable for edge computing, digital signage, and kiosk deployments, it introduces severe hardware abstraction limitations—most notably with native GPIO. This guide provides the exact hardware bill of materials, a reliable I2C GPIO workaround, and the production-ready C# code required to interface with physical hardware on a Windows-based Pi.
The Hardware Reality: What You Actually Need
To run Windows 11 IoT Enterprise or standard Windows 11 ARM64 (version 24H2) without constant thermal throttling or I/O bottlenecks, you need a specific hardware stack. The Raspberry Pi 5 (8GB) is the only current variant that provides enough RAM and PCIe bandwidth to make WoA viable in 2026.
| Component | Exact Variant | Approx. Price (2026) | Why This Specific Part |
|---|---|---|---|
| Compute Board | Raspberry Pi 5 (8GB RAM) | $80 | 4GB variant runs out of RAM during Windows Update; 8GB is mandatory. |
| Storage HAT | Geekworm X1001 NVMe PCIe HAT | $25 | Provides M.2 NGFF M-Key interface; routes PCIe Gen 2 x1 to the Pi 5. |
| Boot Drive | WD Blue SN580 256GB NVMe | $35 | DRAM-less but excellent random 4K R/W; crucial for Windows OS responsiveness. |
| Cooling | Official Raspberry Pi Active Cooler | $5 | WoA runs 15-20% hotter than Linux at idle; passive cooling will throttle. |
| GPIO Expander | PCA9555 I2C 16-bit Expander | $4 | Bypasses broken native WoA GPIO drivers via standard I2C HID. |
Assumptions for this build: We are targeting the Raspberry Pi 5 8GB model, running Windows 11 ARM64 (24H2), utilizing the primary I2C1 bus on physical pins 3 and 5. Ambient temperature is assumed to be 25°C (77°F).
The GPIO Bottleneck and the I2C Workaround
When you ask, "Can I run Windows on a Raspberry Pi?" the hidden question is usually, "Can I use the GPIO pins?" Under Linux, the RPi.GPIO or gpiod libraries map directly to the Broadcom SoC registers. Under Windows on ARM, the ACPI tables provided by the EDK2 UEFI firmware do not fully expose the BCM2712 GPIO controller to the Windows kernel. Attempting to use native GPIO libraries often results in silent failures or kernel panics.
The Solution: Offload hardware switching to an external I2C GPIO expander like the NXP PCA9555. Windows 11 ARM64 has robust, native support for I2C buses via the Windows.Devices.I2c and .NET System.Device.I2c namespaces. The Pi 5's I2C1 bus is fully exposed to the OS.
| Raspberry Pi 5 Pin (Physical) | BCM Function | PCA9555 Pin | Notes |
|---|---|---|---|
| Pin 1 | 3V3 Power | Pin 8 (VDD) | Power the expander logic. |
| Pin 3 | GPIO 2 (SDA1) | Pin 15 (SDA) | Requires 4.7kΩ pull-up to 3V3. |
| Pin 5 | GPIO 3 (SCL1) | Pin 14 (SCL) | Requires 4.7kΩ pull-up to 3V3. |
| Pin 6 | GND | Pin 16 (GND) | Common ground reference. |
| N/A | Tied to GND | Pins 20, 21, 22 (A0, A1, A2) | Sets I2C address to 0x20. |
C# .NET 8 I2C Control Code for Windows ARM64
The following code targets the Raspberry Pi 5 (8GB) running Windows 11 ARM64. It uses the official .NET 8 System.Device.I2c library to initialize the PCA9555 and toggle Port 0. This is a complete, compilable console application.
using System;
using System.Device.I2c;
using System.Threading;
// Target Board: Raspberry Pi 5 (8GB) running Windows 11 on ARM64
// Companion IC: NXP PCA9555 I2C GPIO Expander
namespace PiWindowsI2cControl
{
class Program
{
// PCA9555 default I2C address (A0, A1, A2 address pins tied to GND)
private const int I2cAddress = 0x20;
// I2C Bus 1 on Raspberry Pi 5 (Physical pins 3 for SDA, 5 for SCL)
private const int I2cBusId = 1;
// PCA9555 Internal Registers
private const byte REG_OUTPUT_PORT_0 = 0x02;
private const byte REG_CONFIG_PORT_0 = 0x06;
static void Main(string[] args)
{
// StandardMode (100kHz) is safest for breadboard jumper runs
var i2cSettings = new I2cConnectionSettings(I2cBusId, I2cAddress, I2cBusSpeed.StandardMode);
try
{
using var device = I2cDevice.Create(i2cSettings);
// Step 1: Configure Port 0 as outputs (0x00 = all outputs, 0xFF = all inputs)
device.WriteByte(REG_CONFIG_PORT_0);
device.WriteByte(0x00);
Console.WriteLine("PCA9555 Port 0 configured as OUTPUT.");
Console.WriteLine("Toggling pins every 1 second. Press CTRL+C to exit.");
while (true)
{
// Step 2: Turn ON all Port 0 pins (Write 0xFF)
device.WriteByte(REG_OUTPUT_PORT_0);
device.WriteByte(0xFF);
Thread.Sleep(1000);
// Step 3: Turn OFF all Port 0 pins (Write 0x00)
device.WriteByte(REG_OUTPUT_PORT_0);
device.WriteByte(0x00);
Thread.Sleep(1000);
}
}
catch (Exception ex)
{
Console.WriteLine($"I2C Initialization Failed: {ex.Message}");
// Catch specific HRESULT for I2C bus timeout / device not found
if (ex.HResult == unchecked((int)0x80070490))
{
Console.WriteLine("ERROR 0x80070490: The system cannot find the device specified.");
Console.WriteLine("FIX: Verify physical wiring on Pi pins 3 (SDA) and 5 (SCL).");
Console.WriteLine("FIX: Ensure 4.7k pull-up resistors are installed between SDA/SCL and 3V3.");
}
else if (ex.HResult == unchecked((int)0x8007001F))
{
Console.WriteLine("ERROR 0x8007001F: A device attached to the system is not functioning.");
Console.WriteLine("FIX: I2C bus collision. Check for address conflicts using i2cdetect.");
}
}
}
}
}
Debugging: First Three Things to Check When It Fails
Running an unsupported OS on embedded hardware guarantees edge cases. When your build fails, follow this ranked decision path before reflashing your drive.
1. Boot Failure: INACCESSIBLE_BOOT_DEVICE
Exact Error String: Stop Code: INACCESSIBLE_BOOT_DEVICE (0x0000007B) on the UEFI blue screen.
Ranked Causes:
- PCIe Gen 3 Instability: The Pi 5 PCIe lane defaults to Gen 2. If you forced Gen 3 in
/boot/firmware/config.txt(via the UEFI SD card) and your NVMe drive or ribbon cable lacks the signal integrity for 8 GT/s, the Windows bootloader drops the drive. Fix: Edit config.txt and setdtparam=pciex1_gen=2. - Missing NVMe Drivers in WoA Image: Windows 11 ARM64 lacks native drivers for some third-party NVMe controllers (like certain Phison E13 variants). Fix: Use a WD or Crucial drive with native Microsoft inbox drivers.
- Corrupt UEFI ACPI Tables: An outdated EDK2 bootloader fails to map the PCIe root complex. Fix: Download the latest WoR release image.
2. I2C Failure: Device Not Found (0x80070490)
Exact Error String: System.Exception: The system cannot find the device specified. (Exception from HRESULT: 0x80070490)
Ranked Causes:
- Missing Pull-Up Resistors: The Pi 5's internal pull-ups are ~50kΩ, which is too weak for the PCA9555 at 100kHz over jumper wires. Fix: Solder 4.7kΩ resistors between SDA/SCL and 3.3V.
- Incorrect Bus ID: You targeted
I2cBusId = 0instead of1. Fix: Change the constant in the C# code to 1. - I2C Disabled in UEFI: Rare, but possible if a custom DTB overlay disabled the bus. Fix: Check Windows Device Manager under "Sensors" and "I2C Host Controllers".
3. Thermal Throttling Under Load
Symptom: System clock drops to 600MHz; UI stutters heavily when opening Edge or running Windows Update.
Ranked Causes:
- Passive Cooling Used: WoA lacks the aggressive Linux kernel thermal governor tuning. Fix: Install the official Active Cooler.
- Power Supply Brownout: Windows draws more peak current than Linux during burst compilations. If your PSU cannot sustain 5V/5A (25W) via USB-C PD, the Pi throttles. Fix: Use the official 27W USB-C PD power supply.
Extending or Simplifying the Build
To Simplify: If you only need to read sensors and don't care about the Windows desktop UI, ditch standard Windows 11 and install Windows IoT Enterprise. It strips out the Microsoft Store, Edge, and heavy telemetry, reducing background I/O by roughly 40% and lowering idle RAM usage from ~3.5GB to ~1.8GB. Alternatively, strip the C# code down to a simple UWP background service that runs headless.
To Extend: To scale this to industrial IoT, replace the PCA9555 with an industrial Modbus RTU-to-I2C bridge. You can run a .NET 8 Web API on the Pi 5, exposing the I2C sensors to a central MQTT broker (like Mosquitto) running on a local server. For visual interfaces, wire up the official Raspberry Pi 7-inch Touch Display via the DSI ribbon cable—WoA 24H2 includes the necessary DSI panel drivers in the EDK2 ACPI tables, enabling plug-and-play kiosk modes.
Frequently Asked Questions
Can I run Windows 11 on a Raspberry Pi 3?
Technically yes, but practically no. The Pi 3 uses a 32-bit ARMv7 processor (BCM2837) with only 1GB of RAM. Windows 11 ARM64 requires a 64-bit processor and a minimum of 4GB RAM to boot (though 2GB can be hacked via registry edits during setup). The experience on a Pi 3 is limited to Windows 10 IoT Core, which is now end-of-life. For any modern Windows desktop experience, the Pi 5 8GB is the minimum viable hardware.
Does Windows on Raspberry support the official 7-inch touchscreen and camera modules?
The 7-inch DSI touchscreen is supported out-of-the-box in the 2024/2025 EDK2 UEFI builds, as the ACPI tables correctly map the DSI controller. However, the official Raspberry Pi Camera Modules (V2, V3, and HQ) rely on the Unicam CSI controller, which lacks stable Windows DirectShow/MediaFoundation drivers. If you need machine vision on WoA, use a standard USB UVC-compliant webcam instead of the ribbon-cable CSI cameras.
How much RAM do I really need to run Windows 11 ARM on a Pi 5?
You need the 8GB variant. While Windows 11 ARM64 can boot on 4GB, the OS reserves roughly 3.2GB for system processes, caching, and the integrated GPU memory allocation. This leaves less than 800MB for your actual application, leading to heavy swap-file usage on the NVMe drive and severe performance degradation. The $20 premium for the 8GB model is mandatory for a stable embedded deployment.






