Circuit Board Project

This tutorial covers how to start using the unique features of FabEngine, namely integrating a manufacturing process consisting of multiple fabrication steps. We also introduce some minor variations to functions you have seen before in the 3D printing project tutorial.

The Code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# Because this script will use many modules of the FabEngine package
# we import all of FabEngine instead of specific modules.

import fabengine

# The PCB has to be manufactured before parts can be assembled onto
# it. FabEngine requires industry standard RS-274X Gerber files for
# circuit board fabrication. You need to upload these to your
# fabengine.com account before you can run this script.

fabricatedPCB = fabengine.fabrication.PrintedCircuitBoardFabrication(
    thickness = "0.62in",
    layerCount = 2,
    surfaceFinish = fabengine.fabrication.PrintedCircuitBoardFabrication.SufaceFinishes.TinLead,
    outlineFile = "mypcb.oln",
    copperTop = "mypcb.tsp",
    copperBottom = "mypcb.bsp",
    soldermaskTop = "mypcb.smt",
    soldermaskBottom = "mypcb.smb",
    silkscreenTop = "mypcb.slk",
    drill = "mypcb.drd")

# Next, define the electronics components to be put on the PCB.
# For illustration we'll write this in a long-winded in this
# tutorial. Remember that as long as it's valid Python you are
# free to express your intentions as you wish.

# For resistors we don't care a lot about the specific part as
# long as it meets our spec.

resistors = []

for i in range(4):
  resistors.append(
    fabengine.procurement.Electronics.GenericSurfaceMount.Resistor (
      resistance = 10e3, # 10kOhm
      tolerance = 0.05, # 5%
      footprint = "0603")) # this is an industry standard denomination for component footprint

resistors.append(
  fabengine.procurement.Electronics.GenericSurfaceMount.Resistor (
      resistance = 200e3,
      tolerance = 0.05,
      footprint = "0603")


# For the fuse we want a specific part number, because this is
# a safety critical component.

try:
  fuse = fabengine.procurement.Suppliers.Digikey.partNo ("F2960CT-ND")
except fabengine.ProcurementError, err:
  fuse = fabengine.procurement.Suppliers.Mouser.partNo("576-0157.500DRT")

if (fuse is None):
  raise fabengine.FabEngineException('The fuse is not available from either Digikey or Mouser!')

billOfMaterials = [
    {'name': 'R1', 'part': resistors[0]},
    {'name': 'R2', 'part': resistors[1]},
    {'name': 'R3', 'part': resistors[2]},
    {'name': 'R4', 'part': resistors[3]},
    {'name': 'R5', 'part': resistors[4]},
    {'name': 'FUSE', 'part': fuse}]

assembledPCB = fabengine.assembly.PrintedCircuitBoardAssembly (
  board = fabricatedPCB,
  bom = billOfMaterials,
  centroidsFile = "mypcb_centroids.csv")

# This product can be shipped in an envolope instead of a box

shippingEnvelope = fabengine.fulfillment.pack (
  contents = { assembledPCB },
  box = fabengine.fulfillment.packagingmaterials.PaddedEnvelope ("Letter"))

# This time we specify a custom return address

fabengine.Fulfillment.ship (
    content = shippingEnvelope,
    method = fabengine.fulfillment.shippingmethods.UPSSecondDayAir,

    address = fabengine.fulfillment.Address (
      name = "Chuck Norris",
      street = "1600 Pennsylvania Avenue",
      city = "Washington",
      state = "DC"
      postcode = "20500"),

    returnAdress = fabengine.fulfillment.Address (
      name = "Q",
      street = "85 Vauxhall Cross",
      city = "London",
      postcode = "SE1 1BD",
      country = "United Kingdom"))

The content of the Gerber files used in this example doesn’t really matter for following this tutorial, but you can look at them here<files/tutorial-getting-started-simple-circuit-board-project>_

Points of note

  • Many FabEngine functions are very flexible about the number of supplied arguments. Note how we didn’t specify a silkscreenBottom argument for the PrintedCircuitBoardFabrication function because our circuit board doesn’t require artwork on the bottom layer.
  • One variable represents one physical item, for example a resistor. You can only use it once. If you need four identical resistors, you’ll have to invoke fabengine.procurement.Electronics.GenericSurfaceMount.Resistor() four times.
  • You should always include a return address in your call to fabengine.fulfillment.ship(). There is an entire documentation page on accepting returns.

Concurrency

Did you notice that in the sample code above the Printed Circuit Board is fabricated in line 9, and component are purchased further down in the script? fabengine.com will execute these two processes in parallel because they do not depend on each other. Conversely, PrintedCircuitBoardAssembly depends on both the fabricated circuit board and the purchased components. At every function call, FabEngine will pause code execution of your script until all arguments are fully available.

For you this means that you don’t have to worry about optimizing the manufacturing work flow. FabEngine will always produce your products as fast as possible. This is also considered when you estimate production lead times in the FabEngine dashboard.

What if I don’t know how to make Gerber files?

FabEngine makes it easy for anyone with programming experience to describe the flow of goods through a manufacturing process, but each fabrication step still requires domain knowledge. Our goal is to grow the Library into a comprehensive source of knowledge for all fabrication processes FabEngine supports, but it will take months or even years until we achive this goal. If you want to learn how to design circuit boards before then, we suggest taking a look at this excellent video tutorial series and asking any questions on electronics.stackexchange.com.

What’s next?

Manufacturing an assembled printed circuit board is already a pretty complex manufacturing process and supply chain. But you probably noticed that there are very few products that consist of a printed circuit board only. In the third and final Getting Started tutorial we tackle a complete consumer product including electronics, mechanical parts, custom packaging, and even a user manual.

See how FabEngine is used to create a complete product »