Embedded HandbookApps
All sections › XXVI. From prototype to product
STM32F103 · level intermediate · 12 min read
Open in the interactive handbook

199. Board assembly at the factory: BOM, placement file and Gerber

The board is routed and checked (sections 130–135), the prototype works, and it is time to turn it into a product. The factory does two different things: it fabricates the bare board from the Gerber and drill files, and it assembles it — buys the parts from the bill of materials and places them by machine from the placement file. How to export these files from DipTrace is covered in 132в; this section is about something else: what each file contains, how the factory reads it and how to check the package before you send it, before the factory's questions turn into a week of e-mails.

The experiments use the board from section 131 (LQFP-48, 45×32 mm) in KiCad 9.0.9 from the kicad/kicad:9.0 image: exports and cross-checks are done by _verify/fab199/exports.sh with bom.py, the panel arithmetic by panel.py. Everything is checked by _verify/fab199_check.py.

Terms used in the documentation

Term Meaning
fiducial mark a copper circle the pick-and-place camera looks for
stencil a steel sheet with openings cut from the paste layer
turnkey turnkey assembly: the factory buys the parts
consigned assembly assembly from parts supplied by the customer
DNP, do not populate the part is in the design but is not placed
MSL, moisture sensitivity level how sensitive a package is to moisture before soldering
tab routing, mouse bites milling that leaves tabs with perforation
X-out a rejected board inside a panel
AOI, automated optical inspection automatic optical inspection of the solder joints

199.1 What the factory wants from you

The package is four files, and each one has its own reader at the factory:

File Who reads it What is in it
Gerber + drill board fabrication the geometry of every layer and hole
bill of materials (BOM) purchasing what to buy: values, packages, part numbers, alternates
placement file pick-and-place machine where each part sits: coordinates, rotation, side
assembly drawing engineer and inspection a view of the board with reference designators — the finished board is checked against it

If you order bare boards only, the first row is enough. For assembly you need all four — and the factory cuts the paste stencil itself from the paste layer of the same Gerber set.

The package for the factory: Gerber with drill files makes the board, the BOM is used to buy the parts, the placement file drives the machine, the assembly drawing is read by the engineer

The whole package goes out as one archive, and the archive name carries the board revision. The factory has no "e-mail context": it will assemble exactly what is in the archive, so half a package from a week-old e-mail plus half a package of "here is the new Gerber" is a sure way to a Frankenstein board.


199.2 Bill of materials (BOM)

The BOM is a table of "what to buy and where to place it". The minimum set of columns:

Column Example Why
reference designators C1 C2 C3 C4 C5 C6 link to the board and the placement file
quantity 6 purchasing counts by it
value and tolerance 100 nF ±10 %, 50 V, X7R "just 100 nF" can be rated 6.3 V
package 0603 (1608 metric) which tape the part comes in
manufacturer part number the exact variant, not the series the part is bought by it
alternates 1–2 equivalent part numbers otherwise assembly stops on a shortage

The CAD tool gives you the start of the BOM: board parts grouped by the pair "value + package". On the board from section 131 fifteen parts collapse into nine lines — six 0603 capacitors in one line, two 0805, and one line each for the microcontroller, the regulator, the crystal, the resistor, the LED and the two connectors (bom.py run):

строк перечня: 9, деталей: 15
деталей, у которых номинал пуст или повторяет имя корпуса: 15 из 15

The second line of the run is the main lesson. The board from section 131 was built by a script, nobody gave the parts values, and the value column ended up holding the package name: the BOM looks filled in, but there is nothing you can buy from it. The CAD tool knows exactly what you wrote into a part; value, tolerance and part number will not appear by themselves. Typical BOM mistakes:

Mistake What it leads to
value without voltage and tolerance purchasing takes the cheapest part
package "0603" without the unit system metric 0603 is imperial 0201
series part number instead of the exact variant a series has dozens of package and tape options
"do not place" parts not marked DNP they get bought and placed
no alternates one missing line stops the whole assembly

The imperial and metric package grids are easy to remember from the KiCad footprint names — they carry both: C_0603_1608Metric is imperial 0603, which is metric 1608.


199.3 Placement file (pick-and-place)

The placement file is a table for the machine: the centre of each part, its rotation and the board side. DipTrace exports it with File / Export / Pick and Place (132в.3), KiCad with the command:

kicad-cli pcb export pos --format csv --units mm -o out/pos.csv board.kicad_pcb

A few lines of the file for our board (the full file is in the exports.sh run):

Ref,Val,Package,PosX,PosY,Rot,Side
"C1","C_0603_1608Metric","C_0603_1608Metric",26.750000,-21.962500,90.000000,top
"C2","C_0603_1608Metric","C_0603_1608Metric",30.962500,-12.250000,0.000000,top
"C5","C_0603_1608Metric","C_0603_1608Metric",5.000000,-11.500000,90.000000,top
"U1","LQFP-48_7x7mm_P0.5mm","LQFP-48_7x7mm_P0.5mm",24.000000,-15.000000,0.000000,top

There are 15 lines in total — one per part, all with side top. What you should check by eye:

And one cross-check worth doing every time: the set of designators in the placement file equals the set of designators in the BOM. Ours are 15 and 15, they match (bom.py run). A part that is in one file and missing from the other is either a forgotten DNP or a line lost during an edit.


199.4 Gerber and drill files

What you hand over for a two-layer board: copper of both layers, solder mask and silkscreen on both sides, paste for the SMD side, the outline — and Excellon drill data as a separate file, not as holes in the Gerber. For the board from section 131 that is eight Gerber files plus the drill file; which checkboxes matter during export and how the format reads line by line is covered in 132в.3 and 132в.5, so we will not repeat it.

Before sending, look at the output files in a third-party Gerber viewer — not in the CAD tool that wrote them: it will show you what you have already seen. What to look for:

The numbers between files must agree: on board 131 paste 74 = the number of SMD pads, mask 80 = 74 + 6 through-hole, 10 holes — as many as pins and vias (checked in 132в.5). This cross-check catches a broken export in a minute — before the factory, not after.


199.5 Fiducial marks and tooling rails

The machine places parts to hundredths of a millimetre, but the board reaches it with the accuracy of "put on the conveyor". The camera closes the gap: it looks for fiducial marks — circles of bare copper — and uses them to convert all coordinates of the placement file into coordinates of the real board.

A fiducial is a copper circle with a clear zone around it: no mask, silkscreen or nearby copper, otherwise the camera will not get enough contrast. Typical sizes are visible right in the standard KiCad library Fiducial.pretty (exports.sh run): copper from 0.5 to 1.5 mm, a mask opening at least twice the copper; a typical middle of the range is Fiducial_1mm_Mask2mm: a 1 mm circle in a 2 mm opening.

How many and where:

The board from section 131 has zero fiducials (bom.py run) — for factory assembly you must add them before ordering.

The conveyor holds the edge on two sides, and if parts sit right up to the edge, the board needs tooling rails — strips along the edge that are broken off after assembly. The typical width is 5 mm: the same, 0.2 inch, is what the DipTrace panelization example suggests (132в.2). The rails carry the panel fiducials and the tooling holes.


199.6 Panelization

Small boards are not assembled one at a time but as a panel — several copies on one blank with shared rails. You need a panel when the board is smaller than the conveyor handles comfortably, when parts sit right at the edge, or when there are many boards and machine time for each one separately is a waste.

A two-by-two panel of the board from section 131: tooling rails, three fiducial marks in the corners, a vertical V-score from edge to edge and a routed channel with tabs

Boards are separated in two ways:

The arithmetic of a 2×2 panel of our 45×32 mm board: the columns are separated by a V-score — boards butted together, the rows by a 2 mm routed channel, rails of 5 mm on all sides (panel.py run):

ширина: 5 + 45 + 0 + 45 + 5 = 100 мм
высота: 5 + 32 + 2 + 32 + 5 = 76 мм

A 100×76 mm blank carries four boards — and that is already a size the conveyor likes. How to build such a panel in DipTrace — Tools / Panelizing, 132в.2. One more word from the factory's vocabulary is left: X-out — a panel in which one of the boards is rejected and marked. Whether you accept such panels or require complete ones only is agreed when ordering: complete panels cost more.


199.7 What to order

Three ways to order, in order of rising price and falling hassle:

Option You supply The factory does
boards only Gerber + drill bare boards
boards + assembly from your parts the whole package and the parts themselves consigned: places what you sent
turnkey the whole package buys the parts and assembles

For a small batch, turnkey almost always wins on time: a week of e-mails about alternates is cheaper than a month of buying parts yourself. Customer-supplied parts make sense when the board has something hard to get that you have already bought.

How much to stock:

And about moisture: IC packages absorb it from the air, and during reflow soldering the water boils inside the package — the sensitivity level is called MSL. The practical conclusion for whoever supplies the parts: send ICs in unopened dry packs, and solder opened ones within their floor life or hand them to the factory for baking.


199.8 Checking the package before sending

A checklist — every line catches a real assembly stop:

  1. DRC, net connectivity and comparison with the schematic were run after the last edit (132в.1).
  2. The numbers between files agree: paste = SMD pads, mask = pads, holes are in the drill file, not in the Gerber (132в.5).
  3. The coordinate origin is the same for Gerber, drill and placement files (132в.3).
  4. The designator sets in the BOM and the placement file match — ours are 15 and 15.
  5. Every BOM line has: value with tolerance and voltage, package with the unit system, exact part number and alternates; DNP parts are marked.
  6. There are fiducials on the board or the panel; parts at the edge mean there are rails.
  7. The output files were viewed by eye in a third-party viewer: layers, outline, size, mirrored bottom silkscreen.
  8. Everything in one archive with the revision in its name; inside, a short note for the factory: number of layers, thickness, what to assemble, what is DNP.

Items 1–3 are done by the CAD tool, 4 by a ten-line script, 5–8 by your eyes. Half an hour on the list against a week of e-mails with the factory is a good trade.


199.9 Pitfalls

The factory stopped the assembly and sent a list of questions. The BOM was taken from the CAD tool "as is": the value repeats the package name — like all 15 parts of our board in the bom.py run. There is nothing to buy from such a BOM: values, part numbers and alternates are filled in by hand before sending.

0201 tape arrived instead of 0603. The package in the BOM was written as a number without the unit system: metric 0603 is imperial 0201. Write both, as in the name C_0603_1608Metric.

When checking the placement file, every Y has a minus, "parts are off the board". The Y axis of the file points up, not down as on a screen: C5 at (5; 11.5) became (5; −11.5). This is not an error — but it is worth checking one part against the Gerber.

Polarized parts are placed backwards. The zero rotation of your library does not match how the part sits in the tape. The machine does not care who is right — the factory checks disputed rotations against the assembly drawing, which is why the drawing goes into the package.

The machine rejected the board: no fiducials. The board from section 131 has zero — like most boards routed "for a prototype". Three global ones in the corners plus a local pair next to the LQFP — before ordering.

The panel was broken apart and the edge capacitors cracked. Ceramics do not tolerate bending: when the panel is snapped it bends, and small parts right at the break line crack. Do not place capacitors right next to the V-score, and orient them with their long side along the line.

The tape was ordered to the exact count and fell short. Loading the feeder eats the start of the tape, and an exact count turns into a shortage on the last board. Small parts always with a margin: +5 % or +10 pieces.


199.10 Summary


Next: section 200 "First power-on of a new board".

Open in the interactive handbook