An ESP32-based desktop companion that drives a 128×64 SSD1306 OLED display, showing expressive robot faces, a live clock with weather, and device info — all controllable from a built-in web panel or the physical BOOT button.
Built with Rust using the esp-idf-svc framework and the embedded-graphics crate for rendering.
- 12 animated robot faces — normal, happy, sleepy, angry, surprised, love (with heartbeat animation), wink, sad, dizzy, confused, blinking, and a loading sequence
- Clock mode — large bitmap digits for HH:MM, date line, weather icon + temperature pulled from OpenWeatherMap via NTP-synced time
- Info screen — shows the "WBot" logo, firmware version, and the device's current IP address
- Continuous cycle — loops through all faces with transitions and natural blink interrupts
- Web control panel — a responsive, dark-themed page served directly from the ESP32 on port 80, lets you pick any face or mode from your phone/laptop
- BOOT button — cycles between Info → Clock → Continuous with a single press
- botsh (terminal hook) — a Zsh plugin that watches your shell: the bot reacts in real time to command successes (😄), failures (😵), and long-running tasks (⏳), then idles back to the clock
| Part | Notes |
|---|---|
| ESP32-S3 (or similar) | Tested on boards with built-in Wi-Fi |
| SSD1306 OLED 128×64 | I2C, connected to GPIO41 (SDA) / GPIO42 (SCL) |
| BOOT button | GPIO0, active-low with internal pull-up |
- Rust toolchain with ESP32
stdsupport (espupor the esp-rs tooling) espflashfor flashing- A Wi-Fi network the board can reach
-
Set your Wi-Fi credentials in
src/wifi.rs:const WIFI_SSID: &str = "YourSSID"; const WIFI_PASSWORD: &str = "YourPassword";
-
(Optional) Set your OpenWeatherMap API key and coordinates in
src/clock_data.rsfor weather on the clock screen.
# Build
cargo build --release
# Flash (adjust port as needed)
espflash flash --monitor target/xtensa-esp32s3-espidf/release/starting_stdOr use the helper scripts:
./scripts/build.sh # build only
./scripts/flash.sh # build + flash + monitorOnce the board connects to Wi-Fi, it shows its IP on the Info screen. Open http://<ip> in a browser to get the control page.
The scripts/botsh.zsh plugin hooks into your shell so the bot reacts to what's happening in your terminal.
export BOT_HOST="192.168.x.x" # your bot's IP
source /path/to/scripts/botsh.zsh| Event | Bot reaction |
|---|---|
| Command starts | Normal face 🤖 |
| Command takes > 10s | Loading face ⏳ |
| Command succeeds | Happy face 😄 |
| Command fails | Dizzy face 😵 |
| Idle timeout | Falls back to Clock 🕐 |
Disable/enable on the fly with botsh_disable and botsh_enable.
src/
├── main.rs # entry point, display loop, button handling
├── faces.rs # all face drawing routines (pixel-level bitmap art)
├── clock.rs # clock face layout and big-digit rendering
├── clock_data.rs # NTP sync, weather fetch, time calculations
├── server.rs # embedded HTTP server + web control page
├── bot_info.rs # info/splash screen with "WBot" logo
└── wifi.rs # Wi-Fi connection helper
scripts/
├── botsh.zsh # Zsh shell hook for terminal-reactive faces
├── botsh-setup.sh # one-time setup helper for botsh
├── build.sh # cargo build wrapper
└── flash.sh # build + flash + serial monitor
- Language: Rust (no_std-compatible patterns, std runtime via esp-idf)
- Framework: esp-idf-svc v0.51
- Display driver: ssd1306 + embedded-graphics
- Graphics: Hand-drawn 1bpp bitmap art rendered through
embedded-graphicsprimitives andImageRaw
This is a personal project. Feel free to use it as reference or inspiration for your own ESP32 builds.