A maker set out to design a playful desktop companion—a miniature “pet” that could sit on a desk, blink, react to touch, and display emotions on a tiny OLED screen. Using the Xiao ESP32‑S3 microcontroller, a 0.9‑inch OLED display and a custom enclosure printed through JUSTWAY’s 3D printing service, the project came to life as a step‑by‑step build that others can replicate.
- Objective: Create a small interactive pet with expressive animations.
- Core Hardware: Xiao ESP32‑S3, 0.9" OLED, Li‑Po battery.
- Enclosure: 3D printed shell designed for compactness and personality.
- Xiao ESP32‑S3 development board
- 0.9" OLED (SSD1306/SH1106 controller)
- Li‑Po battery (300–500 mAh)
- 3D printed case from JUSTWAY
- Basic tools: soldering iron, wires, screws, hot glue
- Screen window sized precisely for the OLED.
- Standoffs for mounting the ESP32 board.
- Xiao bay with cable routing.
- USB‑C cutout for charging and programming.
OLED: Connected via I2C (SDA, SCL, 3.3V, GND).
The firmware was written in the Arduino IDE using the Adafruit SSD1306 and RoboEyeslibraries.
A simple sketch controlled the OLED graphics.
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#include <FluxGarage_RoboEyes.h>
// create a RoboEyes instance using an Adafruit_SSD1306 display driver
RoboEyes<Adafruit_SSD1306> roboEyes(display);
// EVENT TIMER
unsigned long eventTimer; // will save the timestamps
bool event1wasPlayed = 0; // flag variables
bool event2wasPlayed = 0;
bool event3wasPlayed = 0;
void setup() {
// OLED Display
// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C or 0x3D
Serial.println(F("SSD1306 allocation failed"));
for(;;); // Don't proceed, loop forever
}
// Startup robo eyes
roboEyes.begin(SCREEN_WIDTH, SCREEN_HEIGHT, 100); // screen-width, screen-height, max framerate - 60-100fps are good for smooth animations
roboEyes.setPosition(DEFAULT); // eye position should be middle center
roboEyes.close(); // start with closed eyes
eventTimer = millis(); // start event timer from here
} // end of setup
void loop() {
roboEyes.update(); // update eyes drawings
// LOOPED ANIMATION SEQUENCE
// Do once after defined number of milliseconds
if(millis() >= eventTimer+2000 && event1wasPlayed == 0){
event1wasPlayed = 1; // flag variable to make sure the event will only be handled once
roboEyes.open(); // open eyes
}
// Do once after defined number of milliseconds
if(millis() >= eventTimer+4000 && event2wasPlayed == 0){
event2wasPlayed = 1; // flag variable to make sure the event will only be handled once
roboEyes.setMood(HAPPY);
roboEyes.anim_laugh();
//roboEyes.anim_confused();
}
// Do once after defined number of milliseconds
if(millis() >= eventTimer+6000 && event3wasPlayed == 0){
event3wasPlayed = 1; // flag variable to make sure the event will only be handled once
roboEyes.setMood(TIRED);
//roboEyes.blink();
}
// Do once after defined number of milliseconds, then reset timer and flags to restart the whole animation sequence
if(millis() >= eventTimer+8000){
roboEyes.close(); // close eyes again
roboEyes.setMood(DEFAULT);
// Reset the timer and the event flags to restart the whole "complex animation loop"
eventTimer = millis(); // reset timer
event1wasPlayed = 0; // reset flags
event2wasPlayed = 0;
event3wasPlayed = 0;
}
// END OF LOOPED ANIMATION SEQUENCE
} // end of main loopPowered by JUSTWAY 3D Printing Service 🖨️For the prototype, I partnered with JUSTWAY 3D Printing Service — a reliable platform that brings ideas to life with precision and speed.
How to Order Your 3D Print 🖨️
For this project, I used JUSTWAY 3D Printing Service to bring my gate prototype to life. Ordering your own custom print is simple and beginner‑friendly:
- Create or download a 3D model (e.g.,. STL
.STLor.OBJfile). - Visit the JUSTWAY 3D Printing Service platform.
- Upload your design file directly through their interface.
- Select from options like PLA, ABS, PETG, or specialty filaments.Pick the color and finish that suits your prototype.
- The platform provides a real‑time cost estimate based on size, material, and complexity.
- Confirm your design and checkout securely.
- JUSTWAY handles the printing and ships the finished part to your address.
- You’ll have a professional‑looking prototype ready for demos.
- Dry fit: Components were placed inside the printed shell.
- OLED mount: The screen was secured behind the faceplate.
- Board installation: Xiao ESP32‑S3 fixed to standoffs.
- Battery placement: Li‑Po taped into its bay.
- Wiring: Neatly routed and secured with hot glue.
- Final closure: Faceplate attached, firmware uploaded, and the pet powered on.
The finished desktop pet blinked, chirped, and responded to touch, giving the impression of a tiny creature with personality. The combination of ESP32‑S3’s power, OLED’s expressiveness, and JUSTWAY’s precise 3D printing made the project both technically sound and emotionally engaging.











Comments