A digital clock with custom animated pixel characters
See preview videos
The preview can be found at: .github/docs/preview.mp4
preview.mp4
The finished build can be seen here .github/docs/build.mp4
build.mp4
The scene configuration can be found in resources/states.prod.csv
Each animation state uses sprite sheets (sheet.png) with configuration files (config.json) that define frame dimensions, count, and layout.
The application behavior can be customized through config.py:
- Display settings: Screen dimensions (480x320), FPS (60)
- Environment flags: Production mode, idle mode, skip start animation
- Time formatting: Date and time display formats
- Special dates: Significant date highlighting with custom prefix
Key configuration options:
IS_PROD: Toggles between production and development animation statesIS_IDLE: Forces static idle display when enabledSKIP_START: Bypasses the startup animation sequenceSCREEN_WIDTH/HEIGHT: Display resolution (optimized for 3.5" displays)
This project requires the following hardware components:
- 3.5" Display - make sure the display is DSI/DPI/HDMI since those support 60 FPS
- Raspberry Pi 4B - with 2GB RAM (minimum)
- 15W USB-C Power Supply - for stable power delivery
- Micro SD card - 16GB (depending on number of assets you may need more or less capacity)
Actual metrics logged over 24h of continues use in a regular room temperature:
| Metric | Average | Peak | Acceptable Range |
|---|---|---|---|
| CPU Usage | 27% | 27% | < 40% |
| RAM Usage | 24.5% | 24.5% | < 80% |
| Temperature | 50°C | 51°C | < 75°C |
The device was left to run non-stop and started logging metrics via the app/metrics.py
The logs were taken from a range 2025-10-06 20:00:00 - 2025-10-07 20:00:00
The raw logs can be found at .github/docs/metrics.log
Full guide...
- Long press (2 seconds): Restart animation (resets the sprite animation state)
- Escape key: Stop service and exit application (will not auto-restart until next boot or manual start)
- Window close button: Stop service and exit application (will not auto-restart until next boot or manual start)
Note: The application automatically detects if it's running as a systemd service and will stop the service when exiting to prevent automatic restart.
Full guide...
-
Create and activate virtual environment
python3 -m venv venv source venv/bin/activate # On windows: venv\Scripts\activate
-
Install dependencies
make install ## production deps only make install-dev ## with development deps
-
Run the application
make run
The project includes a Makefile with common development tasks:
make help # Show available commands
make install # Install production dependencies
make install-dev # Install development dependencies
make format # Format code with black
make lint # Run flake8 linter
make type-check # Run mypy type checker
make check # Run all checks (format, lint, type-check)
make run # Run the application
make clean # Clean up cache files
make dev-script # Use Python development script (e.g., make dev-script ARGS=check)Alternative Python Development Script
You can also use the Python development script directly:
python scripts/dev.py format # Format code with black
python scripts/dev.py lint # Run flake8 linter
python scripts/dev.py type-check # Run mypy type checker
python scripts/dev.py check # Run all checks
python scripts/dev.py run # Run the application
python scripts/dev.py clean # Clean up cache filesThis project uses several tools to maintain code quality:
- Black: Code formatter for consistent style
- Flake8: Linter for code quality and style issues
- MyPy: Static type checker for type safety
Full guide...
This project is optimized for Raspberry Pi 4B with 3.5" display as a digital clock.
KEEP IN MIND
In the example command below, keep in mind that the variable $IP has the value of your devices IP address
IP="<your_raspberry_pi_ip_address>"Configuration
This guide provides comprehensive setup instructions for a display I used, some parts of the setup are generic but some are highly specific based on the exact display you have. The parts marked
Prerequisites
- Raspberry Pi 4B (2GB RAM minimum)
- 3.5" DPI Touch Screen Display (640x480 native resolution)
- Fresh Raspberry Pi OS installation (Bookworm 64bit recommended)
- 15W USB-C Power Supply - for stable power delivery
- Micro SD card - 16GB (depending on number of assets you may need more or less capacity)
Step-by-Step Setup Guide
1. Prepare the SD Card with Raspberry Pi OS
First, we need to create a bootable SD card with the Raspberry Pi operating system:
- Download and install Raspberry Pi Imager from the official website
-
Launch Raspberry Pi Imager and select the following options:
- Choose OS: Raspberry Pi OS (64-bit) - Bookworm is recommended for best performance
- Choose Storage: Select your SD card
-
Advanced Options access advanced options and configure:
-
Set hostname:
digime(this will be your device's network name) - Enable SSH: Check this option for remote access
-
Set username and password: Username:
admin, Password:admin- change this for security but the other commands are specified expecting this config
- Configure wireless LAN: Enter your Wi-Fi network name and password
-
Set hostname:
- Click "Write" to flash the OS to the SD card
- Wait for the process to complete - this may take several minutes
2. Configure the Display $\color{Red}{\textsf{DISPLAY SPECIFIC}}$
After flashing the OS, you'll need to configure the display before booting:
-
Locate the SD card in your file explorer (it should appear as a drive named "boot")
-
Open the
config.txtfile in a text editor (located in the root directory of the SD card) -
Add the following lines at the end of the file:
# Enable the VC4 graphics driver dtoverlay=vc4-kms-v3d # Configure the display driver (specific to Waveshare 3.5" DPI display) dtoverlay=waveshare-35dpi # Enable touch functionality dtoverlay=waveshare-touch-35dpi
Note: These overlay settings are specific to the Waveshare 3.5" DPI display. If you're using a different display, you'll need to find the appropriate overlay settings for your specific model.
-
Download the display driver files:
- For Waveshare displays, download the appropriate DTBO file from the manufacturer's website
- Extract the downloaded file to get the
.dtbofile - Copy this file to the
/boot/overlays/directory on the SD card
-
Save all changes and safely eject the SD card
3. First Boot and Initial Configuration
Now it's time to boot up your Raspberry Pi and complete the setup:
- Insert the SD card into your Raspberry Pi
- Connect the display to your Raspberry Pi following the manufacturer's instructions
- Power on the Raspberry Pi using the 15W USB-C power supply
-
Wait approximately 30 seconds for the initial boot process to complete
- You should see the Raspberry Pi OS desktop appear on your display
4. System Configuration via SSH
Next, we'll configure the system settings remotely via SSH:
-
Find your Raspberry Pi's IP address:
- You can check your router's connected devices list
- Or use a network scanner app on your phone/computer
- Set this as a variable in your terminal:
IP="your_raspberry_pi_ip_address"
-
Connect via SSH from your computer:
ssh admin@$IP -
Switch from Wayland to X11
$\color{Red}{\textsf{DISPLAY SPECIFIC}}$ :sudo raspi-config
- Navigate to: Advanced Options → Wayland → No (to use X11 instead)
- Select "Finish" and reboot if prompted
-
Configure system settings:
sudo raspi-config
- Navigate to: System Options → Boot / Auto Login → Desktop Autologin
- Navigate to: System Options → Splash Screen → Yes (to enable splash screen)
- Select "Finish" and exit
-
Optimize boot parameters for a cleaner boot experience:
sudo nano /boot/firmware/config.txt
- Add these lines at the end of the file:
# Reduce boot messages and hide cursor loglevel=3 quiet vt.global_cursor_default=0 -
Add a virtual keyboard
$\color{Red}{\textsf{DISPLAY SPECIFIC}}$ :sudo apt update sudo apt install matchbox-keyboard
-
Hide the mouse cursor
$\color{Red}{\textsf{DISPLAY SPECIFIC}}$ :sudo nano /etc/lightdm/lightdm.conf
- Find the
[Seat:*]section - Add or modify this line:
xserver-command=X -nocursor
- Find the
-
Add backlight adjustment support
$\color{Red}{\textsf{DISPLAY SPECIFIC}}$ :
- Install WiringPi
cd ~ git clone https://github.com/WiringPi/WiringPi.git cd WiringPi ./build gpio -v gpio -g mode 18 pwm gpio pwmc 100
-
Reboot to apply all changes:
sudo reboot
5. Final UI Configuration
After rebooting, you'll need to make some final adjustments to the user interface:
Disable system notifications to prevent them from appearing over your clock:
- This needs to be done through the desktop UI
- You can use VNC to connect remotely, or do this directly on the Raspberry Pi
- Go to: Start Menu → Preferences → Raspberry Pi Configuration → System
- Uncheck "Show notifications on desktop"
6. Deploy DigiMe to Raspberry Pi
Now it's time to transfer the DigiMe application to your Raspberry Pi:
-
From your development machine, run:
./scripts/deploy.sh admin@$IP:/home/admin/DigiMeThis script will:
- Package the necessary files
- Transfer them to your Raspberry Pi
- Exclude development-only files
- Display instructions for installation
-
Follow the installation instructions displayed after deployment:
ssh admin@$IP cd /home/admin/DigiMe sudo ./scripts/install.sh
Note: The
install.shscript is designed to work with X11 (not Wayland) and will set up a service that handles scaling from the display's native 640x480 resolution to the application's 480x320 resolution.
7. Custom Boot Splash Screen (Optional)
To customize the boot splash screen with the DigiMe logo:
-
Transfer the splash image to your Raspberry Pi:
scp -r .github/docs/splash.png admin@$IP:/home/admin/Desktop/splash.png -
SSH into your Raspberry Pi:
ssh admin@$IP -
Replace the default splash screen:
# Backup the original splash screen cd /usr/share/plymouth/themes/pix sudo mv splash.png splash_default.png # Copy the new splash screen cd /home/admin/Desktop sudo cp splash.png /usr/share/plymouth/themes/pix # Rebuild the initrd to include the new splash screen sudo plymouth-set-default-theme --rebuild-initrd pix # Clean up rm splash.png
-
Reboot to see your new splash screen:
sudo reboot
Install
-
Deploy to Raspberry Pi (excludes dev files)
./scripts/deploy.sh admin@$IP:/home/admin/digime -
SSH into Raspberry Pi and install
ssh admin@$IP cd /home/admin/digime sudo ./scripts/install.sh
-
Reboot to start automatically
sudo reboot
The install script automatically:
- Installs pygame if not present
- Creates a systemd user service
- Enables lingering for the user (allows service to start at boot)
- Configures the service to run in kiosk mode with high priority
Update
For subsequent updates after initial setup:
-
Deploy changes to Raspberry Pi
./scripts/deploy.sh admin@$IP:/home/admin/digime -
SSH into Raspberry Pi and update
ssh admin@$IP cd /home/admin/digime sudo ./scripts/update.sh
The update script automatically:
- Stops the service if running
- Updates service configuration using
install.sh - Reloads systemd daemon
- Restarts the service if it was running before
- Shows service status
Manual Start
You can also start the application manually without the service:
# Start in windowed mode
./scripts/start.sh
# Start in kiosk mode
./scripts/start.sh --kiosk
# Start with metrics monitoring
./scripts/start.sh --metrics
# Start in kiosk mode with metrics
./scripts/start.sh --kiosk --metrics
# Show help
./scripts/start.sh --helpThe script accepts any combination of command-line arguments and passes them directly to the Python application.
Usage
Direct Application Usage:
-
Run in windowed mode (for debugging)
python3 main.py
-
Run in kiosk mode (fullscreen, no cursor)
python3 main.py --kiosk
-
Run with performance metrics monitoring (logs every 10 minutes to
logs/metrics.log)python3 main.py --metrics
-
Run in kiosk mode with metrics
python3 main.py --kiosk --metrics
Service Management (user service):
systemctl --user start digime.service # Start the service
systemctl --user stop digime.service # Stop the service
systemctl --user restart digime.service # Restart the service
systemctl --user status digime.service # Check service statusNote: Service management commands should be run as the regular user, not as root.
Performance Monitoring
The application includes built-in performance monitoring that can be enabled with the --metrics flag:
# Run with metrics monitoring (logs every 10 minutes to logs/metrics.log)
python3 main.py --metrics
# Run in kiosk mode with metrics
python3 main.py --kiosk --metricsFeatures:
- Logs CPU usage, RAM usage, and temperature every 10 minutes exactly on the 0-second mark
- Creates
logs/metrics.logfile automatically - Integrated with the main application lifecycle
- Uses Python's
psutillibrary for cross-platform compatibility - Automatic log directory creation
- Monitoring runs in a separate thread and stops cleanly when the application exits
Log Format: The metrics are logged in a structured format with timestamps, making it easy to analyze performance over time.
Backup
- Power off the Raspberry Pi and remove the SD card.
- Insert the SD card into your Mac using an SD card reader.
- Open Terminal and list drives:
diskutil list
- Identify your SD card’s device, e.g.
/dev/disk3(do not use partition names like/dev/disk3s1) - Unmount the SD card:
diskutil unmountDisk /dev/disk3
- Run the following to create an image (change disk name and image file name as needed):
This may take several minutes depending on card size.
sudo dd if=/dev/disk3 of=digime_vX.X.X_alpha.img bs=1m
- Shrink the image using pishrink
- open docker
- run shrink command
pishrink -z digime_vX.X.X_alpha.img digime_vX.X.X.img
This project is open source. Please check the license file for details.
