Repository navigation
Second Screen Setup and Pairing
Part of Second Screen (Raspberry Pi) ‐ experimental. Wire it first: Second Screen Hardware and Wiring.
Two ways to make the Pi's card: the ready-made card (easiest, no computer setup), or install by hand for an RCA monitor, ignition sense, or to work on the Pi. Pairing and the settings are the same for both.
New on 2026-10-07, experimental. The card is rebuilt after each change to the second screen.
- Download dashwheel-second-screen.img.xz from the Second screen card release.
- In Raspberry Pi Imager, pick the Raspberry Pi model, then Choose OS → Use custom and the downloaded file, then the SD card, and write it. If Imager offers OS customisation, say No: this card doesn't use it.
- Take the card out and put it back into the computer. Open the drive called bootfs, then the dashwheel folder, and open wifi.txt (Notepad works). After
wifi_name=andwifi_password=, write the phone's hotspot name and password, and your country in two letters aftercountry=. Save it. A second pair of lines takes another network, your home Wi-Fi for example. - Pi 3B only: its Wi-Fi is 2.4 GHz only, so set the phone's hotspot to 2.4 GHz or dual band. A 3B+ also does 5 GHz, which leaves more room for the video.
- Put the card in the Pi, start the phone's hotspot, and power the Pi. The first start takes about a minute longer while the card grows to its full size. The monitor then shows a QR code: go to 3. Pair.
Each card makes its own pairing code at its first start, and turns read-only by itself once paired, with no internet needed in the car.
-
Wi-Fi: the Pi saves the networks at its start and clears the password from
wifi.txt. To add a network later, fill in the lines again. Once the card is read-only, after pairing, the password stays in the file and is read at every start. -
Updating: write the new image to the card. To keep the pairing, first copy the
dashwheelfolder from the card's bootfs drive to the computer, then copy it back onto the new card before its first start. - RCA (composite) monitor or ignition sense: install by hand instead (below).
-
SSH, optional (the card has no login): put an empty file named
sshand auserconf.txton bootfs.userconf.txtholds one line:name:followed by the output ofopenssl passwd -6.
- Write Raspberry Pi OS Lite (Bookworm or later; Trixie Lite 64-bit is what runs on the bench) with Raspberry Pi Imager. In its settings (the gear / Edit settings):
- Wi-Fi: the phone's hotspot name and password.
-
Hostname:
dashwheel-display. - SSH: enabled (a key is best).
- Pi 3B only: its Wi-Fi is 2.4 GHz, so set the phone's hotspot to 2.4 GHz or dual band.
- Start the phone's hotspot and boot the Pi. Check you can reach it:
ssh pi@dashwheel-display.local.
For bench work you can put the Pi on your home Wi-Fi instead; it only needs the hotspot once it's in the car with the head unit.
On a computer with this repository (JDK 17–21, see Building from Source):
./gradlew :display:installDist
scp -r display/build/install/dashwheel-display tools/pi pi@dashwheel-display.local:
ssh pi@dashwheel-display.local 'sudo ./pi/install.sh ./dashwheel-display'
ssh pi@dashwheel-display.local 'sudo reboot'Installer flags (add them to the install.sh line):
| Flag | What it does |
|---|---|
--composite |
Drive an RCA monitor from the 3.5 mm jack instead of HDMI |
--acc-sense |
Shut down cleanly when the ignition goes off (GPIO3 through an optocoupler) |
--overlay |
Make the SD card read-only right away. Usually not needed: the Pi does it by itself once paired |
What the installer does: installs a Java runtime and GStreamer (with the Pi's hardware decoder), puts the service in /opt/dashwheel-display, adds the dashwheel-display systemd service (it takes the console screen, tty1), advertises _dashwheel-display._tcp with Avahi, keeps HDMI on, turns off console blanking and boot text, and creates the pairing code. It also sets up the Pi's Ethernet port for a cable from the head unit, and reads networks from wifi.txt on the card at every start, as on the ready-made card.
The installer also makes the Pi start fast (first picture about 17 s after power-up): it doesn't wait for the Wi-Fi, switches off start-up tasks it doesn't need, turns Wi-Fi power saving off, and moves the Wi-Fi from NetworkManager to the lighter wpa_supplicant (your saved networks are kept). It also installs the start-up logo. If it can't prepare the faster start-up file, it shows the last lines of the reason.
To update, run the same commands again. Settings and the pairing are kept, and the picture comes back without a restart. On a read-only card (any Pi already paired), turn that off first: sudo raspi-config nonint do_overlayfs 1, restart, run the installer. The Pi turns read-only again by itself the next time a head unit connects.
Building the card image yourself: on an arm64 Linux, sudo tools/pi/build-image.sh display/build/install/dashwheel-display out.img.xz. GitHub Actions does it for each change to the second screen (.github/workflows/pi-image.yml).
Set the Pi up on your home Wi-Fi, then add the hotspot it will use in the car:
ssh -t pi@dashwheel-display.local sudo ./pi/add-wifi.shIt asks for the name and password (stored hashed) and puts that network ahead of the others. Use this script, or wifi.txt on the card, rather than nmcli, since NetworkManager is no longer in charge.
A Pi that started on the house Wi-Fi moves to the phone's hotspot by itself within a minute or so once it's in range, but never while a head unit is linked: the search made it hop between Wi-Fi access points and cut the picture. On the hotspot, or with no network, it leaves the connection alone.
At home the head unit usually stays on the house Wi-Fi by itself. To try the hotspot there, pick it in the head unit's Wi-Fi settings too, or the two end up on different networks.
- After the reboot, the monitor shows a QR code.
- In Dashwheel Companion on the phone, tap Pair a car and scan the code on the monitor (the phone's camera app works too). Confirm Send to the car. The phone passes the code to the head unit over the phone link, so the head unit must be linked to the phone at that moment.
- The head unit connects within a few seconds. The QR code leaves the idle screen once a head unit has used it.
- The Pi saves the pairing and turns its card read-only from its next start: from then on, cutting the power with the ignition can't damage it. Nothing to do. To keep the card writable, put
read_only=manualindisplay.confbefore pairing.
If no head unit links for 3 minutes, the pairing code shows again.
Without the phone app: the code is also in dashwheel/pairing.txt on the SD card's boot partition (readable from any computer). Copy it to a USB stick and use Import a pairing file in the head unit's second-screen settings.
New pairing: put the SD card in a computer, delete dashwheel/pairing.txt and dashwheel/paired on its boot partition, put it back and start the Pi: it shows a new code, even on a read-only card. Forget on the head unit asks first.
Keep
pairing.txtprivate: anyone who has it can stream to your screen while on the same hotspot.
Settings → Connections → Second screen:
| Setting | Choices |
|---|---|
| What it shows | Off, Cluster, or An app (rooted units on Android 10 or 11) |
| Pages (cluster) | Speed, Media, Directions, Readings: pick which and in what order |
| Background | Black (default), Dark or Light; Follow day and night makes it light by day |
| Alerts full screen | On by default: a door, belt, tyre or radar alert, a ringing call or a climate change covers the whole second screen while it shows, in the dashboard's look |
| Simple display | On: the Pi draws the pages itself, with the speed, fuel and alerts, using almost no Wi-Fi. Off: the head unit sends the full display, with widgets, Maps and the rear camera. It replaces Sharp picture, shown the other way round |
| Design (Simple display on) | Cards: the speed in a ring, the readings in cards. Dials: round gauges with needles. Large: one big number. Retro: an amber digital dash, LCD by day. Coolant shows blue while cold, amber when warm, red when hot; low fuel turns amber |
| Page board | Lay out each page: One, Big + 1, Big + 2, Halves, Three or Four. The pages sit beside the live preview, above it on a narrow upright screen. Tap a widget on the preview to swap it (including the 3D map or an app from a dashboard tile, such as Google Maps), then pick its design. The second screen turns to the page you edit. Reset to the original page resets it. With Simple display on, the Pi draws the page itself with the widgets it knows: speed, clock, fuel, range, engine, media, directions, readings, doors and the map; a slot holding a copy of Maps or Waze shows the Pi's own map |
| App on the screen | The app shown in An app mode |
| Rear-seat screen | The driver can't see it: video apps may play while driving |
| Turn the picture upside down | For a screen mounted the other way up; the Pi turns everything, its logo included, in the display hardware |
| Brightness by day / Brightness at night | A backlight level for each. Day and night follow Settings → Look → Day and night. Shown once a Pi wired to the monitor's brightness buttons has linked; also the Pi screen brightness widget |
| Picture height | 480, 720 or 1080; lower is lighter on the phone's Wi-Fi |
| Steering-wheel keys | Learn a key: press the wheel button that should turn the cluster's page. Forget the keys clears them |
| Media keys turn pages | A long press on next / previous turns the cluster's page |
| Swipe the bar to turn pages | A sideways swipe on the launcher's bar turns the cluster's page |
| Import a pairing file |
pairing.txt from a USB stick |
The status line says what's happening: Looking for the second screen, Connected to … with the screen's size and its program version, Streaming the picture · N kbit/s, or Sending readings; the screen draws the cluster. It also warns when:
- the Pi is under-powered, hot or slowed down by its firmware: no Wi-Fi setting fixes that, see power;
- Lighter picture: the screen could not keep up: a slow Pi gets fewer frames, then a smaller picture;
- the screen's program is older or newer than the app: write a new card, or update Dashwheel.
For keys to work while another app is in front, Dashwheel's accessibility service must be on. If it was on before this feature arrived, turn it off and on again: Android grants key filtering only when the service is switched on.
The Pi shows the head unit's time and time zone, and its own lines (waiting, no signal, the pairing hint) in Dashwheel's language.
Settings → Car → Reverse view → Second screen: Off, Camera and radar (the default), Camera or Radar. It shows once a second screen is paired. In reverse gear the second screen switches to it by itself, and back to its page after. Not car-tested yet.
- It needs Simple display off.
- The camera needs Dashwheel's reverse view on with Camera picture set to Dashwheel; until then the second screen shows the radar.
dashwheel/display.conf on the boot partition (see tools/pi/display.conf.example). Every line is optional:
name=Dashwheel display # the name the head unit shows
#overscan=5 # % cropped per edge on composite monitors (0 for HDMI)
#width=720 # force a size when the monitor reports none
#height=576
#sink=kms # kms = straight to the screen; auto = a desktop window (testing)
#video_pipeline=fdsrc fd=0 ! h264parse ! v4l2h264dec ! kmssink sync=false
#read_only=manual # keep the card writable after pairing
#brightness_up_gpio=17 # the monitor's own brightness buttons, see below
#brightness_down_gpio=27
#tile_url=https://…/{z}/{x}/{y}.png # map tiles for the Pi's own map, see below
#tile_url_night=https://…/{z}/{x}/{y}.png # a dark style for the night
#tile_cache=/var/cache/dashwheel-display/tiles
#map_zoom=16 # 15 a town, 16 its streets, 17 every houseThe Wi-Fi networks go in dashwheel/wifi.txt next to it (see the ready-made card).
Brightness buttons: most 7" HDMI boards have a keypad with brightness + / -. Wire each button to a Pi GPIO through a divider (the buttons sit at about 4.6 V: 220 Ω from the button, 14.7 kΩ to ground) and set the two GPIOs above. The head unit then presses them to reach its day and night levels.
Your own start-up logo: put a PNG named splash.png in dashwheel/ on the boot partition (transparent background, about 300 to 600 px wide), then run the installer again. It shows from power-up until the first picture, and while the Pi waits for the head unit.
Car-verified 2026-10-10 (tiles shown); the route line and the moving car are not car-tested yet.
With Simple display on, a Map slot on the page board makes the Pi draw a flat map itself: north up, the car in the middle, the route, the next turn in a card and the arrival time. The head unit sends only the car's position and the route, a few hundred bytes a second: no video, nothing for the Wi-Fi to carry. A slot holding a copy of Maps or Waze shows this map too.
-
Tiles: put a tile server address in
tile_url, with{z},{x}and{y}in it (256 px raster tiles), for example a MapTiler address with your own free key.tile_url_nighttakes a dark style; without one the day tiles are dimmed at night. The public OpenStreetMap servers are not meant for apps. Withouttile_urlthe map shows the route and the car on a plain ground, with the line No map tiles: set tile_url on the screen's card. -
Cache: fetched tiles are kept under
tile_cache. On a read-only card that folder is in memory and empties at each power-up; point it at a USB stick to keep tiles across drives. -
Zoom:
map_zoom=16by default (streets); 15 shows a town, 17 every house. - Route line: from the in-app navigation. With Google Maps or Waze, Dashwheel works out the same route itself and draws a new one when the car leaves it: for a trip it started (a favourite, the agenda, the phone, a voice request), and for one typed into Maps or Waze, whose destination is read off their route preview (Waze with root: from its own files).
- 3D or flat (Settings → Connections → Second screen → Map): 3D behind the car (tilted, turning with the road, buildings in 3D from MapTiler's heights) or Flat (north up), with tilt, distance and buildings. About 40 tiles a kilometre.
| Problem | Try |
|---|---|
| Nothing on the monitor |
journalctl -u dashwheel-display -f. Check cat /sys/class/drm/card*-HDMI-A-1/modes lists a size (the first line is used) |
| Looking for the second screen forever | Both devices on the hotspot? At home the head unit stays on the house Wi-Fi: pick the hotspot on it too. Did you add the hotspot with wifi.txt or add-wifi.sh? Some phones isolate hotspot clients ("client isolation" / "AP isolation"): turn it off. Check avahi-browse -rt _dashwheel-display._tcp from another Linux machine. Or use a cable
|
| Stuttering video | First look at the head unit's second-screen settings: an under-powered or hot Pi is the usual cause, and no Wi-Fi setting fixes it. Then the Wi-Fi: use a cable, 5 GHz on a 3B+, a lower picture height, or turn Simple display on |
| Random reboots / lightning bolt | Undervoltage: vcgencmd get_throttled must be 0x0. Better converter, shorter thicker cable |
| Wrong time on the screen | The head unit sends its time and time zone at each link. An older head unit sends no zone: set it on the Pi with sudo timedatectl set-timezone Europe/Paris
|
| The screen's program is older than this app | Write the newest card image, or run the installer again |
| No map tiles: set tile_url on the screen's card on the Pi's map | Add tile_url to display.conf, see the map above |
| Apps on the second screen need a rooted head unit on Android 10 or 11 | An app mode can't work on this unit: put the app in a dashboard tile and copy it to a cluster page with the page board instead (needs PMPatch3) |
| This screen can only draw the cluster from readings | The head unit's encoder is busy (dash cam, screen recorder) or missing |
| Decoder check | Stop the service, then gst-launch-1.0 videotestsrc num-buffers=100 ! x264enc ! h264parse ! v4l2h264dec ! kmssink (needs gstreamer1.0-plugins-ugly for x264enc) |
With GStreamer installed (gst-libav for the software decoder):
mkdir -p /tmp/dw && printf 'sink=auto\nwidth=1024\nheight=600\n' > /tmp/dw/display.conf
display/build/install/dashwheel-display/bin/dashwheel-display --config /tmp/dwDashwheel is free software (GPL v3). Enjoying it? ☕ Buy me a coffee on Ko-fi · Releases · Issues
Getting started
Dashboard
Car
Road
Phone and screens
More