Community project
Animated OLED Eyes
This project brings a small OLED display to life with animated eyes that blink and look around. Built around an Arduino Uno and a 0.66-inch OLED screen, the eyes follow a smooth animation cycle with natural-looking pupil movement and periodic blinking.
The guide includes a complete wiring diagram showing how to connect the display to the Arduino via I2C, a full parts list, and ready-to-upload firmware that handles all the animation logic. Assembly takes just a few minutes—connect power, ground, and the two signal wires, then upload the code to see the eyes come alive.
Wiring diagram

Gather all the parts
Assemble it in 4 steps
1. Place the Nano and screen
With the Nano unplugged, place the Classic Arduino Nano and the small four-pin OLED on a breadboard or non-metal table. Find the screen pins labelled VCC, GND, SDA, and SCL.
- The screen must be a 0.96-inch, 128×64 I²C SSD1306 module marked 3.3–5 V or 5 V compatible.
- Do not move wires while the Nano is powered, because a misplaced wire can short the power pins.
2. Connect power and ground
Connect OLED VCC to Nano 5V (power). Connect OLED GND to Nano GND (ground). This 3.3–5 V compatible screen is designed for the Nano's 5 V power and signal wires.
- Use a red wire for VCC and a black wire for GND if you have them.
- Make sure VCC and GND are not swapped — swapped power can damage the screen.
3. Connect the two signal wires
Connect OLED SDA to Nano A4 (data). Connect OLED SCL to Nano A5 (data). These two wires carry the drawing commands that make the eyes move.
- A4 and A5 are printed beside the Nano's analogue-pin header.
- Do not connect the OLED SDA or SCL pin straight to 5V or GND.
4. Start the moving eyes
Check all four screen wires, plug the Nano into USB, then press Deploy in Schematik. The two eyes look left, centre, and right and blink.
- If the screen stays blank, first check that SDA and SCL have not been swapped.
- Only use the direct wiring shown here with the replacement OLED marked 3.3–5 V or 5 V compatible.
Review all connections
1. Connections between "oled_1" and "Arduino"
Deploy the firmware
#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
void drawEye(int centerX, int pupilX, bool blinking);
void drawFace();
const uint8_t SCREEN_WIDTH = 128;
const uint8_t SCREEN_HEIGHT = 64;
const uint8_t OLED_ADDRESS = 0x3C;
const int I2C_SDA_PIN = 18; // Nano A4
const int I2C_SCL_PIN = 19; // Nano A5
const unsigned long FRAME_INTERVAL_MS = 50UL;
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
unsigned long lastFrameMs = 0;
uint16_t frameNumber = 0;
void drawEye(int centerX, int pupilX, bool blinking) {
if (blinking) {
display.drawFastHLine(centerX - 23, 32, 47, SSD1306_WHITE);
return;
}
display.fillRoundRect(centerX - 24, 16, 48, 34, 15, SSD1306_WHITE);
display.fillCircle(pupilX, 33, 9, SSD1306_BLACK);
display.fillCircle(pupilX - 3, 29, 2, SSD1306_WHITE);
}
void drawFace() {
uint16_t cycleFrame = frameNumber % 180;
bool blinking = (cycleFrame >= 150 && cycleFrame < 156) ||
(cycleFrame >= 160 && cycleFrame < 164);
int8_t lookOffset = 0;
if (cycleFrame < 45) {
lookOffset = -6;
} else if (cycleFrame < 90) {
lookOffset = 0;
} else if (cycleFrame < 135) {
lookOffset = 6;
}
display.clearDisplay();
drawEye(35, 35 + lookOffset, blinking);
drawEye(93, 93 + lookOffset, blinking);
display.display();
}
void setup() {
Wire.begin();
if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDRESS)) {
for (;;) {
}
}
drawFace();
}
void loop() {
unsigned long now = millis();
if (now - lastFrameMs >= FRAME_INTERVAL_MS) {
lastFrameMs = now;
frameNumber++;
drawFace();
}
}Remix this project
Make it yours in one click
Open a full copy of this project in your own Schematik workspace — diagram, code, parts, and assembly steps included. Swap the sensor, add features, or redesign the whole thing with AI. The author's original stays untouched.




