Raspberry Pi Pico W Binary Counter Project Using Wokwi (3 Buttons + 3 LEDs)

3-Bit Binary Counter with Raspberry Pi Pico W – Wokwi Tutorial | MakeMindz
🔢 Beginner Digital Logic

3-Bit Binary Counter with Raspberry Pi Pico W

Use three push buttons to control three LEDs and watch the decimal equivalent update in real time. A hands-on introduction to binary numbers, GPIO, and MicroPython — simulated free in Wokwi.

🍓 Pi Pico W 🔴 3× Red LEDs 🟢🔵🟡 3× Push Buttons 🐍 MicroPython 🧪 Wokwi

🚀 No hardware needed — run this binary counter live in your browser

▶ Open Free Simulation + New Wokwi Project
📐

Project Overview

3-bitCounter System
0–7Decimal Range
500msPoll Interval
IRQButton Handler

Three push buttons represent the bits of a 3-bit binary number (bit 2, bit 1, bit 0). Each press lights the matching LED and the system calculates the decimal equivalent instantly. The serial monitor streams button states, binary values, and the integer result every 500 ms.

decimal = (btn3 × 4) + (btn1 × 2) + (btn2 × 1)
Bit weighting — 4-2-1 method — the foundation of binary arithmetic

Interrupts (IRQ_RISING) fire handler functions the instant a button is pressed, turning on the correct LED without waiting for the poll loop. This demonstrates both polling and interrupt-driven programming in a single project.

🔧

Components & Pin Assignments

🍓
Raspberry Pi Pico W
MicroPython v1.24.1
🔴
3× Red LEDs
Represent bits 2, 1, 0
🟩
3× Resistors (220 Ω)
Current limiting for LEDs
🔘
3× Push Buttons
Green, Blue, Yellow (6mm)
🍞
Breadboard
Rotated 90° in diagram
GPIO Pin Map
GP14 Button 1 (Green) INPUT
GP15 Button 2 (Blue) INPUT
GP13 Button 3 (Yellow) INPUT
GP17 LED 1 OUTPUT (bit 1)
GP16 LED 2 OUTPUT (bit 0)
GP18 LED 3 OUTPUT (bit 2)
🔗

Wiring Connections

All components sit on a single breadboard (rotated 90°) connected to the Pico W via breadboard rows. Buttons use PULL_DOWN — pressed = 1, released = 0.

LED Connections (3× Red LEDs with 220 Ω Resistors)
LEDAnode → Pico GPCathode → GNDResistor
LED 1 (bit 1)GP17 via r1 (220Ω)GND rail (bb1:22)r1
LED 2 (bit 0)GP16 via r2 (220Ω)GND rail (bb1:26)r2
LED 3 (bit 2)GP18 via r3 (220Ω)GND rail (bb1:30)r3
Button Connections (PULL_DOWN — pressed reads HIGH)
ButtonColorSignal Pin → PicoOther leg
Button 1 Green (key: 1) GP14 → GND via breadboard
Button 2 Blue GP15 → GND via breadboard
Button 3 Yellow GP13 → GND via breadboard
⚡ Pull-Down vs Pull-Up

This project uses PULL_DOWN resistors. When a button is not pressed the pin reads 0 (LOW). When pressed and connected to 3.3V, the pin reads 1 (HIGH). This is the opposite of PULL_UP logic — no value inversion needed in the code.

📋

Step-by-Step Build Guide

1
Open Wokwi & Start a Pico W Project
Go to wokwi.com, sign in, click New Project, and select Raspberry Pi Pico W. Wokwi will place the board automatically. Alternatively, click the free simulation link at the top to open a pre-wired version instantly.
💡 The free simulation link at the top of this page opens the exact project — no setup needed.
2
Paste the diagram.json
Click the diagram.json tab in Wokwi and replace all existing content with the full JSON from Step 5 below. This loads the breadboard, Pico W, 3 LEDs, 3 resistors, 3 push buttons, and all their connections automatically.
ℹ️ The breadboard is rotated 90° ("rotate": 90) in the diagram — this is intentional for the layout.
3
Set the MicroPython Environment
The diagram.json already sets the board to use MicroPython v1.24.1 via the "env" attribute. In a real Pico W, flash MicroPython firmware from micropython.org before uploading code via Thonny or VS Code.
4
Paste the MicroPython Code
Click the main.py tab (Wokwi uses main.py for MicroPython projects) and replace all content with the complete code from Step 6 below. Verify pin numbers match: buttons on GP13/14/15 and LEDs on GP16/17/18.
💡 The keyboard shortcut key: "1" is set on Button 1 (Green) — in Wokwi you can press the 1 key on your keyboard to simulate pressing it.
5
Run the Simulation
Click the green ▶ Play button. The Serial Monitor at the bottom will start printing button states every 500ms. Initially all values are 0 and all LEDs are off.
ℹ️ The program uses a try/except KeyboardInterrupt block. Stop the simulation to trigger the except block — it prints "You sunk my battle ship!" and turns off all LEDs.
6
Press Buttons and Observe
Click any on-screen button in Wokwi (or press 1 on your keyboard for Button 1). The corresponding LED lights immediately via the IRQ handler, and the Serial Monitor shows the updated binary and decimal values on the next 500ms poll.
7
Read the Serial Monitor Output
The serial output shows all three button states, binary representation for each, and the decimal integer equivalent. Try pressing all three buttons together for Binary: 111 → Decimal: 7 — the maximum value in a 3-bit system.
💡 See the Serial Output Example section below for a sample of what to expect.
📟

Serial Monitor Output Example

Example output when Button 1 (Green, GP14) is pressed — binary 010 → decimal 2:

The state of button 1 is: 1 The state of button 2 is: 0 The state of button 3 is: 0 3-bit binary number: button 1: 0b1 button 2: 0b0 button 3: 0b0 Integer Equivalent: 2

Pressing all 3 buttons gives Integer Equivalent: 7 (binary 111).

🗺

Wokwi diagram.json

Copy and paste this entire JSON into the diagram.json tab. It places the Pico W, breadboard, 3 LEDs, 3 resistors, and 3 buttons with all wiring pre-connected.

📄 diagram.json
{
  "version": 1,
  "author": "MakeMindz",
  "editor": "wokwi",
  "parts": [
    { "type": "wokwi-breadboard", "id": "bb1",
      "top": 53, "left": -322.4, "rotate": 90, "attrs": {} },

    { "type": "board-pi-pico-w", "id": "pico",
      "top": -156.85, "left": -34.85,
      "attrs": { "env": "micropython-20241129-v1.24.1" }
    },

    { "type": "wokwi-led", "id": "led1",
      "top": 28, "left": 1.4, "rotate": 270,
      "attrs": { "color": "red" }
    },
    { "type": "wokwi-led", "id": "led2",
      "top": 66.4, "left": 1.4, "rotate": 270,
      "attrs": { "color": "red" }
    },
    { "type": "wokwi-led", "id": "led3",
      "top": 104.8, "left": 1.4, "rotate": 270,
      "attrs": { "color": "red" }
    },

    { "type": "wokwi-pushbutton-6mm", "id": "btn1",
      "top": 151.4, "left": -9.6,
      "attrs": { "color": "green", "xray": "1", "bounce": "0", "key": "1" }
    },
    { "type": "wokwi-pushbutton-6mm", "id": "btn2",
      "top": 189.8, "left": -9.6,
      "attrs": { "color": "blue", "xray": "1", "bounce": "0" }
    },
    { "type": "wokwi-pushbutton-6mm", "id": "btn3",
      "top": 228.2, "left": -9.6,
      "attrs": { "color": "yellow", "xray": "1", "bounce": "0" }
    },

    { "type": "wokwi-resistor", "id": "r1",
      "top": 32.75, "left": 124.8,
      "attrs": { "value": "220" }
    },
    { "type": "wokwi-resistor", "id": "r2",
      "top": 71.15, "left": 124.8,
      "attrs": { "value": "220" }
    },
    { "type": "wokwi-resistor", "id": "r3",
      "top": 119.15, "left": 134.4,
      "attrs": { "value": "220" }
    }
  ],
  "connections": [
    [ "bb1:34t.a", "bb1:tn.27", "green", ["h0"] ],
    [ "bb1:38t.a", "bb1:tn.31", "green", ["h0"] ],
    [ "bb1:20b.i", "bb1:32b.i", "green", ["h0"] ],
    [ "bb1:19b.j", "bb1:36b.j", "green", ["h0"] ],
    [ "r1:1",      "bb1:22t.a", "green", ["v0"] ],
    [ "r1:2",      "bb1:tp.17", "green", ["v0"] ],
    [ "r2:2",      "bb1:tp.21", "green", ["v0"] ],
    [ "bb1:19t.a", "bb1:25t.a", "green", ["h0"] ],
    [ "r2:1",      "bb1:26t.a", "green", ["v0"] ],
    [ "bb1:3t.a",  "bb1:tp.3",  "green", ["h0"] ],
    [ "bb1:tn.4",  "bb1:5t.a",  "green", ["h0"] ],
    [ "bb1:20t.b", "bb1:21t.b", "green", ["h0"] ],
    [ "bb1:17t.b", "bb1:29t.b", "green", ["h0"] ],
    [ "bb1:17b.i", "bb1:40b.h", "green", ["h0"] ],
    [ "bb1:42t.a", "bb1:tn.35", "green", ["h0"] ],
    [ "r3:1",      "bb1:30t.a", "green", ["v0"] ],
    [ "r3:2",      "bb1:tp.24", "green", ["v0"] ],
    [ "led1:A",    "bb1:21t.c", "",      ["$bb"] ],
    [ "led1:C",    "bb1:22t.c", "",      ["$bb"] ],
    [ "led2:A",    "bb1:25t.c", "",      ["$bb"] ],
    [ "led2:C",    "bb1:26t.c", "",      ["$bb"] ],
    [ "led3:A",    "bb1:29t.c", "",      ["$bb"] ],
    [ "led3:C",    "bb1:30t.c", "",      ["$bb"] ],
    [ "btn1:1.l",  "bb1:32b.f", "",      ["$bb"] ],
    [ "btn1:2.l",  "bb1:34b.f", "",      ["$bb"] ],
    [ "btn1:1.r",  "bb1:32t.e", "",      ["$bb"] ],
    [ "btn1:2.r",  "bb1:34t.e", "",      ["$bb"] ],
    [ "btn2:1.l",  "bb1:36b.f", "",      ["$bb"] ],
    [ "btn2:2.l",  "bb1:38b.f", "",      ["$bb"] ],
    [ "btn2:1.r",  "bb1:36t.e", "",      ["$bb"] ],
    [ "btn2:2.r",  "bb1:38t.e", "",      ["$bb"] ],
    [ "btn3:1.l",  "bb1:40b.f", "",      ["$bb"] ],
    [ "btn3:2.l",  "bb1:42b.f", "",      ["$bb"] ],
    [ "btn3:1.r",  "bb1:40t.e", "",      ["$bb"] ],
    [ "btn3:2.r",  "bb1:42t.e", "",      ["$bb"] ],
    [ "pico:GP0",  "bb1:1b.h",  "",      ["$bb"] ],
    [ "pico:GP1",  "bb1:2b.h",  "",      ["$bb"] ],
    [ "pico:GND.1","bb1:3b.h",  "",      ["$bb"] ],
    [ "pico:GP2",  "bb1:4b.h",  "",      ["$bb"] ],
    [ "pico:GP3",  "bb1:5b.h",  "",      ["$bb"] ],
    [ "pico:GP4",  "bb1:6b.h",  "",      ["$bb"] ],
    [ "pico:GP5",  "bb1:7b.h",  "",      ["$bb"] ],
    [ "pico:GND.2","bb1:8b.h",  "",      ["$bb"] ],
    [ "pico:GP6",  "bb1:9b.h",  "",      ["$bb"] ],
    [ "pico:GP7",  "bb1:10b.h", "",      ["$bb"] ],
    [ "pico:GP8",  "bb1:11b.h", "",      ["$bb"] ],
    [ "pico:GP9",  "bb1:12b.h", "",      ["$bb"] ],
    [ "pico:GND.3","bb1:13b.h", "",      ["$bb"] ],
    [ "pico:GP10", "bb1:14b.h", "",      ["$bb"] ],
    [ "pico:GP11", "bb1:15b.h", "",      ["$bb"] ],
    [ "pico:GP12", "bb1:16b.h", "",      ["$bb"] ],
    [ "pico:GP13", "bb1:17b.h", "",      ["$bb"] ],
    [ "pico:GND.4","bb1:18b.h", "",      ["$bb"] ],
    [ "pico:GP14", "bb1:19b.h", "",      ["$bb"] ],
    [ "pico:GP15", "bb1:20b.h", "",      ["$bb"] ],
    [ "pico:GP16", "bb1:20t.c", "",      ["$bb"] ],
    [ "pico:GP17", "bb1:19t.c", "",      ["$bb"] ],
    [ "pico:GND.5","bb1:18t.c", "",      ["$bb"] ],
    [ "pico:GP18", "bb1:17t.c", "",      ["$bb"] ],
    [ "pico:GP19", "bb1:16t.c", "",      ["$bb"] ],
    [ "pico:GP20", "bb1:15t.c", "",      ["$bb"] ],
    [ "pico:GP21", "bb1:14t.c", "",      ["$bb"] ],
    [ "pico:GND.6","bb1:13t.c", "",      ["$bb"] ],
    [ "pico:GP22", "bb1:12t.c", "",      ["$bb"] ],
    [ "pico:RUN",  "bb1:11t.c", "",      ["$bb"] ],
    [ "pico:GP26", "bb1:10t.c", "",      ["$bb"] ],
    [ "pico:GP27", "bb1:9t.c",  "",      ["$bb"] ],
    [ "pico:GND.7","bb1:8t.c",  "",      ["$bb"] ],
    [ "pico:GP28", "bb1:7t.c",  "",      ["$bb"] ],
    [ "pico:ADC_VREF","bb1:6t.c","",     ["$bb"] ],
    [ "pico:3V3",  "bb1:5t.c",  "",      ["$bb"] ],
    [ "pico:3V3_EN","bb1:4t.c", "",      ["$bb"] ],
    [ "pico:GND.8","bb1:3t.c",  "",      ["$bb"] ],
    [ "pico:VSYS", "bb1:2t.c",  "",      ["$bb"] ],
    [ "pico:VBUS", "bb1:1t.c",  "",      ["$bb"] ]
  ],
  "dependencies": {}
}
🐍

MicroPython Code (main.py)

Paste this into the main.py tab in Wokwi, or save as main.py and upload to your physical Pico W using Thonny IDE.

🐍 main.py (MicroPython)
from machine import Pin
from utime import sleep

# ── Button inputs (PULL_DOWN: not pressed = 0, pressed = 1) ──
button_1 = Pin('GP14', Pin.IN, Pin.PULL_DOWN)  # Green  – bit 1
button_2 = Pin('GP15', Pin.IN, Pin.PULL_DOWN)  # Blue   – bit 0
button_3 = Pin('GP13', Pin.IN, Pin.PULL_DOWN)  # Yellow – bit 2

# ── LED outputs ──
led_1 = Pin('GP17', Pin.OUT)  # bit 1 indicator
led_2 = Pin('GP16', Pin.OUT)  # bit 0 indicator
led_3 = Pin('GP18', Pin.OUT)  # bit 2 indicator

# ── IRQ handlers — fire instantly on button press ──
def handler_1(x):
    led_1.high()
    return

def handler_2(x):
    led_2.high()
    return

def handler_3(x):
    led_3.high()
    return

# Attach interrupts — trigger on rising edge (0→1)
button_1.irq(handler_1, Pin.IRQ_RISING)
button_2.irq(handler_2, Pin.IRQ_RISING)
button_3.irq(handler_3, Pin.IRQ_RISING)

# Start with all LEDs off
led_1.low()
led_2.low()
led_3.low()

try:
    play_again = True
    while play_again == True:
        sleep(0.5)  # poll every 500 ms

        button_1_state = button_1.value()
        button_2_state = button_2.value()
        button_3_state = button_3.value()

        # Decimal = (bit2 × 4) + (bit1 × 2) + (bit0 × 1)
        d = 4 * button_3_state + 2 * button_1_state + 1 * button_2_state

        # Serial monitor output
        print('The state of button 1 is: ', button_1_state)
        print('The state of button 2 is: ', button_2_state)
        print('The state of button 3 is: ', button_3_state)
        print('3-bit binary number: ')
        print('button 1: ', bin(button_1_state))
        print('button 2: ', bin(button_2_state))
        print('button 3: ', bin(button_3_state))
        print('Integer Equivalent: ', d)
        print('\n')

        # Reset LEDs after each poll cycle
        led_1.low()
        led_2.low()
        led_3.low()

except KeyboardInterrupt:
    print('\n')
    print('You sunk my battle ship!')  # cleanup message

finally:
    # Always turn off LEDs on exit
    led_1.low()
    led_2.low()
    led_3.low()
📌 Key Code Concepts
  • Pin.PULL_DOWN — pin reads 0 at rest, 1 when pressed (opposite of PULL_UP)
  • Pin.IRQ_RISING — fires the handler instantly when pin goes from 0→1 (press event)
  • bin(value) — MicroPython built-in converts integer to binary string like 0b1
  • d = 4*btn3 + 2*btn1 + 1*btn2 — positional bit-weight formula for 3-bit decimal
  • sleep(0.5) — 500ms polling loop; LEDs reset each cycle so they only stay on if a button is held
  • try/finally — ensures LEDs always turn off when the program stops, even on error
🔢

3-Bit Binary Reference Table

A 3-bit system can represent 8 unique values — from 000 to 111. Use this table to predict what decimal value the serial monitor will show for any button combination.

Binary (btn3–btn1–btn2)Decimal
0000
0011
0102
0113
1004
1015
1106
1117

Press Button 1 (Green) only → Binary: 010 → Decimal: 2  |  Press all three → Binary: 111 → Decimal: 7

🎓

What You Will Learn

Binary number systems and bit weighting (4-2-1)
GPIO pin configuration as INPUT and OUTPUT
Pull-down resistor logic in MicroPython
Interrupt-driven programming with IRQ_RISING
Binary-to-decimal conversion in code
Real-time serial monitor debugging
MicroPython try/except/finally structure
Wokwi simulation for hardware-free learning
Ideal For
👶
Beginner Electronics Learners
🏫
School STEM Labs
🐍
MicroPython Practice
Digital Logic Demonstrations

🧪 Try the Free Simulation

The complete circuit is already built and wired. Just open, press play, and start pressing buttons to see binary counting in action.

✓ No hardware needed ✓ Press keyboard key "1" for btn1 ✓ Real-time serial monitor ✓ Completely free

Comments

try for free