Free · runs in your browser

OLED robot eyes generator for Arduino and ESP32

Design blinking robot eyes that change mood, look around and breathe on a 128×64 SSD1306 or SH1106 OLED. Watch them in a pixel-exact preview, then copy Arduino, U8g2 or MicroPython code that draws them live, with no bitmaps to store.

No sign-up and nothing to install. The code works on Uno, Nano, ESP32, ESP8266 and Raspberry Pi Pico.
Features

Everything a robot face needs

I built this after wiring the same blink and look-around logic into a dozen student desk robots. Now it's sliders.

Pixel-exact preview

The preview uses the same fill routines as Adafruit GFX, so the pixels you see are the pixels the board lights.

Nine moods

Neutral, happy, angry, sad, surprised, suspicious, sleepy, love and confused, with smooth transitions between them.

Blink, look and breathe

Random blinks on a timer you set, idle glances left, right, up and down, and a slow breathing bob.

Mood sequences

Chain moods with a time for each step. The eyes ease from one to the next on their own.

Three code styles

Arduino with Adafruit SSD1306 or SH110X, Arduino with U8g2, or MicroPython for Pico, ESP32 and ESP8266.

Touch and Serial control

Optional TTP223 touch pad that makes the eyes happy, and Serial Monitor commands to switch moods.

Three screen sizes

128×64 (0.96" and 1.3"), 128×32 bars and 128×128 SH1107 panels, with matching constructors.

Bitmap frames too

Prefer frames? Export the current loop as PROGMEM arrays and a short player sketch.

Moods

How each mood is drawn

Every mood starts from the same two rounded rectangles. The expression comes from black "eyelids" drawn on top, which is cheap on a small microcontroller and easy to animate because each lid is one number that slides from 0 to its target.

  • Neutral is the plain rounded eye. It's the resting face most desk robots return to.
  • Happy cuts a large round shape out of the bottom of each eye, leaving the upside-down "smiling" arches.
  • Angry drops a triangle on the inner top corner of each eye, so the brows slant down toward the nose.
  • Sad or tired mirrors that triangle to the outer corners, so the eyes droop outward.
  • Surprised grows the eyes wider and taller. Add pupils and it reads as wide-eyed shock.
  • Suspicious closes the top and bottom lids a little for a narrow squint.
  • Sleepy lowers a flat top lid over most of each eye. Pair it with a slow blink.
  • Love swaps each eye for a heart built from two circles and a triangle.
  • Confused makes one eye smaller and the other larger, with a slight brow tilt.

Because moods are numbers, not pictures, a change from angry to happy is a smooth morph rather than a jump cut. It's the detail people notice first when a robot looks alive.

How it works

From sliders to a running robot face in three steps

Shape the eyes

Open the generator, pick your screen, then set eye width, height, corner radius, gap and pupils while the live preview updates.

Choose moods and behaviour

Pick a mood or build a sequence of moods, then set the blink interval, the look-around range and the breathing bob.

Copy the code and upload

Choose Adafruit GFX, U8g2 or MicroPython, copy the code, install the library, wire SDA and SCL, and upload.

Why procedural

Drawing the eyes beats storing frames

The usual way to animate eyes on an OLED is a stack of bitmaps. A full 128×64 frame is 1,024 bytes, so a smooth blink of eight frames is 8 KB, and a few moods with blinks quickly pass the 32 KB of flash on an Uno. The generated sketch takes another route: it draws two rounded rectangles every frame and cuts the expression out with triangles and rectangles. The whole face is a handful of numbers.

That has three practical benefits. The sketch fits an Uno with room left for sensors, a servo and your own logic. Blinks and glances are continuous, so the eyes can look anywhere rather than at four fixed positions. And you can change the mood from code with one variable, which is what you want when a distance sensor or a button decides how the robot feels.

Bitmaps still have a place when you want hand-drawn detail, like lashes, sparkles or a logo in the pupil. For that, export frames from this tool or draw them in the OLED Animation Maker. My robot eyes tutorial walks through the same geometry by hand if you want to understand every line.

Wiring

Wire the OLED to your board

Every module here is I2C with four pins. Power the OLED from 3.3 V or 5 V, whichever your module accepts, and share ground with the board.

I2C OLED wiring for common boards
BoardSDASCLNotes
Arduino Uno / NanoA4A5Procedural sketch fits easily. Keep bitmap exports under about 20 frames.
ESP32GPIO 21GPIO 22Plenty of memory for 128×128 SH1107 panels and long frame exports.
ESP8266 NodeMCUD2 (GPIO 4)D1 (GPIO 5)Use 3.3 V for the OLED.
Raspberry Pi PicoGP4GP5Works with the Arduino code or the MicroPython export.

SSD1306 or SH1106?

Most 0.96 inch modules are SSD1306 and most 1.3 inch modules are SH1106. If you pick the wrong one, the SH1106 shows a two-pixel strip of noise on one side and the eyes sit off-centre. Choose SH1106 in the generator and the code switches to the Adafruit SH110X library or the U8g2 SH1106 constructor. If the screen stays dark, try address 0x3D instead of 0x3C.

Tips for 128×32 bar displays

A 0.91 inch 128×32 OLED is only 32 pixels tall, so the generator caps the eye height when you choose it. Wide, short eyes with a radius of 4 to 6 read best, and a look-around range of 2 to 3 pixels up and down keeps them on the glass. Sleepy and happy still work well. Surprised has less room to grow.

One eye per screen

For bigger eyes, use two OLEDs. Generate one-eye (cyclops) code, put the second module on address 0x3D, and draw once per display with the gaze mirrored for the right eye. My guide to two OLED displays on one Arduino covers the address jumper and the wiring, and the ESP32 OLED animation guide covers faster I2C for smoother motion.

Desk robot

Turn the eyes into an EMO or Cozmo-style desk robot

The rounded, pupil-less look of popular desk robots is the Round desk robot preset: two soft squares, a small gap and quick blinks. On its own it already feels alive. Adding one input makes it feel aware.

  • Touch: a TTP223 touch pad on any digital pin. Enter the pin in the generator and a tap makes the eyes happy for two seconds.
  • Head movement: a small SG90 servo. Read gx, the current gaze, and turn the servo the same way so the head follows the eyes.
  • Distance: an ultrasonic or ToF sensor. Set overrideMood = SURPRISED; when something gets close, and back to -1 when it leaves.
  • Sound: a microphone module. A loud clap can trigger a blink with blinking = true; blinkStart = millis();.
  • Time: after 30 seconds without input, switch to sleepy. It's a simple timer and people love it.

Power the servo from its own 5 V supply and share ground. A servo pulling current from the same rail as the OLED causes flicker and random resets, the most common desk robot bug I see.

Ready to give your robot a face?

Open the generator, pick a mood and copy the sketch. It takes about two minutes.

Open the robot eyes generator
Questions

Robot eyes FAQ

Will the robot eyes code fit on an Arduino Uno?

Yes. The procedural sketch draws the eyes with rounded rectangles and triangles, so it stores no images. With the Adafruit SSD1306 library it uses about 60 percent of an Uno's flash and a quarter of its RAM, leaving room for sensors and a servo. Bitmap frame export is bigger, about 1 KB per 128x64 frame.

Does it work with an SH1106 1.3 inch OLED?

Yes. Pick SH1106 128x64 as the screen. The Adafruit option switches to the Adafruit SH110X library and the U8g2 option uses the SH1106 constructor, so the eyes are not shifted by two pixels.

Can I make EMO or Cozmo style eyes?

Yes. Rounded rectangle eyes with no pupils, a small gap and quick blinks give that desk robot look. Start from the Round desk robot preset, then add happy, sleepy and angry moods to a sequence.

How do I change the mood from my own code?

Set overrideMood to a mood such as HAPPY or ANGRY anywhere in your sketch, and set it to -1 to go back to the sequence. You can also tick Serial Monitor control and send 0 to 8, or add a touch sensor pin that makes the eyes happy when tapped.

Can I use two OLEDs, one for each eye?

Yes. Generate one-eye (cyclops) code, create a second display object at I2C address 0x3D, and call the draw function once per screen with the gaze mirrored. The dual OLED guide on this site shows the wiring and the address jumper.

Is the robot eyes generator free?

Yes. The editor, the preview and every code export are free, with no sign-up. Everything runs in your browser and nothing is uploaded.

Related searches: oled robot eyes · robot eyes oled · oled eyes arduino · arduino oled eyes · esp32 robot eyes · ssd1306 robot eyes · sh1106 robot eyes · desk robot eyes · emo robot eyes · cozmo eyes oled · animated eyes arduino · oled face animation · robot face oled · blinking eyes oled · u8g2 robot eyes · micropython robot eyes