A few months ago we started a private PCB website so our team can get cheap PCBs from a fab in China. Someone spilled the beans, and it hit Hack a Day, Hacker News, etc. We almost shut it down, but it was too much fun to hack and refine the process. Dirty Tuesday is a weekly post about our misadventures accidentally starting a PCB service. As a design shop with Seeed Studio doing fulfillment, we’ve never been on this side of the fence and want to share the terrifying experience.
Gerber files are simple text files that describe how to draw a PCB. Most CAD programs export to this common format, and any manufacturer can load them and make exactly the same board. They’re a publishing format though, it’s tough (and usually inappropriate) to make changes to a gerber directly.
Detecting missing files
Boards are submitted to DirtyPCBs as a ZIP archive of gerber files (or a Eagle .brd file, more on that another week). The system, written in PHP, opens the temporary file upload without actually extracting anything. It scans through the file names and catalogs the extensions. Missing drill files (.txt) and board outline files (.gml) are common. We used to reject these orders, but it’s a hassle for people to enter all their info again. Now we accept payment and then give a notice about the problem, new files can be uploaded directly on the order status page. That’s a much friendlier process, while also ensuring we make the sale as quickly as possible.
Measuring the board
Next, we get the board size to see if it fits the ordered size. We pass a file handle pointing to the board outline file (.gml) inside the .zip to a PCB measurement function. Our original function used this very simple code from Wayne and Layne, it just looks for the longest line on the board by comparing all the X/Y coordinates in the outline file. This works on about 60% of boards, but fails if the board doesn’t use a fixed 2.4 leading zero suppression decimal notation. Eventually Jonathan Georgino contributed a more advanced function that reads the gerber opcodes for decimal notation and type of zero suppression, accurate on 98% of boards. The measurement class is available on Github here.
Boards too big for the ordered size are flagged and held for review before we send them to the board house. The board house also checks the size against the ordered size. We don’t reject boards based on the measured size because text outside the outline can mess it up pretty bad. So far every mis-sized order emailed to make full payment before we even noticed the hold.
Creating a PCB image from gerbers
DirtyPCBs started as a convenient way to get cheap boards to our team. We knew every PCB going through and who it belonged to. When it blew up we asked the board house to put stickers on the outside of each package with the PCB ID number. Aaron at Oomlout quipped sarcastically that the sticker innovation would certainly solve the problem in a new and refreshing way. He was right. The board house packing department randomly put stickers on anything of the same color. We had to replace dozens of orders. Later we acquiesced and let the PCB manufacturer put a small ID number on the silk screen, just like every other cheap PCB supplier.
We still occasionally have boards without a number, or with the wrong number. We also need a way to instantly check if a board is the right color before we send it out. We set out to imitate the online gerber viewer Gerblook. Export each layer of the PCB as an image using gerbv, apply color, and create a composite image. Easier said than done.
Anything outside the PCB, such as notes or overhanging headers, throws that layer out of alignment. Gerbv has command line options to specify the origin of the export area, DPI and window size, but most boards don’t have clean lower left corners that start at X=0 Y=0. Many PCBs even have negative coordinates for the placement of the lower left corner. Even the top right corner can be a negative coordinate!
This is a problem already solved by Gerblook, so we wrote to Hadley for help. His solution is as brilliant as it is simple. When exporting a layer, include every other layer with the color set to transparent. Each layer is exported with perfect alignment to every other layer because they’re all included every time. Sorted.
With all the individual layers in hand, it’s time to color them and create the composite image. Our PHP script uses GD for this:
- Get board background color from image pixel 0,0. Despite our best efforts this is not always what we tell gerbv to output
- Change the background color to transparent
- Replace all the red (or whatever is closest to red, grrrbv!) with our desired color. This could be silver (HASL) or gold (ENIG) for pads, white for drill holes, etc
- Soldermask takes a bit of extra work as we need to color the outline first and then subtract all the holes in the mask where the HASL or ENIG pads will be
- Composite the layers together: outline, copper, solder mask, copper again faded a bit, silkscreen, drill holes
Using the copper under and over the mask makes it pop, like seeing the traces under the solder mask on a real PCB. The only major limitation of this method, shared by Gerblook, is that holes inside the outline layer (panelized boards, etc) will be colored and not transparent. We toyed with a method of walking from the top center of the board until we find the outline, then apply a fill to the interior of the board. This has promise, but wasn’t worth perfecting at the time.
When you order a board at DirtyPCBs you get an email with the composite board image attached. The status page also shows the top and bottom views. Images are nice for the buyer’s reference, but crucial to our backend packing crew. They double check every board, and find mislabeled/wrong color boards before they’re mailed. It’s not perfect, but it helps us catch problems before they become a bigger hassle.
DirtyPCBs’ gerber file check, measurement, and image output PHP script is here. It won’t work on cheap shared hosting as you’ll need root access to install gerbv.
Gerblook mentions eventually going open source on their website – turns out it already is. We will definitely swap to Gerblook’s Python scripts if we update DirtyPCBs in the future.