Moving an IoT design from a breadboard full of jumper wires to a reliable printed circuit board is where most hobby projects either become products or stall out. I have taken a dozen sensor nodes and low-power controllers through KiCad from the first schematic symbol to fabricated boards, and the process is far more predictable than it first looks. This article walks through the complete KiCad workflow I use for simple two- and four-layer IoT boards — setting up the project correctly, drawing a schematic that actually passes electrical checks, assigning footprints that match the parts you can buy, laying out the board for stable power and radio performance, and exporting manufacturing files that a fabricator can build without questions. If you are comfortable with basic electronics but have never shipped a board, this is the path from schematic to board layout in KiCad 7 and 8.
Structuring Your KiCad Project for Reusable IoT Hardware
In my experience, the mistakes that cost a board spin rarely happen during routing. They happen in the first ten minutes when the project is created with default settings, wrong units, and no library discipline. KiCad creates a project folder with a .kicad_pro, .kicad_sch, and .kicad_pcb file, but how you organize libraries and grid settings determines how clean the rest of the work will be.
Project Files You Should Version Control
For any pcb design that will be iterated, I track the entire project directory in Git, including the schematic, PCB file, symbol libraries, and footprint libraries. KiCad 7+ stores symbol and footprint libraries as folders (.kicad_sym and .pretty), which makes them easy to bundle with the project. I keep a libs/ folder inside the project and point KiCad to it via Preferences > Manage Symbol/Footprint Libraries > Project Specific Libraries. That way, when you clone the repo on another machine, the exact SOT-23 or QFN you used is still there. I also commit the fp-lib-table and sym-lib-table files so collaborators do not have to remap libraries manually.
I set units to millimeters and keep them there. Even if you think in mils for trace width, most component datasheets, enclosure drawings, and fab houses work in mm. Switching units mid-layout is a classic source of courtyard and keepout errors. In Board Setup, I define a 0.05 mm grid for fine-pitch placement and a 0.25 mm routing grid for general work. A coarse grid forces you to make better placement decisions early instead of nudging parts by 0.01 mm later to make traces fit.
Defining Net Classes and Board Constraints Up Front
Before drawing a single wire, I open Board Setup > Design Rules > Net Classes and define the minimum constraints my fabricator can reliably do at low cost. For a typical 2-layer IoT board built on JLCPCB or PCBWay standard stackup, that is 0.15 mm trace/space and 0.3 mm drill. I create net classes for power (wider traces), signal (default), and if the board has a radio, an RF class with controlled width.
# Example net class definitions I set in Board Setup for a 2-layer IoT sensor node
# Units: mm
NetClass: Default
clearance: 0.15
trace_width: 0.20
via_diameter: 0.60
via_drill: 0.30
NetClass: Power_3V3
clearance: 0.20
trace_width: 0.40 # handles ~800mA with 1oz copper and 10C rise
NetClass: RF_Antenna
clearance: 0.20
trace_width: 0.45 # ~50 ohm microstrip on 1.6mm FR4, adjust per stackup
Defining these early means KiCad will flag a 0.12 mm trace meant for a low-cost fab before you route 50 of them. I've found that spending 15 minutes here saves hours of DRC cleanup later.
Drafting an IoT Schematic That Passes ERC in KiCad
A good schematic for kicad is not just a wiring diagram. It is a readable document that the ERC (Electrical Rules Check) can validate and that maps cleanly to the board layout stage. For IoT hardware, that usually means an MCU, a regulator, a radio or sensor section, and connectors — all of which need consistent power symbols and net labeling.
Placing the MCU, Decoupling and Clocking Correctly
I start with the microcontroller at the center of the sheet, with power pins facing up and I/O facing outward. Every power pin gets a 100 nF decoupling capacitor as close as possible in the schematic, even if placement on the PCB will be optimized later. The schematic should show intent. For an STM32, nRF52, or ESP32-C3, I place the decoupling caps directly adjacent to the VDD/VSS symbols and add a bulk 4.7 uF to 10 uF on the 3.3V rail. I also include the reset circuit, SWD/JTAG header, and a 32.768 kHz crystal if the firmware needs low-power sleep timing. The Zephyr Project Documentation has excellent reference schematics for nRF and STM32 boards that show how decoupling and reset are handled for low-power operation.
For the crystal, keep the load capacitor values explicit. If the datasheet specifies 12 pF load and your crystal is specified at 8 pF, you will need the math in a comment on the schematic so the next person understands the 15 pF caps you chose. I add text notes directly on the schematic — KiCad does not fabricate your comments, but it documents your decisions.
Using Power Symbols, Net Labels and Hierarchical Sheets Without False Errors
IoT schematics get noisy quickly. I use hierarchical sheets to separate functions: one sheet for power, one for MCU, one for sensors/radio. Power nets use global power symbols (+3V3, GND) instead of wires snaked across sheets. Signal nets that cross sheets get net labels or hierarchical labels, not just wires that look connected on screen.
The most common ERC failure for beginners is the "Power pin not driven" error. KiCad's ERC is strict: a power input pin must be driven by a power output. A regulator output or battery connector needs a PWR_FLAG symbol to tell ERC that the net is powered. I place a PWR_FLAG on +3V3 and GND near the regulator output. I also use "No Connect" flags (the X) on unused MCU pins rather than leaving them floating, which otherwise creates ERC warnings that hide real errors.
(rule "RF_keepout_no_copper_under_antenna"
(condition "A.Net == 'RF_ANT'")
(constraint keepout (type copper))
(layer "F.Cu")
(area (polygon (pts (xy 45 10) (xy 55 10) (xy 55 25) (xy 45 25))))
)
# Net tie for star-grounding analog and digital ground at one point
# Use Net Tie symbol between AGND and DGND, then route single connection on PCB
This type of custom rule, added via Board Setup > Design Rules > Custom Rules, lets you enforce RF and analog isolation directly in the design. If you are integrating a trace antenna, following the keepout and ground clearance guidance in PCB Antenna Design for IoT: Trace Antennas, Matching Networks and Layout Rules will keep your tuning iterations to a minimum.
Assigning Footprints and Closing the Symbol-to-Package Workflow
The schematic is logical; the footprint is physical. The bridge between them is Tools > Assign Footprints, and this is where many first boards fail because a beautiful schematic maps to a footprint you cannot solder or buy.
My workflow is: 1) Use only symbols that have a fully specified footprint field or are from my project library, 2) Assign footprints immediately after ERC passes, and 3) Check every footprint against the actual LCSC, Digi-Key, or Mouser part you intend to order. In KiCad's footprint chooser, filter by package and pin count, then double-click to preview courtyard, silk, and pad size.
For low-power IoT boards, package choice affects assembly yield and debugging. I avoid BGA and 0.4 mm pitch QFN for first prototypes unless there is no alternative. QFP, QFN-32 with exposed pad, and SOP are far more forgiving for hand soldering and inspection.
| Component Type | Beginner-Friendly Footprint | Typical Use in IoT Board | Assembly Note |
|---|---|---|---|
| MCU (32-pin) | QFP-32 7x7mm, 0.8mm pitch | nRF52832, STM32G0, ESP32-C3 | Hand-solderable, visible leads for inspection |
| Regulator / LDO | SOT-23-5 or SOP-8-EP | 3.3V buck or LDO for sensor rail | Provide copper pour on VIN/VOUT for heat |
| Passives | 0603 or 0402 (not 0201) | Decoupling, pull-ups, matching | 0603 is ideal for hand rework; 0402 for density |
| Radio / Module | Castellated module footprint | LoRa, Wi-Fi, BLE modules | Keep ground cutout and antenna keepout per datasheet |
| Connector | Pin header 2.54mm / JST-SH 1.0mm | SWD, UART, battery | Use through-hole for mechanical strength |
After assignment, I run Tools > Update PCB from Schematic with "Re-link footprints to schematic symbols" enabled. I also open the 3D viewer (Alt+3) to verify that connectors and tall electrolytics do not collide with the enclosure. I've found that catching a USB-C connector that interferes with a housing wall in 3D is far cheaper than reprinting an enclosure.
For power sections, footprint planning ties directly to electrical performance. The copper area around an LDO or buck converter determines thermal behavior, and the choice of inductor footprint defines your DC resistance. If you are still deciding between topologies, the guidance in Power Supply Design for Embedded Systems: LDO, Buck Converter and Battery Management helped me avoid undersizing input capacitance on a battery-powered node that would brown out during radio TX bursts.
Translating the Schematic into a Physically Routable IoT Board Layout
Board layout is the translation of the schematic into copper, and for IoT devices the priorities are stable power, a solid ground reference, and a predictable RF environment. Aesthetically pleasing routing matters less than a continuous ground plane and short return paths.
Stackup Decisions for Cost-Sensitive 2-Layer Designs
Most first IoT boards should be 2-layer, 1.6 mm FR4, 1 oz copper. It is cheap, widely available, and sufficient for frequencies below ~100 MHz if you are careful with ground. I reserve 4-layer for designs with high-speed interfaces (USB HS, SDIO) or where I need a dedicated power plane to reduce noise for an ADC or RF front end. In KiCad's Board Setup > Board Stackup, define dielectric thickness (1.5 mm core for 1.6 mm board) and copper thickness so impedance calculations are meaningful.
On 2-layer, I treat the bottom layer as a near-continuous ground plane and route most signals on top. I do not route long traces on the ground layer unless absolutely necessary, and when I must, I keep them short and stitch the ground back together with vias on both sides. I pour ground on both layers and stitch with vias every 10-15 mm, more densely around the MCU crystal and radio section.
Placement Flow: Power, MCU, Radio, Then Everything Else
My placement order is deliberate. First, place mounting holes and board outline, including keepouts for enclosures. Second, place the power input, regulator, and bulk capacitors so the 3.3V path is short and the inductor/capacitor loop is tight. Third, place the MCU and its decoupling caps so each cap is within 2-3 mm of its power pin. Fourth, place the radio/antenna section according to its datasheet keepout — never place the antenna over ground pour. Only then do I place sensors, LEDs, and connectors where they make sense for the enclosure.
I lock critical footprints after placement (right-click > Lock) to avoid accidental moves during routing. I also set the grid to 0.1 mm for placement of small passives and use the "Pack and Move" footprint mode to keep relative positions while dragging a group of decoupling caps.
Hand Routing Priorities for IoT Peripherals
I route power and ground first, then crystals, then sensitive analog traces, then high-speed digital, and finally everything else. For a 2-layer IoT board, 0.2-0.25 mm traces are fine for signals, 0.4-0.6 mm for 3.3V distribution, and 0.8-1.0 mm for battery inputs that may carry 1-2A peaks during TX. I use 0.6 mm/0.3 mm vias for signals and 0.8 mm/0.4 mm for power.
For the 32.768 kHz crystal, keep traces short, symmetric, under 5 mm, with ground pour isolated by 0.5 mm clearance and no other signals crossing beneath it. For I2C and SPI to sensors, I keep stubs short and avoid 90-degree bends (use two 45-degree bends). If you have high-speed signals like USB or SDIO, you will want to plan impedance and length matching early — the approach described in Signal Integrity for High-Speed PCB: Impedance Control, Crosstalk and EMI scales down well even to 2-layer IoT boards if you adapt trace width to your stackup.
# KiCad PCB scripting example: list all through-hole components for assembly check
# Run via Tools > Scripting Console in pcbnew
import pcbnew
board = pcbnew.GetBoard()
for fp in board.GetFootprints():
pads = fp.Pads()
is_th = any(p.GetAttribute() == pcbnew.PAD_ATTRIB_PTH for p in pads)
if is_th:
print(f"{fp.GetReference()} : {fp.GetFPIDAsString()} at {fp.GetPosition()}")
# Export netlist with length for I2C matching review
# pcbnew > Inspect > Length Tuner will highlight SDA/SCL parity
This snippet is a quick way to audit which parts will need hand soldering versus reflow, which matters for your assembly plan. I use it to verify that I have not accidentally placed a through-hole header where a low-profile SMD connector was intended.
Validating with DRC, Exporting Gerbers and Closing the Loop to Fabrication
A board that looks routed is not necessarily a board that can be built. Validation in KiCad is two-stage: ERC on the schematic and DRC on the PCB. Both must be clean before you generate fabrication outputs.
Electrical and Design Rule Checks That Catch Real Mistakes
After routing, I run DRC (Inspect > Design Rules Checker) with "Test for parity between PCB and schematic" enabled. DRC will catch copper-to-edge clearance violations, unconnected nets left as airwires, annular ring violations, and solder mask slivers. I pay special attention to courtyard overlaps — parts that overlap courtyards may be technically routable but will be impossible to rework. I also run ERC again after any last-minute schematic change; it is easy to rename a net on the PCB and forget to update the schematic.
I enable "Show clearance boundaries" during final review and visually scan the RF and power sections. For IoT boards with sleep currents under 10 uA, leakage from flux residue or a tiny solder bridge between 3.3V and an enable pin can dominate battery life. DRC will not catch contamination, but a 0.2 mm clearance rule instead of a 0.15 mm rule gives you margin against manufacturing variation at low cost.
Gerber, Drill and Assembly Files Fabricators Expect
KiCad 7+ can output Gerbers, Excellon drill, and a ZIP package directly via File > Fabrication Outputs > Gerbers. The set I always generate is: F.Cu, B.Cu, F.Paste, B.Paste, F.SilkS, B.SilkS, F.Mask, B.Mask, and Edge.Cuts, plus the drill files (PTH and NPTH separate if the fab requests it). I also export the IPC-2581 or ODB++ if the assembler supports it, plus a CSV BOM (File > Fabrication Outputs > BOM) and pick-and-place CSV (File > Fabrication Outputs > Component Placement).
Before sending the ZIP, I open the Gerbers in KiCad's Gerber Viewer or in an external viewer like Gerbv to confirm the board outline is continuous, the drill hits are centered on pads, and the paste openings match the footprint pads. One common beginner error is missing the Edge.Cuts layer, which results in a fabricator asking for board dimensions. Another is including extra user layers in the Gerber export that confuse CAM software.
For assembly, clear silkscreen matters. I keep reference designators readable (0.8 mm height), place pin 1 markers unambiguously, and add polarity marks for electrolytics and diodes outside the courtyard. If you plan to have the board assembled, review your paste and placement against Design for Manufacturing: PCB Rules That Reduce Assembly Defects — especially the guidance on thermal relief, solder mask expansion, and component orientation for reflow.
The final step before ordering is a peer review: print the board 1:1 on paper, place actual components on it, and check that headers clear the enclosure and that test points are accessible with a probe. I have caught reversed JST connectors and missing keepouts this way that DRC never would. Once that passes, I zip Gerbers, drill, and assembly files together with a README noting stackup, copper weight, and any impedance requests, and send it for a 5-board prototype run.
Frequently Asked Questions
Do I need a 4-layer board for a typical low-power IoT sensor node?
No, in most cases a well-laid 2-layer board with a solid ground pour is sufficient for MCUs running at 48-64 MHz, I2C/SPI sensors, and sub-GHz or 2.4 GHz radios using pre-certified modules. I move to 4-layer when I need USB High-Speed, an SD card at 50 MHz, or when analog sensor noise requires a dedicated ground plane. For a first design, 2-layer keeps cost low and forces disciplined grounding.
Why does KiCad ERC report "Power pin not driven" after I connect a battery?
ERC requires a power output to drive power input pins. A battery symbol or connector is often defined as passive, not power output. Place a PWR_FLAG symbol on the +VBAT and GND nets near the connector, or use a regulator whose output pin is defined as power output. This satisfies ERC without changing the physical circuit, and it avoids masking a real floating power net.
What trace width should I use for 3.3V power on a 1 oz copper IoT board?
For sensor nodes drawing under 500 mA average, 0.4-0.5 mm is a safe default for 3.3V distribution on 1 oz copper with modest temperature rise. For battery inputs that see 1-2A peaks during radio transmission, use 0.8-1.0 mm or pour a polygon and stitch with vias. Always verify with an IPC-2221 trace width calculator for your copper weight, allowable temperature rise, and whether the trace is internal or external.
Can KiCad automatically route my IoT board?
KiCad includes an assisted router but not a true high-quality autorouter for complex boards. In my experience, the interactive router with "Walk around" and "Shove" modes is excellent for hand routing, while external autorouters like Freerouting can finish simple, low-speed connections. For RF, crystal, and power nets I always route by hand — automated routing rarely respects keepouts, ground stitching, or antenna isolation correctly.