DIY Retro Video Game Console

Learn to build your own retro video game console from scratch using hardware, software, and electronics skills! Explorers in this course will learn the fundamentals behind electronics and specifically gaming consoles to help them in creating their own video game throughout the course! No prior experience in coding, electronics or hardware is required, as we will teach everything needed from the ground up. Join this project for a cumulative experience of building your own video game in just a few hours!

Build your own handheld retro game console from scratch!

  • Learn the fundamentals of electronics projects
  • Learn to model and design systems before production
  • Covers Digital Modeling, Coding, Electronics, and Breadboarding!

This course also offers you the optional opportunity to purchase your own console kit to build during our working sessions, and take it home with you! If you do, you can reprogram the console at any time, especially whenever we make updates to the code across years of the program! This will allow you to add new games to the console, tune the performance, and customize the display however you would like! Feature requests are always welcome if you would like to reach out to us as well. The below guide can be followed to program your take home consoles!

Console Programming Guide

Arduino Programming & Software Architecture Guide

This guide explains how to install the USB-to-TTL drivers, connect your programming adapter, compile, and upload the 2027 Console Code to your custom Handheld Gaming Console using the Arduino IDE. It also provides a detailed technical overview of the software’s codebase structure.


1. Hardware & Software Prerequisites

Before starting, make sure you have the following hardware and software ready:

Codebase Download

First, download the source files and libraries for the 2027 Console Code:

Download 2027 Console Code Repository (.ZIP)

Hardware Requirements

  • Assembled Retro Gaming Console (based on the ATmega328P / Arduino Pro Mini layout).
  • USB 2.0 to TTL Serial Adapter (based on the Silicon Labs CP2102 chipset).
  • USB Cable to connect the TTL adapter to your computer.
  • Female-to-Female Jumper Wires (5 wires required for connection).

Software Requirements

  • Arduino IDE (version 1.8.x or higher, downloaded from the official Arduino Website).
  • CP210x USB to UART Bridge VCP Driver (included inside the downloaded codebase repository).

2. Installing the CP210x USB-to-TTL Drivers

The USB-to-TTL adapter bridges your computer’s USB port with the serial interface of the Arduino. Windows requires the Silicon Labs Virtual COM Port (VCP) driver to communicate with it.

Driver Installation Steps on Windows:

  1. Navigate to the driver folder within your console code directory at:
    Handheld-Color-Console-master/CP210x_Universal_Windows_Driver
  2. If the driver files are zipped, unzip the CP210x_Universal_Windows_Driver.zip archive.
  3. Locate the file named silabser.inf (this has a “Setup Information” file type).
  4. Right-click on silabser.inf and choose Install from the context menu.
  5. Confirm the security prompt by clicking Yes or Open.
  6. After installation, you will see a popup stating: “The operation completed successfully.”

Verifying Driver Installation:

  1. Connect the USB-to-TTL adapter to your PC’s USB port.
  2. Open the Windows start menu, search for Device Manager, and open it.
  3. Scroll down and expand the Ports (COM & LPT) category.
  4. You should see an entry labeled:
    Silicon Labs CP210x USB to UART Bridge (COMx) (where x is the COM port number, e.g., COM3).
  5. Write down or remember this COM Port number; you will need to select it in the Arduino IDE.

3. Connecting the Adapter to the Arduino Console

Connect the pins of the USB-to-TTL adapter directly to the matching pins on your console’s Arduino board using your jumper wires.

⚠️ WARNING: Check Your Voltage Jumper
Ensure the physical jumper on your USB-to-TTL adapter is set to 5V (not 3.3V) to match the console’s operating voltage. Connecting wrong power configurations can prevent programming or damage components.

Wiring Connection Reference:

TTL Adapter Pin Arduino Console Pin Connection Type Purpose / Description
GND GND Parallel Common ground reference
5V or VCC VCC (or 5V input) Parallel Powers the console during programming
TXD (Transmit) RXI or RX (D0) Cross-Over Transmits code instructions from PC to Arduino
RXD (Receive) TXO or TX (D1) Cross-Over Receives execution feedback from Arduino to PC
DTR (Data Terminal Ready) DTR or GRN / RST Reset Line Sends auto-reset pulse to trigger the bootloader
ℹ️ IMPORTANT: TX to RX Cross-Over Rule
You must connect TXD ↔ RXI and RXD ↔ TXO. Connecting TX to TX and RX to RX will prevent serial communication and cause uploads to fail.

For Adapters Without a DTR Pin:

If your serial programmer does not feature a DTR pin, you will need to trigger the programming reset manually:

  1. Press and hold down the physical Reset button on your console’s Arduino board.
  2. Click Upload in the Arduino IDE.
  3. Watch the progress bar at the bottom. The moment the status message switches from “Compiling sketch…” to “Uploading…”, immediately release the Reset button.

4. Compiling and Uploading via Arduino IDE

Follow these steps to configure the IDE and flash the program:

  1. Open the Arduino IDE.
  2. Click File > Open and navigate to: Handheld-Color-Console-master/Console/Console.ino
  3. Configure your target hardware options in the Tools menu:
    • Board: Choose Arduino Pro or Pro Mini (or Arduino Uno if standard Uno bootloader was flashed).
    • Processor: Select ATmega328P (5V, 8 MHz)
    • Port: Choose the active COM Port assigned to your adapter (e.g., COM3).
  4. Click the Verify icon (checkmark) in the top-left to compile and check for errors.
  5. Click the Upload icon (right-pointing arrow) to flash the console.
  6. Wait until the status line displays “Done uploading”. The console will reboot automatically into the main start menu.

5. Codebase Structure & File Overview

The console firmware compiles using a Single Translation Unit model. Console.ino acts as the controller and imports implementation files (.cpp and .c) directly, ensuring simple compiling without complex library linkage settings.

Console.ino

📁 Common/ (Shared Library)

  • TFTv2_extended.cpp/.h
    Custom SPI display driver & 3D block rendering
  • font.c
    Bitmap text characters
  • highscore.h
    Persistent EEPROM scoring
  • joystick.cpp
    Pin assignments & polling
  • beeping.cpp
    Speaker waveforms & sounds
  • sequencer.cpp
    Timer1 interrupt theme player

📁 Tetris/ (Tetris Game)

  • Tetris.cpp
    Tetris gameplay loop, piece shapes with custom rotations, randomizers, board grid state, line checks, and speed levels.

📁 Breakout/ (Breakout Game)

  • breakout.cpp
    Breakout game core
  • ball.cpp / paddle.cpp
    Physics & layout models
  • tiles.cpp / scoreboard.cpp
    Brick grid & UI renderers
  • config.h
    Speed & dimension metrics

Root entry file:

  • Console.ino: Main entry. Handles hardware system booting (`setup()`), rendering the startup choice interface (Tetris or Breakout selection), managing partial screen refreshes to avoid screen flickering, reading the audio mute toggle button (Pin 7), and executing the chosen game loop.

Shared common files (`Common/`):

  • TFTv2_extended.h & .cpp: Modified SPI screen graphic rendering library optimized for landscape orientations, containing text writing and specialized 3D-beveling block functions (fillRectangleUseBevel) to draw retro screen assets.
  • font.c: Raw bitmap coordinate data representing alphanumeric lettering for the TFT rendering system.
  • highscore.h: Real-time high-score storage writer. Writes score data persistently into the Arduino’s non-volatile EEPROM. Utilizes a validation byte (0x5A at address 10) to format memory safely on first boot to avoid reading empty garbage.
  • joystick.cpp: Input reader class. Sets pins as input pull-ups (`INPUT_PULLUP`). Contains functions for translating analog joystick outputs (X/Y on A0/A1) and hardware buttons (Left/D7, Right/D8, Down/A2, Rotate/A3, Click/D2) into coordinate values.
  • beeping.cpp: Generates sound frequencies on Speaker Pin 3 using the microcontroller’s hardware `tone()` driver.
  • sequencer.cpp: Plays the classic Tetris theme asynchronously in the background. Operates on Timer1 interrupts to feed audio data to the speaker output continuously without halting the game loop.

Game specific scripts (`Tetris/` & `Breakout/`):

  • Tetris.cpp: Manages all Tetris mechanics. Houses tetromino block coordinates, collision detection, game speed increase loops, scoreboard redraws, and randomizers.
  • breakout.cpp: Initiates Breakout modules, updates game physics, manages ball respawns, lives, and increments high score arrays on levels cleared.
  • ball.cpp & paddle.cpp: Coordinates moving coordinate vectors for the ball and paddle. Manages boundary checks and bounce reflection angles.
  • tiles.cpp & scoreboard.cpp: Instantiates and tracks individual brick status (destructible grids) and draws Breakout’s lives/score counters.

6. Troubleshooting Upload Issues

If you encounter an upload failure (e.g., avrdude: stk500_getsync(): not in sync: resp=0x00), check these typical issues:

  • Swap TX/RX leads: Ensure adapter’s TX connects to the Arduino’s RX, and adapter’s RX connects to TX. Swapping these is the most common mistake.
  • Verify COM Port: Unplug your TTL adapter, reopen Device Manager, plug it back in, and confirm which COM Port appears. Make sure it matches the Port selected in the IDE.
  • Check Board Settings: Ensure Arduino Pro or Pro Mini is selected and try toggling the processor between ATmega328P (5V, 8 MHz) and ATmega328P (5V, 16 MHz).
  • Confirm Voltage: Check that your adapter’s jumper is set to 5V.
  • Manual Reset Timing: If uploading manually without a DTR connection, ensure you hold the reset button down until compilation completes, releasing it immediately when “Uploading…” begins.