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.
🚀 No hardware needed — run this binary counter live in your browser
▶ Open Free Simulation + New Wokwi ProjectProject Overview
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.
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
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 | Anode → Pico GP | Cathode → GND | Resistor |
|---|---|---|---|
| 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 | Color | Signal Pin → Pico | Other leg |
|---|---|---|---|
| Button 1 | Green (key: 1) | GP14 | → GND via breadboard |
| Button 2 | Blue | GP15 | → GND via breadboard |
| Button 3 | Yellow | GP13 | → GND via breadboard |
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
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."rotate": 90) in the diagram — this is intentional for the layout."env" attribute. In a real Pico W, flash MicroPython firmware from micropython.org before uploading code via Thonny or VS Code.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.try/except KeyboardInterrupt block. Stop the simulation to trigger the except block — it prints "You sunk my battle ship!" and turns off all LEDs.Serial Monitor Output Example
Example output when Button 1 (Green, GP14) is pressed — binary 010 → decimal 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.
{
"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.
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()
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 like0b1d = 4*btn3 + 2*btn1 + 1*btn2— positional bit-weight formula for 3-bit decimalsleep(0.5)— 500ms polling loop; LEDs reset each cycle so they only stay on if a button is heldtry/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 |
|---|---|
| 000 | 0 |
| 001 | 1 |
| 010 | 2 |
| 011 | 3 |
| 100 | 4 |
| 101 | 5 |
| 110 | 6 |
| 111 | 7 |
Press Button 1 (Green) only → Binary: 010 → Decimal: 2 | Press all three → Binary: 111 → Decimal: 7
What You Will Learn
🧪 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.
Comments
Post a Comment