Skip to content

dariodumlijan/digime

Repository files navigation

DigiMe

A digital clock with custom animated pixel characters

featured

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.

Configuration

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 states
  • IS_IDLE: Forces static idle display when enabled
  • SKIP_START: Bypasses the startup animation sequence
  • SCREEN_WIDTH/HEIGHT: Display resolution (optimized for 3.5" displays)

Hardware Requirements

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)

Performance Metrics

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

Performance Over 24h

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

performance_line_chart

Controls

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.

Development

Full guide...

Quick Start

  1. Create and activate virtual environment

    python3 -m venv venv
    source venv/bin/activate  # On windows: venv\Scripts\activate
  2. Install dependencies

    make install      ## production deps only
    make install-dev  ## with development deps
  3. Run the application

    make run

Development Commands

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 files

Code Quality Tools

This 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

Raspberry Pi Setup

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 $\color{Red}{\textsf{DISPLAY SPECIFIC}}$ make sure to find guides online that are for your exact display.

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:

  1. Download and install Raspberry Pi Imager from the official website
  2. 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
  3. Click "Write" to flash the OS to the SD card
  4. 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:

  1. Locate the SD card in your file explorer (it should appear as a drive named "boot")

  2. Open the config.txt file in a text editor (located in the root directory of the SD card)

  3. 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.

  4. 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 .dtbo file
    • Copy this file to the /boot/overlays/ directory on the SD card
  5. 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:

  1. Insert the SD card into your Raspberry Pi
  2. Connect the display to your Raspberry Pi following the manufacturer's instructions
  3. Power on the Raspberry Pi using the 15W USB-C power supply
  4. 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:

  1. 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"
  2. Connect via SSH from your computer:

    ssh admin@$IP
  3. 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
  4. 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
  5. 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
    
  6. Add a virtual keyboard $\color{Red}{\textsf{DISPLAY SPECIFIC}}$:

    sudo apt update
    sudo apt install matchbox-keyboard
  7. 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
  8. 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
  1. 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:

  1. From your development machine, run:

    ./scripts/deploy.sh admin@$IP:/home/admin/DigiMe

    This script will:

    • Package the necessary files
    • Transfer them to your Raspberry Pi
    • Exclude development-only files
    • Display instructions for installation
  2. Follow the installation instructions displayed after deployment:

    ssh admin@$IP
    cd /home/admin/DigiMe
    sudo ./scripts/install.sh

    Note: The install.sh script 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:

  1. Transfer the splash image to your Raspberry Pi:

    scp -r .github/docs/splash.png admin@$IP:/home/admin/Desktop/splash.png
  2. SSH into your Raspberry Pi:

    ssh admin@$IP
  3. 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
  4. Reboot to see your new splash screen:

    sudo reboot

Install

  1. Deploy to Raspberry Pi (excludes dev files)

    ./scripts/deploy.sh admin@$IP:/home/admin/digime
  2. SSH into Raspberry Pi and install

    ssh admin@$IP
    cd /home/admin/digime
    sudo ./scripts/install.sh
  3. 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:

  1. Deploy changes to Raspberry Pi

    ./scripts/deploy.sh admin@$IP:/home/admin/digime
  2. 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 --help

The 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 status

Note: 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 --metrics

Features:

  • Logs CPU usage, RAM usage, and temperature every 10 minutes exactly on the 0-second mark
  • Creates logs/metrics.log file automatically
  • Integrated with the main application lifecycle
  • Uses Python's psutil library 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

  1. Power off the Raspberry Pi and remove the SD card.
  2. Insert the SD card into your Mac using an SD card reader.
  3. Open Terminal and list drives:
    diskutil list
  4. Identify your SD card’s device, e.g. /dev/disk3 (do not use partition names like /dev/disk3s1)
  5. Unmount the SD card:
    diskutil unmountDisk /dev/disk3
  6. Run the following to create an image (change disk name and image file name as needed):
    sudo dd if=/dev/disk3 of=digime_vX.X.X_alpha.img bs=1m
    This may take several minutes depending on card size.
  7. Shrink the image using pishrink
    • open docker
    • run shrink command
      pishrink -z digime_vX.X.X_alpha.img digime_vX.X.X.img

License

This project is open source. Please check the license file for details.