Blueprint

Tamagotchi

A custom PCB-based Tamagotchi virtual pet built with the XIAO-ESP32-C6!

Created by Tanuki Tanuki ⚡🚀

Tier 4

4 views

0 followers

alexren alexren ⚡🚀 approved Tamagotchi ago

Tier approved: 4

Grant approved: $53.00

nice project :salute:

Tanuki Tanuki ⚡🚀 submitted Tamagotchi for review ago

Tanuki 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


Installing KiCad

Download KiCad from the official site: https://www.kicad.org/download/

  1. Go to the download page and select your operating system (Windows, macOS, or Linux).
  2. Download the latest stable release (KiCad 9.x).
  3. Run the installer and follow the on-screen instructions (the defaults are fine).
  4. When prompted, make sure to install the default libraries (they're selected by default).
  5. Launch KiCad and create a new project (File → New Project or Ctrl+N).
What are the default libraries? KiCad ships with a large set of schematic symbols, PCB footprints, and 3D models. These cover most common components (resistors, capacitors, connectors, etc.) so you don't have to create them from scratch. You'll still need to import specialty parts (like the XIAO or OLED), but the defaults cover the basics.

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:

Displaying external images is not supported. See original

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!

Footprint assignment

Now, press this and open the PCB viewer:

Open PCB viewer


Creating the PCB

The maximum size of your PCB should be 100mm²!

You should see something like this:

PCB editor

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:

Displaying external images is not supported. See original

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:

  1. Drew out the edge cuts layer.
  2. Converted the image into a DXF file using an image-to-DXF converter.
  3. Imported the DXF file into KiCad.
  4. Created a 100×100 mm box as a reference.
  5. Used the measuring tool to determine the correct scale.
  6. 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 | ![PCB layers](https://cdn.hackclub.com/019c545f-32f8-71b8-9b46-079aee118944/c2ec73f247fdb1f466903fc86d345fe0f4b47b6f_image.webp)

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!)
What are ratlines? Ratlines (also called "ratsnest lines") are the thin straight lines that show unrouted connections between pads. They indicate which pads need to be connected with copper traces. Your goal is to arrange components so these lines are as short as possible and don't cross each other, which makes routing much easier.

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:

Displaying external images is not supported. See original

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.

Important: Wires and pads of different colors (except golden) can't be connected together directly! You must use a via to the other side.

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.

Your routing is complete!

Displaying external images is not supported. See original

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.

Displaying external images is not supported. See original

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.

Displaying external images is not supported. See original

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.

Displaying external images is not supported. See original

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 courtyards

Once your PCB passes the DRC, it is finished!

In the PCB editor, click View → 3D Viewer to see your finished work!

Displaying external images is not supported. See original

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:

Displaying external images is not supported. See original

Here's my final schematic:

Displaying external images is not supported. See original

Here's my final PCB:

Displaying external images is not supported. See original

Displaying external images is not supported. See original

Displaying external images is not supported. See original


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
Why does this matter? If you connect a 5V signal to a 3.3V-only GPIO, you can permanently damage your microcontroller. Knowing your power topology tells you whether you need level shifters or if everything is safe at one voltage. In our case, everything runs at 3.3V, so no level shifting is needed.

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
How do I find the GPIO number from the schematic? Look at your MCU symbol in the schematic. Each pin has a label (like `D0`, `GPIO0`, `P0.01`, etc.). Follow the wire from a component (like a button) to the MCU, and read the label on the MCU pin where it connects. That label is the GPIO number you'll use in your code. You can also check the MCU's datasheet or pinout diagram to confirm.

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).

How do I know if my buzzer is active or passive? - **Active buzzer**: Has internal circuitry that generates a tone. You just turn it on/off with a digital signal. - **Passive buzzer**: Needs an external signal (square wave) to produce sound. You control the pitch by changing the frequency using `tone()`. Check the component listing on LCSC or the datasheet. If it says "electromagnetic" or "with oscillator," it's active. If it says "piezoelectric" with no oscillator, it's passive.

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)
How do I export Gerber files? 1. In your PCB editor: **File → Fabrication Outputs → Gerbers (.gbr)** 2. Set an output folder (e.g., a new "Gerbers" folder) 3. Select necessary layers (generally already selected) 4. Click **Plot** 5. Click **Generate Drill Files** 6. Zip the resulting files for your manufacturer Gerber files are the industry-standard format that PCB manufacturers use to fabricate your board. They contain the copper layers, silkscreen, solder mask, drill locations, and board outline.

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.

Displaying external images is not supported. See original

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:

Displaying external images is not supported. See original

For high-spec options, also keep the default. Do not click PCB assembly. We will give you a kit to hand-solder your board.

Displaying external images is not supported. See original

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).

Displaying external images is not supported. See original


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.

Displaying external images is not supported. See original

Displaying external images is not supported. See original

Displaying external images is not supported. See original

I also decided to change the PCB to add the vibration motor to the back and raise the screen!

From

Displaying external images is not supported. See original

to

Displaying external images is not supported. See original

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!

Displaying external images is not supported. See original

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!

Displaying external images is not supported. See original

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!

Displaying external images is not supported. See original

Displaying external images is not supported. See original

Finally, I used the section view tool to confirm that there is no overlapping:

Displaying external images is not supported. See original

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 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.

image

Tanuki 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

image

Tanuki 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.

AHHH HOMEOWRK ill finish laterimage

Tanuki 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.

AHHH HOMEOWRK ill finish laterimage

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

image

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.

image

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


Installing KiCad

Download KiCad from the official site: https://www.kicad.org/download/

  1. Go to the download page and select your operating system (Windows, macOS, or Linux).
  2. Download the latest stable release (KiCad 9.x).
  3. Run the installer and follow the on-screen instructions (the defaults are fine).
  4. When prompted, make sure to install the default libraries (they're selected by default).
  5. Launch KiCad and create a new project (File → New Project or Ctrl+N).
What are the default libraries? KiCad ships with a large set of schematic symbols, PCB footprints, and 3D models. These cover most common components (resistors, capacitors, connectors, etc.) so you don't have to create them from scratch. You'll still need to import specialty parts (like the XIAO or OLED), but the defaults cover the basics.

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:

Displaying external images is not supported. See original

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!

Footprint assignment

Now, press this and open the PCB viewer:

Open PCB viewer


Creating the PCB

The maximum size of your PCB should be 100mm²!

You should see something like this:

PCB editor

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:

Displaying external images is not supported. See original

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:

  1. Drew out the edge cuts layer.
  2. Converted the image into a DXF file using an image-to-DXF converter.
  3. Imported the DXF file into KiCad.
  4. Created a 100×100 mm box as a reference.
  5. Used the measuring tool to determine the correct scale.
  6. 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 | ![PCB layers](https://cdn.hackclub.com/019c545f-32f8-71b8-9b46-079aee118944/c2ec73f247fdb1f466903fc86d345fe0f4b47b6f_image.webp)

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!)
What are ratlines? Ratlines (also called "ratsnest lines") are the thin straight lines that show unrouted connections between pads. They indicate which pads need to be connected with copper traces. Your goal is to arrange components so these lines are as short as possible and don't cross each other, which makes routing much easier.

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:

Displaying external images is not supported. See original

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.

Important: Wires and pads of different colors (except golden) can't be connected together directly! You must use a via to the other side.

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.

Your routing is complete!

Displaying external images is not supported. See original

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.

Displaying external images is not supported. See original

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.

Displaying external images is not supported. See original

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.

Displaying external images is not supported. See original

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 courtyards

Once your PCB passes the DRC, it is finished!

In the PCB editor, click View → 3D Viewer to see your finished work!

Displaying external images is not supported. See original

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:

Displaying external images is not supported. See original

Here's my final schematic:

Displaying external images is not supported. See original

Here's my final PCB:

Displaying external images is not supported. See original

Displaying external images is not supported. See original

Displaying external images is not supported. See original


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
Why does this matter? If you connect a 5V signal to a 3.3V-only GPIO, you can permanently damage your microcontroller. Knowing your power topology tells you whether you need level shifters or if everything is safe at one voltage. In our case, everything runs at 3.3V, so no level shifting is needed.

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
How do I find the GPIO number from the schematic? Look at your MCU symbol in the schematic. Each pin has a label (like `D0`, `GPIO0`, `P0.01`, etc.). Follow the wire from a component (like a button) to the MCU, and read the label on the MCU pin where it connects. That label is the GPIO number you'll use in your code. You can also check the MCU's datasheet or pinout diagram to confirm.

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).

How do I know if my buzzer is active or passive? - **Active buzzer**: Has internal circuitry that generates a tone. You just turn it on/off with a digital signal. - **Passive buzzer**: Needs an external signal (square wave) to produce sound. You control the pitch by changing the frequency using `tone()`. Check the component listing on LCSC or the datasheet. If it says "electromagnetic" or "with oscillator," it's active. If it says "piezoelectric" with no oscillator, it's passive.

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)
How do I export Gerber files? 1. In your PCB editor: **File → Fabrication Outputs → Gerbers (.gbr)** 2. Set an output folder (e.g., a new "Gerbers" folder) 3. Select necessary layers (generally already selected) 4. Click **Plot** 5. Click **Generate Drill Files** 6. Zip the resulting files for your manufacturer Gerber files are the industry-standard format that PCB manufacturers use to fabricate your board. They contain the copper layers, silkscreen, solder mask, drill locations, and board outline.

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.

Displaying external images is not supported. See original

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:

Displaying external images is not supported. See original

For high-spec options, also keep the default. Do not click PCB assembly. We will give you a kit to hand-solder your board.

Displaying external images is not supported. See original

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).

Displaying external images is not supported. See original


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.

Displaying external images is not supported. See original

Displaying external images is not supported. See original

Displaying external images is not supported. See original

I also decided to change the PCB to add the vibration motor to the back and raise the screen!

From

Displaying external images is not supported. See original

to

Displaying external images is not supported. See original

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!

Displaying external images is not supported. See original

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!

Displaying external images is not supported. See original

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!

Displaying external images is not supported. See original

Displaying external images is not supported. See original

Finally, I used the section view tool to confirm that there is no overlapping:

Displaying external images is not supported. See original

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!