# GPIO Button Configuration Guide This guide explains how to configure physical buttons for the DReader e-reader. ## Overview Physical buttons provide tactile feedback for page turns and navigation without requiring touch input. Buttons are connected between GPIO pins and GND, using internal pull-up resistors. ## Hardware Setup ### Basic Button Wiring ``` +3.3V | R (internal pull-up) | GPIO --|------ Button ------ GND | (to BCM2835) ``` When the button is pressed, it connects the GPIO pin to GND (0V), pulling the pin LOW. ### Recommended Button Layout For this e-reader device with 3 buttons: ``` ┌─────────────────────┐ │ │ │ [Power Off] │ ← Side button (GPIO 21) │ │ │ │ │ E-INK │ │ DISPLAY │ │ 1872x1404 │ │ │ │ [Prev] [Next] │ ← Bottom edge │ │ └─────────────────────┘ ``` **Button Mapping:** - **Previous Page** (GPIO 22) - Bottom left - Previous page - **Next Page** (GPIO 27) - Bottom right - Next page - **Power Off** (GPIO 21) - Side button - Shutdown device (long press) ## Software Configuration ### Using Interactive Setup (Recommended) ```bash sudo python3 setup_rpi.py ``` The setup script will: 1. Ask if you want GPIO buttons enabled 2. Let you configure each button individually 3. Allow custom GPIO pin assignments 4. Generate hardware_config.json automatically ### Manual Configuration Edit `hardware_config.json`: ```json { "gpio_buttons": { "enabled": true, "pull_up": true, "bounce_time_ms": 200, "buttons": [ { "name": "prev_page", "gpio": 22, "gesture": "swipe_right", "description": "Previous page button" }, { "name": "next_page", "gpio": 27, "gesture": "swipe_left", "description": "Next page button" }, { "name": "power_off", "gpio": 21, "gesture": "long_press", "description": "Power off button (long press to shutdown)" } ] } } ``` ### Configuration Options - **enabled** (bool): Enable/disable all GPIO buttons - **pull_up** (bool): Use internal pull-up resistors (always true for button-to-GND wiring) - **bounce_time_ms** (int): Debounce time in milliseconds (default 200ms) - **buttons** (array): List of button configurations ### Button Configuration Each button has: - **name** (string): Unique identifier for the button - **gpio** (int): BCM GPIO pin number (2-27) - **gesture** (string): Gesture type to generate when pressed - **description** (string): Human-readable description ### Available Gestures Buttons can trigger any gesture type: | Gesture | Description | Typical Use | |---------|-------------|-------------| | `swipe_left` | Swipe left | Next page | | `swipe_right` | Swipe right | Previous page | | `swipe_up` | Swipe up from bottom | Open navigation/TOC | | `swipe_down` | Swipe down from top | Open settings | | `tap` | Single tap | Select item | | `long_press` | Hold | Context menu | | `pinch_in` | Pinch zoom out | Decrease font size | | `pinch_out` | Pinch zoom in | Increase font size | ## GPIO Pin Selection ### Safe GPIO Pins (BCM numbering) **Recommended for buttons:** - GPIO 5, 6, 12, 13, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27 **Avoid these pins:** - GPIO 2, 3 - I2C (SDA, SCL) - Used for touch, sensors - GPIO 7-11 - SPI - Used for e-ink display - GPIO 14, 15 - UART - Used for serial console - GPIO 0, 1 - Reserved for ID EEPROM ### Pin Layout (BCM Mode) ``` 3V3 (1) (2) 5V GPIO2 (3) (4) 5V GPIO 2,3 = I2C GPIO3 (5) (6) GND GPIO4 (7) (8) GPIO14 GPIO 7-11 = SPI GND (9) (10) GPIO15 GPIO 14,15 = UART GPIO17 (11) (12) GPIO18 GPIO27 (13) (14) GND GPIO22 (15) (16) GPIO23 ← Good for buttons 3V3 (17) (18) GPIO24 ← Good for buttons GPIO10 (19) (20) GND GPIO9 (21) (22) GPIO25 ← Good for buttons GPIO11 (23) (24) GPIO8 GND (25) (26) GPIO7 GPIO0 (27) (28) GPIO1 GPIO5 (29) (30) GND ← Good for buttons GPIO6 (31) (32) GPIO12 ← Good for buttons GPIO13 (33) (34) GND ← Good for buttons GPIO19 (35) (36) GPIO16 ← Good for buttons GPIO26 (37) (38) GPIO20 ← Good for buttons GND (39) (40) GPIO21 ← Good for buttons ``` ## Testing Buttons ### Test Button Connections ```bash # Install GPIO utilities sudo apt install gpiod # Monitor GPIO 23 (next page button) gpioget gpiochip0 23 # Press button - should show 0 (LOW) # Release button - should show 1 (HIGH with pull-up) ``` ### Test in Application Run with verbose logging to see button events: ```bash python examples/run_on_hardware_config.py --verbose ``` Press each button and verify you see log messages like: ``` Button pressed: next_page (GPIO 23) Button event queued: next_page -> swipe_left ``` ## Troubleshooting ### Buttons Not Working **Problem:** Buttons don't generate events **Solutions:** 1. Check wiring - button should connect GPIO to GND 2. Verify GPIO pin number in config (BCM mode, not physical pin) 3. Check permissions: `sudo usermod -a -G gpio $USER` then log out/in 4. Test GPIO with `gpioget` (see above) 5. Check logs: `python examples/run_on_hardware_config.py --verbose` ### False Triggers **Problem:** Button triggers multiple times from single press **Solutions:** 1. Increase `bounce_time_ms` in config (try 300-500ms) 2. Add hardware debounce capacitor (0.1µF between GPIO and GND) 3. Check for loose connections ### Wrong Action **Problem:** Button does wrong action **Solutions:** 1. Check `gesture` field in button config 2. Verify button name matches intended function 3. Check logs to see what gesture is generated ## Advanced: Custom Button Functions You can map buttons to any gesture, creating custom layouts: ### Example: Reading Mode Buttons ```json { "gpio_buttons": { "enabled": true, "buttons": [ {"name": "next", "gpio": 23, "gesture": "swipe_left"}, {"name": "prev", "gpio": 24, "gesture": "swipe_right"}, {"name": "zoom_in", "gpio": 25, "gesture": "pinch_out"}, {"name": "zoom_out", "gpio": 22, "gesture": "pinch_in"} ] } } ``` ### Example: Simple 2-Button Layout ```json { "gpio_buttons": { "enabled": true, "buttons": [ {"name": "next", "gpio": 23, "gesture": "swipe_left"}, {"name": "prev", "gpio": 24, "gesture": "swipe_right"} ] } } ``` ## Hardware Tips ### Button Quality - Use momentary pushbuttons (normally open) - Tactile switches provide good feedback - Rated for at least 10,000 cycles - Consider waterproof buttons for outdoor use ### Mounting - Mount buttons accessible from device edge - Label buttons for user convenience - Consider button guards to prevent accidental presses - Use hot glue or button caps for secure mounting ### Wiring - Keep wires short to reduce noise - Use stranded wire for flexibility - Consider using a ribbon cable for clean routing - Add strain relief at connection points ## See Also - [HARDWARE_SETUP.md](HARDWARE_SETUP.md) - Complete hardware integration guide - [hardware_config.json](hardware_config.json) - Example configuration - [dreader/gpio_buttons.py](dreader/gpio_buttons.py) - Button handler source code