Dual-Controller OLED Tic-Tac-Toe

Introduction

Dual-Controller OLED Tic-Tac-Toe is a portable handheld gaming device specifically designed for two players or player versus bot. This project brings the classic game of Tic-Tac-Toe to a custom electronic platform built around an Arduino Uno board.

Project Goals:

  • Functionality: Provides the opportunity for two players to compete in Tic-Tac-Toe on a digital display using independent controllers.
  • Purpose: To demonstrate the synchronization between hardware components and embedded software to ensure real-time response to user inputs.
  • Inspiration: The project started from the desire to create a “face-to-face” multiplayer experience using physical joysticks instead of a simple smartphone screen.
  • Relevance: For the developer, it is an excellent way to learn how to interface with OLED displays (expanding on lab knowledge) and how to process analog signals from joysticks. For users, it offers a simple and fun way to spend time together.
  • Versatility: Includes both a Multiplayer mode for head-to-head competition and a Single Player mode featuring an automated opponent (Bot) to allow for solo practice and testing.

General Description

The project consists of several integrated subsystems that handle input processing, game logic execution, and visual feedback:

Hardware Components:

  • Control Unit: Two joysticks (one for each player). These are used to navigate the cursor on the screen and select a cell by pressing down on the stick (integrated button).
  • Central Processing Unit: The Arduino Uno board, which manages the game state, tracks the score, validates winning conditions, and toggles player turns.
  • Display Unit: A small OLED display used to render the game grid, as well as the X and O symbols.
  • Audio Feedback: A passive buzzer that emits short tones for each move or a specific melody upon game completion.

Software Components:

  • Input Handling: The firmware monitors joystick analog movements and maps voltage variations to grid positions (0, 1, or 2 for both axes).
  • Game Logic: Implements a 2D array representation of the board and detects winning conditions (rows, columns, or diagonals) or a draw.
  • Display Control: Utilizes I2C communication to render graphics dynamically using the Adafruit GFX library.

Hardware Design

This section describes the electronic components used to build the gaming console and their interconnections.

Bill of Materials (BOM)

Component Quantity Description / Role
Arduino Uno R3 1 Central Processing Unit (ATmega328P microcontroller).
OLED Display (SSD1306) 1 128×64 pixel monochrome screen, I2C interface, for rendering the game grid.
Joystick KY-023 2 Analog modules for cursor control (X/Y) and selection (integrated button).
Passive Buzzer KY-006 1 Provides audio feedback (PWM tones) for moves, errors, and victory.
Breadboard (400 points) 1 Platform for solderless electrical connections.
Dupont Wires 1 set Interconnecting wires for the components.

Electrical Schematic

Software Design

The firmware is designed using a Finite State Machine (FSM) approach to manage game transitions, coupled with real-time polling of analog sensors.

Development Environment

Arduino IDE 2.3.x: Used for coding, compiling, and flashing the firmware onto the ATmega328P microcontroller. Serial Monitor: Utilized during the debugging phase to calibrate joystick thresholds and I2C address discovery.

3rd-party Libraries

Adafruit_SSD1306: Essential for handling the display buffer and I2C communication protocol for the SSD1306 OLED.

Adafruit_GFX: Provides the graphics core for rendering lines, circles, and text characters.

Wire.h: The standard Arduino I2C library used for data transmission between the MCU and the display.

Algorithms and Data Structures

2D Array Representation: The game board is stored in a int board[3][3] matrix, where $0$ is empty, $1$ is 'X', and $2$ is 'O'.

Threshold Detection Algorithm: Analog joystick values ($0-1023$) are processed using a hysteresis-like logic ($<300$ and $>700$) to prevent “ghost” movements.

Win-Check Algorithm: A deterministic function that scans 8 possible vectors (3 rows, 3 columns, 2 diagonals) for identical non-zero values.

Randomized AI Logic: A pseudo-random selection algorithm that identifies available indices in the board matrix to perform automated moves.

Implemented Functions

setup(): Initializes I2C communication, sets pin modes for joysticks, and seeds the random generator using noise from an open analog pin (A5).

drawMenu(): Handles the UI for mode selection (Single Player vs Multiplayer) and processes Joystick 1 input for navigation.

tttGameLoop(): The core engine that manages turns, calls the input mapping functions, and updates the game state.

botMove(): Implements the automated opponent logic with an artificial delay to simulate human-like interaction.

checkWin() & checkDraw(): Logic functions that return boolean values to trigger the end-of-game state.

drawTTTGrid(): A dedicated rendering function that draws the board lines and iterates through the matrix to display X and O symbols.

playVictorySound() / playDrawSound(): PWM-based functions that use the tone() command to provide audio feedback through the buzzer.

Results

The project resulted in a fully functional handheld console. The system successfully handles real-time input from two controllers without latency. The OLED display provides a clear interface, and the integrated Bot offers a challenging solo experience. The memory optimizations (using the F() macro) ensured the system remains stable during long play sessions.

Conclusions

todo

Source Code

todo

Bibliography/Resources

Software Resources

Hardware Resources

pm/prj2026/jan.vaduva/bogdan.ciupitu.txt · Last modified: 2026/05/15 14:34 by bogdan.ciupitu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0