Components and supplies
Arduino Uno Rev3
SSD1306 OLED Display
Breadboard - 400 contacts
40 colored male-male jumper wires
USB 2.0 Cable Type A/B
Apps and platforms
Arduino IDE
Project description
Code
opt1
cpp
Eye Animation on OLED Display by Intellar
1#include <Wire.h> 2#include <Adafruit_GFX.h> 3#include <Adafruit_SSD1306.h> 4 5 6#define SCREEN_WIDTH 128 // OLED display width, in pixels 7#define SCREEN_HEIGHT 64 // OLED display height, in pixels 8 9#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin) 10#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32 11Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); 12 13 14// Adjustable 15int ref_eye_height = 40; 16int ref_eye_width = 40; 17int ref_space_between_eye = 10; 18int ref_corner_radius = 10; 19 20//current state of the eyes 21int left_eye_height = ref_eye_height; 22int left_eye_width = ref_eye_width; 23int left_eye_x = 32; 24int left_eye_y = 32; 25int right_eye_x = 32 + ref_eye_width + ref_space_between_eye; 26int right_eye_y = 32; 27int right_eye_height = ref_eye_height; 28int right_eye_width = ref_eye_width; 29 30int dir_x = 0; 31int dir_y = 0; 32int count = 0; 33 34void draw_eyes(bool update = true); 35void center_eyes(bool update = true); 36void blink(int speed = 12); 37void sleep(); 38void wakeup(); 39void happy_eye(); 40void saccade(int direction_x, int direction_y); 41void move_right_big_eye(); 42void move_left_big_eye(); 43void move_big_eye(int direction); 44 45int timeD = 1000; 46 47 48void draw_eyes(bool update = true) { 49 display.clearDisplay(); 50 //draw from center 51 int x = int(left_eye_x - left_eye_width / 2); 52 int y = int(left_eye_y - left_eye_height / 2); 53 display.fillRoundRect(x, y, left_eye_width, left_eye_height, ref_corner_radius, SSD1306_WHITE); 54 x = int(right_eye_x - right_eye_width / 2); 55 y = int(right_eye_y - right_eye_height / 2); 56 display.fillRoundRect(x, y, right_eye_width, right_eye_height, ref_corner_radius, SSD1306_WHITE); 57 if (update) { 58 display.display(); 59 } 60} 61 62void center_eyes(bool update = true) { 63 //move eyes to the center of the display, defined by SCREEN_WIDTH, SCREEN_HEIGHT 64 left_eye_height = ref_eye_height; 65 left_eye_width = ref_eye_width; 66 right_eye_height = ref_eye_height; 67 right_eye_width = ref_eye_width; 68 69 left_eye_x = SCREEN_WIDTH / 2 - ref_eye_width / 2 - ref_space_between_eye / 2; 70 left_eye_y = SCREEN_HEIGHT / 2; 71 right_eye_x = SCREEN_WIDTH / 2 + ref_eye_width / 2 + ref_space_between_eye / 2; 72 right_eye_y = SCREEN_HEIGHT / 2; 73 74 draw_eyes(update); 75} 76 77void blink(int speed = 12) { 78 draw_eyes(); 79 80 81 for (int i = 0; i < 3; i++) { 82 left_eye_height = left_eye_height - speed; 83 right_eye_height = right_eye_height - speed; 84 draw_eyes(); 85 delay(1); 86 } 87 for (int i = 0; i < 3; i++) { 88 left_eye_height = left_eye_height + speed; 89 right_eye_height = right_eye_height + speed; 90 91 draw_eyes(); 92 delay(1); 93 } 94} 95 96void sleep() { // DRAWS A LINE TO LOOK LIKE SLEEPING 97 left_eye_height = 2; 98 right_eye_height = 2; 99 draw_eyes(true); 100} 101 102void wakeup() { // WAKE UP THE EYES FROM AN LINE TO ROUND CORNERED SQUARE 103 104 sleep(); 105 106 for (int h = 0; h <= ref_eye_height; h += 2) { 107 left_eye_height = h; 108 right_eye_height = h; 109 draw_eyes(true); 110 } 111} 112 113void happy_eye() { 114 center_eyes(false); 115 //draw inverted triangle over eye lower part 116 int offset = ref_eye_height / 2; 117 for (int i = 0; i < 10; i++) { 118 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); 119 // display.fillRect(left_eye_x-left_eye_width/2-1, left_eye_y+5, left_eye_width+1, 20,SSD1306_BLACK); 120 121 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); 122 // display.fillRect(right_eye_x-right_eye_width/2-1, right_eye_y+5, right_eye_width+1, 20,SSD1306_BLACK); 123 offset -= 2; 124 display.display(); 125 delay(1); 126 } 127 128 129 display.display(); 130 delay(1000); 131} 132 133void saccade(int direction_x, int direction_y) { 134 //quick movement of the eye, no size change. stay at position after movement, will not move back, call again with opposite direction 135 //direction == -1 : move left 136 //direction == 1 : move right 137 138 int direction_x_movement_amplitude = 8; 139 int direction_y_movement_amplitude = 6; 140 int blink_amplitude = 8; 141 142 for (int i = 0; i < 1; i++) { 143 left_eye_x += direction_x_movement_amplitude * direction_x; 144 right_eye_x += direction_x_movement_amplitude * direction_x; 145 left_eye_y += direction_y_movement_amplitude * direction_y; 146 right_eye_y += direction_y_movement_amplitude * direction_y; 147 148 right_eye_height -= blink_amplitude; 149 left_eye_height -= blink_amplitude; 150 draw_eyes(); 151 delay(1); 152 } 153 154 for (int i = 0; i < 1; i++) { 155 left_eye_x += direction_x_movement_amplitude * direction_x; 156 right_eye_x += direction_x_movement_amplitude * direction_x; 157 left_eye_y += direction_y_movement_amplitude * direction_y; 158 right_eye_y += direction_y_movement_amplitude * direction_y; 159 160 right_eye_height += blink_amplitude; 161 left_eye_height += blink_amplitude; 162 163 draw_eyes(); 164 delay(1); 165 } 166} 167 168void move_right_big_eye() { 169 move_big_eye(1); 170} 171 172void move_left_big_eye() { 173 move_big_eye(-1); 174} 175 176void move_big_eye(int direction) { // MOVES TO RIGHT OR LEFT DEPENDING ON 1 OR -1 INPUT. 177 //direction == -1 : move left 178 //direction == 1 : move right 179 180 int direction_oversize = 1; 181 int direction_movement_amplitude = 2; 182 int blink_amplitude = 5; 183 184 for (int i = 0; i < 3; i++) { 185 left_eye_x += direction_movement_amplitude * direction; 186 right_eye_x += direction_movement_amplitude * direction; 187 right_eye_height -= blink_amplitude; 188 left_eye_height -= blink_amplitude; 189 if (direction > 0) { 190 right_eye_height += direction_oversize; 191 right_eye_width += direction_oversize; 192 } else { 193 left_eye_height += direction_oversize; 194 left_eye_width += direction_oversize; 195 } 196 197 draw_eyes(); 198 delay(1); 199 } 200 for (int i = 0; i < 3; i++) { 201 left_eye_x += direction_movement_amplitude * direction; 202 right_eye_x += direction_movement_amplitude * direction; 203 right_eye_height += blink_amplitude; 204 left_eye_height += blink_amplitude; 205 if (direction > 0) { 206 right_eye_height += direction_oversize; 207 right_eye_width += direction_oversize; 208 } else { 209 left_eye_height += direction_oversize; 210 left_eye_width += direction_oversize; 211 } 212 draw_eyes(); 213 delay(1); 214 } 215 216 delay(1000); 217 218 for (int i = 0; i < 3; i++) { 219 left_eye_x -= direction_movement_amplitude * direction; 220 right_eye_x -= direction_movement_amplitude * direction; 221 right_eye_height -= blink_amplitude; 222 left_eye_height -= blink_amplitude; 223 if (direction > 0) { 224 right_eye_height -= direction_oversize; 225 right_eye_width -= direction_oversize; 226 } else { 227 left_eye_height -= direction_oversize; 228 left_eye_width -= direction_oversize; 229 } 230 draw_eyes(); 231 delay(1); 232 } 233 for (int i = 0; i < 3; i++) { 234 left_eye_x -= direction_movement_amplitude * direction; 235 right_eye_x -= direction_movement_amplitude * direction; 236 right_eye_height += blink_amplitude; 237 left_eye_height += blink_amplitude; 238 if (direction > 0) { 239 right_eye_height -= direction_oversize; 240 right_eye_width -= direction_oversize; 241 } else { 242 left_eye_height -= direction_oversize; 243 left_eye_width -= direction_oversize; 244 } 245 draw_eyes(); 246 delay(1); 247 } 248 249 250 center_eyes(); 251} 252 253 254void setup() { 255 256 Serial.begin(115200); 257 258 // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally 259 if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) { // Address 0x3D for 128x64 260 Serial.println(F("SSD1306 allocation failed")); 261 for (;;) 262 ; // Don't proceed, loop forever 263 } 264 265 266 // Clear the buffer 267 display.clearDisplay(); 268 269 display.setTextSize(1); // Normal 1:1 pixel scale 270 display.setTextColor(SSD1306_WHITE); // Draw white text 271 display.setCursor(0, 0); // Start at top-left corner 272 273 display.println(F("GITHUB Link:")); 274 display.println(F(" ")); 275 display.println(F("intellar/oled_eye_display")); 276 display.println(F(" ")); 277 display.println(F("Press \"N\" for Next Animation")); 278 279 display.display(); 280 delay(5000); 281} 282 283 284void loop() { 285 // delay(timeD); 286 // wakeup(); 287 // Serial.println("Wake UP!"); 288 // delay(timeD); 289 // center_eyes(true); 290 // Serial.println("Center Eyes!"); 291 // delay(timeD); 292 // move_right_big_eye(); 293 // Serial.println("Moving Right!"); 294 // delay(timeD); 295 // move_left_big_eye(); 296 // Serial.println("Moving Left!"); 297 // delay(timeD); 298 // blink(10); 299 // Serial.println("Short Blink!"); 300 // delay(timeD); 301 // happy_eye(); 302 // Serial.println("Happy Eye!"); 303 // delay(timeD); 304 // blink(20); 305 // Serial.println("Long Blink!"); 306 // delay(timeD); 307 // Serial.println("All Motion!"); 308 // // BOTTOM LEFT 309 // dir_x = -1; 310 // dir_y = 1; 311 // saccade(dir_x, dir_y); 312 // delay(300); 313 // saccade(-dir_x, -dir_y); 314 // delay(300); 315 316 // // BOTTOM 317 // dir_x = 0; 318 // dir_y = 1; 319 // saccade(dir_x, dir_y); 320 // delay(300); 321 // saccade(-dir_x, -dir_y); 322 // delay(300); 323 324 // // BOTTOM RIGHT 325 // dir_x = 1; 326 // dir_y = 1; 327 // saccade(dir_x, dir_y); 328 // delay(300); 329 // saccade(-dir_x, -dir_y); 330 // delay(300); 331 332 // // RIGHT 333 // dir_x = 1; 334 // dir_y = 0; 335 // saccade(dir_x, dir_y); 336 // delay(300); 337 // saccade(-dir_x, -dir_y); 338 // delay(300); 339 340 // // TOP RIGHT 341 // dir_x = 1; 342 // dir_y = -1; 343 // saccade(dir_x, dir_y); 344 // delay(300); 345 // saccade(-dir_x, -dir_y); 346 // delay(300); 347 348 // // TOP 349 // dir_x = 0; 350 // dir_y = -1; 351 // saccade(dir_x, dir_y); 352 // delay(300); 353 // saccade(-dir_x, -dir_y); 354 // delay(300); 355 356 // // TOP LEFT 357 // dir_x = -1; 358 // dir_y = -1; 359 // saccade(dir_x, dir_y); 360 // delay(300); 361 // saccade(-dir_x, -dir_y); 362 // delay(300); 363 364 // // LEFT 365 // dir_x = -1; 366 // dir_y = 0; 367 // saccade(dir_x, dir_y); 368 // delay(300); 369 // saccade(-dir_x, -dir_y); 370 // delay(300); 371 // delay(timeD); 372 // sleep(); 373 374 //send A for one by one animation 375 if (Serial.available()) { 376 String data = Serial.readString(); 377 data.trim(); 378 char cmd = data[0]; 379 380 if (cmd == 'N') { 381 382 switch (count) { 383 case 0: 384 wakeup(); 385 Serial.println("Wake UP!"); 386 break; 387 case 1: 388 center_eyes(true); 389 Serial.println("Center Eyes!"); 390 break; 391 case 2: 392 move_right_big_eye(); 393 Serial.println("Moving Right!"); 394 break; 395 case 3: 396 move_left_big_eye(); 397 Serial.println("Moving Left!"); 398 break; 399 case 4: 400 blink(10); 401 Serial.println("Short Blink!"); 402 break; 403 case 5: 404 happy_eye(); 405 Serial.println("Happy Eye!"); 406 break; 407 case 6: 408 blink(20); 409 Serial.println("Long Blink!"); 410 break; 411 case 7: 412 Serial.println("All Motion!"); 413 // BOTTOM LEFT 414 dir_x = -1; 415 dir_y = 1; 416 saccade(dir_x, dir_y); 417 delay(300); 418 saccade(-dir_x, -dir_y); 419 delay(300); 420 421 // BOTTOM 422 dir_x = 0; 423 dir_y = 1; 424 saccade(dir_x, dir_y); 425 delay(300); 426 saccade(-dir_x, -dir_y); 427 delay(300); 428 429 // BOTTOM RIGHT 430 dir_x = 1; 431 dir_y = 1; 432 saccade(dir_x, dir_y); 433 delay(300); 434 saccade(-dir_x, -dir_y); 435 delay(300); 436 437 // RIGHT 438 dir_x = 1; 439 dir_y = 0; 440 saccade(dir_x, dir_y); 441 delay(300); 442 saccade(-dir_x, -dir_y); 443 delay(300); 444 445 // TOP RIGHT 446 dir_x = 1; 447 dir_y = -1; 448 saccade(dir_x, dir_y); 449 delay(300); 450 saccade(-dir_x, -dir_y); 451 delay(300); 452 453 // TOP 454 dir_x = 0; 455 dir_y = -1; 456 saccade(dir_x, dir_y); 457 delay(300); 458 saccade(-dir_x, -dir_y); 459 delay(300); 460 461 // TOP LEFT 462 dir_x = -1; 463 dir_y = -1; 464 saccade(dir_x, dir_y); 465 delay(300); 466 saccade(-dir_x, -dir_y); 467 delay(300); 468 469 // LEFT 470 dir_x = -1; 471 dir_y = 0; 472 saccade(dir_x, dir_y); 473 delay(300); 474 saccade(-dir_x, -dir_y); 475 delay(300); 476 477 break; 478 case 8: 479 sleep(); 480 break; 481 default: 482 Serial.println("Default!"); 483 break; 484 } 485 486 count += 1; 487 if (count == 9) { count = 0; } 488 } 489 } 490}
Other Option's Code
cpp
You can find the program code for other options
1// Follow the below link to reach code of other options 2// https://circuitdigest.com/microcontroller-projects/arduino-oled-eyes-animation-for-robotics-projects
Documentation
Circuit Diagram
OLED Display Connected to Arduino UNO Via I2C
1.png
Comments
Only logged in users can leave comments