Skip to content

CHaerem/Glance

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

606 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

๐Ÿ–ผ๏ธ Glance - ESP32 E-Ink Display System

A battery-powered ESP32 e-ink display that fetches images from a local Raspberry Pi server with intelligent power management and remote control.

๐ŸŒ Try the Live Demo - Interactive web interface preview with mock data

โœจ Features

๐Ÿ”‹ Ultra-Low Power - Months of battery life with deep sleep cycles ๐ŸŽจ 6-Color Display - Beautiful Spectra 6 e-paper technology ๐Ÿ“ก OTA Updates - Wireless firmware updates with automatic rollback protection ๐Ÿค– AI Art Generation - GPT-4o powered artwork optimized for e-ink displays ๐Ÿ” Semantic Visual Search - CLIP-powered search by vibe, not keywords โœจ Visual Similarity - "More like this" finds artworks with 0.73-0.84 similarity ๐ŸŽฏ Personalized Recommendations - Taste profile learns from your interactions ๐Ÿ–ผ๏ธ Personal Gallery - Unified collection of generated, uploaded, and saved artworks ๐Ÿ“ฑ Minimal Web Interface - Clean, calm design for creating and exploring art ๐ŸŒ Local First - Runs on your Raspberry Pi, no cloud dependencies ๐Ÿณ Docker Ready - Easy server deployment with published Docker images

๐Ÿ—๏ธ Architecture

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    WiFi     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                 โ”‚โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บโ”‚                 โ”‚
โ”‚     ESP32       โ”‚             โ”‚  Raspberry Pi   โ”‚
โ”‚   (Display)     โ”‚    HTTP     โ”‚    (Server)     โ”‚
โ”‚                 โ”‚             โ”‚                 โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜             โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
          โ”‚ SPI                          โ”‚
          โ–ผ                              โ”‚ Port 3000
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                      โ–ผ
โ”‚  Waveshare      โ”‚               โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  13.3" E-Ink    โ”‚               โ”‚  Web Dashboard  โ”‚
โ”‚  Spectra 6      โ”‚               โ”‚                 โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜               โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

How it works:

  1. ESP32 wakes from deep sleep every 1-6 hours
  2. Connects to WiFi and fetches current image from Raspberry Pi server
  3. Updates the e-ink display with new content
  4. Reports battery status and device health
  5. Enters deep sleep until next scheduled wake-up

๐Ÿ› ๏ธ Hardware Requirements

Component Model Purpose
Controller Good Display ESP32-133C02 ESP32-S3 with QSPI interface
Display Waveshare 13.3" Spectra 6 1200ร—1600 6-color e-paper
Server Raspberry Pi 3/4/Zero 2W Local server hosting
Battery LiPo 12,000mAh (PiJuice) Months of battery life
Power Mgmt LiPo Amigo Pro + MiniBoost Charging + 5V boost

๐Ÿ”Œ ESP32 to Display Connections (Good Display ESP32-133C02)

GPIO Function Notes
18 SPI_CS0 Chip select 0
17 SPI_CS1 Chip select 1
9 SPI_CLK SPI clock
41 SPI_Data0 QSPI data line 0
40 SPI_Data1 QSPI data line 1
39 SPI_Data2 QSPI data line 2
38 SPI_Data3 QSPI data line 3
7 EPD_BUSY Display busy signal (input)
6 EPD_RST Display reset (output)
45 LOAD_SW Load switch control
2 BATTERY Battery ADC via voltage divider

๐Ÿš€ Quick Start

1. ๐Ÿฅง Deploy Server (Raspberry Pi)

Option A: One-command deploy

./deploy-to-pi.sh serverpi.local your-dockerhub-username

Option B: Manual Docker deploy

# On your Raspberry Pi
docker run -d \
  --name glance-server \
  -p 3000:3000 \
  -v $(pwd)/data:/app/data \
  --restart unless-stopped \
  your-username/glance-server:latest

2. ๐ŸŒ Configure via Web Dashboard

Access the dashboard at: http://your-pi-ip:3000

New to Glance? Try the interactive demo to explore the interface with mock data.

Three Simple Modes:

  • Create - Generate AI artwork or upload images
  • Explore - AI-powered search across 8 museum sources with 2+ million artworks
  • My Collection - View all your generated, uploaded, and saved artworks

Museum Sources: Met Museum, Art Institute of Chicago, Cleveland Museum, Rijksmuseum, Wikimedia Commons, Victoria & Albert Museum, Harvard Art Museums*, Smithsonian* (*API key required)

The interface follows calm design principles - minimalistic and distraction-free.

3. ๐Ÿ”ง Setup ESP32 Client

# Clone repository
git clone https://github.com/your-username/Glance.git
cd Glance/esp32-client/

# Set WiFi credentials
export WIFI_SSID="YourWiFiNetwork"
export WIFI_PASSWORD="YourWiFiPassword"
export DEVICE_ID="esp32-001"  # Optional: unique device ID

# Build and upload firmware
./build.sh

4. ๐Ÿ”‹ Deploy Device

  1. Connect LiPo battery to ESP32 BAT pin
  2. Verify display shows test pattern or fetched image
  3. Check web dashboard shows device as "online"
  4. System now runs autonomously!

๐Ÿ”„ Operation Cycle

graph LR
    A[๐Ÿ˜ด Deep Sleep<br/>~10ฮผA] --> B[โฐ Wake Up<br/>RTC Timer]
    B --> C[๐Ÿ“ถ WiFi Connect<br/>2-3 seconds]
    C --> D[๐Ÿ“ฅ Check Commands<br/>Remote control]
    D --> E[๐Ÿ“ท Fetch Image<br/>From server API]
    E --> F[๐Ÿ–ผ๏ธ Update Display<br/>30-45 seconds]
    F --> G[๐Ÿ“Š Report Status<br/>Battery, signal]
    G --> H[๐Ÿ’ค Calculate Sleep<br/>Server controlled]
    H --> A
Loading

๐Ÿ“ก API Endpoints

The ESP32 communicates with these server endpoints:

  • GET /api/current.json - Fetch current image and sleep duration
  • POST /api/device-status - Report device health (battery, signal, firmware version)
  • GET /api/firmware/version - Check for available firmware updates
  • GET /api/firmware/download - Download firmware binary for OTA update
  • POST /api/logs - Send device logs to server
  • GET /api/commands/:deviceId - Check for pending remote commands

๐ŸŽ›๏ธ Remote Control & Monitoring

Send commands to sleeping devices via web dashboard:

  • ๐Ÿ“ฑ Stay Awake - Keep device active for 5 minutes for debugging
  • ๐Ÿ”„ Force Update - Trigger immediate display refresh
  • ๐Ÿ“Š View Logs - Real-time ESP32 serial output
  • ๐Ÿ”‹ Battery Monitor - Track voltage, charging status, and battery history
  • ๐Ÿ“ก OTA Updates - Deploy firmware updates wirelessly with automatic rollback
  • ๐Ÿ“ˆ Device Stats - Monitor wake cycles, display updates, brownouts, and firmware version

๐Ÿ“ Project Structure

Glance/
โ”œโ”€โ”€ README.md              # This file
โ”œโ”€โ”€ CLAUDE.md              # Claude Code instructions
โ”œโ”€โ”€ docker-compose.yml     # Local development
โ”œโ”€โ”€ deploy-to-pi.sh        # Raspberry Pi deployment script
โ”‚
โ”œโ”€โ”€ docs/                  # ๐Ÿ“š Documentation
โ”‚   โ”œโ”€โ”€ DESIGN.md          # Design principles & philosophy
โ”‚   โ”œโ”€โ”€ SECURITY.md        # Security guidelines
โ”‚   โ”œโ”€โ”€ DEPLOYMENT.md      # Deployment instructions
โ”‚   โ”œโ”€โ”€ HARDWARE.md        # Hardware documentation
โ”‚   โ””โ”€โ”€ PROJECT_GOALS.md   # Project goals & roadmap
โ”‚
โ”œโ”€โ”€ esp32-client/          # ๐Ÿ”ง ESP32 Firmware
โ”‚   โ”œโ”€โ”€ gooddisplay-clean/ # Production firmware (Good Display board)
โ”‚   โ”‚   โ”œโ”€โ”€ src/
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ main.c         # Main application with battery monitoring
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ ota.c/h        # OTA firmware update system
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ server_config.h # Shared server configuration
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ GDEP133C02.c/h # E-ink display driver
โ”‚   โ”‚   โ””โ”€โ”€ platformio.ini     # Build config with firmware version
โ”‚   โ”œโ”€โ”€ lib/epd/           # E-ink display drivers
โ”‚   โ””โ”€โ”€ build.sh           # Build & upload script
โ”‚
โ”œโ”€โ”€ server/                # ๐Ÿ–ฅ๏ธ Node.js Server
โ”‚   โ”œโ”€โ”€ server.js          # Express.js entry point
โ”‚   โ”œโ”€โ”€ routes/            # API route handlers (9 modules)
โ”‚   โ”œโ”€โ”€ services/          # Business logic (7 modules)
โ”‚   โ”œโ”€โ”€ utils/             # Shared utilities (3 modules)
โ”‚   โ”œโ”€โ”€ public/            # Web interface
โ”‚   โ”‚   โ”œโ”€โ”€ index.html     # Main template
โ”‚   โ”‚   โ”œโ”€โ”€ css/           # Stylesheets
โ”‚   โ”‚   โ””โ”€โ”€ js/            # Modular JavaScript
โ”‚   โ”œโ”€โ”€ __tests__/         # Test suite (188 tests)
โ”‚   โ””โ”€โ”€ Dockerfile         # Container build
โ”‚
โ”œโ”€โ”€ hardware/              # ๐Ÿ”Œ PCB Design (KiCad)
โ”‚   โ””โ”€โ”€ Glance.kicad_*     # Circuit board files
โ”‚
โ””โ”€โ”€ scripts/               # ๐Ÿš€ Automation
    โ”œโ”€โ”€ build-and-push.sh  # Docker Hub publishing
    โ””โ”€โ”€ update-glance.sh   # Update helper

๐ŸŽจ Image Processing & AI Art

Image Processing

  • ๐ŸŒˆ 6-Color Optimization - Automatic conversion to Spectra 6 palette (black, white, yellow, red, blue, green)
  • โœจ Floyd-Steinberg Dithering - Professional quality color mapping for art reproduction
  • ๐Ÿ“ฆ Server-Side Processing - Reduces ESP32 memory usage
  • โœ‚๏ธ Auto-Crop - Removes whitespace margins from AI-generated images
  • ๐Ÿ”† Contrast Enhancement - Optimizes images for e-ink characteristics
  • ๐Ÿ”„ Rotation Support - 0ยฐ, 90ยฐ, 180ยฐ, or 270ยฐ rotation
  • ๐Ÿ“บ Full Resolution - 1150ร—1550 pixels (93% screen coverage)

AI Art Generation & Exploration

  • ๐Ÿค– GPT-4o Integration - Generate custom artwork via OpenAI image models
  • ๐Ÿ” Smart Search - Natural language queries interpreted by AI ("peaceful blue paintings")
  • ๐Ÿ›๏ธ 8 Museum Sources - Met, ARTIC, Cleveland, Rijksmuseum, Wikimedia, V&A, Harvard*, Smithsonian*
  • ๐ŸŒ 2M+ Artworks - Search across millions of public domain artworks simultaneously
  • ๐Ÿ“œ Prompt History - View the original prompt used to generate any artwork
  • ๐ŸŽจ E-Ink Optimized - AI prompts emphasize full-bleed, high-contrast compositions
  • ๐Ÿ’พ Personal Collection - Unified view of generated, uploaded, and saved artworks

Semantic Visual Search (CLIP-Powered)

  • ๐ŸŽฏ Search by Vibe - "peaceful blue water" finds Japanese winter landscapes, not keyword matching
  • โœจ Visual Similarity - "More like this" finds artworks with 0.73-0.84 similarity accuracy
  • ๐Ÿง  Personalized Recommendations - Taste profile learns from your interactions (likes weighted 2x)
  • โšก Local & Fast - CLIP ViT-B/32 runs locally (~600MB cached), ~200ms searches, no API costs
  • ๐Ÿ“ˆ Scalable Collection - Start with 105 artworks, easily scale to 1000-5000

Scale Up Your Collection:

cd server
# Requires Qdrant running: docker run -d -p 6333:6333 qdrant/qdrant
node scripts/populate-from-museums.js 100   # Add 200 artworks (100/museum)
node scripts/populate-from-museums.js 500   # Scale to 1000 artworks (500/museum)

๐Ÿ“Š Performance & Power

Metric Value Notes
Display Resolution 1150ร—1550px 93% screen area
Refresh Time 30-45 seconds Full 6-color update
Deep Sleep Current ~10ฮผA Months of battery life
Active Current (WiFi On) ~460mA @ 5V Peak during display refresh
Active Current (WiFi Off) ~250-300mA @ 5V Display-only operation
Wake-up Time 2-3 seconds WiFi connection ready
Battery Life 3-6 months 3000mAh LiPo, 6-hour cycle

๐Ÿ”‹ Battery Optimization & Monitoring

The firmware includes intelligent power management and monitoring:

  • WiFi Auto-Shutdown: Automatically disables WiFi during display refresh to save ~160-210mA
  • Row-by-Row Updates: 1ms delays between display rows for stable power draw
  • Progressive Delays: Strategic pauses between driver ICs to prevent voltage sag
  • Battery Monitoring: Real-time voltage tracking via GPIO 2 (calibrated 4.7:1 voltage divider)
  • Charging Detection: Automatic detection when battery voltage >= 4.0V
  • Brownout Protection: Recovery mode after 3 brownouts to prevent boot loops
  • Smart OTA: Only performs firmware updates when battery >= 3.6V or charging
  • Median Filtering: 20-sample ADC readings reject electrical noise outliers
  • Verified with KCX-017: Tested at 460mA peak with WiFi on, 250-300mA with WiFi off
  • Works on Battery: Successfully operates on PowerBoost 1000C + LiPo battery

๐Ÿงช Worst-Case Test Images

Power consumption varies by image complexity. Test images are included in server/data/:

  • test-1-checkerboard-worst-case.png - Maximum power draw (all pixels change)
  • test-2-solid-blue.png โ†’ test-3-solid-yellow.png - Full color shift test
  • test-4-color-stripes.png - All 6 colors displayed
  • test-5-fine-lines-extreme.png - Highest frequency pattern

If your battery setup works with test-1-checkerboard-worst-case.png, all normal images will work reliably.

๐Ÿ”ง Development

Server Development

cd server/
npm install
npm run dev      # Auto-reload development
npm test         # Run test suite
npm run coverage # Test coverage report

ESP32 Development

cd esp32-client/
./build.sh compile  # Build only
./build.sh upload   # Build + upload + monitor
./build.sh monitor  # Serial monitor only
./build.sh clean    # Clean build files

๐Ÿ’พ Persistent Storage & Data Management

Glance uses a multi-layered storage architecture for reliable data persistence:

Storage Architecture

SQLite Database (data/embeddings.db)

  • Artwork metadata and embeddings
  • User interaction history (likes, displays, skips)
  • Personalized taste profiles
  • 768-dimensional SigLIP embeddings for recommendations

Qdrant Vector Database (Port 6333)

  • High-performance vector similarity search
  • 512-dimensional CLIP embeddings
  • Semantic search by natural language
  • Visual similarity matching

JSON Files (data/)

  • current.json - Current display image (7.4 MB with base64 RGB data)
  • playlist.json - Automated playlist configuration
  • my-collection.json - User's saved artwork collection
  • collections.json - Collection metadata
  • user-interactions.json - Recent interaction history

File Storage (uploads/)

  • User-uploaded images
  • Processed artwork files

Docker Compose Setup

The docker-compose.yml includes persistent volumes for all data:

services:
  glance-server:
    volumes:
      - glance-data:/app/data              # SQLite + JSON files
      - glance-uploads:/app/uploads        # User uploads
      - huggingface-cache:/root/.cache/huggingface  # ML models (~600MB)
    environment:
      - QDRANT_URL=http://qdrant:6333
      - HF_TOKEN=${HF_TOKEN:-}            # Optional: Hugging Face API
    depends_on:
      - qdrant

  qdrant:
    image: qdrant/qdrant:latest
    ports:
      - "6333:6333"                        # REST API
      - "6334:6334"                        # gRPC (optional)
    volumes:
      - qdrant-storage:/qdrant/storage    # Vector database

volumes:
  glance-data:
  glance-uploads:
  qdrant-storage:
  huggingface-cache:

Storage Initialization

Verify and initialize storage:

cd server/
npm run init:storage

This command will:

  • Create necessary data directories
  • Initialize SQLite database with proper schema
  • Verify Qdrant connection
  • Report storage statistics and file sizes

Output example:

โœ“ Directory exists: /app/data
โœ“ SQLite database initialized
  - Total artworks: 1,247
  - With embeddings: 1,247
  - Coverage: 100%
โœ“ Qdrant connection successful
  - Total artworks indexed: 1,247
  - Vector size: 512
๐Ÿ’พ Storage Status Report
  Data Directory: 14.2 MB
  Uploads Directory: 42.8 MB (15 files)

Data Persistence Strategy

Local Development:

# Data stored in ./server/data/ and ./server/uploads/
npm start

Docker Deployment:

# Named volumes persist across container restarts
docker-compose up -d

# View volume locations
docker volume inspect glance_glance-data
docker volume inspect glance_qdrant-storage

Backup Strategy:

# Backup SQLite database
docker cp glance-server:/app/data/embeddings.db ./backup/

# Backup all data
docker run --rm \
  -v glance_glance-data:/data \
  -v $(pwd)/backup:/backup \
  alpine tar czf /backup/glance-data.tar.gz -C /data .

# Backup Qdrant
docker run --rm \
  -v glance_qdrant-storage:/qdrant \
  -v $(pwd)/backup:/backup \
  alpine tar czf /backup/qdrant-storage.tar.gz -C /qdrant .

Environment Variables

Required:

  • OPENAI_API_KEY - For AI art generation (optional if not using AI features)

Optional:

  • HF_TOKEN - Hugging Face API token for SigLIP embeddings (falls back to local CLIP)
  • QDRANT_URL - Qdrant server URL (default: http://localhost:6333)
  • PORT - Server port (default: 3000)
  • NODE_ENV - Environment mode (production/development)

Populating the Vector Database

Index artworks from various sources:

cd server/

# Index from JSON collection
node scripts/populate-qdrant.js path/to/artworks.json

# Index WikiArt dataset
node scripts/populate-qdrant-wikiart.js

# Fetch and index from museums
node scripts/populate-from-museums.js

Storage Monitoring

Check database stats via API:

# SQLite statistics
curl http://localhost:3000/api/semantic/stats

# Qdrant statistics
curl http://localhost:6333/collections/artworks

Monitor disk usage:

# Local development
du -sh server/data server/uploads

# Docker volumes
docker system df -v | grep glance

๐Ÿšข Deployment & Updates

Automated Deployment

Pushing to main branch automatically:

  1. Runs full test suite
  2. Builds multi-architecture Docker image
  3. Deploys to Raspberry Pi via Tailscale SSH
  4. Updates running container with zero downtime

Manual Deployment

# Deploy specific version
IMAGE_VERSION=abc1234 ./deploy-to-pi.sh serverpi.local your-username

# Check running version
docker exec glance-server env | grep IMAGE_VERSION

๐Ÿ› Troubleshooting

ESP32 Issues

  • WiFi fails: Check SSID/password, ensure 2.4GHz network
  • Display blank: Verify SPI connections, check power supply
  • Won't sleep: Check for active serial monitor connection
  • Battery drain: Verify deep sleep current with multimeter

Server Issues

  • Can't access dashboard: Check port 3000, firewall settings
  • Images not processing: Verify Sharp dependencies installed
  • Container won't start: Check disk space, Docker daemon

Network Issues

  • ESP32 can't reach server: Check serverpi.local resolution
  • Slow image downloads: Verify network bandwidth, WiFi signal
  • Commands not working: Ensure device recently active (within 5 min)

๐Ÿ—บ๏ธ Roadmap

โœ… Completed

  • ESP32 firmware with ultra-low power management
  • Node.js server with modular architecture
  • AI art generation with GPT-4o
  • AI-powered museum art search
  • Semantic visual search with CLIP - Find art by vibe, not keywords
  • "More like this" - Visual similarity search (0.73-0.84 accuracy)
  • Personalized recommendations - Taste profile learns from interactions
  • Personal art collection management
  • Clean, minimalistic web interface
  • Automated deployment pipeline
  • Comprehensive test coverage

๐Ÿ”ฎ Future Ideas

  • Scheduling art for different times of day
  • Battery usage analytics and optimization
  • Multi-device synchronization
  • Collaborative collections

๐Ÿ“š Documentation

Detailed documentation is available in the docs/ directory:

  • DESIGN.md - Design principles, UI guidelines, calm technology philosophy
  • SECURITY.md - Security best practices, credential management
  • DEPLOYMENT.md - Complete deployment guide (GitHub Actions, Docker, Tailscale)
  • HARDWARE.md - Hardware specifications and wiring diagrams
  • PROJECT_GOALS.md - Project goals and vision

Ready to build your own smart e-ink display? ๐Ÿš€

Start with the Quick Start guide above!

About

No description, website, or topics provided.

Resources

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors