Tamagotchi
A custom PCB-based Tamagotchi virtual pet built with the XIAO-ESP32-C6!
Created by
Tanuki ⚡🚀
Tier 4
4 views
0 followers
alexren ⚡🚀
approved Tamagotchi ago
Tier approved: 4
Grant approved: $53.00
nice project :salute:
Tanuki ⚡🚀
submitted Tamagotchi for review ago
Tanuki ⚡🚀
added to the journal ago
Tutorial
Note: This is the tutorial I made! I chose a journal-like format. Please let me know if you have any questions or this isn't sufficient
Tamagotchi PCB Tutorial
Note: Your schematic should NOT look like this at the end of the tutorial! You are required to add your own components and switch it up to personalize it :D
Table of Contents
-
Tamagotchi PCB Tutorial
- Table of Contents
- Installing KiCad
- Creating the Schematic
- Importing the MCU
- Adding the OLED Display
- Adding Buttons
- Adding a Buzzer
- Assigning Footprints
- Creating the PCB
- Laying Out Components
- Defining the Board Outline
- PCB Routing
- Placing Components
- Routing Traces
- Customization
- Run Design Rules Check
- Common DRC Errors
- Late Additions
- Reading Your Schematic for Firmware
- Add Your Files to Your GitHub Repo
- Upload Your Files to GitHub
- Edit Your README
- Getting a JLCPCB Price
- Settings
- Designing the Case
Installing KiCad
Download KiCad from the official site: https://www.kicad.org/download/
- Go to the download page and select your operating system (Windows, macOS, or Linux).
- Download the latest stable release (KiCad 9.x).
- Run the installer and follow the on-screen instructions (the defaults are fine).
- When prompted, make sure to install the default libraries (they're selected by default).
- Launch KiCad and create a new project (File → New Project or Ctrl+N).
New to KiCad? Read the official getting started guide before continuing:
KiCad 9.0: Getting Started
Creating the Schematic
The XIAO-ESP32-C6 will be used as the MCU! This is because it's tiny and includes WiFi, Bluetooth, and built‑in battery charging, which makes it perfect for this.
What is an MCU? MCU stands for **Microcontroller Unit**, the tiny computer (brain) of your project. It runs your code and controls all the other components (display, buttons, buzzer, etc.). The XIAO-ESP32-C6 is the MCU we're using here. Useful schematic editor keybinds | Key | Action | |-----|--------| | **A** | Add a symbol (component) | | **W** | Draw a wire | | **P** | Add a power symbol (VCC, GND, 3V3, etc.) | | **L** | Add a net label | | **M** | Move a component | | **R** | Rotate a component | | **G** | Grab/drag a component (keeps wires attached) | | **E** | Edit component properties | | **C** | Copy a component | | **Delete** | Delete selected item | | **Ctrl+Z** | Undo | | **Ctrl+S** | Save |Importing the MCU
First, I imported the XIAO-ESP32-C6 from the OPL Library. Here's an excellent tutorial on using it!
I then clicked A (Add Symbol), searched for the part, and imported it. I ended up with this:
Now, for this tutorial, I will create the base Tamagotchi. Spice your own Tamagotchi up more than this one! Add some flavor!
Adding the OLED Display
I then added the 0.96" OLED via EasyEDA to KiCad. Follow this guide!
I connected GND to GND, SDA to SDA, and SCL to SCL. Use W to draw wires between pins.
What are SDA, SCL, and GND? - **GND** = Ground, the common reference point for all electrical signals. - **SDA** = Serial Data, the line that carries data back and forth over I2C. - **SCL** = Serial Clock, the line that provides the timing signal for I2C communication. I2C is a protocol that lets multiple devices talk over just two wires (SDA + SCL). Do I need pull-up resistors on SDA and SCL? Normally yes. I2C requires pull‑up resistors on SDA and SCL; however, the XIAO boards already include internal pull‑ups, so you don't need external ones here.I checked the datasheet attached on the LCSC page and found that VCC should be connected to 3V3.
Adding Buttons
Since a Tamagotchi has three buttons, I decided to add those as well!
For this, I decided to use an active‑low button layout (which is the most common approach).
Each button connects one side to GND and the other to a GPIO pin with the XIAO's internal pull‑up enabled. This makes the pin read HIGH when the button is idle, and LOW when the button is pressed.
What does "active-low" mean? "Active-low" means the button is considered "pressed" when the signal goes LOW (0V / GND). When the button is not pressed, the internal pull-up resistor keeps the pin HIGH (3.3V). This is the most common button wiring approach because it's simple: you only need the button and a ground connection, no extra resistors. What is a GPIO pin? GPIO stands for **General Purpose Input/Output**. These are the programmable pins on your microcontroller that can be configured as either inputs (to read sensors/buttons) or outputs (to drive LEDs/buzzers). On the XIAO, pins like D0–D10 are GPIOs.Adding a Buzzer
I also added a buzzer from here!
The buzzer is wired with one pin to a GPIO output and the other to GND, letting the GPIO drive it with a square‑wave tone.
Assigning Footprints
This is my final schematic! Let's make the PCB now. First, let's assign parts. Click this:
Then assign the corresponding EasyEDA / OPL parts! For the buttons, import from here!
Now, press this and open the PCB viewer:
Creating the PCB
The maximum size of your PCB should be 100mm²!
You should see something like this:
To synchronize changes between your schematic and PCB layout in KiCad:
- Press F8, or
- Click the Update PCB from Schematic button
You can do this anytime you want to refresh the PCB with the latest schematic updates.
Laying Out Components
First, I laid my PCB out in a 100×100 box. I then laid out all my components:
Defining the Board Outline
You'll notice a white outline surrounding the entire board. This is the Edge Cuts layer, which defines the physical boundary where the PCB will be cut.
This is done by modifying the Edge.Cuts layer on the right side. There are many ways to do this, such as manually drawing it with the given menu.
I found the default outline options limiting and wanted to create something more complex. To do this, I:
- Drew out the edge cuts layer.
- Converted the image into a DXF file using an image-to-DXF converter.
- Imported the DXF file into KiCad.
- Created a 100×100 mm box as a reference.
- Used the measuring tool to determine the correct scale.
- Scaled the outline down so it fit within 100 mm.
PCB Routing
A PCB is made up of multiple layers. Our boards are "two-layer," meaning that they have two layers of copper wire.
What are the PCB layers? | Layer | Description | |-------|-------------| | **Top & bottom silkscreen** | The white ink layer where you can add art | | **Top & bottom copper** | The layers where you make your copper wires | | **Substrate** | The actual plastic (usually green) which makes up your board | | **Via** | The tunnels which connect the top and bottom copper layers | Placing Components
Place all of your components inside the board outline. Move components to shorten ratlines, which are the straight blue lines.
- M: Move a component
- R: Rotate a component
- F: Flip a component to the other side of the board
- Ctrl+S / ⌘+S: Save (do this often!)
Routing Traces
Now it's time to route the PCB! Hit X on your keyboard and click anything with a thin blue line poking out of it. It should dim the entire screen, show you which direction you need to go with a thin blue line, and highlight the destination:
Key routing shortcuts:
- X: Start routing a trace
- V: Add a via (switch trace to the other side of the board mid-route)
- Backspace: Delete the last trace segment while routing
- Esc: Cancel the current route
- D: Drag a trace (reposition it without breaking connections)
- U: Select the entire trace from the point you click
Join the highlighted points together. If there isn't enough space on the front side, or there is a trace already present that is blocking you, you can route on the back side by clicking B.Cu on the right toolbar. If you want to change sides during routing, press V and a via will be added, which will transfer your trace to the other side of the board.
What is a via? A via is a small plated hole that connects a copper trace on one layer of the board to a trace on another layer. Think of it as a tiny tunnel through the PCB. You use them when you can't route a trace on one side because another trace is in the way. Press **V** while routing to drop a via and continue the trace on the other side.Important: Wires and pads of different colors (except golden) can't be connected together directly! You must use a via to the other side.
Your routing is complete!
Tip: Place everything based on what shortens the blue lines, and what makes them not cross!
Tip: Use a ground plane to help with routing and to reduce noise. That's what the red and blue layers are for! It's not necessary, but looks nice and is easy to set up!
Note: You may notice stitching vias in my board (the small holes scattered across the ground plane). You do NOT need to add these. They are completely optional and unnecessary for a board like this. I only added them for fun.
Displaying external images is not supported. See original
Customization
You may have already added some text and art to customize your board like me. If not, you can click F.Silkscreen and use the text tool.
To add art, select the Top Silkscreen Layer or Bottom Silkscreen Layer in the sidebars, then use the KiCad image converter to add custom art.
Your board is now beautiful!
Run Design Rules Check
DRC stands for Design Rules Check. This runs a check that makes sure your board has no interference errors, no components are off the board, and no wires are intersecting. It does not, however, confirm that your board works.
Using the output, correct any errors. This can be confusing, so remember: you can always ask for help!
What are common DRC errors? - **Track and copper errors** : clearance violations, track width, annular rings - **Via errors** : diameter, micro vias, blind/buried vias - **Pad and footprint errors** : pad-to-pad, hole clearances - **Edge and board outline errors** : copper edge clearance, silkscreen issues - **Zone errors** : copper slivers, starved thermals, unconnected items - **Net and connection errors** : missing connections, net conflicts - **Courtyard errors** : overlaps, missing courtyardsOnce your PCB passes the DRC, it is finished!
In the PCB editor, click View → 3D Viewer to see your finished work!
Late Additions
There will be moments when you realize you want to add something after you've done most of the work. That's totally fine!
Here, I decided to add battery functionality. Since the XIAO's underside pins are extremely difficult to solder, I designed the board so those pins connect to a pad instead. The battery can then plug into a set of male pins that interface with that pad. Here's what it looks like:
Here's my final schematic:
Here's my final PCB:
Reading Your Schematic for Firmware
Before writing any firmware, you need to read your schematic and extract the information your code needs. Your schematic is the single source of truth for how everything is wired. Open it in KiCad and work through these questions:
1. Identify Your Microcontroller
Find your MCU symbol and note:
- What chip is it? (e.g., XIAO ESP32-C6)
- What voltage does it run at? (e.g., 3.3V logic)
This tells you what board to select in the Arduino IDE and what voltage levels your code should expect.
2. Trace the Power
Follow the power nets in your schematic to understand how everything is powered:
- Where does power come in? (e.g., USB 5V on VBUS)
- What voltage rail do your components use? (e.g., 3.3V from the regulator)
- What connects to what power pin?
For my board, this looks like:
| Power Net | Source | What It Powers |
|---|---|---|
| VBUS (5V) | USB input | MCU power input |
| 3V3 | On-board regulator | OLED, buzzer |
| GND | Common ground | Everything |
3. Map Every GPIO Pin
This is the most important part. For every component connected to your MCU, write down which physical pin and which GPIO number it uses. Look at the pin labels on your MCU symbol and trace the wires to each component.
For my board:
Buttons (Active LOW, connect to GND when pressed):
| Button | MCU Pin | GPIO | Pressed State |
|---|---|---|---|
| SW1 | Pin 1 | GPIO0 | LOW |
| SW2 | Pin 2 | GPIO1 | LOW |
| SW3 | Pin 3 | GPIO2 | LOW |
OLED Display (I²C):
| Signal | MCU Pin | GPIO |
|---|---|---|
| SDA | Pin 5 | GPIO22 |
| SCL | Pin 6 | GPIO23 |
| VCC | 3.3V | — |
| GND | GND | — |
Buzzer:
| Connection | MCU Pin | GPIO |
|---|---|---|
| Signal | Pin 10 | GPIO20 |
| + | 3.3V | — |
| − | GND | — |
4. Understand How Each Component Is Wired
Don't just note the pin number. Understand the circuit behavior:
Buttons: The schematic shows each button connects between a GPIO pin and GND. Since we configure INPUT_PULLUP in firmware, the pin sits at HIGH (3.3V) when idle, and goes LOW when pressed. This is called active-low.
Buzzer: In my schematic, the buzzer's positive terminal is tied to 3.3V and the GPIO drives the other side. This means the GPIO sinks current to activate the buzzer. Setting the GPIO LOW turns the buzzer ON, and HIGH turns it OFF. If it's a passive buzzer, you drive it with PWM using tone().
OLED: It communicates over I²C using two data lines (SDA and SCL). The I²C address is usually 0x3C (check the display datasheet to confirm).
5. Note Unused Pins
Write down which GPIO pins are not connected to anything. These are available for future expansion if you want to add more features:
| Available GPIO |
|---|
| GPIO21 |
| GPIO18 |
| GPIO19 |
| GPIO17 |
| GPIO16 |
6. Write Your Pin Definitions
Now turn all of this into the #define statements your firmware needs:
// Buttons
#define BTN1 0 // GPIO0
#define BTN2 1 // GPIO1
#define BTN3 2 // GPIO2
// I2C (OLED)
#define SDA_PIN 22 // GPIO22
#define SCL_PIN 23 // GPIO23
// Buzzer
#define BUZZER 20 // GPIO20
These numbers come directly from your schematic. Your pin numbers will be different from mine if your schematic is different. Always check your own schematic, not someone else's code.
What if I can't figure out my pin mapping? 1. Open your schematic in KiCad. 2. Click on a wire connected to the MCU. 3. KiCad will highlight the entire net (all connected points). 4. Read the pin name on the MCU side of that highlighted net. 5. If you're still stuck, ask for help in #fallout!This step is critical. If your pin definitions don't match your schematic, your firmware will compile fine but nothing will work when you flash it to the board. The schematic is always the source of truth.
Add Your Files to Your GitHub Repo
Now it is time to order your board. Get the following files from your project:
-
A screenshot of your 3D view
- In PCB Editor: View → 3D Viewer → Edit → Copy 3D Image
-
.kicad_pro(KiCad project file) -
.kicad_sch(schematic) -
.kicad_pcb(PCB layout) - Your Gerber files (see below)
Upload Your Files to GitHub
Go back to the GitHub repo you created at the start. Click Add File → Upload files.
Drag in your:
- Screenshot of your 3D view
-
.kicad_pro(KiCad project file) -
.kicad_sch(schematic) -
.kicad_pcb(PCB layout) - Gerbers (zipped)
You should have downloaded all of these in the previous step.
Click to commit your changes.
Edit Your README
Finally, edit your README to include the submission requirements:
- A short description of what your project is
- A couple sentences on why you made the project
- A couple sentences on how to use your project
Pictures of your project:
- A screenshot of a full 3D model of your project
- A screenshot of your PCB, if you have one
- A wiring diagram, if you're doing any wiring that isn't on a PCB
A BOM (Bill of Materials) in table format at the end of the README, with links.
NOTE: ALL projects you make for Blueprint must have a project photo in your README.
Getting a JLCPCB Price
Go to jlcpcb.com and make an account. Then, add your Gerber file for the instant quote.
Settings
You should keep the default settings for everything. The only thing you should/can change is the PCB Color. I did black as seen below:
For high-spec options, also keep the default. Do not click PCB assembly. We will give you a kit to hand-solder your board.
Once you have successfully not changed any of the settings (except the board color), on the right, change the shipping method to Global Standard Direct (or Air Registered Mail if it is cheaper), and take a screenshot (this is very important).
Designing the Case
Export the PCB from KiCad into your CAD platform! For me, this is Onshape.
I googled and found headers! I found this from here!
I then experimented with the CAD a lot. I used revolve, but it did not look nice and was hard to use. I also tried multiple placements for the battery and found it was optimal if it's placed vertically.
To make these, I created a sketch by clicking the sketch button in the upper-left-hand side and made multiple shapes that include tolerance and my shell size.
I also decided to change the PCB to add the vibration motor to the back and raise the screen!
From
to
My headers overlapped with the buzzer, so I decided to reposition the buzzer to the middle of the board! The gap between the LCD and the headers should give me enough space!
I made the back portion with 3D-printed standoffs and added large fillets to round the edges. I made the top part and added some tolerance between the top of the plate and the bottom of the top half of the case!
I added a hole for the battery and a hole for the USB-C. Generally, there may be issues printing this, but for this small amount of bridging there shouldn't be any issues!
Finally, I used the section view tool to confirm that there is no overlapping:
Now, my design is finished! I uploaded all necessary files to my GitHub repo.
Note: Design is an iterative process. I spent about 20 hours manually adjusting everything to look as pretty as possible! But don't worry, #fallout is here to guide you! This is a normal process and you are not alone.
I recommend not following the above 1:1; this was my process, and it will differ greatly from yours!
I also recommend checking my Onshape for inspiration! Check my feature tree and see my iterations yourself.
Enjoy making :D!
Tanuki ⚡🚀
added to the journal ago
Schematic
The ESPC3 Has bat pads, which I want to use. Im not sure how to use it, as its hard to reach. I was wondering, the battery pins are underside. Is there a better way to use the battery pins then to solder a wire to the bat pins and then soder it on? My concern is that when you solder the pins on and if the battery wire gets loose, you would have to desolder everything. I then thought, wait what if I solder them to short wires, connect the wires to the PCB, and connect those to THT?
Additionally, I had issues with EasyEDA2KiCad.

Tanuki ⚡🚀
added to the journal ago
Minor design change
After a little bit of research, I desided to use the Seeed Studio XIAO ESP32-C6 MCU instead of the 2350. The 2350 really has no advantage, and the c6 has wifi

Tanuki ⚡🚀
added to the journal ago
Created BOM
Ok so
I want this to have the option of battery power, so I use RP2350
- MCU: Seeed Studio XIAO RP2350, https://www.seeedstudio.com/Seeed-XIAO-RP2350-p-5944.html, 5 USD (if wifi or ble needed can switch to nRF52840 or XIAO ESP32‑C3)
- 11 gpio means largest matrix = 6 x 5, so gpio isnt the limit here. I dont think 30 keys is reasonable, ill stick to 25 maybe?
https://www.aliexpress.us/item/3256810565239286.html is more expensive in single but cheaper inm bulk then https://www.amazon.com/YELUFT-Rechargeable-Protection-Compatiable-Development/dp/B0F1S1NMP6
for the battery, the ultras sleep mode will be very useful, "Efficient Power Design: Ultra-low power consumption of just 50μA in sleep mode, enabling battery power supply. Direct battery voltage measurement via internal IO enhances the battery management system (BMS)." average seems to be abt like 22mA tho, like battery.
250mAh
so,
battery life = m/Ah / draw, about 22mA, the OLED is 15 mA max. so, 250/(44)= about 5.5 hours of battery, which is decent.
- MCU: Seeed Studio XIAO RP2350, https://www.seeedstudio.com/Seeed-XIAO-RP2350-p-5944.html, 5 USD (if wifi or ble needed can switch to nRF52840 or XIAO ESP32‑C3)
- Diodes, https://www.lcsc.com/product-detail/C5383214.html, 0.53*3= 1.59
- https://www.lcsc.com/product-detail/C5248080.html, $ 2.15,, OLED 0.96
- https://www.amazon.com/YELUFT-Rechargeable-Protection-Compatiable-Development/dp/B0F1S1NMP6/ Battery, 4 USD for one. in bulk, aliexpress is just 2.5.
- For buttons, https://www.lcsc.com/product-detail/C2829953.html will be out of stock soon. I can use that, but also https://www.lcsc.com/product-detail/C2888493.html
AHHH HOMEOWRK ill finish later
Tanuki ⚡🚀
started Tamagotchi ago
2/8/2026 - Created BOM
Ok so
I want this to have the option of battery power, so I use RP2350
- MCU: Seeed Studio XIAO RP2350, https://www.seeedstudio.com/Seeed-XIAO-RP2350-p-5944.html, 5 USD (if wifi or ble needed can switch to nRF52840 or XIAO ESP32‑C3)
- 11 gpio means largest matrix = 6 x 5, so gpio isnt the limit here. I dont think 30 keys is reasonable, ill stick to 25 maybe?
https://www.aliexpress.us/item/3256810565239286.html is more expensive in single but cheaper inm bulk then https://www.amazon.com/YELUFT-Rechargeable-Protection-Compatiable-Development/dp/B0F1S1NMP6
for the battery, the ultras sleep mode will be very useful, "Efficient Power Design: Ultra-low power consumption of just 50μA in sleep mode, enabling battery power supply. Direct battery voltage measurement via internal IO enhances the battery management system (BMS)." average seems to be abt like 22mA tho, like battery.
250mAh
so,
battery life = m/Ah / draw, about 22mA, the OLED is 15 mA max. so, 250/(44)= about 5.5 hours of battery, which is decent.
- MCU: Seeed Studio XIAO RP2350, https://www.seeedstudio.com/Seeed-XIAO-RP2350-p-5944.html, 5 USD (if wifi or ble needed can switch to nRF52840 or XIAO ESP32‑C3)
- Diodes, https://www.lcsc.com/product-detail/C5383214.html, 0.53*3= 1.59
- https://www.lcsc.com/product-detail/C5248080.html, $ 2.15,, OLED 0.96
- https://www.amazon.com/YELUFT-Rechargeable-Protection-Compatiable-Development/dp/B0F1S1NMP6/ Battery, 4 USD for one. in bulk, aliexpress is just 2.5.
- For buttons, https://www.lcsc.com/product-detail/C2829953.html will be out of stock soon. I can use that, but also https://www.lcsc.com/product-detail/C2888493.html
AHHH HOMEOWRK ill finish later
2/11/2026 - Minor design change
After a little bit of research, I desided to use the Seeed Studio XIAO ESP32-C6 MCU instead of the 2350. The 2350 really has no advantage, and the c6 has wifi

2/12/2026 - Schematic
The ESPC3 Has bat pads, which I want to use. Im not sure how to use it, as its hard to reach. I was wondering, the battery pins are underside. Is there a better way to use the battery pins then to solder a wire to the bat pins and then soder it on? My concern is that when you solder the pins on and if the battery wire gets loose, you would have to desolder everything. I then thought, wait what if I solder them to short wires, connect the wires to the PCB, and connect those to THT?
Additionally, I had issues with EasyEDA2KiCad.
2/17/2026 - Tutorial
Note: This is the tutorial I made! I chose a journal-like format. Please let me know if you have any questions or this isn't sufficient
Tamagotchi PCB Tutorial
Note: Your schematic should NOT look like this at the end of the tutorial! You are required to add your own components and switch it up to personalize it :D
Table of Contents
-
Tamagotchi PCB Tutorial
- Table of Contents
- Installing KiCad
- Creating the Schematic
- Importing the MCU
- Adding the OLED Display
- Adding Buttons
- Adding a Buzzer
- Assigning Footprints
- Creating the PCB
- Laying Out Components
- Defining the Board Outline
- PCB Routing
- Placing Components
- Routing Traces
- Customization
- Run Design Rules Check
- Common DRC Errors
- Late Additions
- Reading Your Schematic for Firmware
- Add Your Files to Your GitHub Repo
- Upload Your Files to GitHub
- Edit Your README
- Getting a JLCPCB Price
- Settings
- Designing the Case
Installing KiCad
Download KiCad from the official site: https://www.kicad.org/download/
- Go to the download page and select your operating system (Windows, macOS, or Linux).
- Download the latest stable release (KiCad 9.x).
- Run the installer and follow the on-screen instructions (the defaults are fine).
- When prompted, make sure to install the default libraries (they're selected by default).
- Launch KiCad and create a new project (File → New Project or Ctrl+N).
New to KiCad? Read the official getting started guide before continuing:
KiCad 9.0: Getting Started
Creating the Schematic
The XIAO-ESP32-C6 will be used as the MCU! This is because it's tiny and includes WiFi, Bluetooth, and built‑in battery charging, which makes it perfect for this.
What is an MCU? MCU stands for **Microcontroller Unit**, the tiny computer (brain) of your project. It runs your code and controls all the other components (display, buttons, buzzer, etc.). The XIAO-ESP32-C6 is the MCU we're using here. Useful schematic editor keybinds | Key | Action | |-----|--------| | **A** | Add a symbol (component) | | **W** | Draw a wire | | **P** | Add a power symbol (VCC, GND, 3V3, etc.) | | **L** | Add a net label | | **M** | Move a component | | **R** | Rotate a component | | **G** | Grab/drag a component (keeps wires attached) | | **E** | Edit component properties | | **C** | Copy a component | | **Delete** | Delete selected item | | **Ctrl+Z** | Undo | | **Ctrl+S** | Save |Importing the MCU
First, I imported the XIAO-ESP32-C6 from the OPL Library. Here's an excellent tutorial on using it!
I then clicked A (Add Symbol), searched for the part, and imported it. I ended up with this:
Now, for this tutorial, I will create the base Tamagotchi. Spice your own Tamagotchi up more than this one! Add some flavor!
Adding the OLED Display
I then added the 0.96" OLED via EasyEDA to KiCad. Follow this guide!
I connected GND to GND, SDA to SDA, and SCL to SCL. Use W to draw wires between pins.
What are SDA, SCL, and GND? - **GND** = Ground, the common reference point for all electrical signals. - **SDA** = Serial Data, the line that carries data back and forth over I2C. - **SCL** = Serial Clock, the line that provides the timing signal for I2C communication. I2C is a protocol that lets multiple devices talk over just two wires (SDA + SCL). Do I need pull-up resistors on SDA and SCL? Normally yes. I2C requires pull‑up resistors on SDA and SCL; however, the XIAO boards already include internal pull‑ups, so you don't need external ones here.I checked the datasheet attached on the LCSC page and found that VCC should be connected to 3V3.
Adding Buttons
Since a Tamagotchi has three buttons, I decided to add those as well!
For this, I decided to use an active‑low button layout (which is the most common approach).
Each button connects one side to GND and the other to a GPIO pin with the XIAO's internal pull‑up enabled. This makes the pin read HIGH when the button is idle, and LOW when the button is pressed.
What does "active-low" mean? "Active-low" means the button is considered "pressed" when the signal goes LOW (0V / GND). When the button is not pressed, the internal pull-up resistor keeps the pin HIGH (3.3V). This is the most common button wiring approach because it's simple: you only need the button and a ground connection, no extra resistors. What is a GPIO pin? GPIO stands for **General Purpose Input/Output**. These are the programmable pins on your microcontroller that can be configured as either inputs (to read sensors/buttons) or outputs (to drive LEDs/buzzers). On the XIAO, pins like D0–D10 are GPIOs.Adding a Buzzer
I also added a buzzer from here!
The buzzer is wired with one pin to a GPIO output and the other to GND, letting the GPIO drive it with a square‑wave tone.
Assigning Footprints
This is my final schematic! Let's make the PCB now. First, let's assign parts. Click this:
Then assign the corresponding EasyEDA / OPL parts! For the buttons, import from here!
Now, press this and open the PCB viewer:
Creating the PCB
The maximum size of your PCB should be 100mm²!
You should see something like this:
To synchronize changes between your schematic and PCB layout in KiCad:
- Press F8, or
- Click the Update PCB from Schematic button
You can do this anytime you want to refresh the PCB with the latest schematic updates.
Laying Out Components
First, I laid my PCB out in a 100×100 box. I then laid out all my components:
Defining the Board Outline
You'll notice a white outline surrounding the entire board. This is the Edge Cuts layer, which defines the physical boundary where the PCB will be cut.
This is done by modifying the Edge.Cuts layer on the right side. There are many ways to do this, such as manually drawing it with the given menu.
I found the default outline options limiting and wanted to create something more complex. To do this, I:
- Drew out the edge cuts layer.
- Converted the image into a DXF file using an image-to-DXF converter.
- Imported the DXF file into KiCad.
- Created a 100×100 mm box as a reference.
- Used the measuring tool to determine the correct scale.
- Scaled the outline down so it fit within 100 mm.
PCB Routing
A PCB is made up of multiple layers. Our boards are "two-layer," meaning that they have two layers of copper wire.
What are the PCB layers? | Layer | Description | |-------|-------------| | **Top & bottom silkscreen** | The white ink layer where you can add art | | **Top & bottom copper** | The layers where you make your copper wires | | **Substrate** | The actual plastic (usually green) which makes up your board | | **Via** | The tunnels which connect the top and bottom copper layers | Placing Components
Place all of your components inside the board outline. Move components to shorten ratlines, which are the straight blue lines.
- M: Move a component
- R: Rotate a component
- F: Flip a component to the other side of the board
- Ctrl+S / ⌘+S: Save (do this often!)
Routing Traces
Now it's time to route the PCB! Hit X on your keyboard and click anything with a thin blue line poking out of it. It should dim the entire screen, show you which direction you need to go with a thin blue line, and highlight the destination:
Key routing shortcuts:
- X: Start routing a trace
- V: Add a via (switch trace to the other side of the board mid-route)
- Backspace: Delete the last trace segment while routing
- Esc: Cancel the current route
- D: Drag a trace (reposition it without breaking connections)
- U: Select the entire trace from the point you click
Join the highlighted points together. If there isn't enough space on the front side, or there is a trace already present that is blocking you, you can route on the back side by clicking B.Cu on the right toolbar. If you want to change sides during routing, press V and a via will be added, which will transfer your trace to the other side of the board.
What is a via? A via is a small plated hole that connects a copper trace on one layer of the board to a trace on another layer. Think of it as a tiny tunnel through the PCB. You use them when you can't route a trace on one side because another trace is in the way. Press **V** while routing to drop a via and continue the trace on the other side.Important: Wires and pads of different colors (except golden) can't be connected together directly! You must use a via to the other side.
Your routing is complete!
Tip: Place everything based on what shortens the blue lines, and what makes them not cross!
Tip: Use a ground plane to help with routing and to reduce noise. That's what the red and blue layers are for! It's not necessary, but looks nice and is easy to set up!
Note: You may notice stitching vias in my board (the small holes scattered across the ground plane). You do NOT need to add these. They are completely optional and unnecessary for a board like this. I only added them for fun.
Displaying external images is not supported. See original
Customization
You may have already added some text and art to customize your board like me. If not, you can click F.Silkscreen and use the text tool.
To add art, select the Top Silkscreen Layer or Bottom Silkscreen Layer in the sidebars, then use the KiCad image converter to add custom art.
Your board is now beautiful!
Run Design Rules Check
DRC stands for Design Rules Check. This runs a check that makes sure your board has no interference errors, no components are off the board, and no wires are intersecting. It does not, however, confirm that your board works.
Using the output, correct any errors. This can be confusing, so remember: you can always ask for help!
What are common DRC errors? - **Track and copper errors** : clearance violations, track width, annular rings - **Via errors** : diameter, micro vias, blind/buried vias - **Pad and footprint errors** : pad-to-pad, hole clearances - **Edge and board outline errors** : copper edge clearance, silkscreen issues - **Zone errors** : copper slivers, starved thermals, unconnected items - **Net and connection errors** : missing connections, net conflicts - **Courtyard errors** : overlaps, missing courtyardsOnce your PCB passes the DRC, it is finished!
In the PCB editor, click View → 3D Viewer to see your finished work!
Late Additions
There will be moments when you realize you want to add something after you've done most of the work. That's totally fine!
Here, I decided to add battery functionality. Since the XIAO's underside pins are extremely difficult to solder, I designed the board so those pins connect to a pad instead. The battery can then plug into a set of male pins that interface with that pad. Here's what it looks like:
Here's my final schematic:
Here's my final PCB:
Reading Your Schematic for Firmware
Before writing any firmware, you need to read your schematic and extract the information your code needs. Your schematic is the single source of truth for how everything is wired. Open it in KiCad and work through these questions:
1. Identify Your Microcontroller
Find your MCU symbol and note:
- What chip is it? (e.g., XIAO ESP32-C6)
- What voltage does it run at? (e.g., 3.3V logic)
This tells you what board to select in the Arduino IDE and what voltage levels your code should expect.
2. Trace the Power
Follow the power nets in your schematic to understand how everything is powered:
- Where does power come in? (e.g., USB 5V on VBUS)
- What voltage rail do your components use? (e.g., 3.3V from the regulator)
- What connects to what power pin?
For my board, this looks like:
| Power Net | Source | What It Powers |
|---|---|---|
| VBUS (5V) | USB input | MCU power input |
| 3V3 | On-board regulator | OLED, buzzer |
| GND | Common ground | Everything |
3. Map Every GPIO Pin
This is the most important part. For every component connected to your MCU, write down which physical pin and which GPIO number it uses. Look at the pin labels on your MCU symbol and trace the wires to each component.
For my board:
Buttons (Active LOW, connect to GND when pressed):
| Button | MCU Pin | GPIO | Pressed State |
|---|---|---|---|
| SW1 | Pin 1 | GPIO0 | LOW |
| SW2 | Pin 2 | GPIO1 | LOW |
| SW3 | Pin 3 | GPIO2 | LOW |
OLED Display (I²C):
| Signal | MCU Pin | GPIO |
|---|---|---|
| SDA | Pin 5 | GPIO22 |
| SCL | Pin 6 | GPIO23 |
| VCC | 3.3V | — |
| GND | GND | — |
Buzzer:
| Connection | MCU Pin | GPIO |
|---|---|---|
| Signal | Pin 10 | GPIO20 |
| + | 3.3V | — |
| − | GND | — |
4. Understand How Each Component Is Wired
Don't just note the pin number. Understand the circuit behavior:
Buttons: The schematic shows each button connects between a GPIO pin and GND. Since we configure INPUT_PULLUP in firmware, the pin sits at HIGH (3.3V) when idle, and goes LOW when pressed. This is called active-low.
Buzzer: In my schematic, the buzzer's positive terminal is tied to 3.3V and the GPIO drives the other side. This means the GPIO sinks current to activate the buzzer. Setting the GPIO LOW turns the buzzer ON, and HIGH turns it OFF. If it's a passive buzzer, you drive it with PWM using tone().
OLED: It communicates over I²C using two data lines (SDA and SCL). The I²C address is usually 0x3C (check the display datasheet to confirm).
5. Note Unused Pins
Write down which GPIO pins are not connected to anything. These are available for future expansion if you want to add more features:
| Available GPIO |
|---|
| GPIO21 |
| GPIO18 |
| GPIO19 |
| GPIO17 |
| GPIO16 |
6. Write Your Pin Definitions
Now turn all of this into the #define statements your firmware needs:
// Buttons
#define BTN1 0 // GPIO0
#define BTN2 1 // GPIO1
#define BTN3 2 // GPIO2
// I2C (OLED)
#define SDA_PIN 22 // GPIO22
#define SCL_PIN 23 // GPIO23
// Buzzer
#define BUZZER 20 // GPIO20
These numbers come directly from your schematic. Your pin numbers will be different from mine if your schematic is different. Always check your own schematic, not someone else's code.
What if I can't figure out my pin mapping? 1. Open your schematic in KiCad. 2. Click on a wire connected to the MCU. 3. KiCad will highlight the entire net (all connected points). 4. Read the pin name on the MCU side of that highlighted net. 5. If you're still stuck, ask for help in #fallout!This step is critical. If your pin definitions don't match your schematic, your firmware will compile fine but nothing will work when you flash it to the board. The schematic is always the source of truth.
Add Your Files to Your GitHub Repo
Now it is time to order your board. Get the following files from your project:
-
A screenshot of your 3D view
- In PCB Editor: View → 3D Viewer → Edit → Copy 3D Image
-
.kicad_pro(KiCad project file) -
.kicad_sch(schematic) -
.kicad_pcb(PCB layout) - Your Gerber files (see below)
Upload Your Files to GitHub
Go back to the GitHub repo you created at the start. Click Add File → Upload files.
Drag in your:
- Screenshot of your 3D view
-
.kicad_pro(KiCad project file) -
.kicad_sch(schematic) -
.kicad_pcb(PCB layout) - Gerbers (zipped)
You should have downloaded all of these in the previous step.
Click to commit your changes.
Edit Your README
Finally, edit your README to include the submission requirements:
- A short description of what your project is
- A couple sentences on why you made the project
- A couple sentences on how to use your project
Pictures of your project:
- A screenshot of a full 3D model of your project
- A screenshot of your PCB, if you have one
- A wiring diagram, if you're doing any wiring that isn't on a PCB
A BOM (Bill of Materials) in table format at the end of the README, with links.
NOTE: ALL projects you make for Blueprint must have a project photo in your README.
Getting a JLCPCB Price
Go to jlcpcb.com and make an account. Then, add your Gerber file for the instant quote.
Settings
You should keep the default settings for everything. The only thing you should/can change is the PCB Color. I did black as seen below:
For high-spec options, also keep the default. Do not click PCB assembly. We will give you a kit to hand-solder your board.
Once you have successfully not changed any of the settings (except the board color), on the right, change the shipping method to Global Standard Direct (or Air Registered Mail if it is cheaper), and take a screenshot (this is very important).
Designing the Case
Export the PCB from KiCad into your CAD platform! For me, this is Onshape.
I googled and found headers! I found this from here!
I then experimented with the CAD a lot. I used revolve, but it did not look nice and was hard to use. I also tried multiple placements for the battery and found it was optimal if it's placed vertically.
To make these, I created a sketch by clicking the sketch button in the upper-left-hand side and made multiple shapes that include tolerance and my shell size.
I also decided to change the PCB to add the vibration motor to the back and raise the screen!
From
to
My headers overlapped with the buzzer, so I decided to reposition the buzzer to the middle of the board! The gap between the LCD and the headers should give me enough space!
I made the back portion with 3D-printed standoffs and added large fillets to round the edges. I made the top part and added some tolerance between the top of the plate and the bottom of the top half of the case!
I added a hole for the battery and a hole for the USB-C. Generally, there may be issues printing this, but for this small amount of bridging there shouldn't be any issues!
Finally, I used the section view tool to confirm that there is no overlapping:
Now, my design is finished! I uploaded all necessary files to my GitHub repo.
Note: Design is an iterative process. I spent about 20 hours manually adjusting everything to look as pretty as possible! But don't worry, #fallout is here to guide you! This is a normal process and you are not alone.
I recommend not following the above 1:1; this was my process, and it will differ greatly from yours!
I also recommend checking my Onshape for inspiration! Check my feature tree and see my iterations yourself.
Enjoy making :D!