Month 2 Box - Hardware 101 w/Soldering, PCB Design & more

Lesson 5 – Breadboard Prototyping for the Game Shield

Breadboard Prototyping for the Game Shield

Before you solder anything permanent, you prototype it on a breadboard where mistakes cost a few seconds, not a rework. In this lesson you will wire up a handheld game shield, an OLED screen, six control buttons, and a buzzer, and confirm it all works with a test sketch. This is step one of three: breadboard first, then a soldered shield, then eventually a manufactured board.

Why prototype on a breadboard first

A breadboard lets you build and change a circuit without permanently fixing anything, so you can test and troubleshoot freely. Soldering can be undone, but it is far more work than pulling a jumper wire. The rule is simple: confirm the circuit works completely on the breadboard before you commit it to solder. If you solder an untested design and it is wrong, you have wasted real time and materials. This is exactly how product development works, prototype, verify, then make it permanent.

What you are building

The project is a handheld game shield in the style of a tiny game console: an OLED screen for graphics, six buttons for control (a direction pad of up, down, left, and right, plus A and B), and a buzzer for sound. Once soldered into a shield, it pops onto the board and you can run any of the many open-source games written for this kind of device. Today you build and test it on the breadboard.

The pin map

The OLED uses the I2C protocol, so it needs only four wires: GND to ground, VCC to 5V, SCL (clock) to A5, and SDA (data) to A4. The six buttons go to digital pins 2 through 7: up to 2, down to 3, left to 4, right to 5, A to 6, and B to 7, with the other leg of each button going to ground. The passive buzzer's signal goes to pin 8 and its other lead to ground. Keeping this map straight is what makes the test sketch work without changes.

INPUT_PULLUP: buttons without extra resistors

You might expect each button to need a resistor, but these do not, because they use INPUT_PULLUP mode. That mode turns on a resistor built into the microcontroller, which holds the pin HIGH by default. Wiring the other side of the button to ground means pressing it pulls the pin LOW. So a pressed button reads LOW and a released button reads HIGH, which is the reverse of what beginners expect, and it saves you six external resistors.

Working through it

Place the buttons. Arrange the six push buttons on the breadboard. Any layout works; a natural one is a direction cluster for up, down, left, right and a pair for A and B.

Wire the buttons to ground and to pins. Run the breadboard ground rail to a GND pin, connect one leg of every button to that rail, and connect each button's other leg to its pin: up to 2, down to 3, left to 4, right to 5, A to 6, B to 7. No resistors needed thanks to INPUT_PULLUP.

Connect the OLED over I2C. Wire GND to ground, VCC to 5V, SCL to A5, and SDA to A4. These four wires are all the I2C display needs.

Connect the buzzer. Wire the buzzer's signal to pin 8 and its other lead to ground. A module-style or plain passive buzzer both work.

Upload the test sketch and check everything. Upload the test sketch, then press each button and confirm the screen and buzzer respond. If a part fails, troubleshoot it before moving on; the whole circuit must work before soldering.

Game shield test sketch

#include <Wire.h>
#include <U8g2lib.h>

U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0);

// button pins: up, down, left, right, A, B
const int buttons[6] = {2, 3, 4, 5, 6, 7};
const char* names[6] = {"UP", "DOWN", "LEFT", "RIGHT", "A", "B"};
const int buzzerPin = 8;

void setup() {
  for (int i = 0; i < 6; i++) {
    pinMode(buttons[i], INPUT_PULLUP); // internal resistor, no external one
  }
  pinMode(buzzerPin, OUTPUT);
  u8g2.begin();
}

void loop() {
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_7x13_tf);
  u8g2.drawStr(0, 12, "Press a button:");
  int y = 30;
  for (int i = 0; i < 6; i++) {
    if (digitalRead(buttons[i]) == LOW) { // pressed pulls the pin LOW
      u8g2.drawStr(0, y, names[i]);
      y += 14;
      tone(buzzerPin, 1000, 50);         // short beep on press
    }
  }
  u8g2.sendBuffer();
}

Each button is read with INPUT_PULLUP, so a press reads LOW. The screen lists whichever buttons are down and the buzzer beeps, which confirms the display, all six buttons, and the buzzer in one test.

Common mistakes and troubleshooting

The OLED stays dark. Check the SDA and SCL wiring and confirm the I2C address matches your module (often 0x3C).

A button never registers. Verify one leg goes to ground and the other to the correct pin, and that the pin uses INPUT_PULLUP so a press reads LOW.

The buzzer is silent.