A pocket virtual pet with a full-color round display, built around one all-in-one board instead of a separate MCU and display module. This guide covers hardware and wiring only — firmware comes in a follow-up guide.
Why this edition instead of a separate MCU + display module
This build uses the Waveshare RP2350-LCD-1.28 — a single round board with the RP2350 MCU, a 240×240 color display, a 6-axis IMU, and Li-ion battery charge management already integrated. An earlier pass of this guide used a separate ESP32-C3 SuperMini + GC9A01 display module instead, on the reasoning that having 4 spares of each part left more room to prototype. For a one-time build, that reasoning doesn't apply — this edition is meaningfully simpler to wire (no separate charge board, no boost converter, no 7-wire SPI harness between two boards) at the cost of having only one unit on hand if something goes wrong. It also picks up two things the separate-module build didn't have: a backlight you can actually dim/turn off in software (battery-life relevant), and a free 6-axis IMU for future tilt/shake interactions.
What you're building
A Tamagotchi-style virtual pet themed around a hummingbird, built on a single integrated board rather than wiring a display to a separate microcontroller. This guide is hardware and wiring only — component selection, the power system, the input controls, a component-compatibility validation pass, and the 3D-printed enclosure. Firmware (the pet logic, sprite animation, save state, power management) is intentionally left as a placeholder for a follow-up guide.
Note on graphics
A hummingbird's whole visual appeal is iridescent color — the reason this build uses a 240×240 full-color IPS panel rather than a monochrome OLED. The tradeoff is battery life: see the callout in Step 1. This board's backlight is independently software-controllable (dimmable/off), which the bare 7-pin GC9A01 module used in an earlier version of this guide could not do — a real advantage for managing that tradeoff later in firmware.
Battery safety — read this before you buy or wire anything
LiPo batteries are not optional-safety territory
Never puncture, crush, bend, or short the battery's two leads together, even briefly.
This board's onboard charge circuit expects USB-C for charging — never wire a bare LiPo directly to a USB port or bench supply by any other path.
Charge on a non-flammable surface, within sight, for at least the first several cycles of this cell/board combination.
If a cell ever puffs up, gets hot to the touch outside of normal charging, or smells sweet/chemical, stop using it, move it away from flammables, and dispose of it at a battery recycling point — do not keep using a swollen cell.
You'll be cutting and re-soldering the battery's factory pigtail wire in Step 1 to add a power switch — work on one wire at a time, insulate every joint with heat shrink immediately, and never let both cut ends of the same wire touch anything metal simultaneously.
Tools required
Soldering iron + solder (fine tip)
Wire strippers
Multimeter (non-negotiable — used for continuity/polarity checks in the validation step)
Small Phillips/flat screwdriver
Hex (Allen) key set, M2
Heat-set insert installation tip (or a spare soldering iron tip)
Digital calipers (connector pitch and case-fit verification)
3D printer + filament (PLA for a desk pet; PETG if it'll live in a bag/hot car)
Heat shrink tubing (small diameter, for the battery-lead splice)
CAD software of your choice, to model the enclosure from the guidance in the case section
Bill of materials
This edition needs far fewer parts than a separate-MCU build — no charge board, no boost converter, no display module, no long SPI wiring harness.
Waveshare RP2350-LCD-1.28
MCU + Display + IMU · qty 1
RP2350, 240×240 round IPS (GC9A01A), QMI8658 6-axis IMU, onboard Li-ion charge management — all on one board.
~$15–20 · waveshare.com
3.7V LiPo, 503035 (500mAh)
Battery · qty 1
Small pouch cell. Needs a 1.25mm-pitch (MX1.25) 2-pin JST-style plug to match this board's connector — verify before buying (see Validation step).
~$5–8
12×12mm Tactile Switch + Knob Cap
Input · qty 3 (of 12 owned, any colors)
Through-hole, 4-pin (2 common pairs), bare legs — no pigtail. Snap-on colored cap for a bigger, easier-to-press face. Not waterproof, not panel-securing on its own — see Validation and the case notes.
~$0.30 each · common "12x12 tactile switch + cap" kits
Passive Buzzer (~160Ω)
Audio · qty 1
2-terminal, non-polarized. Passive — needs a PWM/tone signal to make sound.
~$0.50
SPDT Slide Switch
Power · qty 1
Spliced inline into the battery's positive lead — this board has no onboard power switch of its own.
~$0.30
M2 Heat-Set Threaded Inserts
Fasteners · qty 4–6
Brass, knurled. M2×3mm or M2×4mm. Pressed into printed bosses with a heated iron tip.
~$0.10 each in bulk packs
M2 Hex Socket Bolts
Fasteners · qty 4–6
M2×8mm or M2×12mm button head, threads into the heat-set inserts above.
~$0.10 each in bulk packs
What's no longer needed
Compared to a separate-MCU build: no standalone display module, no TP4057 charge board, no MT3608 boost converter, and no 7-wire SPI harness — this board's onboard battery management (an ETA6096 charge IC) and internally-wired display/IMU remove all of that.
Tradeoff: tactile switches instead of panel buttons
This edition uses 12×12mm tactile switches with snap-on knob caps for the controls, not panel-mount waterproof pushbuttons. They're smaller and give you 6 cap colors to pick from, but they give up two things the panel buttons had: they don't seal against dust/moisture, and they don't self-secure in a case wall with just a hole and a nut — they need to be soldered to a small mounting board and held in place structurally (see enclosure notes). Worth it for a smaller, more colorful control cluster; not worth it if this pet needs to survive a rainy backpack.
Also needed, not pictured
Hookup/solder wire (26–28AWG), solder, heat shrink tubing, 3D printer filament.
Component validation — do this before wiring anything
This board's own wiki was unreachable while researching this guide (blocked automated access), so several details below come from independent third-party sources rather than Waveshare directly. Treat this section as mandatory, not optional — it's specifically designed to catch the things that weren't independently confirmed before you commit solder to anything.
ABoard identity check
Confirm your board's silkscreen reads RP2350-LCD-1.28, with legible H1/H2 header labels and BOOT/RESET buttons in the expected positions.
Note: this board's own pinout diagram is image-based on Waveshare's wiki and wasn't independently re-extracted for this guide. The GPIO table in this guide (Full pin reference) comes from Adafruit's official CircuitPython board definition for this exact board instead — an independent, authoritative source, but cross-check GPIO numbers against your own board's printed silkscreen before soldering, since which physical header (H1 or H2) each GPIO lands on isn't confirmed here.
BBattery connector compatibility
This board's battery input is a 2-pin, 1.25mm-pitch (MX1.25/JST-SH style) connector. Before plugging anything in, compare your battery's JST plug side-by-side against the board's onboard receptacle — pin spacing should visually match. If your battery's plug looks noticeably wider (a 2.0mm JST-PH plug, common on larger battery packs), do not force it — it won't seat correctly and risks a bad connection or reversed polarity.
If you have calipers, measure the pin-to-pin spacing on both the battery plug and the board's receptacle to confirm the 1.25mm match directly rather than by eye.
Check polarity: the board's silkscreen should mark +/− (or similar) next to the battery footprint. Confirm the battery's red (+) wire lines up with the board's marked positive before ever seating the connector.
CConfirm the ground pins
This step used to be a hunt. It isn't any more — Waveshare's official pinout diagram documents three GND pins, so you're confirming known positions rather than discovering unknown ones.
H1 pin 20, H2 pin 19 and H2 pin 20 are all GND. Each header has at least one, so external wiring can ground on its own header — no jumper across the board.
Still verify before soldering, because a pin-1 orientation mistake is silent and permanent: board unpowered, multimeter in continuity mode, one probe on the USB-C connector's metal shell (reliably grounded on any USB device), the other on the pin you believe is GND. It should beep.
If it doesn't, you have the header's pin 1 at the wrong end — recheck against the silkscreen before going further. That single check is the cheapest insurance in this guide.
Mark the two you'll actually use (H1 p20 for the buttons, H2 p19 or p20 for the buzzer) with a dot of nail polish or a tape flag.
DPower-on baseline, before adding anything
Plug the bare board into USB-C only — no battery, no buttons, no buzzer yet.
Confirm the display backlight illuminates and nothing feels warm to the touch beyond mild.
Press RESET and confirm the board comes back up cleanly. This establishes a known-good baseline before you add anything that could introduce a wiring mistake.
EConfirm each tactile switch's pin pairs
The 12×12mm switches' pin layout (pins 1&2 common on one side, pins 3&4 common on the other) is the standard convention for this switch family, but wasn't independently confirmed against this specific kit's own switches.
Before soldering any of them in: with a multimeter in continuity mode, press each switch and probe pin-to-pin to confirm which two legs read as one side and which two read as the other. Takes a few seconds per switch and rules out a bent-pin or mislabeled-family surprise before it's permanent.
Pick any one pin from each side to use (the second pin on each side is redundant, for mechanical stability only) — that's your GPIO leg and your GND leg.
One thing this validation pass could not confirm
Whether the onboard ETA6096 charge IC supports true power-path operation (running the board off USB while the battery is connected and the power switch is on) wasn't confirmed from its datasheet. Until it's verified by testing, treat USB-connected-plus-battery-switched-on the same way as any other unverified dual-power-source setup: avoid relying on it, and if you must have both connected, watch for anything getting unexpectedly warm.
System overview
Power flows left to right (teal); MCU-to-peripheral signal wiring shown in pink. Not a physical layout — see the pin reference table for exact GPIOs.
Step 1 — Battery & power switch
1Splice the slide switch into the battery's positive lead
With the battery disconnected from the board, cut the battery's red (+) wire only, a few centimeters from the JST plug.
Strip both cut ends, solder one to each outer terminal of the slide switch (either orientation — it's a simple on/off break in the circuit here, not using the switch's third throw position).
Insulate both solder joints individually with heat shrink before moving on — don't leave bare wire exposed on a battery lead.
Leave the black (−) wire untouched, running straight from the cell to the JST plug.
Confirm with a multimeter (continuity mode, battery disconnected) that flipping the switch actually makes and breaks the connection before plugging it into the board.
This switch is not a normal power switch — it stops the pet's clock
Worth understanding before you build it in, because it shapes the firmware and the case labelling. The RP2350 has no real-time clock — the RP2040 had one, the RP2350 replaced it with an always-on (POWMAN) timer that draws from the chip's own supply and has no separate battery-backed pin. So when this switch cuts the battery, the timer isn't merely inaccurate, it's gone. The pet cannot know how long it was off.
Rather than fight that, this build leans into it: the slide switch means torpor. Real hummingbirds enter nocturnal torpor, dropping their metabolism by roughly 95% to survive the night without feeding — so flipping this switch puts the bird into torpor, time stops, and no stats decay across the gap. It wakes exactly as you left it. That's for long-term storage, air travel, or a safety cut.
Everyday "off" is a different thing: a press-and-hold on a button, which puts the chip into a deep sleep with the clock still running, so the pet does get hungry while it sits in your bag. That's where the classic "you neglected me" mechanic lives, and it covers virtually all real not-looking time. Make sure the two are visibly distinct in the firmware — it should be a choice the owner makes, not a trap they fall into.
The real risk here is battery life, not graphics
A 240×240 always-on color IPS panel draws meaningfully more current than the segment LCD in a real Tamagotchi. This board's independently-controllable backlight (see pin reference) is a genuine tool for managing that in firmware later (dimming, sleep between checks) — but it's still something to budget for in software, not something solved by the hardware alone.
Step 2 — Buttons
2Wire the three control switches
For each of the 3 switches, solder a short length of hookup wire directly to one leg on each of its two independent sides (the pair you confirmed in Validation step E) — one wire becomes the GPIO leg, the other the GND leg. These switches have no pigtail; this is a direct solder joint to the switch's own through-hole legs.
Snap a colored knob cap onto each switch's actuator before mounting — much easier now than after it's wired into the case.
Mount the three switches to a small offcut of perfboard (their legs through-hole solder in directly), sized to fit behind the case's button cluster cutout — see enclosure notes. This gives them the structural support panel-mount buttons got for free from their own threaded barrel + nut.
Run each switch's two wires back to the board per the table below.
Switches → RP2350-LCD-1.28 — all on header H1 (internal pull-ups, configured in firmware later)
Switch
GPIO leg
GND leg
A (left / feed)
GP13 — H1 pin 11
GND — H1 pin 20
B (middle / select)
GP14 — H1 pin 13
GND — H1 pin 20
C (right / play)
GP15 — H1 pin 15
GND — H1 pin 20
Cap color has no electrical meaning — pick any 3 of the 6 available colors and assign them to functions however makes sense to you.
Wire these switch-to-GND and pull them UP in firmware — never down
The table above is not one of two equally valid options. The RP2350 has a documented erratum (E9): increased leakage current on Bank 0 GPIO when the pad's input buffer is enabled, which can overcome an internal pull-down and make the pin read unreliably. GP13, GP14 and GP15 are all Bank 0. Internal pull-ups are unaffected, so the button must idle high and be pulled to GND when pressed (active-low) — which is what the wiring above does.
Two practical follow-ons: solder a 100nF ceramic capacitor across each switch to ground (it shortens the mid-rail transition E9 dislikes and handles most of the debounce in hardware), and never configure these pins INPUT_PULLDOWN in firmware. Newer A4-stepping silicon fixes E9 outright, but wire it this way regardless — it costs nothing and makes the build independent of which stepping you happen to have.
Step 3 — Buzzer
3Wire the passive buzzer
This buzzer is also bare-legged, no pigtail — solder hookup wire directly to its two terminals, same as the switches. Mount it on the same small perfboard sub-assembly as the 3 switches from Step 2 so the input/audio cluster stays one internal module.
Buzzer terminal
Board pin
Terminal 1
GP16 — H2 pin 2
Terminal 2
GND — H2 pin 19 or 20
The buzzer lands on the other header — plan for two harnesses
The three buttons are on H1; the buzzer is on H2, the opposite side of the board. So the perfboard cluster runs two short harnesses, not one: three signal wires plus a ground to H1, and one signal plus a ground to H2.
This is fine electrically — each header carries its own GND (H1 p20, H2 p19/p20), so nothing has to bridge across the board. But route the two bundles before you glue anything down; on a Φ32.4mm board there is not much slack, and discovering the split after the case is assembled is annoying.
If you'd rather have a single harness, GP0–GP5 are free and sit on H1 — GP5 is H1 pin 12, right beside GP13. That was considered and deliberately not taken here; GP16 stays.
Passive, not active
Stays silent on plain DC — needs a PWM tone signal from firmware to make any sound. Exact current draw isn't confirmed by its datasheet; if you notice a weak/distorted tone, add a small NPN transistor as a driver stage between GP16 and the buzzer rather than driving it directly.
Step 4 — Smoke test
4First full power-up with battery installed
Double-check every button/buzzer ground lands on the GND pin you identified in Validation step C, and the battery's spliced switch works both ways.
Plug the battery's JST connector into the board (Validation step B should already have confirmed pitch/polarity match).
Flip the slide switch on. The display backlight should illuminate the same way it did in Validation step D's USB-only test — no firmware required for this, since backlight-on is this board's default power-up state.
With a multimeter, confirm the battery reads a sane voltage (3.0–4.2V) at the board's battery input while the switch is on.
Full pin reference
Every GPIO wired in this build, plus the board's full reserved-pin map for reference
Design guidance for modeling your own case — not a ready-made STL. This edition's internal layout is simpler than a two-board build: one round board, one small battery, three buttons, and a buzzer.
Conceptual top-down layout, not to scale — use it to plan relative placement, not exact geometry.
Design notes
Two-piece shell: front bezel with a display cutout, rear shell holding standoffs for the battery, joined with 4–6 M2 heat-set inserts + matching bolts rather than glue or snap-fit — lets you reopen it for battery access or a firmware-flash session.
Display window: the active display area is 32.4mm; the board's own overall PCB outline (including where the H1/H2 headers and BOOT/RESET buttons sit) isn't documented to the millimeter here — measure your physical unit with calipers before committing to the bezel's exact inner diameter and mounting-standoff positions.
Button cutouts: unlike a panel-mount button, a 12×12mm tactile switch doesn't self-secure in a hole with a nut — it needs a small internal perfboard (or a printed mounting boss) sized for the 3-switch cluster, positioned so each switch's knob cap just clears a matching hole in the case wall. Measure your actual knob caps (body + cap height) before sizing that clearance, since the component doc flags this as not independently measured.
No waterproofing on the switch cutouts: this is the real tradeoff versus the panel-mount buttons from the earlier plan — these holes are a direct path to dust/moisture. Fine for a desk pet, worth reconsidering if this is meant to survive a bag or pocket regularly.
Sound vents: a small cluster of 1–2mm holes in the wall above the buzzer's position.
USB-C access: a rectangular cutout aligned to this board's own USB-C port — used for both programming and charging, so make sure it's reachable without fully disassembling the case.
Material: PLA is fine for an indoor desk pet; PETG holds up better in a bag/pocket/hot car.
What's next
Placeholder — firmware guide to follow
This guide stops at working, tested hardware: display backlight confirmed alive on both USB and battery power, battery connector and ground pin verified by the validation pass, every input wired to a known GPIO. The pet's actual behavior — sprite animation, hunger/happiness stats, button handling, sleep/wake power management, and optionally the onboard IMU for tilt/shake interactions — is software, covered in a follow-up guide once this hardware is built and validated.
Sources & verification notes
Hardware sources used for this edition:
Adafruit CircuitPython board definition — the authoritative source for this guide's full GPIO map, used after Waveshare's own wiki/product pages returned HTTP 403 to automated fetching.
Component specs are drawn from each part's own datasheet or official product page where available; generic/commodity parts (buttons, switch, buzzer) are sourced from vendor listings only, flagged as typical-for-class rather than lab-verified. The Component Validation section above exists specifically to catch what neither source category could confirm — verify against your own physical parts before finalizing anything permanent.