Arduino OLED Eyes Animation for Robotics Projects
Quote from Matoo robot on 2024年7月2日, pm4:45The "Arduino OLED Eyes Animation for Robotics Projects" is a curated guide showcasing five different methods for creating lively and expressive eye animations on Arduino-based robots using OLED displays. Each method offers unique features and functionalities, from simple eye movements and mood expressions to more sophisticated techniques involving bitmap images and optimized memory usage. Whether you're a beginner or seasoned hobbyist, this project provides a comprehensive overview of how to implement captivating eye animations that add personality and realism to your robotic creations. Explore the diverse options and unleash your creativity in the exciting realm of Arduino robotics!
Project description
In the vast realm of robotics, enthusiasts are venturing into the exciting world of OLED eye animations for Arduino robots. If you've found yourself lost in the maze of online searches, fear not! We've done the legwork and distilled the top five methods for creating captivating eye animations into a clear and fun comparison.
Introducing our selections:
Option 1: Eye Animation on OLED Display by Intellar
Eye Animation on OLED Display by Intellar
Intellar's approach brings cool eye animations to life with simple functions mimicking various moods (Normal, Sleep, Smile) and versatile eye movements. Pro: Easy to use with adjustable eye positions. Con: Limited to three moods.
Option 2: Simple Animated Eye Using Arduino by SpiderMaf
Simple Animated Eye Using Arduino by SpiderMaf
SpiderMaf's method features circular eyes with pupils for precise movements, adding a touch of humanity to your robot. Pro: Compact functions with customizable features. Con: Similar to Intellar's approach.
Option 3: Akno by AbdulsalamAbbod
Akno by AbdulsalamAbbod
Akno stands out with its expressive rectangular eyes and a wide range of emotions, suitable for various display types. Pro: Supports multiple expressions. Con: Less flexible in adjusting eye size.
Option 4: Arduino OLED Moving Eyes by Vinny
Arduino OLED Moving Eyes by Vinny
Vinny's innovative technique involves rendering custom images on OLED displays, though it comes with memory constraints. Pro: External image rendering capability. Con: Memory-intensive process.
Option 5: Arduino UNO Robotic Eye Animations by Picaio
Arduino UNO Robotic Eye Animations by Picaio
Picaio offers a sophisticated yet realistic approach with diverse eye movements and expressions, enhancing animation realism. Pro: Optimized technique for efficient memory usage. Con: May be challenging for beginners due to its complexity.
Whether you're a seasoned hobbyist or just starting out, these methods provide a gateway to bringing your robot's personality to life! Get ready to dive in, experiment, and unleash your creativity with our official webpage Explaining this project $ Arduino OLED Animations $ as your guide!
Let's animate those robotic eyes and inject some fun into your Arduino projects! 🤖👀
Code
Eye Animation on OLED Display by Intellar
#include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels #define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin) #define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32 Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); // Adjustable int ref_eye_height = 40; int ref_eye_width = 40; int ref_space_between_eye = 10; int ref_corner_radius = 10; //current state of the eyes int left_eye_height = ref_eye_height; int left_eye_width = ref_eye_width; int left_eye_x = 32; int left_eye_y = 32; int right_eye_x = 32 + ref_eye_width + ref_space_between_eye; int right_eye_y = 32; int right_eye_height = ref_eye_height; int right_eye_width = ref_eye_width; int dir_x = 0; int dir_y = 0; int count = 0; void draw_eyes(bool update = true); void center_eyes(bool update = true); void blink(int speed = 12); void sleep(); void wakeup(); void happy_eye(); void saccade(int direction_x, int direction_y); void move_right_big_eye(); void move_left_big_eye(); void move_big_eye(int direction); int timeD = 1000; void draw_eyes(bool update = true) { display.clearDisplay(); //draw from center int x = int(left_eye_x - left_eye_width / 2); int y = int(left_eye_y - left_eye_height / 2); display.fillRoundRect(x, y, left_eye_width, left_eye_height, ref_corner_radius, SSD1306_WHITE); x = int(right_eye_x - right_eye_width / 2); y = int(right_eye_y - right_eye_height / 2); display.fillRoundRect(x, y, right_eye_width, right_eye_height, ref_corner_radius, SSD1306_WHITE); if (update) { display.display(); } } void center_eyes(bool update = true) { //move eyes to the center of the display, defined by SCREEN_WIDTH, SCREEN_HEIGHT left_eye_height = ref_eye_height; left_eye_width = ref_eye_width; right_eye_height = ref_eye_height; right_eye_width = ref_eye_width; left_eye_x = SCREEN_WIDTH / 2 - ref_eye_width / 2 - ref_space_between_eye / 2; left_eye_y = SCREEN_HEIGHT / 2; right_eye_x = SCREEN_WIDTH / 2 + ref_eye_width / 2 + ref_space_between_eye / 2; right_eye_y = SCREEN_HEIGHT / 2; draw_eyes(update); } void blink(int speed = 12) { draw_eyes(); for (int i = 0; i < 3; i++) { left_eye_height = left_eye_height - speed; right_eye_height = right_eye_height - speed; draw_eyes(); delay(1); } for (int i = 0; i < 3; i++) { left_eye_height = left_eye_height + speed; right_eye_height = right_eye_height + speed; draw_eyes(); delay(1); } } void sleep() { // DRAWS A LINE TO LOOK LIKE SLEEPING left_eye_height = 2; right_eye_height = 2; draw_eyes(true); } void wakeup() { // WAKE UP THE EYES FROM AN LINE TO ROUND CORNERED SQUARE sleep(); for (int h = 0; h <= ref_eye_height; h += 2) { left_eye_height = h; right_eye_height = h; draw_eyes(true); } } void happy_eye() { center_eyes(false); //draw inverted triangle over eye lower part int offset = ref_eye_height / 2; for (int i = 0; i < 10; i++) { display.fillTriangle(left_eye_x - left_eye_width / 2 - 1, left_eye_y + offset, left_eye_x + left_eye_width / 2 + 1, left_eye_y + 5 + offset, left_eye_x - left_eye_width / 2 - 1, left_eye_y + left_eye_height + offset, SSD1306_BLACK); // display.fillRect(left_eye_x-left_eye_width/2-1, left_eye_y+5, left_eye_width+1, 20,SSD1306_BLACK); display.fillTriangle(right_eye_x + right_eye_width / 2 + 1, right_eye_y + offset, right_eye_x - left_eye_width / 2 - 1, right_eye_y + 5 + offset, right_eye_x + right_eye_width / 2 + 1, right_eye_y + right_eye_height + offset, SSD1306_BLACK); // display.fillRect(right_eye_x-right_eye_width/2-1, right_eye_y+5, right_eye_width+1, 20,SSD1306_BLACK); offset -= 2; display.display(); delay(1); } display.display(); delay(1000); } void saccade(int direction_x, int direction_y) { //quick movement of the eye, no size change. stay at position after movement, will not move back, call again with opposite direction //direction == -1 : move left //direction == 1 : move right int direction_x_movement_amplitude = 8; int direction_y_movement_amplitude = 6; int blink_amplitude = 8; for (int i = 0; i < 1; i++) { left_eye_x += direction_x_movement_amplitude * direction_x; right_eye_x += direction_x_movement_amplitude * direction_x; left_eye_y += direction_y_movement_amplitude * direction_y; right_eye_y += direction_y_movement_amplitude * direction_y; right_eye_height -= blink_amplitude; left_eye_height -= blink_amplitude; draw_eyes(); delay(1); } for (int i = 0; i < 1; i++) { left_eye_x += direction_x_movement_amplitude * direction_x; right_eye_x += direction_x_movement_amplitude * direction_x; left_eye_y += direction_y_movement_amplitude * direction_y; right_eye_y += direction_y_movement_amplitude * direction_y; right_eye_height += blink_amplitude; left_eye_height += blink_amplitude; draw_eyes(); delay(1); } } void move_right_big_eye() { move_big_eye(1); } void move_left_big_eye() { move_big_eye(-1); } void move_big_eye(int direction) { // MOVES TO RIGHT OR LEFT DEPENDING ON 1 OR -1 INPUT. //direction == -1 : move left //direction == 1 : move right int direction_oversize = 1; int direction_movement_amplitude = 2; int blink_amplitude = 5; for (int i = 0; i < 3; i++) { left_eye_x += direction_movement_amplitude * direction; right_eye_x += direction_movement_amplitude * direction; right_eye_height -= blink_amplitude; left_eye_height -= blink_amplitude; if (direction > 0) { right_eye_height += direction_oversize; right_eye_width += direction_oversize; } else { left_eye_height += direction_oversize; left_eye_width += direction_oversize; } draw_eyes(); delay(1); } for (int i = 0; i < 3; i++) { left_eye_x += direction_movement_amplitude * direction; right_eye_x += direction_movement_amplitude * direction; right_eye_height += blink_amplitude; left_eye_height += blink_amplitude; if (direction > 0) { right_eye_height += direction_oversize; right_eye_width += direction_oversize; } else { left_eye_height += direction_oversize; left_eye_width += direction_oversize; } draw_eyes(); delay(1); } delay(1000); for (int i = 0; i < 3; i++) { left_eye_x -= direction_movement_amplitude * direction; right_eye_x -= direction_movement_amplitude * direction; right_eye_height -= blink_amplitude; left_eye_height -= blink_amplitude; if (direction > 0) { right_eye_height -= direction_oversize; right_eye_width -= direction_oversize; } else { left_eye_height -= direction_oversize; left_eye_width -= direction_oversize; } draw_eyes(); delay(1); } for (int i = 0; i < 3; i++) { left_eye_x -= direction_movement_amplitude * direction; right_eye_x -= direction_movement_amplitude * direction; right_eye_height += blink_amplitude; left_eye_height += blink_amplitude; if (direction > 0) { right_eye_height -= direction_oversize; right_eye_width -= direction_oversize; } else { left_eye_height -= direction_oversize; left_eye_width -= direction_oversize; } draw_eyes(); delay(1); } center_eyes(); } void setup() { Serial.begin(115200); // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) { // Address 0x3D for 128x64 Serial.println(F("SSD1306 allocation failed")); for (;;) ; // Don't proceed, loop forever } // Clear the buffer display.clearDisplay(); display.setTextSize(1); // Normal 1:1 pixel scale display.setTextColor(SSD1306_WHITE); // Draw white text display.setCursor(0, 0); // Start at top-left corner display.println(F("GITHUB Link:")); display.println(F(" ")); display.println(F("intellar/oled_eye_display")); display.println(F(" ")); display.println(F("Press "N" for Next Animation")); display.display(); delay(5000); } void loop() { // delay(timeD); // wakeup(); // Serial.println("Wake UP!"); // delay(timeD); // center_eyes(true); // Serial.println("Center Eyes!"); // delay(timeD); // move_right_big_eye(); // Serial.println("Moving Right!"); // delay(timeD); // move_left_big_eye(); // Serial.println("Moving Left!"); // delay(timeD); // blink(10); // Serial.println("Short Blink!"); // delay(timeD); // happy_eye(); // Serial.println("Happy Eye!"); // delay(timeD); // blink(20); // Serial.println("Long Blink!"); // delay(timeD); // Serial.println("All Motion!"); // // BOTTOM LEFT // dir_x = -1; // dir_y = 1; // saccade(dir_x, dir_y); // delay(300); // saccade(-dir_x, -dir_y); // delay(300); // // BOTTOM // dir_x = 0; // dir_y = 1; // saccade(dir_x, dir_y); // delay(300); // saccade(-dir_x, -dir_y); // delay(300); // // BOTTOM RIGHT // dir_x = 1; // dir_y = 1; // saccade(dir_x, dir_y); // delay(300); // saccade(-dir_x, -dir_y); // delay(300); // // RIGHT // dir_x = 1; // dir_y = 0; // saccade(dir_x, dir_y); // delay(300); // saccade(-dir_x, -dir_y); // delay(300); // // TOP RIGHT // dir_x = 1; // dir_y = -1; // saccade(dir_x, dir_y); // delay(300); // saccade(-dir_x, -dir_y); // delay(300); // // TOP // dir_x = 0; // dir_y = -1; // saccade(dir_x, dir_y); // delay(300); // saccade(-dir_x, -dir_y); // delay(300); // // TOP LEFT // dir_x = -1; // dir_y = -1; // saccade(dir_x, dir_y); // delay(300); // saccade(-dir_x, -dir_y); // delay(300); // // LEFT // dir_x = -1; // dir_y = 0; // saccade(dir_x, dir_y); // delay(300); // saccade(-dir_x, -dir_y); // delay(300); // delay(timeD); // sleep(); //send A for one by one animation if (Serial.available()) { String data = Serial.readString(); data.trim(); char cmd = data[0]; if (cmd == 'N') { switch (count) { case 0: wakeup(); Serial.println("Wake UP!"); break; case 1: center_eyes(true); Serial.println("Center Eyes!"); break; case 2: move_right_big_eye(); Serial.println("Moving Right!"); break; case 3: move_left_big_eye(); Serial.println("Moving Left!"); break; case 4: blink(10); Serial.println("Short Blink!"); break; case 5: happy_eye(); Serial.println("Happy Eye!"); break; case 6: blink(20); Serial.println("Long Blink!"); break; case 7: Serial.println("All Motion!"); // BOTTOM LEFT dir_x = -1; dir_y = 1; saccade(dir_x, dir_y); delay(300); saccade(-dir_x, -dir_y); delay(300); // BOTTOM dir_x = 0; dir_y = 1; saccade(dir_x, dir_y); delay(300); saccade(-dir_x, -dir_y); delay(300); // BOTTOM RIGHT dir_x = 1; dir_y = 1; saccade(dir_x, dir_y); delay(300); saccade(-dir_x, -dir_y); delay(300); // RIGHT dir_x = 1; dir_y = 0; saccade(dir_x, dir_y); delay(300); saccade(-dir_x, -dir_y); delay(300); // TOP RIGHT dir_x = 1; dir_y = -1; saccade(dir_x, dir_y); delay(300); saccade(-dir_x, -dir_y); delay(300); // TOP dir_x = 0; dir_y = -1; saccade(dir_x, dir_y); delay(300); saccade(-dir_x, -dir_y); delay(300); // TOP LEFT dir_x = -1; dir_y = -1; saccade(dir_x, dir_y); delay(300); saccade(-dir_x, -dir_y); delay(300); // LEFT dir_x = -1; dir_y = 0; saccade(dir_x, dir_y); delay(300); saccade(-dir_x, -dir_y); delay(300); break; case 8: sleep(); break; default: Serial.println("Default!"); break; } count += 1; if (count == 9) { count = 0; } } } }
The "Arduino OLED Eyes Animation for Robotics Projects" is a curated guide showcasing five different methods for creating lively and expressive eye animations on Arduino-based robots using OLED displays. Each method offers unique features and functionalities, from simple eye movements and mood expressions to more sophisticated techniques involving bitmap images and optimized memory usage. Whether you're a beginner or seasoned hobbyist, this project provides a comprehensive overview of how to implement captivating eye animations that add personality and realism to your robotic creations. Explore the diverse options and unleash your creativity in the exciting realm of Arduino robotics!
Project description
In the vast realm of robotics, enthusiasts are venturing into the exciting world of OLED eye animations for Arduino robots. If you've found yourself lost in the maze of online searches, fear not! We've done the legwork and distilled the top five methods for creating captivating eye animations into a clear and fun comparison.
Introducing our selections:
Option 1: Eye Animation on OLED Display by Intellar
Eye Animation on OLED Display by Intellar
Intellar's approach brings cool eye animations to life with simple functions mimicking various moods (Normal, Sleep, Smile) and versatile eye movements. Pro: Easy to use with adjustable eye positions. Con: Limited to three moods.
Option 2: Simple Animated Eye Using Arduino by SpiderMaf
Simple Animated Eye Using Arduino by SpiderMaf
SpiderMaf's method features circular eyes with pupils for precise movements, adding a touch of humanity to your robot. Pro: Compact functions with customizable features. Con: Similar to Intellar's approach.
Option 3: Akno by AbdulsalamAbbod
Akno by AbdulsalamAbbod
Akno stands out with its expressive rectangular eyes and a wide range of emotions, suitable for various display types. Pro: Supports multiple expressions. Con: Less flexible in adjusting eye size.
Option 4: Arduino OLED Moving Eyes by Vinny
Arduino OLED Moving Eyes by Vinny
Vinny's innovative technique involves rendering custom images on OLED displays, though it comes with memory constraints. Pro: External image rendering capability. Con: Memory-intensive process.
Option 5: Arduino UNO Robotic Eye Animations by Picaio
Arduino UNO Robotic Eye Animations by Picaio
Picaio offers a sophisticated yet realistic approach with diverse eye movements and expressions, enhancing animation realism. Pro: Optimized technique for efficient memory usage. Con: May be challenging for beginners due to its complexity.
Whether you're a seasoned hobbyist or just starting out, these methods provide a gateway to bringing your robot's personality to life! Get ready to dive in, experiment, and unleash your creativity with our official webpage Explaining this project $ Arduino OLED Animations $ as your guide!
Let's animate those robotic eyes and inject some fun into your Arduino projects! 🤖👀
Code
Eye Animation on OLED Display by Intellar
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// Adjustable
int ref_eye_height = 40;
int ref_eye_width = 40;
int ref_space_between_eye = 10;
int ref_corner_radius = 10;
//current state of the eyes
int left_eye_height = ref_eye_height;
int left_eye_width = ref_eye_width;
int left_eye_x = 32;
int left_eye_y = 32;
int right_eye_x = 32 + ref_eye_width + ref_space_between_eye;
int right_eye_y = 32;
int right_eye_height = ref_eye_height;
int right_eye_width = ref_eye_width;
int dir_x = 0;
int dir_y = 0;
int count = 0;
void draw_eyes(bool update = true);
void center_eyes(bool update = true);
void blink(int speed = 12);
void sleep();
void wakeup();
void happy_eye();
void saccade(int direction_x, int direction_y);
void move_right_big_eye();
void move_left_big_eye();
void move_big_eye(int direction);
int timeD = 1000;
void draw_eyes(bool update = true) {
display.clearDisplay();
//draw from center
int x = int(left_eye_x - left_eye_width / 2);
int y = int(left_eye_y - left_eye_height / 2);
display.fillRoundRect(x, y, left_eye_width, left_eye_height, ref_corner_radius, SSD1306_WHITE);
x = int(right_eye_x - right_eye_width / 2);
y = int(right_eye_y - right_eye_height / 2);
display.fillRoundRect(x, y, right_eye_width, right_eye_height, ref_corner_radius, SSD1306_WHITE);
if (update) {
display.display();
}
}
void center_eyes(bool update = true) {
//move eyes to the center of the display, defined by SCREEN_WIDTH, SCREEN_HEIGHT
left_eye_height = ref_eye_height;
left_eye_width = ref_eye_width;
right_eye_height = ref_eye_height;
right_eye_width = ref_eye_width;
left_eye_x = SCREEN_WIDTH / 2 - ref_eye_width / 2 - ref_space_between_eye / 2;
left_eye_y = SCREEN_HEIGHT / 2;
right_eye_x = SCREEN_WIDTH / 2 + ref_eye_width / 2 + ref_space_between_eye / 2;
right_eye_y = SCREEN_HEIGHT / 2;
draw_eyes(update);
}
void blink(int speed = 12) {
draw_eyes();
for (int i = 0; i < 3; i++) {
left_eye_height = left_eye_height - speed;
right_eye_height = right_eye_height - speed;
draw_eyes();
delay(1);
}
for (int i = 0; i < 3; i++) {
left_eye_height = left_eye_height + speed;
right_eye_height = right_eye_height + speed;
draw_eyes();
delay(1);
}
}
void sleep() { // DRAWS A LINE TO LOOK LIKE SLEEPING
left_eye_height = 2;
right_eye_height = 2;
draw_eyes(true);
}
void wakeup() { // WAKE UP THE EYES FROM AN LINE TO ROUND CORNERED SQUARE
sleep();
for (int h = 0; h <= ref_eye_height; h += 2) {
left_eye_height = h;
right_eye_height = h;
draw_eyes(true);
}
}
void happy_eye() {
center_eyes(false);
//draw inverted triangle over eye lower part
int offset = ref_eye_height / 2;
for (int i = 0; i < 10; i++) {
display.fillTriangle(left_eye_x - left_eye_width / 2 - 1, left_eye_y + offset, left_eye_x + left_eye_width / 2 + 1, left_eye_y + 5 + offset, left_eye_x - left_eye_width / 2 - 1, left_eye_y + left_eye_height + offset, SSD1306_BLACK);
// display.fillRect(left_eye_x-left_eye_width/2-1, left_eye_y+5, left_eye_width+1, 20,SSD1306_BLACK);
display.fillTriangle(right_eye_x + right_eye_width / 2 + 1, right_eye_y + offset, right_eye_x - left_eye_width / 2 - 1, right_eye_y + 5 + offset, right_eye_x + right_eye_width / 2 + 1, right_eye_y + right_eye_height + offset, SSD1306_BLACK);
// display.fillRect(right_eye_x-right_eye_width/2-1, right_eye_y+5, right_eye_width+1, 20,SSD1306_BLACK);
offset -= 2;
display.display();
delay(1);
}
display.display();
delay(1000);
}
void saccade(int direction_x, int direction_y) {
//quick movement of the eye, no size change. stay at position after movement, will not move back, call again with opposite direction
//direction == -1 : move left
//direction == 1 : move right
int direction_x_movement_amplitude = 8;
int direction_y_movement_amplitude = 6;
int blink_amplitude = 8;
for (int i = 0; i < 1; i++) {
left_eye_x += direction_x_movement_amplitude * direction_x;
right_eye_x += direction_x_movement_amplitude * direction_x;
left_eye_y += direction_y_movement_amplitude * direction_y;
right_eye_y += direction_y_movement_amplitude * direction_y;
right_eye_height -= blink_amplitude;
left_eye_height -= blink_amplitude;
draw_eyes();
delay(1);
}
for (int i = 0; i < 1; i++) {
left_eye_x += direction_x_movement_amplitude * direction_x;
right_eye_x += direction_x_movement_amplitude * direction_x;
left_eye_y += direction_y_movement_amplitude * direction_y;
right_eye_y += direction_y_movement_amplitude * direction_y;
right_eye_height += blink_amplitude;
left_eye_height += blink_amplitude;
draw_eyes();
delay(1);
}
}
void move_right_big_eye() {
move_big_eye(1);
}
void move_left_big_eye() {
move_big_eye(-1);
}
void move_big_eye(int direction) { // MOVES TO RIGHT OR LEFT DEPENDING ON 1 OR -1 INPUT.
//direction == -1 : move left
//direction == 1 : move right
int direction_oversize = 1;
int direction_movement_amplitude = 2;
int blink_amplitude = 5;
for (int i = 0; i < 3; i++) {
left_eye_x += direction_movement_amplitude * direction;
right_eye_x += direction_movement_amplitude * direction;
right_eye_height -= blink_amplitude;
left_eye_height -= blink_amplitude;
if (direction > 0) {
right_eye_height += direction_oversize;
right_eye_width += direction_oversize;
} else {
left_eye_height += direction_oversize;
left_eye_width += direction_oversize;
}
draw_eyes();
delay(1);
}
for (int i = 0; i < 3; i++) {
left_eye_x += direction_movement_amplitude * direction;
right_eye_x += direction_movement_amplitude * direction;
right_eye_height += blink_amplitude;
left_eye_height += blink_amplitude;
if (direction > 0) {
right_eye_height += direction_oversize;
right_eye_width += direction_oversize;
} else {
left_eye_height += direction_oversize;
left_eye_width += direction_oversize;
}
draw_eyes();
delay(1);
}
delay(1000);
for (int i = 0; i < 3; i++) {
left_eye_x -= direction_movement_amplitude * direction;
right_eye_x -= direction_movement_amplitude * direction;
right_eye_height -= blink_amplitude;
left_eye_height -= blink_amplitude;
if (direction > 0) {
right_eye_height -= direction_oversize;
right_eye_width -= direction_oversize;
} else {
left_eye_height -= direction_oversize;
left_eye_width -= direction_oversize;
}
draw_eyes();
delay(1);
}
for (int i = 0; i < 3; i++) {
left_eye_x -= direction_movement_amplitude * direction;
right_eye_x -= direction_movement_amplitude * direction;
right_eye_height += blink_amplitude;
left_eye_height += blink_amplitude;
if (direction > 0) {
right_eye_height -= direction_oversize;
right_eye_width -= direction_oversize;
} else {
left_eye_height -= direction_oversize;
left_eye_width -= direction_oversize;
}
draw_eyes();
delay(1);
}
center_eyes();
}
void setup() {
Serial.begin(115200);
// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) { // Address 0x3D for 128x64
Serial.println(F("SSD1306 allocation failed"));
for (;;)
; // Don't proceed, loop forever
}
// Clear the buffer
display.clearDisplay();
display.setTextSize(1); // Normal 1:1 pixel scale
display.setTextColor(SSD1306_WHITE); // Draw white text
display.setCursor(0, 0); // Start at top-left corner
display.println(F("GITHUB Link:"));
display.println(F(" "));
display.println(F("intellar/oled_eye_display"));
display.println(F(" "));
display.println(F("Press "N" for Next Animation"));
display.display();
delay(5000);
}
void loop() {
// delay(timeD);
// wakeup();
// Serial.println("Wake UP!");
// delay(timeD);
// center_eyes(true);
// Serial.println("Center Eyes!");
// delay(timeD);
// move_right_big_eye();
// Serial.println("Moving Right!");
// delay(timeD);
// move_left_big_eye();
// Serial.println("Moving Left!");
// delay(timeD);
// blink(10);
// Serial.println("Short Blink!");
// delay(timeD);
// happy_eye();
// Serial.println("Happy Eye!");
// delay(timeD);
// blink(20);
// Serial.println("Long Blink!");
// delay(timeD);
// Serial.println("All Motion!");
// // BOTTOM LEFT
// dir_x = -1;
// dir_y = 1;
// saccade(dir_x, dir_y);
// delay(300);
// saccade(-dir_x, -dir_y);
// delay(300);
// // BOTTOM
// dir_x = 0;
// dir_y = 1;
// saccade(dir_x, dir_y);
// delay(300);
// saccade(-dir_x, -dir_y);
// delay(300);
// // BOTTOM RIGHT
// dir_x = 1;
// dir_y = 1;
// saccade(dir_x, dir_y);
// delay(300);
// saccade(-dir_x, -dir_y);
// delay(300);
// // RIGHT
// dir_x = 1;
// dir_y = 0;
// saccade(dir_x, dir_y);
// delay(300);
// saccade(-dir_x, -dir_y);
// delay(300);
// // TOP RIGHT
// dir_x = 1;
// dir_y = -1;
// saccade(dir_x, dir_y);
// delay(300);
// saccade(-dir_x, -dir_y);
// delay(300);
// // TOP
// dir_x = 0;
// dir_y = -1;
// saccade(dir_x, dir_y);
// delay(300);
// saccade(-dir_x, -dir_y);
// delay(300);
// // TOP LEFT
// dir_x = -1;
// dir_y = -1;
// saccade(dir_x, dir_y);
// delay(300);
// saccade(-dir_x, -dir_y);
// delay(300);
// // LEFT
// dir_x = -1;
// dir_y = 0;
// saccade(dir_x, dir_y);
// delay(300);
// saccade(-dir_x, -dir_y);
// delay(300);
// delay(timeD);
// sleep();
//send A for one by one animation
if (Serial.available()) {
String data = Serial.readString();
data.trim();
char cmd = data[0];
if (cmd == 'N') {
switch (count) {
case 0:
wakeup();
Serial.println("Wake UP!");
break;
case 1:
center_eyes(true);
Serial.println("Center Eyes!");
break;
case 2:
move_right_big_eye();
Serial.println("Moving Right!");
break;
case 3:
move_left_big_eye();
Serial.println("Moving Left!");
break;
case 4:
blink(10);
Serial.println("Short Blink!");
break;
case 5:
happy_eye();
Serial.println("Happy Eye!");
break;
case 6:
blink(20);
Serial.println("Long Blink!");
break;
case 7:
Serial.println("All Motion!");
// BOTTOM LEFT
dir_x = -1;
dir_y = 1;
saccade(dir_x, dir_y);
delay(300);
saccade(-dir_x, -dir_y);
delay(300);
// BOTTOM
dir_x = 0;
dir_y = 1;
saccade(dir_x, dir_y);
delay(300);
saccade(-dir_x, -dir_y);
delay(300);
// BOTTOM RIGHT
dir_x = 1;
dir_y = 1;
saccade(dir_x, dir_y);
delay(300);
saccade(-dir_x, -dir_y);
delay(300);
// RIGHT
dir_x = 1;
dir_y = 0;
saccade(dir_x, dir_y);
delay(300);
saccade(-dir_x, -dir_y);
delay(300);
// TOP RIGHT
dir_x = 1;
dir_y = -1;
saccade(dir_x, dir_y);
delay(300);
saccade(-dir_x, -dir_y);
delay(300);
// TOP
dir_x = 0;
dir_y = -1;
saccade(dir_x, dir_y);
delay(300);
saccade(-dir_x, -dir_y);
delay(300);
// TOP LEFT
dir_x = -1;
dir_y = -1;
saccade(dir_x, dir_y);
delay(300);
saccade(-dir_x, -dir_y);
delay(300);
// LEFT
dir_x = -1;
dir_y = 0;
saccade(dir_x, dir_y);
delay(300);
saccade(-dir_x, -dir_y);
delay(300);
break;
case 8:
sleep();
break;
default:
Serial.println("Default!");
break;
}
count += 1;
if (count == 9) { count = 0; }
}
}
}