Joystick-Controlled Animated Eyes on OLED Display Using Arduino

Bring your projects to life with a pair of expressive eyes! In this Arduino project, we use a joystick to control two animated pupils on an OLED screen. Pressing the joystick button makes the eyes “close,” simulating blinking. This project is perfect for interactive props, beginner animatronics, or just learning how to handle displays and analog input.

It’s simple, fun, and a great introduction to combining input controls with graphic displays using the Adafruit SSD1306 OLED and Adafruit GFX libraries.

PCBWay offers high-quality PCB prototyping and assembly at an affordable price, starting at just $5 for 5 PCBs. With fast turnaround, great customer support, and easy online ordering, it’s a top choice for hobbyists and professionals alike.

Hardware Components

You’ll need the following hardware components to get started:

ComponentModel / TypeQty
Arduino UNOR3 Board1
OLED DisplaySSD1306 128×64 I2C (0.96″)1
Joystick ModuleAnalog X/Y + Pushbutton1
BreadboardFull-size or half-size1
Jumper WiresMale-to-male1 set
USB CableFor Arduino UNO (Type B)1

How It Works ?

Joystick Inputs

  • The analog X and Y values are read from pins A0 and A1.
  • The push button is read from digital pin D2.
  • Analog values are mapped to pupil movement ranges (-7 to +7).

Drawing Eyes

  • Two large eye outlines are drawn at fixed positions.
  • Pupils are drawn inside those eyes based on joystick input.

Button = Blink

  • If the button is pressed, instead of pupils, two eyelids (lines) are drawn.
  • This simulates a “blinking” action.

OLED Display Update

After each update, the OLED screen is cleared and redrawn for smooth animation.

Schematic

Make connections according to the circuit diagram given below.

Wiring / Connections

Arduino UNOJoystickOLED (SSD1306)
A0X-axis output
A1Y-axis output
D2Button (SW pin)
5VVCCVCC
GNDGNDGND
A4SDA
A5SCL

Arduino Code

#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET    -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

// Joystick pins
#define JOYSTICK_X A0
#define JOYSTICK_Y A1
#define JOYSTICK_BUTTON 2

void setup() {
  pinMode(JOYSTICK_BUTTON, INPUT_PULLUP);

  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;);
  }

  display.clearDisplay();
  display.display();
}

void drawEye(int x, int y) {
  display.drawCircle(32, 32, 15, SSD1306_WHITE); // Left eye
  display.drawCircle(96, 32, 15, SSD1306_WHITE); // Right eye

  display.fillCircle(32 + x, 32 + y, 5, SSD1306_WHITE); // Left pupil
  display.fillCircle(96 + x, 32 + y, 5, SSD1306_WHITE); // Right pupil
}

void drawEyelids() {
  display.drawLine(17, 32, 47, 32, SSD1306_WHITE);  // Left lid
  display.drawLine(81, 32, 111, 32, SSD1306_WHITE); // Right lid
}

void loop() {
  int joystickX = analogRead(JOYSTICK_X);
  int joystickY = analogRead(JOYSTICK_Y);
  bool buttonPressed = !digitalRead(JOYSTICK_BUTTON);

  int pupilX = map(joystickX, 0, 1023, -7, 7);
  int pupilY = map(joystickY, 0, 1023, -7, 7);

  display.clearDisplay();

  if (buttonPressed) {
    drawEyelids(); // Close eyes
  } else {
    drawEye(pupilX, pupilY); // Move pupils
  }

  display.display();
  delay(50);
}

Conclusion

This project is a perfect weekend build that introduces joystick control, basic animation, and interactive display techniques.