I've used Pwnagotchis for a while, and they were a big part of how I learned to use SBCs and some of the basics of wireless security. Years went by and I got sucked into tinkering with ESP32 boards. I wanted to see if I could make a pwnagotchi on an ESP32, specifically the Waveshare ESP32-S3-ePaper-1.54.
I found minigotchi-ESP32 by dj1ch and started working from that. I kept adding to it until it became its own thing, and eventually I pulled the minigotchi guts out completely. What's left is Nico. I wanted it to be shareable and easy for other people to build too, so the whole thing is on GitHub under GPLv3.
Code:
The hardware
It's a single off-the-shelf board, no custom PCB. The Waveshare ESP32-S3-ePaper-1.54 has:
- a 200x200 SSD1681 e-paper screen
- an SHTC3 temp/humidity sensor
- a PCF85063 real-time clock
- an ES8311 audio codec with a mic and a little speaker
- a microSD slot
- two buttons (BOOT and PWR)
- a LiPo header with onboard charging
- a 2x6 header on the back
Add a single-cell LiPo and a micro SD card and that's it. Everything runs off the two buttons: tap BOOT for next, double tap for back a step, hold to go back, PWR to select.
One thing that tripped me up early: the e-paper has a power enable on GPIO6 that's active-low. If you don't drive it low, the panel just stays dark, which is why a lot of plain e-ink sketches show nothing on this board.
The pet
Nico is a little tamagotchi. He has food, fun, energy, and a bond level that drift over time (even while he's off), and you look after him with the buttons.
Every Nico rolls hidden stats when he hatches: what temperature feels comfy, early bird or night owl, how fast he gets hungry, shy or outgoing, and a favorite game he'll grin about even when he loses. There's no stat screen. You figure your Nico out by living with him, and as your bond grows a traits page spells it out one trait at a time.
The one trait you can see is his body. Every face is drawn inside a bracket shell: round (^-^), boxy [^-^], curly {^-^}, a cat (=^-^=), bear ears o(^-^)o, and a few more. The faces are kaomoji that change with his mood and with his body temperature. The SHTC3 sits right next to the warm guts of the board so it reads way hotter than the room, so I just made that Nico's body temp. He gets sweaty when he's hot and shivery when he's cold.
He levels up through ranks from Hatchling to Legend and unlocks about 70 bonus faces and a veteran badge on the way. XP comes from the radio stuff, winning games, taking care of him, and a slow drip just from being awake and looked after.
Once you raise a Nico all the way to Legend you can release him. He gets a little send-off, waves goodbye, and the next generation wanders in. The new one inherits one gene and one "heirloom" face, and every generation unlocks rarer bodies. Every Nico you release goes into a Hall of Fame for good. It works the other way too: if you neglect a Nico for days he'll leave on his own (with plenty of warning first, and you can turn that off in Settings).
Games
- 21 (blackjack) with Nico as the dealer
- Pig dice, a push-your-luck race to 100. You watch Nico decide roll by roll whether to keep going or bank, and how greedy he gets depends on whether he's shy or outgoing.
- Copynico: hold PWR and talk into the mic, and he plays it back pitched up in a little "neko" voice.
- Treasure hunt: a metal detector game. Nico locks onto a nearby network as buried treasure and you walk around sweeping for the strongest signal to dig it up. Loot is rolled by rarity, and each network can only be dug once a day.
- SSID fishing: cast a line and the wait for a bite is a Wi-Fi scan. Each AP is a fish (SSID is the name, signal is the size, encryption is the rarity), and every catch goes into a logbook on the SD card. It's a plain scan, no connecting, no attacking.
I'm still adding more.
The radio stuff
Nico only has one radio, so capture and tracker are one or the other.
Packet capture: passive sniffing to a normal .pcap on the SD card, but Nico only keeps the stuff a cracker can actually use. That's WPA handshakes (EAPOL) and PMKIDs, plus one beacon per network that hands over a handshake so the .pcap has the network name the crack needs. Everything else gets dropped. Frames are only counted once they're confirmed written to the card. Use a card 32 GB or smaller, bigger cards lose the SD write-complete interrupt while Wi-Fi is running and nothing saves.
Nico doesn't hop channels at random, He learns which channels around him are busy and worth camping on and keeps drifting back to those, with the odd random check so he notices when the neighborhood changes. It's the same idea as a real Pwnagotchi's "AI", just shrunk down to 13 numbers. That knowledge gets passed down (a little blurred) when you release a Nico, and wiped if one leaves because he was neglected. Shy Nicos tend to work one good channel, outgoing ones wander the whole band.
Tracker Tracker: sweeps for BLE item trackers (AirTag / Find My, Tile, Samsung SmartTag) and warns you if one seems to be following you. It also listens on Wi-Fi for deauth attacks and for other pwnagotchis nearby.
Only capture on networks you own or have permission to test.
Tools
- WiFi Meter: pick your network, walk around the house, and watch the bars to find the dead spots. It keeps the best and worst reading.
- Notes: an e-paper reader for .txt files on the SD card.
- QR codes: Nico's own Wi-Fi, a URL, or a saved note.
- Stopwatch, countdown timer, and pomodoro.
- Flashdrive: Nico shows up on your computer as a read/write USB thumb drive backed by the SD card, so your logs and captures are drag and drop. Reads are around 1 MB/s and writes around 350-600 KB/s. Getting writes to work at all was a whole saga, because the ESP32-S3 loses the SD write-complete interrupt while USB is busy. It's written up in docs/FLASHDRIVE.md.
- Sleep picture: drop a 200x200 black and white BMP on the card and Nico wears it while he sleeps. The e-ink holds it the whole nap for free. There's a little script in extras/ to make one from any photo.
There's also a phone control panel. Tap Connect (QR) and Nico spins up his own hotspot with a settings page. You can name your Nico, flip toggles, see his rank and XP and Hall of Fame, set the clock from your phone, and download all the logs.
Linking Nicos together
Two Nicos can link up with an ordinary USB-C cable, through the charging port, Game Boy style. The S3's USB D- and D+ pins are just GPIO19/20 behind the USB PHY, so flipping one register bit turns the port into a two-wire serial cable. The two sides find each other half-duplex on D+, then split the wires and run normal full-duplex UART. No VBUS flows between them, so each Nico stays on its own battery.
Over the cable they can:
- Co-Scan: split the Wi-Fi channels between them (one takes 1-6, the other 7-11) and share everything they find, so together they sweep the band twice as fast
- Gift a treat
- Duel at rock paper scissors
- Just hang out on a playdate and grow their bond
You can also chain Nicos over the rear header into a ring. It's a counter-rotating ring, two little UART loops running opposite ways, so every Nico hears both neighbors directly without relaying and it keeps working past three. The home screen shows your neighbors' faces next to yours. Each Nico remembers the friends it's met.
Backpacks
The 2x6 header on the back is the Nico Backpack Bus (NBB). It's a small UART protocol where Nico is the host and a backpack tells Nico what it can do when it plugs in. New backpacks hook in through that detect step instead of being hardcoded into the main firmware. The full spec is in docs/BACKPACK_SPEC.md.
Backpacks so far:
- Boombox: an original ESP32 (WROOM-32) that gives Nico real Bluetooth audio, since the S3 is BLE only. Nico streams .mp3 files over the bus and the backpack sends them to Bluetooth headphones.
- Flipper Zero bridge: a Flipper app that answers Nico's handshake and advertises the radios Nico doesn't have (sub-GHz, NFC, 125 kHz RFID, IR, iButton). Wire it TX to RX, share ground, no power pins. Right now it just proves the link, both sides see each other. Driving those radios is next.
- NFC (PN532): on the bench.
Two looks
Nico's screens come in two looks. Classic is the original. Liquid is a dressier one I did later: a black system bar on every screen with his name, a link lamp, the battery as little memory card blocks, and the clock, plus slanted tabs, cut-corner panels, and a dithered haze behind the face. Same info and buttons either way, and you can switch in Settings or from the phone panel.
Make it your own
All the faces live in one file, NicoGotchi/faces.cpp, as a "face pack." Each mood has a pool of kaomoji it cycles through. If you want him to look different, that's the only file you have to touch. There's also a drawn example (shapes instead of text) in extras/ if you'd rather go that way.
Building it
I build with arduino-cli and the esp32 core 2.0.10, which is what this is pinned to. There's a build.sh at the root that compiles or flashes (./build.sh flash). Setup steps and the libraries are in docs/INSTALL.md. The shipping build is USBMode=default (TinyUSB), since that's the one that has both Flashdrive and the link cable.
Thanks
Nico only exists because of minigotchi-ESP32 by dj1ch. That's where Nico started and I'm grateful for it. The pwnagotchi engine has since been removed and the rest rewritten, but it began as a fork of dj1ch's work and keeps the same GPLv3 license. It also leans on GxEPD2 and Adafruit GFX for the display, ricmoo's QRCode, and the ESP32 Arduino core. Full credits are in NOTICE.
Nico is a toy and a learning project, not meant for anything criminal. Only capture on networks you own or have permission to test :)
Dallin Adams