The Core Architecture Divide: Microcontroller vs. Microprocessor
If you are asking what is the difference between Arduino and Raspberry Pi, the short answer is architectural: Arduino is a microcontroller ecosystem designed to run a single C++ program in a continuous loop on bare metal, while the classic Raspberry Pi is a microprocessor ecosystem that runs a full Linux operating system capable of multitasking.
But in 2026, that binary definition is incomplete. The Raspberry Pi Foundation now makes the Pico W (a microcontroller), and Arduino makes the Portenta H7 (a board capable of running high-level OS tasks). To make the right choice, you need to look at memory management, interrupt latency, and boot times.
| Specification | Arduino Uno R3 (Classic) | Raspberry Pi 4 Model B (Classic) | Raspberry Pi Pico W (Modern Hybrid) |
|---|---|---|---|
| Core Chip | ATmega328P (Microcontroller) | BCM2711 (Microprocessor) | RP2040 (Microcontroller) |
| Clock Speed | 16 MHz | 1.5 GHz (Quad-core) | 133 MHz (Dual-core) |
| RAM | 2 KB SRAM | 2 GB - 8 GB LPDDR4 | 264 KB SRAM |
| Operating System | None (Bare Metal) | Linux (Raspberry Pi OS) | None (Bare Metal / RTOS) |
| Boot Time | < 50 milliseconds | 15 - 30 seconds | < 200 milliseconds |
| Interrupt Latency | < 1 microsecond | > 1 millisecond (OS jitter) | < 2 microseconds |
| Typical Price | $27.00 | $55.00+ | $6.00 |
The Decision Tree: Which Board Wins for Your Build?
Do not default to the Raspberry Pi 5 just because it has more horsepower. Linux adds massive overhead for simple sensor polling. Use this decision matrix to select your hardware.
| If your project requires... | Then choose... | Why? |
|---|---|---|
| Computer vision, local LLMs, or a web server GUI | Raspberry Pi 5 (8GB) | Requires Linux, massive RAM, and hardware video encoding. |
| Ultra-low power sleep modes (microamps) and instant wake | Arduino Uno R4 Minima | Bare-metal sleep states draw negligible current; no OS to shut down. |
| Hard real-time motor control (sub-microsecond PWM) | Arduino Giga R1 or Teensy 4.1 | Deterministic interrupt handling without OS thread preemption. |
| Wi-Fi IoT sensor logging, MQTT, and low cost | Raspberry Pi Pico W | $6 price point, 264KB RAM handles TLS handshakes, dual-core allows Wi-Fi on core 1 and logic on core 0. |
Reference Build: Wi-Fi Environmental Relay Controller
To prove the Pico W's capability as the ultimate middle-ground board, we are building a Wi-Fi environmental monitor that triggers a physical relay when the temperature exceeds a threshold.
Parts List & Exact Variants
- Microcontroller: Raspberry Pi Pico W (with pre-soldered headers) - $6
- Sensor: Adafruit BME280 I2C Breakout (Product ID: 2652) - $15 (Includes onboard 3.3V regulator and I2C pull-ups)
- Actuator: Adafruit Mini Relay Board (Product ID: 2935) - $5 (3V-5V logic compatible, crucial for the Pico's 3.3V GPIO)
- Power: 5V 2A USB Micro power supply - $8
Pin Mapping Table
| Pico W GPIO | Function | Connects To |
|---|---|---|
| GP4 (Pin 6) | I2C SDA | BME280 SDA |
| GP5 (Pin 7) | I2C SCL | BME280 SCL |
| 3V3 (Pin 36) | Logic Power | BME280 VIN & Relay VCC |
| GND (Pin 38) | Common Ground | BME280 GND & Relay GND |
| GP15 (Pin 20) | Digital Out | Relay IN (Signal) |
Complete Firmware: Arduino C++ on the Pico W
Target Board Variant: This code targets the Raspberry Pi Pico W using the Earle Philhower arduino-pico core in the Arduino IDE. Do not use the official Mbed-based Raspberry Pi core; it has higher overhead and poorer Wi-Fi stability.
#include <WiFi.h>
#include <Wire.h>
#include <Adafruit_BME280.h>
// --- PIN DEFINITIONS ---
#define PIN_RELAY 15
#define SEALEVELPRESSURE_HPA (1013.25)
#define TEMP_THRESHOLD 28.5 // Celsius
// --- CREDENTIALS ---
const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASSWORD";
Adafruit_BME280 bme;
unsigned long lastRead = 0;
const long readInterval = 5000; // 5 seconds
void setup() {
Serial.begin(115200);
while (!Serial) delay(10);
pinMode(PIN_RELAY, OUTPUT);
digitalWrite(PIN_RELAY, LOW); // Ensure relay is off at boot
// Initialize I2C on GP4 (SDA) and GP5 (SCL)
Wire.setSDA(4);
Wire.setSCL(5);
Wire.begin();
if (!bme.begin(0x77, &Wire)) {
Serial.println("FATAL: BME280 I2C init failed. Check wiring.");
while (1) { delay(100); } // Halt execution
}
Serial.print("Connecting to WiFi: ");
Serial.println(ssid);
WiFi.begin(ssid, password);
int attempts = 0;
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
attempts++;
if (attempts > 40) {
Serial.println("\nERROR: WiFi connection timed out. Restarting.");
rp2040.restart(); // Hardware reset via Pico SDK
}
}
Serial.println("\nConnected! IP: " + WiFi.localIP().toString());
}
void loop() {
// Non-blocking sensor read
if (millis() - lastRead >= readInterval) {
lastRead = millis();
float temp = bme.readTemperature();
Serial.printf("Temp: %.2f C | Humidity: %.1f %%\n", temp, bme.readHumidity());
// Hysteresis logic to prevent relay chatter
if (temp > TEMP_THRESHOLD) {
digitalWrite(PIN_RELAY, HIGH);
} else if (temp < (TEMP_THRESHOLD - 1.0)) {
digitalWrite(PIN_RELAY, LOW);
}
}
// WiFi watchdog
if (WiFi.status() != WL_CONNECTED) {
Serial.println("WiFi dropped. Reconnecting...");
WiFi.reconnect();
}
}
Debugging Boot and Connection Failures
When moving from classic Arduinos or ESP32s to the Pico W, you will hit specific toolchain and hardware errors. Here is how to debug them.
Error 1: error: 'WiFi' was not declared in this scope
Ranked Causes:
- Wrong Core Selected: You are using the official Arduino Mbed OS core instead of the Earle Philhower core. The Mbed core handles Wi-Fi differently and lacks the standard ESP-style
WiFi.hAPI. - Board Misidentification: You selected 'Raspberry Pi Pico' instead of 'Raspberry Pi Pico W' in the IDE Tools menu. The non-W variant does not compile Wi-Fi libraries.
- Missing Library: You haven't installed the Pico W networking libraries via the Board Manager.
Fix: Go to File > Preferences, add https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json to your Additional Board Manager URLs. Open Board Manager, install 'Raspberry Pi Pico/RP2040' by Earle Philhower, and select Raspberry Pi Pico W.
Error 2: FATAL: BME280 I2C init failed. Check wiring.
Ranked Causes:
- I2C Address Mismatch: The Adafruit breakout defaults to
0x77. Cheaper Amazon clones often use0x76. Change the hex address inbme.begin(). - Missing Pull-up Resistors: If you are using a raw BME280 chip on a custom PCB instead of a breakout board, the I2C bus requires 4.7kΩ pull-up resistors on SDA and SCL to 3.3V.
- SDA/SCL Swap: The Pico W has multiple I2C buses. Ensure GP4 is SDA and GP5 is SCL. Reversing them will cause a timeout.
- Power Supply Brownout: When the Pico W transmits over Wi-Fi, current draw spikes to ~150mA. If your USB cable is thin or your PC port is underpowered, the 3.3V rail droops, resetting the chip. Use a dedicated 5V 2A wall adapter.
- Flash Memory Lock: If the board fails to upload and shows 'No drive found', hold the white BOOTSEL button while plugging in the USB cable to force it into USB mass-storage bootloader mode.
- Logic Level Mismatch: Never feed 5V into a Pico W GPIO pin. It will instantly fry the RP2040 silicon. Always use logic level shifters or 3.3V-compatible modules.
Extending and Simplifying the Build
The beauty of the Pico W is its scalability. You are not locked into a single paradigm.
How to Simplify (Strip it Down)
If you do not need remote monitoring and just want a standalone thermostat, delete the WiFi.h includes and Wi-Fi logic entirely. The Pico W will drop its idle current consumption from ~20mA down to ~2mA. You can then power the entire circuit from a 2000mAh 18650 lithium cell for months. Just remember to add a TP4056 charging module for safe lithium charging.
How to Extend (Scale it Up)
If you need to integrate this into a broader smart home network, upgrade the serial logging to MQTT over TLS. The RP2040's 264KB of SRAM is large enough to hold the TLS handshake buffers required by the PubSubClient and WiFiClientSecure libraries. Assign Core 0 to handle the sensor polling and relay logic, and use the Pico SDK multicore API to assign Core 1 exclusively to the Wi-Fi stack and MQTT keep-alive pings. This prevents network latency from delaying your real-time relay switching.






