15 Mood Animated AI Robot Eyes on MagicBit & ESP32 – Cozmo Style DIY Project

 


Bring your DIY robot to life with animated eyes that express 16 moods: Neutral, Happy, Sad, Angry, Shock, and Sleep (with ZZZ animation and optional buzzer sound). Using MagicBit with built-in OLED or ESP32 with SSD1306 OLED, you can add realistic AI-style emotions to your robot. This project is perfect for hobbyists, makers, and students looking to make their robots more expressive.

Each mood lasts about 5 seconds, and smooth micro-movements (saccades) make the eyes appear alive and reactive. Sleep mood includes a ZZZ animation with sound, while shock or angry moods use simple blink animations for realism.

Animated eyes add realistic AI-like emotions to your robot. Instead of static rectangles or circles, your robot can look happy, sad, angry, or even sleepy, making it more interactive. This is especially helpful for hobbyists, students, and makers creating desktop robots similar to Cozmo-style robots.


MagicBit vs ESP32 Comparison

MagicBit:

  • Built-in OLED – no external display needed

  • Compact and beginner-friendly

  • Quick to setup and run

  • Ideal for small desktop robots or simple AI eyes

ESP32:

  • More powerful, supports complex animations and AI

  • External OLED (SSD1306) required

  • Can integrate Wi-Fi or Bluetooth for web-based mood control

  • Great for advanced robotics projects or remote control

Both platforms can run this project with 6 expressive moods, making your robot interactive and lively.


Libraries Used

  1. Adafruit SSD1306 – for OLED display control

  2. Adafruit GFX Library – required by SSD1306


Components Needed

  • MagicBit with built-in OLED or ESP32 + SSD1306 OLED

  • Passive buzzer (optional for sleep or mood sounds)

  • Jumper wires (if using ESP32 + external OLED)


15 Expressive Moods for Animated Eyes

  • Neutral

  • Happy

  • Sad

  • Angry

  • Blink

  • Sleep

  • Crying

  • Thinking

  • Love

  • Excited

  • Confused

  • Flirt

  • Scared

  • Grumpy

  • Shock


Full Arduino Code

#include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1); // Eye base parameters int eyeW = 40, eyeH = 40; int eyeSpacing = 10; int cornerRadius = 10; int leftX = SCREEN_WIDTH/2 - eyeW/2 - eyeSpacing/2; int rightX = SCREEN_WIDTH/2 + eyeW/2 + eyeSpacing/2; int leftY = SCREEN_HEIGHT/2; int rightY = SCREEN_HEIGHT/2; // Mood timing const int MOOD_COUNT = 15; int currentMood = 0; unsigned long lastMoodChange = 0; const int MOOD_TIME = 5000; // 5 seconds per mood void setup() { Serial.begin(115200); if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) while(1); randomSeed(analogRead(0)); } // Draw both eyes void drawEyes(int w, int h) { display.clearDisplay(); display.fillRoundRect(leftX - w/2, leftY - h/2, w, h, cornerRadius, SSD1306_WHITE); display.fillRoundRect(rightX - w/2, rightY - h/2, w, h, cornerRadius, SSD1306_WHITE); display.display(); } // Blink both eyes void blink() { drawEyes(eyeW, eyeH-10); delay(100); drawEyes(eyeW, eyeH); delay(100); } // Blink one eye only (leftEye = true for left, false for right) void singleEyeBlink(bool leftEye) { display.clearDisplay(); if(leftEye) { display.fillRoundRect(leftX - eyeW/2, leftY - (eyeH-10)/2, eyeW, eyeH-10, cornerRadius, SSD1306_WHITE); display.fillRoundRect(rightX - eyeW/2, rightY - eyeH/2, eyeW, eyeH, cornerRadius, SSD1306_WHITE); } else { display.fillRoundRect(leftX - eyeW/2, leftY - eyeH/2, eyeW, eyeH, cornerRadius, SSD1306_WHITE); display.fillRoundRect(rightX - eyeW/2, rightY - (eyeH-10)/2, eyeW, eyeH-10, cornerRadius, SSD1306_WHITE); } display.display(); delay(100); // Reopen the blinking eye drawEyes(eyeW, eyeH); delay(100); } // Sleep mood with ZZZ void sleepMood() { for(int h=eyeH; h>=10; h-=2) { drawEyes(eyeW,h); delay(50); } display.setTextSize(2); display.setTextColor(SSD1306_WHITE); display.setCursor(50,5); display.println("ZZZ"); display.display(); delay(800); for(int h=10; h<=eyeH; h+=2) { drawEyes(eyeW,h); delay(50); } } // Angry mood void angryMood() { for(int i=0;i<5;i++){ display.clearDisplay(); display.fillTriangle(leftX-20,leftY-15,leftX+20,leftY-15,leftX-20,leftY-10,SSD1306_WHITE); display.fillTriangle(rightX-20,rightY-15,rightX+20,rightY-15,rightX+20,rightY-10,SSD1306_WHITE); display.fillRoundRect(leftX-eyeW/2,leftY-10,eyeW,eyeH-10,cornerRadius,SSD1306_WHITE); display.fillRoundRect(rightX-eyeW/2,rightY-10,eyeW,eyeH-10,cornerRadius,SSD1306_WHITE); display.display(); delay(200); } } // Crying mood void cryingMood() { drawEyes(eyeW, eyeH-5); for(int t=0;t<5;t++){ display.fillCircle(leftX-10,leftY+20+t*2,3,SSD1306_WHITE); display.fillCircle(rightX+10,rightY+20+t*2,3,SSD1306_WHITE); display.display(); delay(200); } } // Thinking mood void thinkingMood() { for(int i=0;i<5;i++){ leftX+=2; rightX+=2; drawEyes(eyeW,eyeH); delay(200); } for(int i=5;i>=0;i--){ leftX-=2; rightX-=2; drawEyes(eyeW,eyeH); delay(200); } leftX = SCREEN_WIDTH/2 - eyeW/2 - eyeSpacing/2; rightX = SCREEN_WIDTH/2 + eyeW/2 + eyeSpacing/2; } // Love / heart eyes void loveMood() { display.clearDisplay(); display.fillTriangle(leftX,leftY-10,leftX-10,leftY+5,leftX+10,leftY+5,SSD1306_WHITE); display.fillTriangle(rightX,rightY-10,rightX-10,rightY+5,rightX+10,rightY+5,SSD1306_WHITE); display.display(); delay(500); } // Excited mood void excitedMood() { for(int i=0;i<5;i++){ drawEyes(eyeW+random(0,5),eyeH+random(0,5)); delay(100); } } // Confused mood void confusedMood() { drawEyes(eyeW+5, eyeH-5); delay(500); } // Flirt / Sexy void flirtMood() { drawEyes(eyeW,eyeH-10); delay(500); } // Scared void scaredMood() { drawEyes(eyeW+10, eyeH-10); delay(300); } // Grumpy void grumpyMood() { drawEyes(eyeW-5,eyeH+5); delay(300); } // Slight shock void shockMood() { drawEyes(eyeW+3,eyeH-3); delay(300); } // Micro-movement for realism void saccade() { int dx=random(-2,3); int dy=random(-1,2); leftX=SCREEN_WIDTH/2 - eyeW/2 - eyeSpacing/2 + dx; rightX=SCREEN_WIDTH/2 + eyeW/2 + eyeSpacing/2 + dx; leftY=SCREEN_HEIGHT/2 + dy; rightY=SCREEN_HEIGHT/2 + dy; } // Execute mood void doMood(int m) { switch(m) { case 0: drawEyes(eyeW,eyeH); break; // Neutral case 1: drawEyes(eyeW+5,eyeH); break; // Happy case 2: drawEyes(eyeW,eyeH-5); break; // Sad case 3: angryMood(); break; case 4: blink(); break; case 5: sleepMood(); break; case 6: cryingMood(); break; case 7: thinkingMood(); break; case 8: loveMood(); break; case 9: excitedMood(); break; case 10: confusedMood(); break; case 11: flirtMood(); break; case 12: scaredMood(); break; case 13: grumpyMood(); break; case 14: shockMood(); break; } } void loop() { // Change mood every MOOD_TIME if(millis()-lastMoodChange>=MOOD_TIME){ currentMood = (currentMood+1) % MOOD_COUNT; lastMoodChange = millis(); } // Random blink: full blink 5% or one-eye blink 5% int r = random(0,100); if(r < 5) blink(); else if(r >=5 && r < 10) singleEyeBlink(random(0,2)); doMood(currentMood); saccade(); delay(50); }

“Create AI robot eyes with 6 moods on MagicBit or ESP32 using OLED. Includes Neutral, Happy, Sad, Angry, Shock, and Sleep (ZZZ with buzzer) moods for expressive robots.”

MagicBit, ESP32, AI Robot, Animated Eyes, DIY Robot, Cozmo Robot, SSD1306 OLED, Sleep Mood, Blink Animation, Angry Mood, Shock Mood, Happy Mood, Sad Mood, Crying Mood, Thinking Mood, Electronics Project, Maker Project, Robot Personality, Robotics, Hobby Electronics, Arduino Project, Arduino OLED, Passive Buzzer, Robot Animation


Comments