---
slug: "orangepi-zero2w-web-signage"
title: "How to turn Orange Pi Zero 2W into a Web Signage Display"
description: "A guide to turning Orange Pi Zero 2W into a web signage display with auto-starting Chromium kiosk mode. Covers stable systemd boot configuration (getty conflict, D-Bus/GPU workarounds, unlimited retries) and interrupt-driven GPIO button control using gpiomon."
url: "https://www.ytyng.com/en/blog/orangepi-zero2w-web-signage"
publish_date: "2026-02-09T09:34:38Z"
created: "2026-02-09T09:34:38.942Z"
updated: "2026-02-27T03:55:10.144Z"
categories: []
keywords: ""
featured_image_url: "https://media.ytyng.com/resize/20260209/44a8ebd91d014613ba3f7abf8d3ff3c8.png.webp?width=768"
has_video: true
has_music: true
video_urls: ["https://media.ytyng.net/ytyng-blog/332/featured-video-1.mp4", "https://media.ytyng.net/ytyng-blog/332/featured-video-2.mp4", "https://media.ytyng.net/ytyng-blog/332/featured-video-3.mp4"]
music_urls: ["https://media.ytyng.net/ytyng-blog/332/featured-music-332-6.mp3", "https://media.ytyng.net/ytyng-blog/332/featured-music-332-7.mp3"]
lang: "en"
---

# How to turn Orange Pi Zero 2W into a Web Signage Display

## Introduction

The Orange Pi Zero 2W is a compact single-board computer with an Allwinner H618 SoC.
It has HDMI output and runs Linux, making it suitable as a web signage (digital signage) terminal.

This article covers two goals:

1. **Auto-starting Chromium in kiosk mode** to display a web page fullscreen on power-up
2. **Using GPIO-connected tactile switches** for physical button control of display power and browser reload

---

## Part 1: Web Signage with Chromium Kiosk Mode

### Prerequisites

```bash
sudo apt update
sudo apt install -y xserver-xorg xinit chromium x11-xserver-utils xdotool fonts-noto-cjk
```

### kiosk.sh — Chromium Startup Script

```bash
#!/bin/bash

export DISPLAY=:0
xhost +local:

# Rotate display (for vertical monitors used horizontally)
xrandr --output HDMI-1 --rotate left

# Disable screen blanking
xset s off -dpms s noblank

sleep 2

# Launch Chromium as non-root user
# dbus-run-session: creates a temporary D-Bus session (not available at boot)
# --disable-gpu: Mali G31 GPU fails Chromium initialization
sudo -u orangepi \
    DISPLAY=:0 \
    HOME=/home/orangepi \
    dbus-run-session \
    chromium --kiosk --noerrdialogs --disable-infobars \
        --disable-session-crashed-bubble \
        --disable-gpu \
        --start-fullscreen \
        --window-size=1920,480 \
        --window-position=0,0 \
        "https://your-dashboard-url.example.com/"
```

### kiosk.service — systemd Service

```ini
[Unit]
Description=Kiosk Browser
After=multi-user.target systemd-user-sessions.service
Conflicts=getty@tty1.service
StartLimitIntervalSec=0

[Service]
Type=idle
User=root
Environment=DISPLAY=:0
ExecStartPre=/bin/udevadm settle --timeout=30
ExecStartPre=/bin/bash -c 'for i in $(seq 1 30); do for f in /sys/class/drm/card*-HDMI-A-*/status; do [ -f "$f" ] && grep -q "^connected$" "$f" && exit 0; done; sleep 2; done; echo "HDMI not detected"; exit 1'
ExecStart=/usr/bin/startx /home/orangepi/kiosk.sh -- :0 vt1
Restart=on-failure
RestartSec=10

[Install]
WantedBy=multi-user.target
```

Key settings:

- `Conflicts=getty@tty1.service` — Prevents getty from stealing VT1 from X server
- `StartLimitIntervalSec=0` — Unlimited restart attempts
- `udevadm settle` — Waits for hardware initialization
- HDMI connection polling — Waits up to 60 seconds for display connection

---

## Part 2: GPIO Physical Buttons

### Hardware Wiring

H618 GPIO operates at 3.3V with built-in pull-up resistors.
Connect tactile switches between GPIO pins and GND (Active LOW).
No external resistors needed.

```
GPIO pin ---[tactile switch]--- GND
```

Linux GPIO numbers are calculated as: `(port_number × 32) + pin_number`

| Button | Pin | GPIO# | Function |
|--------|-----|-------|----------|
| Left | PI3 | 259 | Display ON/OFF |
| Center | PI16 | 272 | Browser reload (Shift+F5) |
| Right | PI4 | 260 | Unassigned |

### switch_daemon.py — GPIO Button Daemon

Uses `gpiomon` (libgpiod) for kernel interrupt-based monitoring with near-zero CPU usage.
See the Japanese version for the full source code with detailed comments.

### switch-daemon.service

```ini
[Unit]
Description=GPIO Switch Daemon
After=multi-user.target systemd-user-sessions.service

[Service]
Type=simple
User=root
Environment=DISPLAY=:0
Environment=XAUTHORITY=/home/orangepi/.Xauthority
ExecStartPre=/bin/udevadm settle --timeout=30
ExecStart=/usr/bin/python3 /home/orangepi/switch-server/switch_daemon.py
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
```

---

## Troubleshooting

- **Screen flashes then shows terminal**: Add `Conflicts=getty@tty1.service`
- **D-Bus errors**: Add `dbus-run-session` before chromium command
- **GPU errors**: Add `--disable-gpu` flag to Chromium
- **Buttons not responding**: Ensure `udevadm settle` in ExecStartPre
