Productivity · Raspberry Pi Pico
Deep Focus Timer
A Raspberry Pi Pico build with 3 components. Reads: Encoder. Drives: OLED, Buzzer.
3 parts · 11 connections · 8 steps
Wiring
Parts
| Part | Refs | Qty | Est. |
|---|---|---|---|
| SSD1306 OLED display (128×64, I²C) | OLED | 1 | $3.20 |
| KY-040 rotary encoder | Encoder | 1 | $1.10 |
| Passive piezo buzzer | Buzzer | 1 | $0.60 |
| Plus: breadboard, jumper wires, USB cable | ≈ $4.90 | ||
Prices are rough hobby-market estimates. Click a part for wiring notes and specs.
Firmware
1// Focus Timer2// Generated by Wirecraft for the Raspberry Pi Pico (RP2040)3// Prompt: A pomodoro focus timer with an OLED display, rotary encoder to set minutes, and a buzzer when time is up4//5// Wiring, parts and step-by-step assembly live alongside this file.67#include <Arduino.h>8#include <Wire.h>9#include <Adafruit_GFX.h>10#include <Adafruit_SSD1306.h>1112#define ENCODER_CLK 213#define ENCODER_DT 314#define ENCODER_SW 615#define BUZZER_PIN 71617Adafruit_SSD1306 oLED(128, 64, &Wire, -1);18int encoderPosition = 0;19int encoderLastClk = HIGH;2021void setup() {22 Serial.begin(115200);23 if (!oLED.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { Serial.println(F("OLED not found")); }24 oLED.clearDisplay();25 oLED.setTextColor(SSD1306_WHITE);26 oLED.setTextSize(1);27 pinMode(ENCODER_CLK, INPUT);28 pinMode(ENCODER_DT, INPUT);29 pinMode(ENCODER_SW, INPUT_PULLUP);30 pinMode(BUZZER_PIN, OUTPUT);31 Serial.println(F("Focus Timer ready."));32}3334void loop() {35 // --- Read sensors ---36 int encoderClk = digitalRead(ENCODER_CLK);37 if (encoderClk != encoderLastClk && encoderClk == LOW) {38 encoderPosition += (digitalRead(ENCODER_DT) != encoderClk) ? 1 : -1;39 }40 encoderLastClk = encoderClk;4142 // Refresh the display with live readings43 oLED.clearDisplay();44 oLED.setCursor(0, 0);45 oLED.setCursor(0, 0);46 oLED.print("Encoder: "); oLED.println(encoderPosition);47 oLED.display();4849 delay(50);50}511; PlatformIO project for Focus Timer2[env:pico]3platform = raspberrypi4board = pico5framework = arduino6monitor_speed = 1152007lib_deps =8 adafruit/Adafruit SSD1306@^2.5.109 adafruit/Adafruit GFX Library@^1.11.910Assembly
- 1
Lay out your workbench
Gather the Raspberry Pi Pico, a half-size breadboard, and a bundle of male-to-male jumper wires. Keep the parts list open — every component below gets its own spot on the breadboard. Don't plug in USB power until the last wire is placed.
- 2
Seat the board and power rails
Run a red jumper from the Raspberry Pi Pico's 3V3 pin to the breadboard's + rail, and a black jumper from GND to the − rail. Every component's power and ground will tap these rails.
- 3
Wire the OLED
Place the SSD1306 OLED display (128×64, I²C) on the breadboard. Power first: VCC → + rail, GND → − rail. Then signals: SDA → GP4, SCL → GP5. Tip: If nothing shows up, try I²C address 0x3D — some modules ship with it.
- 4
Wire the Encoder
Place the KY-040 rotary encoder on the breadboard. Power first: VCC → + rail, GND → − rail. Then signals: CLK → GP2, DT → GP3, SW → GP6. Tip: If the count moves two steps per detent, only act on the falling edge of CLK (as this code does).
- 5
Wire the Buzzer
Place the Passive piezo buzzer on the breadboard. Power first: GND → − rail. Then signals: SIG → GP7. Tip: Passive buzzers need tone(); active ones just want HIGH. This design assumes passive.
- 6
Double-check before power
Trace every wire against the diagram once more — 11 connections in total. The classic mistakes: swapped power and ground, and off-by-one rows on the breadboard. Thirty seconds of checking saves a component.
- 7
Flash the firmware
Open the exported folder in VS Code with the PlatformIO extension (free), plug in the Raspberry Pi Pico over USB, and hit Upload. PlatformIO fetches the libraries listed in platformio.ini automatically. Prefer the Arduino IDE? Copy src/main.cpp into a new sketch and install the same libraries from the Library Manager.
- 8
Bring it to life
Open the Serial Monitor at 115200 baud — you should see "Focus Timer ready." Then start customizing the loop; the sketch is organized so every component's code is easy to find.