dreader-application/HARDWARE_SETUP.md
Duncan Tourolle 70c0b4a1f2
All checks were successful
Python CI / test (3.12) (push) Successful in 7m1s
Python CI / test (3.13) (push) Successful in 7m10s
HW integratation
2025-11-11 11:57:39 +01:00

12 KiB
Raw Permalink Blame History

Hardware Integration Guide

This guide explains how to run DReader on real e-ink hardware using the dreader-hal library.

Quick Start

On Raspberry Pi:

# 1. Clone and setup
git clone https://gitea.tourolle.paris/dtourolle/dreader-application.git
cd dreader-application
python3 -m venv venv
source venv/bin/activate

# 2. Install everything
pip install -e .
./install_hardware_drivers.sh

# 3. Run interactive setup (detects hardware and configures)
sudo python3 setup_rpi.py

# 4. Run DReader (uses hardware_config.json)
python examples/run_on_hardware_config.py

Overview

The DReader application uses a plugin-based Hardware Abstraction Layer (HAL) architecture. You can choose different HAL implementations:

Configuration Files

  • hardware_config.json - Hardware configuration (display, buttons, sensors)
  • accelerometer_config.json - Accelerometer calibration for tilt gestures

Hardware Requirements

Required Components

  • Raspberry Pi (or compatible SBC)
  • IT8951 E-ink Display Controller (1872×1404 resolution)
  • FT5316 Capacitive Touch Panel

Optional Components

  • BMA400 Accelerometer - Auto-rotation based on device orientation
  • PCF8523 RTC - Timekeeping with battery backup
  • INA219 Power Monitor - Battery level monitoring

Software Installation

1. Install System Dependencies

On Raspberry Pi:

# Update package list
sudo apt update

# Install system dependencies
sudo apt install -y python3-dev python3-pip python3-venv
sudo apt install -y i2c-tools python3-smbus

# Enable I2C and SPI interfaces
sudo raspi-config
# Navigate to: Interface Options -> Enable I2C and SPI

2. Clone and Set Up DReader Application

# Clone the application
git clone https://gitea.tourolle.paris/dtourolle/dreader-application.git
cd dreader-application

# Initialize and update submodules (includes dreader-hal)
git submodule update --init --recursive

# Create virtual environment
python3 -m venv venv
source venv/bin/activate

# Install dreader-application
pip install -e .

3. Install dreader-hal and Dependencies

The dreader-hal library has external driver dependencies in its external/ directory:

# Install dreader-hal in editable mode
pip install -e external/dreader-hal

# Install external driver libraries
cd external/dreader-hal/external

# Install each driver
pip install -e IT8951
pip install -e PyFTtxx6
pip install -e PyBMA400
pip install -e PyPCF8523
pip install -e pi_ina219

cd ../../..  # Back to dreader-application root

4. Install Raspberry Pi GPIO (if on RPi)

pip install RPi.GPIO spidev

Hardware Wiring

IT8951 E-ink Display (SPI)

IT8951 Pin Raspberry Pi Pin Description
VCC 3.3V (Pin 1) Power supply
GND GND (Pin 6) Ground
MISO GPIO 9 (Pin 21) SPI MISO
MOSI GPIO 10 (Pin 19) SPI MOSI
SCK GPIO 11 (Pin 23) SPI Clock
CS GPIO 8 (Pin 24) SPI Chip Select
RST GPIO 17 (Pin 11) Reset
HRDY GPIO 24 (Pin 18) Ready signal

FT5316 Touch Panel (I2C)

FT5316 Pin Raspberry Pi Pin Description
VCC 3.3V (Pin 1) Power supply
GND GND (Pin 6) Ground
SDA GPIO 2 (Pin 3) I2C Data
SCL GPIO 3 (Pin 5) I2C Clock
INT GPIO 27 (Pin 13) Interrupt (optional)

BMA400 Accelerometer (I2C) - Optional

BMA400 Pin Raspberry Pi Pin Description
VCC 3.3V (Pin 1) Power supply
GND GND (Pin 6) Ground
SDA GPIO 2 (Pin 3) I2C Data
SCL GPIO 3 (Pin 5) I2C Clock
I2C Address 0x14 or 0x15 Check your module

PCF8523 RTC (I2C) - Optional

PCF8523 Pin Raspberry Pi Pin Description
VCC 3.3V (Pin 1) Power supply
GND GND (Pin 6) Ground
SDA GPIO 2 (Pin 3) I2C Data
SCL GPIO 3 (Pin 5) I2C Clock
BAT CR2032 Battery Backup battery

INA219 Power Monitor (I2C) - Optional

INA219 Pin Raspberry Pi Pin Description
VCC 3.3V (Pin 1) Power supply
GND GND (Pin 6) Ground
SDA GPIO 2 (Pin 3) I2C Data
SCL GPIO 3 (Pin 5) I2C Clock
VIN+ Battery + Positive voltage sense
VIN- Shunt resistor Through shunt to load

Note: Multiple I2C devices can share the same SDA/SCL pins. Ensure each has a unique I2C address.

GPIO Buttons (Optional)

Physical buttons for navigation:

Button Function GPIO Pin Connection
Previous Page GPIO 22 Button between GPIO 22 and GND
Next Page GPIO 27 Button between GPIO 27 and GND
Power Off GPIO 21 Button between GPIO 21 and GND

Wiring:

  • Connect one side of button to GPIO pin
  • Connect other side to GND
  • Internal pull-up resistors are enabled in software
  • Button press pulls GPIO LOW (0V)

Available GPIOs (BCM numbering):

  • Safe to use: 5-27 (except 14, 15 if using UART)
  • Avoid: GPIO 2, 3 (I2C), GPIO 7-11 (SPI), GPIO 14, 15 (UART)

Verify Hardware Connections

Check I2C Devices

# Scan I2C bus
i2cdetect -y 1

# Expected addresses (approximate):
# 0x38 - FT5316 touch panel
# 0x14 - BMA400 accelerometer
# 0x68 - PCF8523 RTC
# 0x40 - INA219 power monitor

Check SPI

# List SPI devices
ls /dev/spi*
# Should show: /dev/spidev0.0  /dev/spidev0.1

Important: VCOM Voltage

⚠️ CRITICAL: Each e-ink display has a unique VCOM voltage printed on a label (usually on the back).

  • Check your display label for VCOM voltage (e.g., -2.06V, -1.98V, etc.)
  • Pass this value to the HAL using the --vcom parameter
  • Using incorrect VCOM can damage your display!

Example from label: VCOM = -2.06V → use --vcom -2.06

Running on Hardware

The easiest way to get started is using the interactive setup script:

# 1. Run setup (detects hardware, configures GPIO buttons, etc.)
sudo python3 setup_rpi.py

# 2. Run DReader using generated config
python examples/run_on_hardware_config.py

The setup script will:

  • Detect connected I2C devices (touch, accelerometer, RTC, power monitor)
  • Enable I2C/SPI interfaces if needed
  • Configure GPIO button mappings
  • Set VCOM voltage
  • Generate hardware_config.json

Manual Configuration

Edit hardware_config.json to customize your hardware setup:

{
  "display": {
    "width": 1872,
    "height": 1404,
    "vcom": -2.06
  },
  "gpio_buttons": {
    "enabled": true,
    "buttons": [
      {"name": "prev_page", "gpio": 22, "gesture": "swipe_right"},
      {"name": "next_page", "gpio": 27, "gesture": "swipe_left"},
      {"name": "power_off", "gpio": 21, "gesture": "long_press"}
    ]
  }
}

Then run:

python examples/run_on_hardware_config.py

Direct Command Line (No Config File)

# Activate virtual environment
source venv/bin/activate

# Run with correct VCOM voltage (CHECK YOUR DISPLAY LABEL!)
python examples/run_on_hardware.py /path/to/books --vcom -2.06

Testing Without Hardware (Virtual Display)

You can test the integration on your development machine using virtual display mode:

python examples/run_on_hardware.py /path/to/books \
    --virtual \
    --no-orientation \
    --no-rtc \
    --no-power

This creates a Tkinter window simulating the e-ink display.

Advanced Options

# Disable optional hardware components
python examples/run_on_hardware.py /path/to/books \
    --vcom -2.06 \
    --no-orientation \  # Disable accelerometer
    --no-rtc \           # Disable RTC
    --no-power           # Disable battery monitor

# Show battery level periodically
python examples/run_on_hardware.py /path/to/books \
    --vcom -2.06 \
    --show-battery

# Custom battery capacity
python examples/run_on_hardware.py /path/to/books \
    --vcom -2.06 \
    --battery-capacity 5000  # mAh

# Enable verbose debug logging
python examples/run_on_hardware.py /path/to/books \
    --vcom -2.06 \
    --verbose

# Always start in library mode (ignore saved state)
python examples/run_on_hardware.py /path/to/books \
    --vcom -2.06 \
    --force-library

Full Options Reference

python examples/run_on_hardware.py --help

Touch Gestures

Once running, the following touch gestures are supported:

Gesture Action
Swipe Left Next page
Swipe Right Previous page
Swipe Up (from bottom) Open navigation/TOC overlay
Swipe Down (from top) Open settings overlay
Tap Select book, word, or link
Long Press Show word definition (if implemented)
Pinch In/Out Adjust font size

Troubleshooting

Display Not Working

  1. Check VCOM voltage - Must match label on display
  2. Check SPI connections - Run ls /dev/spi*
  3. Check SPI permissions - Add user to spi group: sudo usermod -a -G spi $USER
  4. Try virtual display mode - Test software without hardware

Touch Not Working

  1. Check I2C connections - Run i2cdetect -y 1
  2. Check I2C permissions - Add user to i2c group: sudo usermod -a -G i2c $USER
  3. Check touch panel I2C address - Should be 0x38 for FT5316
  4. Calibrate touch - See dreader-hal calibration docs

Import Errors

If you see ModuleNotFoundError for drivers:

# Ensure all external drivers are installed
cd external/dreader-hal/external
for dir in */; do pip install -e "$dir"; done
cd ../../..

Permission Errors

# Add user to required groups
sudo usermod -a -G spi,i2c,gpio $USER

# Log out and back in for changes to take effect

Display Ghosting

E-ink displays can show ghosting (image retention). The HAL automatically performs full refreshes every 10 page turns, but you can force one:

  • The RefreshMode.FULL is automatically triggered periodically
  • Check dreader-hal documentation for manual refresh control

Programmatic Usage

You can also use the hardware HAL programmatically in your own scripts:

import asyncio
from dreader.hal_hardware import HardwareDisplayHAL
from dreader.main import DReaderApplication, AppConfig

async def main():
    # Create hardware HAL
    hal = HardwareDisplayHAL(
        width=1872,
        height=1404,
        vcom=-2.06,  # YOUR DISPLAY'S VCOM!
        virtual_display=False,
        enable_orientation=True,
        enable_rtc=True,
        enable_power_monitor=True,
    )

    # Create application config
    config = AppConfig(
        display_hal=hal,
        library_path="/home/pi/Books",
        page_size=(1872, 1404),
    )

    # Create and run application
    app = DReaderApplication(config)

    try:
        await hal.initialize()
        await app.start()

        # Main event loop
        while app.is_running():
            event = await hal.get_touch_event()
            if event:
                await app.handle_touch(event)
            await asyncio.sleep(0.01)

    finally:
        await app.shutdown()
        await hal.cleanup()

if __name__ == '__main__':
    asyncio.run(main())

Performance Notes

E-ink Refresh Modes

The dreader-hal library automatically selects refresh modes:

  • Fast (DU mode): ~200ms - Used for text updates
  • Quality (GC16 mode): ~1000ms - Used for images
  • Full (INIT mode): ~1000ms - Used every 10 pages to clear ghosting

Battery Life

With default settings:

  • Active reading: ~10-20 hours
  • Standby (display sleeping): ~1-2 weeks
  • Enable low power mode for extended battery life

Memory Usage

  • Base application: ~30-50MB
  • Per book: ~10-30MB (depends on book size)
  • Ensure Raspberry Pi has at least 512MB RAM

Next Steps

Support

For hardware-specific issues, check:

For application issues, check: