Waveshare PocketTerm35 Batocera Setup Guide (Raspberry Pi 5)
HandheldHardware retro-gaming terminal:used: Raspberry Pi 5 (4GB) in the· Waveshare PocketTerm35 housing (3.5" 640×480 DPI touchscreen +touchscreen, QWERTY keyboard with gaming keys), a· 500GB NVMe SSD on the PCIe TO M.2 Board (E), running Batocera 43.1.
This page documents the full configuration as set up on 2026-08-22, so it can be reproduced from scratch.
Hardware
PocketTerm35 display setup in Batocera (2026-05-29)
Display (boot partition: /boot/config.txt)
The 3.5" display uses Waveshare's custom DPI overlays. These .dtbo files are not part of Batocera — they come from Waveshare's 3.5HDMI_E_DTBO.zip (software guide) and must be extracted to /boot/overlays/. Then in /boot/config.txt:
dtparam=i2c_arm=on
dtoverlay=waveshare-35dpi-4b
dtoverlay=waveshare-35dpi-5b
dtoverlay=dwc2,dr_mode=host # required for the keyboard (USB OTG host)
dtparam=pciex1_gen=3 # NVMe at gen 3 speed
In batocera.conf, keep EmulationStation at panel resolution: es.resolution=max-640x480.
Important:Warning: a Batocera version upgrade rewrites the boot partition and deletes the custom overlays.overlays Backups— the screen stays black afterwards. Keep backups of waveshare-35dpi-4b.dtbo, waveshare-35dpi-5b.dtbo and config.txt live in /userdata/system/pocketterm-backup/ on the device (survives upgrades) and on the PC under ~/backups/pocketterm35/. After an upgrade, copy them back toafter /boot/upgrading (/boot/overlaysremount rw: mount -o remount,rw /boot).
KeyboardFix: PocketTerm35 gaming keys not working in games (RetroArch keyboard mapping)
The PocketTerm35 keyboard enumerates as a USB HID devicekeyboard ("My Custom Pico Keyboard"). TheIts gaming keys emit ordinary keyboard keycodes matching their printed labels (verified by capturing /dev/input/event0):
| Physical key | Keycode sent |
|---|---|
| D-pad ▲▼◀▶ | arrow keys |
| A / B / X / Y | letters a / b / x / y |
| L / R | letters l / r |
| Select (PrtSc) | KEY_SYSRQ (print screen) |
| Start (Pause) | KEY_PAUSE |
| Esc, F1–F12 | Fn layer: Fn+Q = Esc, Fn+1…0 = F1–F10 |
This clashes with RetroArch's default keyboard layout (expects retropad A on key x, B on z, …)Y and with default letter hotkeys (r = rewind,on la = hold fast-forward) — out of the boxso the buttons do the wrong things.things in games. Worse, letter r is RetroArch's default rewind hotkey and l is hold-fast-forward, so the shoulder keys rewind and fast-forward the game. Fix viaeverything in /userdata/system/batocera.conf (update-proof,proof injected— Batocera injects these into every generated RetroArch config):
## POCKETTERM35 KEYBOARD BLOCK START
global.retroarch.input_player1_up=up
global.retroarch.input_player1_down=down
global.retroarch.input_player1_left=left
global.retroarch.input_player1_right=right
global.retroarch.input_player1_a=a
global.retroarch.input_player1_b=b
global.retroarch.input_player1_x=x
global.retroarch.input_player1_y=y
global.retroarch.input_player1_l=l
global.retroarch.input_player1_r=r
global.retroarch.input_player1_l2=q
global.retroarch.input_player1_r2=w
global.retroarch.input_player1_start=pause
global.retroarch.input_player1_select=print_screen
# default letter hotkeys collide with the gaming keys -> move/disable
global.retroarch.input_rewind=f6
global.retroarch.input_toggle_fast_forward=f7
global.retroarch.input_hold_fast_forward=nul
global.retroarch.input_reset=nul
global.retroarch.input_frame_advance=nul
global.retroarch.input_hold_slowmotion=nul
global.retroarch.input_toggle_slowmotion=nul
# Batocera generates input_enable_hotkey=shift which forces Shift+hotkey; disable
global.retroarch.input_enable_hotkey=nul
# N64 games are analog-driven -> map the stick onto the arrows too
n64.retroarch.input_player1_l_x_minus=left
n64.retroarch.input_player1_l_x_plus=right
n64.retroarch.input_player1_l_y_minus=up
n64.retroarch.input_player1_l_y_plus=down
## POCKETTERM35 KEYBOARD BLOCK END
The
Fix: input_enable_hotkey=nulEsc linedoes matters:not withoutexit itgames in Batocera (keyboard hotkeys need Shift)
Batocera generates input_enable_hotkey = "shift" into the RetroArch config, which silently requires holding Shift together with every keyboard hotkey,hotkey so— Esc alone never exits a game. The line global.retroarch.input_enable_hotkey=nul in the block above removes that requirement. (On the PocketTerm35, Esc itself is the Fn+Q combo, so accidental exits are not a concern.)
In-gameBatocera controlskeyboard hotkeys on the PocketTerm35 after this config
| Keys | Function |
|---|---|
| gaming keys | exactly as labeled (SNES-style layout) |
| Pause / PrtSc | Start / Select |
| Q / W | L2 / R2 |
| Fn+Q (Esc) | quit game |
| Fn+1 (F1) | RetroArch menu |
| Fn+2 / Fn+4 | save / load state |
| Fn+6 / Fn+7 | rewind / fast-forward |
Limitation: since the gaming keys emit plain letters, keyboard-centric systems (DOS, Amiga, ScummVM) see them as typed letters — play those with the keyboard itself.
PerformanceRaspberry &Pi quality-of-life5 performance settings for Batocera (batocera.conf)
system.cpu.governor=performance
kodi.enabled=0 # keyboard 'x' in ES could trigger Kodi launch
global.rewind=0 # rewind costs CPU each frame
global.autosave=1 # quit = snapshot, relaunch = resume (handheld style)
# one frame less input lag on light cores:
nes.runahead=1
famicom.runahead=1
snes.runahead=1
megadrive.runahead=1
mastersystem.runahead=1
gamegear.runahead=1
gb.runahead=1
gbc.runahead=1
gba.runahead=1
pcengine.runahead=1
QuieterFix: Raspberry Pi 5 fan curvetoo loud (PCIe TO M.2 Board E fan curve)
The M.2 Board (E) hascools with a 30×30×7mm 5V blower (8000 RPM, PWM + tach) on the Pi 5 fan header — audible even at 30% duty. FirmwareThe Pi 5 firmware fan curve can be tuned in /boot/config.txt: silent below 55°C, gentle midrange, full speed only near the 85°C throttle point:
dtparam=fan_temp0=55000,fan_temp0_hyst=5000,fan_temp0_speed=60
dtparam=fan_temp1=63000,fan_temp1_hyst=5000,fan_temp1_speed=100
dtparam=fan_temp2=70000,fan_temp2_hyst=5000,fan_temp2_speed=160
dtparam=fan_temp3=76000,fan_temp3_hyst=5000,fan_temp3_speed=255
Monitor with cat /sys/class/hwmon/hwmon2/fan1_input (RPM) and vcgencmd measure_temp. Drop-in replacement if the blower develops bearing rattle: a 3007 5V blower with 4-pin JST plug (e.g. GMBYLBY 3007); pinout on the Pi 5 fan header is GND, 5V, PWM, tach.
Batocera WiFi configuration
In batocera.conf:
wifi.enabled=1
wifi.ssid=<ssid>
wifi.key=<password>
Apply with batocera-wifi enable or reboot. Batocera's connman runs with SingleConnectedTechnology=true and prefers ethernet — WiFi connects automatically only when no cable is plugged in, and the IP changes when it switches.
Which systems run well on a Raspberry Pi 5 handheld (ROM libraryselection)
Source:Source library: a 1TB Batocera share image (BobbyCera_Pi4_1TB_V42_C.L.A.M, 882GB of content) — too big for the 463GB NVMe, so a curated ~390GB subset (~390GB) was synced. Selection principle: systems that emulate well on a Pi 5 and play well on a 3.5" screen with keyboard controls.
- Included: full PSX (CHD set), N64,
NDSNintendo DS (the touchscreen makes it playable), Saturn, all 8/16-bit consoles and handhelds, arcade (FBNeo, MAME, Neo Geo, Naomi, Atomiswave), Sega CD, PC Engine CD, Amiga/C64/Amstrad/Atari ST (great with the physical keyboard), OpenBOR, Daphne, all small systems. - Excluded: 3DS (poor emulation on Pi 5), PSP and Dreamcast (analog-stick-dependent, 267GB together), 3DO, Neo Geo CD, MSU-1 sets (duplicates).
Procedure from a WSL/Linux PC (image lives on a NAS SMB share):
sudo mount -t cifs //NAS/stash /mnt/stash -o username=USER,uid=$(id -u)
sudo losetup -P /dev/loop0 /mnt/stash/games/<image>.img
sudo mount /dev/loop0p2 /mnt/imgshare # ext4 "share" partition
rsync -a --partial --info=progress2 /mnt/imgshare/bios/ root@<pi>:/userdata/bios/
rsync -a --partial --info=progress2 \
--exclude=/3ds --exclude=/psp --exclude=/dreamcast --exclude=/snes-msu1 \
--exclude=/msu-md --exclude=/3do --exclude=/neogeocd \
/mnt/imgshare/roms/ root@<pi>:/userdata/roms/
(Batocera SSH: user root, default password linux. After the sync, refresh game lists: ES menu → Game settings → Update gamelists, or batocera-es-swissknife --restart.)
Backups
- On-device:
/userdata/system/pocketterm-backup/(custom overlays + config.txt) — survives upgrades. - On PC:
a~/backups/pocketterm35/(overlays,mirrorconfig.txt,ofbatocera.conftheincl.samepre-changefilesoriginal).
batocera.conf (which contains the WiFi password in plain text — handle FAQ
Why do the PocketTerm35 gaming keys type letters instead of acting as a controller?
The keyboard firmware sends each gaming key's printed label as a normal keyboard keycode (A sends a, the d-pad sends arrow keys). There is no separate gamepad mode — the fix is remapping RetroArch's player-1 keyboard binds as shown above.
How do I exit a game on the PocketTerm35?
Fn+Q sends Esc. With input_enable_hotkey=nul set, Esc alone exits; without it Batocera requires Shift+Esc.
Does the PocketTerm35 touchscreen work in Batocera? Yes — the Goodix capacitive touchscreen works out of the box and makes Nintendo DS games playable.
Can I overclock the Raspberry Pi 5 in the PocketTerm35? Not advisable: the enclosure already reaches ~60°C under sustained load at stock 2.4GHz, so an overclock mostly buys thermal throttling and battery drain.
Which Batocera version does this apply to? Written and tested on Batocera 43.1 (May 2026) on a Raspberry Pi 5 Model B Rev 1.1.