Eye animation on OLED display with arduino nano

Demo of the animated eyes running on the arduino nano and a 128x64 oled display.

Demo of the animated eyes on a ESP32 microcontroller and 128x128 oled display.

Intro

Source code https://github.com/intellar/oled_eye_display

#with git, use this command to clone (download) the code :
git clone https://github.com/intellar/oled_eye_display


updates:
2025-03: ported to U8G2 library.  check the repo
2024-10: there is a color lcd version of this project, Animated eyes with arduino nano on color LCD display


This is a simple project to give a visual feedback to someone interacting with a device. Here the display shows eyes, that can blink, look up, look down, look amused, annoyed, etc.  

The microcontroller renders simple basic forms (rounded squares, triangles) that mimic eyes.  The project was realised with two microcontroller, the arduino nano and the esp32. The first section describe the animation project with the arduino nano on a 128x64 oled screen . The second section presents the project with the esp32 alternative on a 128x128 oled screen. 

If you want to see a quick demo of how the project works, from wiring to compiling the code, check the following tutorial video. It takes you through each steps of described on this page:

Hardware - Arduino Nano

For this project, we used an oled display found on amazon based on the ssd1306 controller, costing 11$, and a canaduino, which is a cost effective alternative to the arduino nano v3, costing 6$. This brings the total cost under 20$cad. And if you go on aliexpress, you can get all this for under 5$. No links are published since they will most likely not age well. Both devices are shown here:

Fig.1a  Amazon.ca

Fig.1b Aliexpress

The nano I bought comes without the pins attached, so a little MacGyver soldering is required to connect the pins on the arduino board. It is easily done with a fine tip and common soldering iron.  You can spend the 0.50$ if you think the soldering is not worth your time (I recommand it).

The connection of the arduino to the display is fairly simple, and it is important to note that the display uses power on 3v.  So dont plug it on the 5v pin. You need to use the pinout SCL,SDA on A5 and A4 for the i2c connection, this is required for the hardware i2c of the nano. 

Arduino - Display
3v3 - vcc
Gnd - gnd
A5 - SCL
A4 - SDA

this results in the wiring shown in the next figure :

Fig.2schematic of the wiring. 

Fig.2b  pinout of the arduino, you can see the hardware pins of the scl and sda. this is fixed by hardware, it enables faster communications.

Fig.2c  Final wiring

Software - Arduino Nano

Now the fun part begins. You can download the code here (for free! just say thanks). It is a cleaned and concise example of the library. It is meant to be simple and can easily be adapted for more complexe animation. 

https://github.com/intellar/oled_eye_display

There are two folders, one contains the arduino code, and the other contains the python script to communicate with the nano. To program the nano, you must upload the program "control_display.ino", that will handle the drawing and the communication with the pc.  I use the program arduino ide to compile and upload. The nano must be plugged in the computer for the programmation. 

Fig.3 I used the arduino ide version 2.2.1 in this project (from 2023). It will work with more recent version.

A quick note about the drawing libraries. I used 2 libraries to handle the rounded rectangle drawing,  adafruitgfx and u8g2. Both work the same way and can go fast enough to create the animation illusion. I had to change some this to make the code compatible with u8g2, mainly when drawing the rounded rectangle.  We need to make sure the radius of the corner is not bigger than the height or width. On the next figure, you can see the radius (7).  The condition to respect is w<2*(r+1)   and h<2*(r+1) ,  or else the behavior is not defined. Since this happens a lot in the sleep and blink animation, it needs to be adressed  before calling the drawRBox function of u8g2.

Fig.4 description of a rounded rectangle. 

 The function are almost directly compatible, for example, to draw a rounded rectangle, 

Adafruit.clearDisplay()
Adafruit.fillRoundRect(x, y, w, h,  r, color);
Adafruit.display();

U8G2.clearBuffer(); 
U8G2.setDrawColor(color);
U8G2.drawRBox(x, y, w, h, r);
U8G2.sendBuffer();

Currently, there are 8 animations in the program, starting with the closed eyes. To trigger other animations, run the example script in the python folder. Note that in the example, the serial port in COM3,  it might not be the case on your computer. To find out which one to use,  start the hardware manager on windows.   

Fig.5a declaration of the serial com.

Fig.5b.  the serial comm can be found in the windows device manager 

Quick explanation of the code

Animation









Loop and usb




This next video shows the eyes installed on a small robot. This was my first attempt to use the eyes in a project. 

Hardware - ESP32


In this second part, I upgraded the display to a full 128x128 pixels OLED screen. Unfortunatly, it was not possible to continue using the arduino nano. The internal memory is too small to map the whole screen. I had to upgrade the microcontroller. A good choice is to use the ESP32. It is faster, has more than enough memory and is almost as budget friendly as the arduino nano. you can see it on Fig6c. 

The connection between the esp32 and the display is straightforward, 

GND -  GND
VCC - 3V3
SCL -  D22
SDA - D21

I recommend using D21,D22 for hardware accelerated i2c communication. You can use other pins with the software i2c that will be slow to update the screen, very very slow.

Fig.4

Fig.6a  A screenshot of the eyes on the 128x128 oled display

Fig.6b  The back of the display, we can see the hardware driver SH1107. You can also see the IIC address (0x78) selected by the soldered jumper, on the top left. This information will be required to initialize the display.

Fig.6c   The ESP32 board used in this project.

Software - ESP32

The source code is on the github repo, follow the esp32 folder. Except for the pin configuration, the code is similar to the arduino version.

https://github.com/intellar/oled_eye_display

The code to initialize the display and library u8g2 holds on 5 lines, and can be seen on Fig.7a.  Special care must be taken to select the right chip and config for your setup. For my display, I used the SH1107 chip, and the pimoroni config ( U8G2_SH1107_PIMORONI_128X128_F_HW_I2C ). I tried different config before finding the right one, like the generic ( U8G2_SH1107_128X128_F_HW_I2C) which resulted in the content not aligned properly with the screen, as shown on Fig7b.  

The next command set the correct I2C address, make sure it matches the one of your board

u8g2.setI2CAddress(0x78);

Next, I draw a initial image before starting the animations. I intentionally left the software simulated I2C declaration (U8G2_SH1107_PIMORONI_128X128_F_SW_I2C), so you can try it out. 

Fig.7a   Initialisation of the display. 

Fig.7b  Using the wrong config will result in alignement problem like here, or event not images at all.

Fig.7c  Correctly aligned content with config pimoroni, for this specific setup.

Fig.7d  the i2c address of the software must match the board ! u8g2.setI2CAddress(0x78);


To create the animation, it is similar to the arduino nano code. The screen is cleared

u8g2.clearBuffer();   

After that, the shapes are drawn. Draw all the shapes one after to other without refreshing the screen. Everything is drawn in a buffer. One important note, if you change the drawRBox argument, be sure to respect the condition w >= 2*(r+1) and h >= 2*(r+1), or else the result is undefined.

u8g2.setDrawColor(color);
u8g2.drawRBox(x,y,w,h,r);  
...

When everything is drawn, you call the function to send the buffer to the display

u8g2.sendBuffer();

Compilation - ESP32

To compile the project, you need to select the board you are using on arduino ide Fig.8a  (https://www.arduino.cc/en/software#ide). In my case it is the "esp32 dev module",  shown on Fig8b. Select the right com port. Don't forget to install the u8g2 library, by searching for "u8g2" in the library manager of arduino ide.

Fig.8a  I am using arduino IDE 2.3.5 to compile and upload the project on the esp32. https://www.arduino.cc/en/software#ide

Fig.8a  Selecting the correct module for your project, here it is the esp32 dev module.

Fig.8c  Install the u8g2 library using the manager. 

And that's about it !  you can modify the animation as you see fit.  Enjoy !