Once upon a time, I browsed the internet and discovered the RoboEyes video from FluxGarage on YouTube.
RoboEyes is open source library draws smoothly animated robot eyes on OLED displays (using the GFX library). It offers configurable eye shapes, several mood types and animations to add that certain kind of personality to your robot.
The eyes was so lovely but unfortunately, the library was written for Arduino Uno by FluxGarage and I'm a MicroPython addict.
This library is a MicroPython portage of RoboEyes for Arduino.
Some enhancement was added into the library like:
- Based on MicroPython's FrameBuffer (so works with 99% of displays)
- Monochrome and color displays! 1 bit color by default (for OLED).
- Adding FROZEN, SCARY, CURIOUS moods to the exising DEFAULT, TIRED, ANGRY, HAPPY.
- Adding the wink() animation.
- Managing animation sequence (see test_anim_sequence.py ).
The RoboEyes library and its dependencies must be copied to the MicroPython board before using the examples.
Dependencies are:
- GFX library for MicroPython
- Display driver (SSD1306 for most of OLED screen)
On a WiFi based plateform:
>>> import mip
>>> mip.install("github:mchobby/micropython-roboeyes")
>>> mip.install("github:mchobby/esp8266-upy/FBGFX")
Or via the mpremote
utility:
mpremote mip install github:mchobby/micropython-roboeyes
mpremote mip install github:mchobby/esp8266-upy/FBGFX
The SSD1306 library is available in the official MicroPython repository. You can download it into and transfert it to your MicroPython board.
Here the instruction used in install.sh bash script.
$ wget https://raw.githubusercontent.com/micropython/micropython-lib/refs/heads/master/micropython/drivers/display/ssd1306/ssd1306.py -O lib/ssd1306.py
$ mpremote connect $1 fs cp lib/ssd1306.py :lib/
As said, this FrameBuffer implementation of RoboEyes should work with any display (OLED, RGB, etc).
Qwiic (SparFun) or StemmaQt (Adafruit Industries) is a standardized 4 pins connector shipping I2C bus (sda, scl) as well as power and ground.
Here a wiring via a Qwiic-to-wire cable used for prototyping. The OLED screen used is the Adafruit 128x64 OLED display - 1.3" Monochrome - I2C - StemmaQT / Qwiic
The OLED can be directly plugged with qwiic wire on a microcontroler/board exposing a Qwiic connector.
The RoboEyes API is described in the MicroPython-RoboEyes-API.md document
The best way to learn how to use the RoboEyes is to read the examples below then read the RoboEye API to understand the responsabilities of various calls.
This YouTube Video show the micropython-RoboEyes in action on an 1.3" OLED Adafruit 938 .
This correspond to minimalist implementation of test_basic.py visible here below:
from machine import I2C, Pin
from roboeyes import *
import ssd1306
i2c = I2C( 1, sda=Pin.board.GP6, scl=Pin.board.GP7 )
lcd = ssd1306.SSD1306_I2C( 128, 64, i2c, addr=0x3d )
def robo_show( roboeyes ):
global lcd
lcd.show()
# Plug RoboEyes on any FrameBuffer descendant
robo = RoboEyes( lcd, 128, 64, frame_rate=100, on_show = robo_show )
robo.set_auto_blinker( ON, 3, 2)
robo.set_idle_mode( ON, 2, 2)
while True:
robo.update() # update eyes drawings
The library was also tested on a 0.91" OLED-B from DFRobot .
The minimalist implementation of test_basic.py was adapted to that screen.
from machine import I2C, Pin
from roboeyes import *
import ssd1306
i2c = I2C( 1, sda=Pin.board.GP6, scl=Pin.board.GP7 )
# DFRobot 128*32 have a different I2C address.
lcd = ssd1306.SSD1306_I2C( 128, 32, i2c, addr=0x3c )
def robo_show( roboeyes ):
global lcd
lcd.show()
# Plug RoboEyes on any FrameBuffer descendant
robo = RoboEyes( lcd, 128, 21, frame_rate=100, on_show = robo_show )
robo.set_auto_blinker( ON, 3, 2)
robo.set_idle_mode( ON, 2, 2)
# Defines Eyes size smaller the screen
robo.eyes_width(28, 28) # byte leftEye, byte rightEye
robo.eyes_height(28, 28) # byte leftEye, byte rightEye
while True:
robo.update() # update eyes drawings
When the test_basic.py runs on your hardware then you can switch to the test_interactive.py example.
In that example, the script takes advantage of FrameBuffer capabilities by overlaying questions and configuration messages before displaying screen content.
The test_interactive.py example uses 3 buttons to control the behavious of the running RoboEye.
Thanks to the buttons, the user can select the option with question mark. Then modify the value with the equal sign.
The question mark:
The interactive example shows one of the options followed by a question mark at the bottom on the screen.
The possible actions are:
- Press 'Enter/Exit' button to enter the option (and change its value)
- Press '+' button for next option.
- Press '-' button for previous option.
Remark: the list of option will automatically cycle to opposite end when reaching the end+1 (or begining-1) position.
The value setting:
When an option is selected, the option label is shorten and the current value is displayed behind an equal sign .
The possible actions are:
- Press '+' button for next value.
- Press '-' button for previous value.
- Press 'Enter/Exit' button to return to the option selection.
Notes:
- value change is immediately applied to the running RoboEye.
- Numerical values are not bounded.
In the example below, the screen update the "Right Eye Width" value:
The options:
The possible options (and short label) are the following:
- Auto Blinker? (A.Blinker) : automatically blink the eyes.
- Auto Idle? (A.Idle) : automatically move the eyes.
- Eyes Width? (Eyes.W)
- Eyes Height? (Eyes.H)
- Eyes Radius? (Eyes.r)
- Eyes Spacing? (Eyes.Sp)
- Cyclops mode? (Cyclops)
- Select Mood? (Mood) : Curious mood only activates visual effect when eyes are on the right or left border.
- Position? (Position)
- Confuse & Laugh? ( (-)Conf (+)Laugh ) : better to deactivate auto-blink and auto-idle to test theses. Laugh gives better result with Happy mood.
- Wink? ( (-)Left (+)Right ) : better to deactivate auto-blink to test theses.
- Close & Open? ( (-)Close (+)Open ) : better to deactivate auto-blink to test theses.
- Horiz flicker? (H.flicker) : better to deactivate auto-idle to test theses.
- Vert flicker? (V.flicker) : better to deactivate auto-blink to test theses.
- Left Eye Width? (L.Eye.W)
- Left Eye Height? (L.Eye.H)
- Left Eye Radius? (L.Eye.r)
- Right Eye Width? (R.Eye.W)
- Right Eye Heigh? (R.Eye.H)
- Right Eye Radiu? (R.Eye.r)
The repository comes with examples ported from Flux garage. Examples are mainly tested on 128x64 I2C capable OLED.
- test_basic.py : Simple script that can be used to test each features, one at the time.
- test_color.py : show how to define colors when creating RoboEyes object.
- test_anim_sequence.py : create animation sequence without using delay.
- test_interactive.py : change the RoboEyes parameters in a live sessions.
Other examples:
- test_round.py : create round eyes with negative spacing.
- test_cyclops.py : create a square cyclops eye.