A MicroPython-based launcher for the BeagleBadge, using LVGL (Light and Versatile Graphics Library) for the UI. This project provides a robust application launcher with games, tools, and media players.
- BeagleBadge (or compatible Linux-based badge device)
- Linux distribution with
systemd(e.g., Debian) - Display: 400x300 E-Ink display
- Input: GPIO buttons or compatible input device
gcc(for compiling asset conversion tools)sshpass(optional, for deployment scripts)
badge-slop/
├── main.py # Application entry point
├── config.py # Configuration management
├── core/ # Framework core
│ ├── app.py # Base app class
│ ├── app_loader.py # Dynamic app loader
│ ├── menu.py # Main menu interface
│ ├── statusbar.py # Status bar (CPU, RAM, battery)
│ └── bottombar.py # Bottom bar (network, USB)
├── applications/ # User applications
│ ├── apps/ # General applications (flat files & folders)
│ │ ├── chiptunez/ # Folder-based app example
│ │ ├── dvd_app.py # Flat file app example
│ │ └── ...
│ ├── games/ # Games (Snake, Brick, etc.)
│ ├── settings/ # System settings
│ └── tools/ # Utilities (I2C scanner, etc.)
├── drivers/ # Hardware drivers
│ ├── display.py # Display driver
│ ├── input.py # Input handling
│ ├── sound.py # Sound/beeper driver
│ └── tty.py # TTY management
├── lib/ # Helper libraries
├── assets/ # Binary assets
│ ├── *.bin # Converted images
│ └── *.c # C source images
├── scripts/ # Build and deployment
│ ├── run.sh # Launcher script
│ ├── sync.sh # Deploy to device
│ └── build_deb.sh # Build debian package
├── tools/ # Development tools
│ ├── img2bin.c # Image converter
│ ├── convert_assets.py # Asset conversion helper
│ └── debug_loader.py # Debug utility
├── tests/ # Test scripts
├── debian/ # Debian packaging files
├── lv_micropython/ # MicroPython with LVGL (submodule)
# Basic build tools (if building MicroPython on device)
apt install -y build-essential libreadline-dev libffi-dev pkg-config
# I2C tools (for I2C Scanner application)
apt install -y i2c-toolssudo apt-get install libsdl2-dev cmake build-essential python3-dev python3-pip python3-venv libffi-devOn your development machine, from the project root:
# Make sure you have the MicroPython binary
# (see "Building MicroPython" section below)
# Build the .deb package
./scripts/build_deb.shThis creates badge-launcher_<version>_arm64.deb in the current directory.
# Copy package to device
scp badge-launcher_*.deb root@<device-ip>:~
# Install on device
ssh root@<device-ip>
dpkg -i badge-launcher_*.deb
# Enable autostart
systemctl enable badge-launcher.service
systemctl start badge-launcher.serviceThe package installs to /opt/badge_launcher and sets up systemd autostart.
For active development, use the sync script to deploy directly:
Edit scripts/sync.sh and set your device information:
BADGE_IP="192.168.1.xxx" # Your device IP
BADGE_USER="root"
BADGE_PASS="your-password"
DEST_DIR="~/badge_launcher" # Installation directory./scripts/sync.shThis syncs all files to ~/badge_launcher on the device.
ssh root@<device-ip>
cd ~/badge_launcher
./scripts/run.shThe launcher requires MicroPython with LVGL bindings. Build natively on the BeagleBadge for best compatibility.
git submodule update --init --recursiveA small patch is required for header inclusion:
sed -i 's|INC += -I$(LVGL_BINDING_DIR)|INC += -I$(LVGL_BINDING_DIR) -I$(LVGL_DIR)|' \
lv_micropython/user_modules/lv_binding_micropython/micropython.mkOn the device:
cd lv_micropython/mpy-cross
make -j$(nproc)cd ../ports/unix
make -j$(nproc) \
USER_C_MODULES=../../user_modules \
LV_CFLAGS="-DLV_LVGL_H_INCLUDE_SIMPLE"# For debian package build
cp ports/unix/build-standard/micropython /path/to/badge-slop/micropython
# For manual install
cp ports/unix/build-standard/micropython ~/badge_launcher/micropython
chmod +x ~/badge_launcher/micropythonImages must be converted to raw binary format for fast loading on the E-Ink display.
The img2bin tool is required for the Photos app to convert images on-the-fly.
Note: The source file
tools/img2bin.cis currently missing from the repository. Using the pre-compiled binary is recommended if available for your architecture.
# If source is available:
gcc -o img2bin tools/img2bin.c -lm -O2This creates the img2bin binary in the project root.
# Basic usage (default 128x128)
./img2bin input_image.png output_file.bin
# Specify custom dimensions
./img2bin input_image.png output.bin 400 300
# Maintain aspect ratio with 'contain' mode (adds white borders)
./img2bin input_image.png output.bin 400 300 contain
# Fill the area with 'cover' mode (crops if needed)
./img2bin input_image.png output.bin 400 300 cover
# Stretch to fill (ignores aspect ratio)
./img2bin input_image.png output.bin 400 300 stretchFit Modes:
stretch- Stretch to exact dimensions (default, ignores aspect ratio)contain- Fit inside target area, maintain aspect ratio, add white borders if neededcover- Cover target area, maintain aspect ratio, crop from center if needed
The tool:
- Resizes images to specified dimensions (default: 400x300)
- Converts to L8 (grayscale) format
- Applies Floyd-Steinberg dithering for E-Ink display
- Supports aspect ratio preservation with letterboxing/pillarboxing
- Outputs raw binary files
Usage with Photos App:
- Place
.jpg,.jpeg,.png, or.bmpfiles in thephotos/directory - The Photos app automatically converts them to 400x300 on first view
- Uses
containmode to preserve aspect ratio with white borders - Converted images are cached in
/tmp/for fast subsequent loading within the same session - Cache files are automatically cleaned up when you exit the Photos app
Pre-converted Assets:
- Place
.binfiles in theassets/directory for use by other apps
The launcher stores configuration in config.json in the application directory:
{
"sound_enabled": true,
"badge_name": "Beagle\nBadge",
"badge_info": "Linux (CES Port)\nBuild - Python",
"badge_logo": 0
}Settings:
sound_enabled: Enable/disable beeper soundsbadge_name: Name shown in Badge Modebadge_info: Info text shown in Badge Modebadge_logo: Logo preference (0=Random, 1=Beagle, 2=TI)
Configuration is editable through the Settings app or Badge Mode interface.
The badge launcher supports two app structures:
Create a single .py file in the appropriate category:
# applications/apps/myapp.py
from core import app
import lvgl as lv
class MyApp(app.App):
def __init__(self):
super().__init__("My App")
def enter(self, on_exit=None):
# Your app logic here
passFor apps with resources, data files, or multiple modules:
applications/apps/
└── myapp/
├── myapp_app.py # Main app file
├── data/ # Data files
├── assets/ # Images, fonts, etc.
└── README.md # Documentation
Benefits:
- Self-contained and portable
- Easy to distribute as Git repos
- Can be managed as Git submodules
- App store ready
Quick Start:
# Copy the template
cp -r applications/apps/_template_app applications/apps/myapp
# Rename the main file
cd applications/apps/myapp
mv template_app_app.py myapp_app.py
# Edit and customizeSee also:
- FOLDER_APPS_GUIDE.md - Complete guide to folder-based apps
- applications/README.md - Detailed app development docs
- applications/apps/chiptunez/ - Working example
The badge launcher includes an integrated app store for discovering and installing community-developed apps.
- Navigate to Settings → App Store on your badge
- Browse available apps
- Use ↑/↓ to select an app
- Press ENTER to install
- Restart the launcher to see new apps
Create a community app store repository:
# Create store repository
./scripts/create_app_store_repo.sh ../badge-app-store
cd ../badge-app-store
# Push to GitHub
git remote add origin https://github.com/YOUR_ORG/badge-app-store.git
git push -u origin main# Validate your app first
./scripts/validate_app.sh ../my-awesome-app
# Add to store
./scripts/add_app_to_store.sh \
../badge-app-store \
my-app \
https://github.com/user/my-app-repo.git \
"My Awesome App" \
"Your Name" \
"Description of the app" \
"tools" \
"1.0.0"
# Push changes
cd ../badge-app-store
git pushUpdate the store URLs in applications/tools/app_store_app.py:
self.store_repo = "https://github.com/YOUR_ORG/badge-app-store.git"
self.manifest_url = "https://raw.githubusercontent.com/YOUR_ORG/badge-app-store/main/manifest.json"Documentation:
- Learn about store architecture, app submission, and best practices
Technical Details:
- Uses git submodules for version control
- Apps are downloaded on-demand
- Each app has metadata (name, version, author, category)
- Supports automatic dependency checking
- Apps install to
applications/apps/{app-id}/
The debian package automatically sets up systemd integration:
# Check status
systemctl status badge-launcher.service
# Stop service
systemctl stop badge-launcher.service
# Start service
systemctl start badge-launcher.service
# Disable autostart
systemctl disable badge-launcher.service
# View logs
journalctl -u badge-launcher.service -fcd /opt/badge_launcher # or ~/badge_launcher
./scripts/run.shThe launcher will:
- Kill any existing MicroPython instances
- Disable the framebuffer cursor
- Clear the screen
- Launch the application
-
Create a new Python file in the appropriate
applications/subdirectory:applications/apps/- General applicationsapplications/games/- Gamesapplications/tools/- Utilitiesapplications/settings/- Settings screens
-
Import the base app class:
import sys
if "core" not in sys.path: sys.path.append("core")
from core import app
import lvgl as lv
class MyApp(app.App):
def __init__(self):
super().__init__("My App Name")
def enter(self, on_exit=None):
self.on_exit_cb = on_exit
# Create your UI here
def exit(self):
# Clean up resources
pass- The app will be automatically discovered by
core/app_loader.pyand appear in the menu.
- Keep apps self-contained - Each app should be in a single file
- Use relative paths - Assets in
assets/, drivers indrivers/ - Follow naming conventions - Apps end with
_app.py - Handle cleanup - Always implement the
exit()method
The application version is managed centrally through the VERSION file at the project root. This version is automatically displayed in the menu and synced with the debian package.
Use the provided script to update the version across all files:
./scripts/update_version.sh 1.0.1This will:
- Update the
VERSIONfile - Prepend a new entry to
debian/changelog - Display instructions for committing and tagging
If you prefer to update manually:
-
Edit the
VERSIONfile:echo "1.0.1" > VERSION
-
Update
debian/changelog:dch -v 1.0.1 "Your changelog message" # OR manually edit debian/changelog
-
The version will automatically appear in the menu on next launch
The version is loaded by config.py and displayed in core/menu.py.
The launcher reads from /dev/input/event* devices. Ensure proper permissions:
# Check input devices
ls -l /dev/input/event*
# Run as root or add user to input group
usermod -aG input <username>If you see "ImportError" for lvgl:
- Verify MicroPython was built with LVGL bindings
- Check that the patch was applied to
micropython.mk - Rebuild with
USER_C_MODULESflag
- Ensure images were converted using
img2bin - Check that
.binfiles are inassets/directory - Verify file permissions (should be readable)
If the display shows artifacts or doesn't refresh:
- The launcher uses E-Ink refresh sweeps to clear ghosting
- Check that
/dev/fb0exists and is accessible - Verify the display driver is loaded
Check systemd logs:
journalctl -u badge-launcher.service -n 50Common issues:
- Missing
micropythonbinary - Wrong working directory
- Missing dependencies
- Logo display (TI/Beagle, configurable)
- Category-based app organization
- Status bar with system info
- Bottom bar with network status
- Customizable name and info display
- Logo selection (Random, TI, Beagle)
- Editable via on-screen keyboard
- Configuration persistence
- Media: Image viewer, music player
- Games: Snake, Brick
- Tools: I2C scanner, serial monitor
- Settings: WiFi, Bluetooth, system info
- Real-time CPU/RAM monitoring
- Battery status display
- Network status (Ethernet/WiFi)
- USB device detection
See LICENSE file for details.
- LVGL Graphics Library: https://lvgl.io
- MicroPython: https://micropython.org
- BeagleBoard.org Foundation