Only this pageAll pages
Powered by GitBook
Couldn't generate the PDF for 145 pages, generation stopped at 100.
Extend with 50 more pages.
1 of 100

Hacker Fab Documentation

Loading...

Overview

Loading...

Loading...

Fab Capabilities May 2023

Guides

Loading...

Loading...

Loading...

Loading...

Processes

Loading...

Fab Toolkit

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Plasma Etcher

HF Jig

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

SMU - Keithley 4200SCS

Loading...

Spectrometer

Profilometer

Loading...

Loading...

Photoresists

Dielectrics

Spin on Glass

Conductors

Loading...

Etchants

Hydrofluoric Acid

Aluminum Etchant (Nitric, Acetic, Phosphoric Acids)

Dopant Sources

Loading...

Loading...

Gantry

Gripper

Liquid Handling

Tube Furnace (automated)

Wafer Cleaver

Submodules

Loading...

Interferometer

Loading...

Loading...

Steps and Processes

Streamlining steps and processes in the database

Standard Operating Procedures

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

WORKING DOCS

Loading...

Loading...

Loading...

Loading...

Loading...

Current Fab Capabilities

Last Updated April 2024

Hacker Fab Documentation

the first open-source semiconductor fab.

intro.

Our Goals:

  1. Make integrated circuit prototyping as fast as 3D printing

  2. Make DIY version of every nanofabrication tool

  3. Get there with collaborative open source hardware

Right now we use factories and tools that are optimized to manufacture at scale to do our integrated circuit prototyping. There does not exist a set of machines that enable rapid tape-out of semiconductor devices on a budget, nor are there sufficient resources to make/modify fab tools from the ground up.

The use of low-cost, abundant, and fast-turn-around hardware serves a larger purpose than making the fab cheaper. These design constraints are what enable others to recreate, modify, and contribute to our work. The simpler the better.

Number of People Who Have Made a Transistor by Hand in a Hacker Fab

75

Number of Hacker Fabs

3 (+1 in progress)


working on the hacker fab.

You don't need prior nanofabrication experience to create meaningful contributions.


this website.

This page is a home for all shared documentation. There are enough resources here to turn an empty room into one that fabricates simple IC's in a matter of months.

Many pages are works-in-progress. It is natural for individual contributors' work-in-progress notes to exist on google drive, notion, etc. Links to these exist at the top of each page, however these notes move to Gitbook as soon as possible.

Any contributor can submit change requests with a free Gitbook account. All of this is on Github, but formatted nicely here on Gitbook. You can contribute directly through Github as well.


fab toolkit.

Here is a list of all the tools built or bought necessary to make our devices.

Every build contains:

  • BOM

  • Links to Design Files

  • Links to Code

  • First Principles Understanding of Machine Design (WIP)

fabrication tools.

verification / metrology tools.

chemicals.


background and licensing.

The Hacker Fab was started by Elio Bourcart, Alexander Hakim, and Sam Zeloof.

The Hacker Fab is run entirely by independent contributors.

Hardware: CERN-OHL-W

For example, if you release HDL files under CERN-OHL-W and then somebody uses those files in their FPGA, when they distribute the bitstream (either putting it online or shipping a product with it) they do not to make the rest of the HDL design available under CERN-OHL-W as well.

Software: MPL v2.0

The MPL’s “file-level” copyleft is designed to encourage contributors to share modifications they make to your code, while still allowing them to combine your code with code under other licenses (open or proprietary) with minimal restrictions.

Documentation: CC BY-SA 4.0

Fab Capabilities November 2023

Build-a-Fab

Link to General Lab Equipment BOM

BOM of each machine is included in separate build documents.

Part Sourcing

Strategies for sourcing parts effectively, and a constantly updated list of part suppliers

The Way we Source Parts

Use ChatGPT to Source Parts for You
  • With Bing feature, you ask "source ___ for me" and add other details:

    • "prioritize parts with low lead times"

    • "inexpensive" or "hobby level"

    • "i liked this one you found, find me more of those"

Find the Part on Amazon
  • Nothing is better than prime shipping

  • If you found a part on a manufacturer's website, look up that exact part

  • If you cannot find it, try searching for the manufacturer's amazon page

    • They normally have one

Avoid "Contact us for a Quote" at all times
  • We try our best to not support companies that do this. If you ever start a company in the future, put a "buy now" button please.

  • Long lead times, wasted time talking to someone, different prices if you are a university, company, individual, they try to package you in with expensive software, etc.

If you don't know which part to buy, use ChatGPT
  • "what else are these parts called? anything else I could use instead"

  • "I am trying to find a part that does X, Y, and Z, but I don't know what its called"

  • "I am trying to attach ___ to ____, what can i use?"

As a last resort, you can contact manufacturers

Some teams, such as Thorlabs, Kurt Lesker, Filmtronics, are very knowledgable and can help bridge the gap of understanding. You can describe to them your situation, send them links of the parts you were considering, and ask them for their advice. Do this sooner rather than later - they take multiple days to respond.

Organized List of Sellers

Nanofabrication is often communicated as complex , where every machine is immutable. We believe that innovation in the industry requires a thorough understanding of these machines from first principles, which will lead us to simpler solutions. Even on machines and processes of magnitudes less complexity than modern industry, there are designs worth sharing.

You do need to read the .

You don't need to recreate the entire fab to contribute, .

We communicate entirely over .

For the most up-to-date status on everything, join the .

The Hacker Fab was inspired by .

The first Hacker Fab was opened at .

This license enables reusers to distribute, remix, adapt, and build upon the material in any medium or format, so long as attribution is given to the creator. The license allows for commercial use. If you remix, adapt, or build upon the material, you must license the modified material under identical terms.

We like making hardware, fast

To do, for now search our

Device Type

NMOS

Gate:

2μm

# of Transistors:

UPDATE

Photoresists + Developers

Dielectrics

Conductors

Etchants

Dopant Sources

Device Type

NMOS

Gate:

10μm

# of Transistors:

15

discord.

github.

x.

magic
Required Reading
although you can
Discord
Discord
Sam Zeloof
Carnegie Mellon University
https://ohwr.org/project/cernohl/wikis/faq#q-what-are-all-these-suffixes
https://ohwr.org/cern_ohl_w_v2.pdf
https://www.mozilla.org/en-US/MPL/2.0/
https://www.mozilla.org/en-US/MPL/2.0/FAQ/
https://creativecommons.org/licenses/by-sa/4.0/
https://creativecommons.org/share-your-work/cclicenses/

Required Reading (todo)

The goal function of the Hacker Fab is to never debug the same thing twice.

We operate under different constraints from the semiconductor fab industry. This allows us to curb a lot of complexity.

Goals:

  1. Low cost

  2. Create the simplest designs possible

    1. Increase reliability

    2. Reduce manufacturing complexity

  3. Minimal danger

  4. Small size

  5. No cleanroom

  6. Highly sourcable materials

  7. High literacy in understanding working principles of tools and processes

  8. End-to-end custom - from sand to NAND

    1. Make the wafers

    2. Design the tools

    3. Design the processes

    4. Design the IC

    5. Package the chip

Non-Goals:

  1. Reuse of existing fab equipment

The 1970s vs. Now

On Open-Source Hardware

Who we are looking for, how we grow, how to get support

Design Constraints

On Improvement

Central to the Hacker Fab is fast turnaround hardware development - it’s in the name. This means extremely fast hardware prototyping, and with that comes the need for iteration. The careful design constraints placed on all projects and focus on documentation enables someone else to iterate on anything developed in the Hacker Fab. Improvement to a V1, V2, Vn of a design means

  1. Directly improving upon a tool’s functionality

    1. Precision

    2. Reliability

    3. Throughput

    4. New features

    5. Safety

But there are other equally important ways to improve a design. Every tool version should try to be:

  1. Easier to manufacture than the last

    1. Reduce number of tools required to manufacture

    2. Reduce # of vendors, lead time, BOM length

  2. Better documented than the last

    1. Tool specs as close to first principles as possible

    2. Every tool spec should have a standardized test for others to verify performance

    3. Explain working principles to the detail of variables we can control (no more, no less). Referenced sources.

  3. More “closed-loop” than the last

    1. In-situ sensors

    2. Calibration software should be more generalizable (“now you can use any camera…any piezo with draw distance in range X to Y…”)

On Cleanliness

On Process Node

On Education

Where to Start

KEM-497AAA Pin Out Analysis

TBD

🏃‍♀️
🏃‍♂️
Purchase Tracker

Software

Introduction

The SW needed for this project can be broken down into the following subsections.

Pattern Capture

KLayout

OpenROAD

CAM Translator

Computer-Aided Manufacturing software translates a 3D design into G-code instructions that a CNC machine (in this case laser burner) can understand, essentially "slicing" the design into smaller, machinable steps.

This SW takes a file with the desired mask (Pattern Capture Output) as an input and translates it into a set of machine instructions.

Burner Firmware

This software runs on the micro-controller that drives all the HW. It is responsible for taking sensor inputs and driving all output motors and lasers. This device also has an interface which can transmit all the data to/from the user.

Device Driver

This software is responsible for general control of the laser burner from the PC side.

Graphical User Interface

This SW is responsible for the user facing interface which gives the user full control of the burner.

Self-Aligned NMOS V1

Simplified View of Process

See Fabublox for Interactive View

Alternatively: See Google Sheets for Comprehensive Example with all Parameter Values (Chip 336 Shown Below)

Patterning

Goals of this page:

  • Not to try and cover theory or industry standard, but to break the problem into first principles just enough to give context to the quantifiable parameters

  • Also an opportunity to frame the problem wide enough to set the tone of thinking of these machines from the ground up (aligned with goal, don't think of industry as immutable)

  • Exhaustive list of industry methods and examples

  • Quantifiable end user parameters with descriptions + standardized tests


Background

Overview

A photolithography stepper is a machine that exposes a pattern of light onto a layer of photoresist chemical on the wafer, then ‘steps’ over to the next pattern. Before each exposure, it must align with previous patterns on the wafer so that each layer of the device is in the correct position relative to the previous. The accuracy with which it can do this is called “alignment accuracy”. Alignment accuracy and optical resolution are the two most important metrics of a stepper’s performance.

There are 2 main components of our stepper: the light source and optics, and then the mechanical micropositioning stage that moves the chip itself. Alignment accuracy is a function of both the mechanical micropositioning stage and the reliability of the projector’s optomechanical components.

Masked vs. Maskless Lithography Systems

Commercial lithography machines use photomasks to create the image, typically made of chrome on glass. Instead, our Maskless Photolithography Stepper uses a DLP projector to create a pattern. This allows us to change patterns instantly, opening the option up for advanced techniques like tiling (making a circuit larger than one exposure field).

Quantifiable Parameters

Functional Specifications: The End Product

Developed Resolution

describe out standardized test: darkfield/brightfield, developed with AZ400K for 80s, measured pitch distance, used airforce test pattern

Value:

Tools Required for Verification:

Method of Verification:

References: pics/videos

Automation Capabilities / Throughput

what human actions are required: manual loading/unloading, choose the pattern, align manually or automatically with software

approximate area exposed per second

how much time to do one exposure, how much of that is active work vs. waiting around

Patterning Machine Specifications:

Optical Resolution

Tools Required for Verification: Microscope + Calibrated Camera to convert pixels to μm

Method of Verification: make another page for optical resolution test?

Possible Variation: misalignment of optics during assembly

References: pics/

Developed Resolution

Tools Required for Verification:

Method of Verification:

References: pics/videos

Single Exposure Area

Approximate Exposure Time (for AZ P4210 photoresist)

Tools Required for Verification: AZ400K Developer Solution + Microscope

Method of Verification:

Possible Variation: Can vary UV LED power and beam splitter ratio to decrease/increase exposure time

References: pics/videos

Mechanical Resolution - Step Size

Mechanical Resolution - Repeatability

Maximum Wafer Size

Lithography Stepper V2.1

  • Rotate the optics so that the objective points downward instead of sideways

    • This allows using the much-improved X and Y axes of the stage, instead of X and Z, which permits higher movement resolution and repeatability

    • This also means that we no longer need the vacuum chuck, which means reduced vibration (and less complexity)

    • Unlike Stepper V1, which was cantilevered, V2.1 is supported on all sides by rigid optical mounting posts, which should avoid V1's vibration issues

  • Mount the optics and projector much more rigidly, using a plate offset by posts to secure the optics directly, rather than relying on the projector's case and rubber feet

    • This further reduces relative vibrations between the optics and stage

    • This also makes the DLP DMD plane and the chip plane more parallel == more consistent focus both across a single exposure and between exposures

    • This also decouples the structure of the stepper from the mechanical design of the projector (as Stepper V2 relies on the actual shape of the projector to work) which will allow us to change to a different projector in the future

  • Switch from a FLIR Blackfly camera to a Basler Ace camera, and reduce the sensor size from 1" to 1/1.2"

    • Not only is the Basler less expensive for an equivalent sensor, it also has a much, much nicer software suite that is distributable (a particular pain point with FLIR's)

    • Smaller sensor size means we're paying for less unused sensor (since any sensor area outside of the size of the projector's DMD is not used)

As a whole, these changes should improve the results we get out of Stepper V2.1 compared to Stepper V2, and the mechanical changes will set the stage for further patterning capabilities such as reliable automatic alignment. Furthermore, the decoupling of the projector from the rest of the design will in the future allow us to use different projector for further improvements.

Specifications

Spec
Value

Cost

$3,012.13

Build Time

6 hours

Optical Resolution

1 µm

Vibration susceptibility

1.2 µm (when built onto optical table)

Reticle (Exposure) Dimensions

1.04mm by 0.58mm

Exposure Time

8 seconds

Mechanical Step Size

1.5 µm

Maximum Wafer Size

1 cm x 1 cm

Size

20 cm x 20 cm x 50 cm

These remaining specs are from Stepper V2's documentation and have not been verified. The optical performance of both systems should be the same.

Spec
Value

Developed Resolution

2 µm

Tiling Alignment Accuracy

5 µm

Overlay Alignment Accuracy

5 µm

Mechanical Repeatability

5 µm (to verify)

Bill of Materials

Total cost as currently specified: $3,012.13

Name
Quantity
Total
Link

TI DLP Evaluation Module

1

$1328.63

Assorted optics and optomechanics

1

$772.89

10X Din Plan Objective

1

$159.00

Basler ace U acA1920-40uc

1

$609

USB Type A to Micro B locking cable

1

$3.99

19V 4.74A Projector Power Supply

1

$17.99

XYZ Stage 40mm

1

$125

NEMA 28 Steppers

3

$53.97

Arduino Uno (Elegoo)

1

$16.99

CNC Shield for Arduino V3.0

1

$10.99

Stepper Motor Drivers

1

$22.99

Shield Power Supply 12V

2

$23.98

M2.5 Screw Assortment

1

$16.99

410nm Lumiled LED

4

$27.96

Pico-spox 10pos Vertical Connector

2

$1.86

Proximity sensors (4 pack)

1

$19.90

(Not included in BOM: misc. bolts)

Design Files

Several parts from Stepper V2's CAD are used on 2.1:

Build Instructions

Tools required

  • 3D Printer

  • SMD soldering tools (solder paste, reflow oven, tweezers)

  • Calipers

  • Metric and imperial allen wrench sets

Fabricate the mechanical parts

There are several mechanical parts that will need to be fabricated:

  • for builds that are not making use of an existing optical table: bottom plate. laser cut or machined, 1 inch grid of ¼ inch holes at least 6x6 inches

UV LED PCB Assembly

Projector Modification

These steps are heavily based on the steps done for V2, but some have changed.

  1. Test the projector before we completely take it apart :)

  1. Unplug all the connectors and remove the top PCB by unscrewing the standoffs.

  1. Remove the side PCB.

  1. Unscrew and remove the shroud by sliding it away from the rest of the optics.

  1. NEW FOR 2.1: Remove the bolts and standoffs that hold the main projector assembly to the bottom plate. This should free the bottom assembly.

  1. Unscrew and remove the heatsink for the front-most LED, which should be the blue one.

  1. Disconnect the LED PCB from the cable. Heat it slightly on a hot plate or with a hot air gun to soften the adhesive and remove the black plastic housing.

  2. Glue the black plastic piece to the DIY UV LED PCB, connect it to the blue cable, and reattach it to the optics housing. Put the heatsink back as well.

  1. Unscrew the projection lens. That one makes things bigger, but we're trying to make things smaller. It's got to go.

  1. Screw on the adapter plate with four countersunk M2 screws.

  1. Use four M2.5 screws to screw on the Thorlabs SM1A53 adapter flange

  2. NEW FOR 2.1: Do not reassemble the projector case - we will use it as-is.

Optics + Mechanics Assembly

These steps are heavily based on the same steps for V2, but slightly modified.

  1. Start with the beamsplitter cube. Unscrew the set screws, remove the holder, and clip in the beamsplitter. The text ("Thorlabs") should be facing the microscope objective and camera when the holder is reinserted. Keep track of this during assembly and fix it later if necessary.

  1. Assemble the DLP tube. From left to right, the parts in the first picture are 0.3" lens tube (SM1L03), 0.5" lens tube coupler (SM1CPL05), 0.5" adjustable lens tube (SM1V05), and 0.5" lens tube (SM1L05). You may want to remove any internal lens rings. The adjustable lens tube allows axial length adjustment and the coupler allows rotation about the optical axis.

  1. Screw the DLP tube into the beamsplitter cube. The correct orientation is shown above, and the arrow points to the side of the beamsplitter with the text (and optical coating).

  2. Assemble the camera tube, which similarly constructed. The parts are 1" lens tube (SM1L10), 1" lens tube coupler (SM1CPL10), 1" adjustable lens tube (SM1V10), another 1" lens tube (SM1L10), and C-mount SM1 adapter (SM1A9) (last two shown below).

  1. Screw on the C-mount SM1 adapter (SM1A9) to the camera and the 1" lens tube. Adjust the lens tube coupler to align the camera with the beamsplitter cube.

  1. Assemble the objective tube, which consists of a 0.3" lens tube (SM1L03), an SM1 to RMS adapter (SM1A3), and the microscope objective.

  1. Use four #4-32 bolts to mount the beamsplitter cube to the top plate.

  1. Mount the top plate to either your optical table (if you have one) or the bottom plate. First, mount the posts to the bottom plate/table using four 1/4-20 bolts (if you're using a bottom plate) or four 1/4-20 grub screws (if you're using the table). Then, mount the top plate on top with four #8-32 bolts.

  1. Temporarily loosen the top lens tube coupler in order to screw that tube into the projector, and finally tighten it again with the projector mounted.

  1. Mount the main PCB with the power connector facing downward using the 3D printed PCB holder part. Reconnect the ribbon cables and LED power cables.

Motion Stage Assembly

Print all of the parts in the table below. Any PLA is fine. You may need to re-orient them so they print well. The stepper mounts will all need small supports in the motor flange. The X and Y axes need other supports as well.

File Name w/ link
Description
QTY

"Base"

Three parts that connect stepper motors to the micropositioning stage x , y and z axes.

1

Press fits onto micrometer and uses a grub screw to rigidly attach to motor D-shaft

2

Press fits onto micrometer and meshes with part press fit onto motor D-shaft

1

"Upright Chip Mount"

Provides a platform for the chip

1

The video below describes the necessary components and the assembly process.

Electrical Assembly

To test the proximity switches, connect them to a 12V supply. The sensor output can be left unconnected. The red LED on the back of the switches should illuminate when the front of the sensor is held within ~4mm of a metal part of the stage, which will also pull the sensor output to ground.

Note: the limit switch pin block on the CNC shield has two rows of pins. One of the rows is connected only to ground; do not connect your limit switches to that row.

The sensors should be connected through a pull-up resistor to the Arduino's 5V supply. 12V should be supplied externally.

TODO: Add picture of CNC shield!

Software Setup

The video below descries the basic electronics setup and how to install GRBL and integrate the two. Make sure to cross reference this with the stepper instructions above.

Final Focusing

Once the software is set up, the final focus alignment can be done. These steps will align the two focus planes within the stepper (the projector and the camera) to ensure that images that appear in focus on the camera are actually in focus on the surface of the chip. This is done by adjusting the tube length between the projector housing and the beamsplitter cube (the length in the image below) such that both the projected image and the chip's surface are in focus in the camera view.

  1. Load a chip with recognizable features into the stepper (a dirty chip is a good option).

  2. Project a red-focus pattern with recognizable features that can be used to determine projector focus.

  3. Adjust the Z position to focus onto the surface of the chip. This means that you should ensure that the features of the chip (the dirt, most likely) is sharp, but the projected focus pattern most likely is not.

  4. Loosen the clamp that connects the two parts of the DLP-beamsplitter tube so that they freely rotate. (the bottom circle in the image)

  5. Loosen the locking ring on the adjustable lens tube. (the top circle in the image)

  6. Screw the adjustable lens tube in/out while periodically checking to see if the projected image gets more or less in focus. You may need to push the optics into the coupler to ensure that the surfaces of the lens tubes are coplanar.

  7. Once both images are in focus at the same time, tighten the locking ring on the adjustable lens tune as well as the coupler.

Characterization

One of the core goals of Stepper V2.1 as compared to Stepper V2 is reduction of vibration through a more rigid frame. In order to test this, we characterized the amount of vibration that affects V2.1 using the following procedure:

  1. Load a chip with recognizable features into the stepper and focus on it (in our testing, we just used a dirty chip)

  2. Using the Basler Pylon Viewer software, collect a 10 second video clip of the surface of the chip. Pylon Viewer gives the video clip as a collection of .tiff frame images. Here is an example of a single frame:

  1. Use ImageMagick to threshold the frames: magick '*.tiff' -channel G -threshold 75% -separate threshold.png (this is a bulk operation on all frames). Here is an example of a single frame:

  1. Using an image editor, find a specific feature on the chip to focus on, and crop all of the frames to it: magick 'threshold*.png' -crop 300x300+1000+800 crop.png Here is an example of a single frame, plus a GIF of the frames playing in real time:

  1. Multiply the thresholded frames together to produce a footprint of where the feature moved throughout the duration: magick 'crop*.png' -compose multiply -layers merge product.png

  1. Subtract a frame from the footprint to produce an image that shows how much the feature meandered from its starting point: magick product.png crop-0.png -compose subtract -composite diff.png

In this final image, all of the white pixels are deviations from the starting image. This allows us to count a maximum deviation: in this image (which is from when we were testing the effect of someone resting their hands on the table) there is a maximum 3 pixel deviation.

From this, we can calculate the maximum peak-to-peak vibration amplitude: each pixel on the camera sensor is 5.86 μm square, which after the 10x reduction of our objective, means each pixel in this image is 586 nm on the chip. 3 pixels then is 3 * 586nm = 1.8 µm.

We also ran another test of "ideal" conditions, in which there was no external vibration added to the stepper table, which had 2px deviation. This leads to the result being 1.2 µm.

Assessment and Future Work

This section is a reflection by me, Sky.

The core design goal of V2.1 was pretty much a mixture of "make it less susceptible to vibration" and "make it less janky". I think I mostly succeeded in this department: although I lack proper numbers on V2's vibration issues, I am confident in asserting that V2.1 fixes them (mainly because you could visually see the vibration occurring on V2's camera, and you can't anymore on V2.1), and now that we have a rigidly mounted frame, the slop from the projector moving around on the table is gone.

However, there's still definitely some improvements to be made. For one, I think that the projector should probably be more directly supported - I didn't end up adding a direct support for the projector this semester because it didn't appear to be necessary, but I think this could further reduce vibration issues. This shouldn't be particularly hard because the disassembled projector has very convenient standoff mounting points directly on it.

Another improvement to make is to fix up the centering of the image on the camera: currently, the hole on the adapter plate is perfectly centered to the part's center, but it appears that the projector's actual image is slightly off to one side. This wasn't really an issue when the camera had a larger sensor, but now that it's smaller it very slightly cuts off part of the image. This only require a small change to the adapter plate to correct.

Lithography Stepper V1 Build

Background

Hardware Specs

Cost

$5,820.10

Approximate Work Time

5 hours

Optical resolution

~10 µm

Alignment accuracy

5 µm


Related Links

Litho Stepper Software


Tools Required for Manufacturing

  • Water jet capable of cutting ¼” aluminum plate

  • Manual milling machine and small end mill

  • Drill

  • Screwdriver and metric allen key sets

  • Glass scribe (tungsten carbide or diamond)

  • 3+ large C clamps or similar.

Bill of Materials

Total Cost: $5,820.10

Name

QTY

Cost per unit - USD

Total cost - USD

Purchasing Link

ViewSonic PX-701 4k Projector

1

$909.99

$909.99

Multiple Optical Components

1

$3,796.97

$3,796.97

¼” x 12” x 12” 6061 Aluminum plate

1

$35.61

$35.61

¼” x 6” x 18” 6061 Aluminum plate

1

$40.54

$40.54

Amscope Camera MU2003-BI

1

$841.99

$841.99

Manual XYZR Stage

1

$195.00

$195.00

Screws: mostly M3, M4

$0

$0

Design File Summary

File Name w/ link

Description

QTY

Tools Used

Water jet from ¼” x 6” x 18” aluminum plate. Serves as a flat surface on which everything is mounted.

1

Water jet

Water jet from ¼” x 12” x 12” aluminum plate. Holds the projector via vertically slotted holes. Connects to the base, triangle bracket, and support arm.

1

Water jet

Water jet from ¼” x 12” x 12” aluminum plate. Adds stiffness between base and back plate.

1

Water jet

Water jet from ¼” x 12” x 12” aluminum plate. Connects back plate to the optics.

1

Water jet

Water jet from ¼” x 12” x 12” aluminum plate. Connect the support arm to the optics.

1

Water jet

Machined from 1 ¼” aluminum angle iron.

1

Manual milling machine

Machined from 1 ¼” aluminum angle iron.

2

Manual milling machine

Machined from 1 ¼” aluminum angle iron.

Use an ⅛” end mill for the slot.

1

Manual milling machine

3D printed part for connecting the optics to the projector. Not load-bearing, mainly serves to dampen vibrations and aid alignment.

1

3D printer

1

1

Most of the water jet components can be cut from a single 12” square aluminum plate. Water jet layout.SLDASM provides the pattern for this. The base needs a separate 18”x6” plate.

Build Instructions

The following steps do not need to be completed in order, except for the last three sections (assembling the structure, stepper, and alignment).

Fabricate the structural parts

  1. Export “Water jet layout.sldasm” and “base.sldprt” to the appropriate 2D vector format for your water jet (likely .DXF).

  2. Water jet these two files, following the instructions for your specific machine. A CNC router may also work.

    1. Be aware that the “base” part takes up the full 6”x18” plate, so no need to cut the outside edges. You may need to adjust the kerf settings so your water jet cuts on the inside of each hole.

  3. Countersink all the holes on the bottom of the base plate.

  4. Cut the angle iron into three 80 mm long pieces and one 60 mm long piece using a saw.

  5. Cut the slot in the adjustable bracket using a 4mm or slightly larger endmill (3/16” works). None of the dimensions of the slot need to be precise. The holes in all the brackets will be drilled during the assembly process.

Assemble the optics

  1. Bolt the two filter holders together using four M3x20 or similar screws and washers.

  1. Screw together the rest of the optics, paying attention to the direction of the tube lenses.

Prepare the projector

  1. Unscrew all available philips screws in the projector.

  2. Use a small flathead screwdriver to pry open and remove the top projector housing. This takes some rough handling.

  3. Remove the front foot by removing the metal pin as shown below, then unscrewing the foot out while pushing the tabs in.

  1. Unscrew the three screws that hold the stock lens assembly to the projector and remove the lens.

  1. Remove the plastic half-lens cover and cut the top housing as shown above.

  1. Unscrew and detach the lamp assembly (screw circled).

    1. Use a scribe to mark the correct width on both sides of the UV-pass hot mirror.

    2. Use a straightedge to scribe a deep groove in the hot mirror. Use a lot of force and several passes.

    3. Apply bending pressure to the hot mirror with the groove facing away from you until it breaks.

Assemble the structure

The following steps will benefit from having two or more helpers. In the images below, the red arrows indicate applied pressure for ensuring parts are correctly mated. Green arrows indicate clamps. Yellow dots indicate tightened fasteners. For all drilling steps use the largest drill bit available that freely fits inside the holes for the brackets.

  1. Put the projector back plate and triangle bracket into their slots in the base. Apply pressure as shown so that both parts are flat against the base and in the corner of their grooves.

  1. While maintaining pressure, place one 80mm bracket between the triangle and the back plate and clamp it to the triangle.

  1. With the clamp still attached, drill through the bracket using the holes in the triangle for alignment. Use M5 nuts and bolts to fasten the two parts together. Put the nuts on the outside to avoid interference with the projector.

  1. Return the parts to their previous position, apply pressure, and clamp the bracket to the back plate.

  1. With the parts still clamped, drill two holes and fasten. Depending on the size of your drill, it may be necessary to unbolt the triangle first.

  1. Clamp the other 80 mm bracket to the back plate. Clamp the 60 mm bracket to the triangle. Ensure the brackets lay flush on the base.

  1. Drill into the brackets using the holes in the back plate and triangle for alignment. Fasten with any protruding screws on the outside to avoid interfering with the projector.

  1. Place the assembly back into the grooves on the base, again pushing them into the corner. Clamp both brackets to the base.

  1. Flip the base upside down and use the holes on the bottom to drill into the brackets.

  1. Attach all three brackets and plates.

  1. Use three M4 screws to attach the support arm. Use a straightedge to ensure that the top edges of the support arm and back plate are parallel.

  1. Clamp and drill holes in the adjustable bracket. Make sure the top surface of the bracket is flush with the support arm.

  1. Structure is complete and ready for further assembly.

Assemble the stepper

  1. Push the optics onto the projector coupler. You may need to temporarily detach the vertical parts of the optics assembly. This part was designed iteratively and may not fit perfectly because the true position of the DLP chip inside the projector is unknown. In that case, it can be modified or removed as needed.

  1. Screw the camera onto the C-mount threads at the top of the optics.

Alignment

  1. Connect the camera to your computer with a USB 3.0 cable.

  2. Connect the projector to your computing using an HDMI cable.

  3. Put in the UV filter. Remove the red filter.

  4. Turn on the projector.

  5. Open AmScope. Select the camera in “camera list”. If everything is working an image should appear (might be black).

  6. Place a flat mirror-like object on the stage. This can be a bare silicon chip.

  7. Adjust the height of the microscope objective to approximately 16 mm.

Default configuration Without objective

  1. Unscrew and remove the microscope objective. You may still see an image. This is because if the two tube lenses are in the correct positions they will perfectly focus the collimated light between them. We will use this to our advantage by translating the entire optical assembly towards/away from the projector until the image is focused. When this step is complete, we know that the first tube lens is 151.8 mm from the DLP chip.

  1. We can also use the no-objective configuration to check the stage’s orthogonality relative to the vertical axis of the optics. When aligned, the image will be centered in the camera frame. Any offset (shown below) can be fixed by adjusting the structure in the angles labeled A and B above. This correction fixes the planarity of the focal plane, visible in the images below. Rotation in A moves the image vertically and rotation in B moves the image horizontally in the camera frame.

To add: details about how to mechanically execute alignment, including shims.

No objective, before alignment

With objective, before alignment. Non-uniform focus is apparent in the top left corner.

No objective, after alignment. The projected image (purple) is centered in the camera frame.

With objective, after alignment. Focus is much more uniform.

Validation and Characterization

Demonstrate the operation of the hardware and characterize its performance for a specific application.

  • Highlight a relevant use case.

  • If possible, characterize performance of the hardware over operational parameters.

  • Create a bulleted list describing the capabilities (and limitations) of the hardware. For example, load and operation time, spin speed, coefficient of variation, accuracy, precision, etc

Safety

Appendix

Getting started with Klayout

  1. Download Klayout from their websites and follow the instructions to install the software

  2. After it is successfully installed, open the Klayout editor

  1. To create a new layout File>>New Layout

  1. Set the initial layer(s) that you need. The current hacker fab process would require 5 layers which are substrate, poly, active, contact, and aluminum. This is just for getting started, you can always add new layers later if you need to do so.

The layers will be shown in the upper right corner.

  1. Go to View>>Layer Toolbox to open the layer toolbox so that you can adjust the order of the layers and the texture of the layers based on your preference.

Double-click the layer to hide it. If you are drawing on a hidden layer, the following tip will show up.

  1. To create a new layer, go to Edit>>Layer>>New Layer

  1. Scroll your mouse to adjust the size of the grid

The grid can also be hidden through View>>Show Grid. When you need to export the masks as screenshots, the mask needs to be hidden.

  1. Klayout has the following tools to draw the shapes. Press “shift” to draw straight lines.

  1. Draw the rough shape of an object then adjust it to be the exact size by pressing “Q” to edit its property.

  1. Mask Exporting (method 1):

    1. Go to Display>>Zoom Fit to maximize the size of the mask on the screenshot

  1. Rename and sort the order of the layers according to the order of the fabrication steps. In this case, the easiest way is to sort them by name (0:substrate, 1:poly gate, 2:active layer, 3:contact hole, 4:aluminum)

  1. To make the masks compatible with the lithography stepper, adjust the size of the substrate layer (layer 0 in this case) to be proportional to its resolution (3840x2160). In this set of masks, the size of the substrate layer is set to be 384x216. Under this setting, the actual size of the pattern coming from the stepper is 2.5 times the designed size.

  2. Adjust the color and texture of the mask to be blue/red/black accordingly to make them compatible with the red focusing and UV focusing.

  1. Hide or show certain layers based on the property of the mask and take screenshots via File>>Screenshot and save the mask.

  2. Corp the screenshots since the exported screenshot would normally have white sides.

  1. Mask Exporting (method 2):

    1. Set up steps are the same as Step 10 a. to c. steps.

    2. Go to Macros>>Macro Development to write Maros in Klayout

  1. Select “Python” and change the Macro Template to “Plain Python file”

  1. Paste the following code into the Python file you just created. 1

lv = pya.LayoutView.current()
ly = pya.CellView.active().layout()


# top cell bounding box in micrometer units
bbox = ly.top_cell().dbbox()


# compute an image size having the same aspect ratio than 
# the bounding box
w = 3840
h = int(0.5 + w * bbox.height() / bbox.width())


lv.save_image_with_options('/your_directory/your_picture_name.png', w, h, 0, 0, 0, bbox, True)
  1. Change the path to the folder where you want your images to be saved. Note that if the name of your folder or file starts with a number, it will give you the following error message.

  1. The .png file of your mask will be saved in black and white. Be sure to adjust the color and texture of the mask to be blue/red/black accordingly to make them compatible with the red focusing and UV focusing.

Reference:

Appendix 1. Klayout user guides

Klayout user manual from their websites:

Shorter one for getting started with basic functions:

Appendix 2. Masks for an NMOS enhancement load inverter

Patterning Tasks - Spring 2025

This page documents the current work being done on patterning systems and the goals of that work. If you want to start a new project or research related to patterning, add it here so we can keep track of what's being done!

Task
Metrics
Timeline
Task Lead

Backlash Improvements

<2µm backlash

Before February

Carson Swoveland (@_salix)

Absolute Positioning

<5µm accuracy+precision

End of semester

Carson Swoveland (@_salix)

Cost Reductions

Stepper price <$2000

End of semester

Joel Gonzalez Sky Bailey

Backlash Improvements

The current design for stepper v2 involves having the micrometer-motor couplers slide along the shaft of the motor. This leads to wear in the 3D print and prevents the use of a rigid connection, leading to the coupler eventually becoming loose. This can cause ~30º of backlash in the rotation, which corresponds to about 15 microns.

Mounting the motors on the stage that they move, rather than on a (relatively) fixed stage allows for using a rigid coupling without significant modification to other parts of the design. These fixes should be applicable to any fab with an existing v2 stage. This is a major enabler for Absolute Positioning.

This may require redesigning the stage to be mounted upright, or the stage to be turned sideways.

Absolute Positioning

In order to enable many features like automated or computer-assisted patterning, it must be possible to consistently refer to positions on a die. This requires being able to determine the absolute position of the stage.

There has been some experimentation with using inductive sensors for determining the stage position, though calibrating and mounting the sensors is difficult. The accuracy for a properly calibrated and mounted sensor may be sufficient, though. (TODO: Link inductive sensor notes once those get merged)

Currently, a design using simple limit switches is being developed (though blocked on Backlash Improvements).

Cost Reductions

The current optics system is not physically capable of handling the projector's resolution, i.e. some amount of detail is wasted in the optics system. This means that we can use a lower resolution (read: cheaper) projector.

Lastly, there are other components in the optics system itself that we believe can be modified/replaced to further reduce the cost. The ThorLabs components cost at least $700, but many of those parts such as tubes and flanges could be replaced by 3D-printed parts. We will have to test to see if heat generated by the stepper becomes an issue, but this would provide a significant reduction in cost.

Altogether, we believe that we can bring the cost of the stepper below $2000 - perhaps even $1500.

Lithography Spinner V1

Introduction

The Lithography Spinner V1 plans to use the Blu-Ray disc assembly from a Play Station 5 (KEM-497AAA) to drive the whole system. They are readily available and can be found for $30-$70 in most places.

Typically a single IC is used to drive these modules but most vendors wont sell chips to individuals. So the plan is to design a discrete controller board to manage all the HW and write our own controller SW.

Blu-Ray Lithography

Introduction

This is the project page for a lithography system based on repurposing Blu-Ray drives. The initial goal is to reach a feature size of at least 500nm (2x the Blu-ray laser spot size). As a stretch goal, we would like to also use the sled and spindle motors as high speed nano-positioners and to spin coat and cure photo-resin.

Safety

✓ Safety goggles/glasses are absolutely necessary. A laser dot contains a large amount of energy in such a small space, in the form of light. Your eyes are extremely sensitive to light, and a direct exposure to this very dense energy light for less than a second will blind you for life. We can prevent this by wearing a special type of light filtering glasses, somewhat like the way sunglasses work. But, sunglasses will not work as laser safety glasses. These glasses need to be coated for the correct wavelength. Do not purchase any laser safety glasses under $30, buy from an authorized and reputable seller such as survival lasers. $5 lenses from China will not be sufficient, and have been proven unsafe.

Source: laserpointerforums.com

Project Status

Right now, the first project for this technology (Lithography Spinner V1) is in the research/idea stage. See work in progress page for details on upcoming tasks if you want to contribute.

Work in Progress

Want to work on something? Plan a task add your name next to it!

Design Datasheets

Datasheets Used in the OPU Driver PCB

ECP5 Files

Power Supply

BU40N Reference Design

Introduction

In order to develop the SW for Texas Instruments TPIC2050 and test a good bit of the system, the BU40N blu-ray module was chosen for early development. Although available online, this module may not be available for long which is what disqualifies it from general use. Removing the MT1950 chip allows access to a lot of the pins of interest. Powering it is also relatively simple as it should only need 5V.

Hardware

Introduction

The HW needed to drive the OPU can be broken into 3 sections:

  1. Motors

  2. PMIC

  3. Laser Diode

Preliminary PCB

OPU_Driver_rev0p1 PCB CAD capture has been completed and is up for review on github here:

The board has been roughly quoted on JLCPCB:

  • PCB= ~$35.00 / Ea

  • Components = ~ $110.00 / Ea

3x Assembled PCBs = $550

At this time no orders are planned until firmware is far enough along to confirm pin out and FPGA logic size.

3-Axis Piezo Nanopositioner

Build for $500

Electroless Plating

Optical Spectrometer

For a description of what the team at CMU is working on in Spring 2025, check out !

Possible Variation: Error during development (see )

Possible Variation: Error during development (see )

Stepper V2.1 is an incremental improvement upon the existing with mechanical improvements. As such, a lot of the content here will be the same as V2! The changes from V2 (and reasoning):

(on backorder as of May 2025)

*

*For Thorlabs order: upload the file below to to retrieve the cart:

Currently the CAD for Stepper 2.1 is all in FreeCAD, with the files stored in , but will be ported to Onshape soon for consistency.

The software ( and ) are the same as Stepper V2.

top plate x1: laser cut from acrylic or machined, from (assembly.FCStd, part top_plate)

adapter plate x1: 3D printed or machined, from modified (part adapter-DLP471EVM)

PCB holder x1: 3D printed, CAD . I can't make this one shared publicly due to weird permissions problems, this is a HackerFab admin issue.

This step is the same as for V2, see the instructions .

Plug in the projector over USB and use the to set the LED current to 150mA. (The projector defaults to 1023 mA, which is its maximum output - our UV LEDs are not able to handle that much current, so reducing the current makes sure they don't burn out!)

Make sure this camera tube is 86.8 mm long. We calculate this number by subtracting the various component lengths from the standard microscope objective back focal length of 150mm: 150 - 17.5 (c-mount camera) - 7.6 (objective tube) - 38.1 (beamsplitter cube) = 86.8mm (NOTE: Our objective is rated for a 160mm optical tube length, but this is NOT the same as the back focal length, which is 150mm... this is a very confusing specification, see for what lengths are what)

(Folder "XYZ Platform") "X Motor Mount" "Y Motor Mount" "Z Motor Mount" (Optional, for sensors:) "Y Sensor Mount" "Z Sensor Mount"

(Folder "XYZ Platform") "Fixed Coupler"

"Z Coupler"

A detailed 3D model of the fully-assembled stage is available in the under the "XYZ Platform > Fully Assembled" document.

Instructions for installing and preparing the software are available on the .

Finally, one of the biggest issues that remains with the stepper is that the whole projector situation is not ideal: specifically, the fact that all of our existing litho setups have used projectors that hook up to a computer monitor output leads to a bunch of undesirable effects from the OS taking over (like unexpected popups showing up and getting imaged onto the chip). Another issue with the projector is that it's really not ideal to UV-mod a color projector: the projector is designed to always be emitting all 3 color channels, which means that we're outputting a small but noticeable amount of UV even when not actively imaging. Also- the DLPDLCR471TPEVM projector used on V2 and V2.1 is currently (May 2025) out of stock everywhere in the world, which is very bad for reproducibility. One thing we could do to solve all of these issues is to create a custom projector design which gives us more control over UV emissions and the image pipeline. I have written up an essay on the design process and ideation behind a custom projector .

Our design was based on and ’ versions of this tool. Sam repurposed a vertical microscope for structure and laid out optics experimentally with a 5x reduction objective, whereas Huygens built his own horizontal structure, and used more involved optics with a 20x reduction. We took the middle road by combining a scratch built structure with ThorLabs optical and optomechanical components to ensure alignment. We use a 10x objective for demagnification. We also opted for a different mechanical XYZ stage.

Completed LithoStepper V1 with Manual Stage

- edit sheet then update or copy table here

The complete list of ThorLabs parts is in the in the Stepper BOM. To order all of these at once, download the as a CSV and upload it to .

Assembly containing all projector parts, obtained from . Used for geometry of the 3D printed adapter.

Assembly of all ThorLabs components. Original part files from .

3D print the with default settings.

Open “” for reference during assembly. The cutaway view may be helpful.

Unscrew the set screw on the to remove the filter mount. Insert the beamsplitter into the mount so that the text on the beamsplitter reads forwards when viewed from the projector.

Use SM1 locking rings to mount the UV bandpass and red longpass filters in the two . Make sure the filters are inserted in the correct direction. Label the filter holders “red” and “UV”.

Use calipers to adjust the length of the vertical SM2 tube so that the distance between the tube lens and the camera flange is exactly 134.3 mm. This value is calculated by subtracting the standard (17.526 mm) from the tube lens’ working distance (151.8 mm).

Remove the metal clip and the stock hot mirror from the lamp assembly. The stock hot mirror blocks ultraviolet light, so it needs to be replaced.

Cut the Thorlabs to the same width as the stock hot mirror.

Screw the into the base plate using countersunk screws.

Screw the 3D printed into the projector with three M3x? screws.

Attach the to the with 4-40 screws. Attach the cube adjuster to the adjustable bracket with M3 screws and washers on both sides.

Go to and install the correct Amscope software for the camera MU2003-BI and your operating system.

Focus the image using the Z-axis on the stage. You should see your projected screen. Try projecting some to test the focus.

Adjust the so that the projected image is square inside the camera frame.

Wear whenever light leakage from the projector is possible.

See step 11 for an alternative way of exporting the masks using Python scripts

1 GDS to image

The WIP CAD files are available on and more information can be found .

There are two main items that we are looking at replacing to reduce our cost. The first is the projector itself, as we are using an expensive 4K projector that does not appear to yield much benefit in patterning resolution. We are considering going from the ($999) to the ($299).

The second item that we are looking at is our camera. We are currently using a high-resolution ($700) which, again, is excessive for our application. We believe that we can find a similar C-mount camera for less than $200.

Currently Recommended: ✓ Be fully aware of what you are pointing at. With a massive amount of light comes the heat as well. Lasers higher than Class IV (>500mW) burn certain objects very easily, lower powers do burn as well but not as intensely. Lasers like this can most definitely burn furniture such as carpet and couches, hardwood floors, curtains, walls etc. You need to make sure that you are not burning anything against your desire. If the heat build up in an object from a laser is sufficient enough, the object could be set on fire. ✓ Keep in mind of any dangerous objects/surfaces. Look out for anything noticeably reflective/smooth such as a mirror, polished metal, or even something smooth like a desk. The last thing you want is a laser beam reflected back at you into your eye. Even with safety goggles/glasses, you should not take a chance. Something else dangerous that you need to look out for are flammable items, a high powered laser can easily ignite a match or alcohol. CAREFUL WITH WINDOWS - None are 100% transparent, and WILL reflect a solid beam back towards you, this goes for any type of glass at all. All reflected beams are also a danger and this is no exception. Windows are also a bad thing to be pointing a laser through, you don't know exactly where/what you'll hit. __________________________________________________ Be careful with lasers, treat them like a loaded gun. It is very easy to create dangerous situations with a laser if you're not careful, be responsible and eliminate that possibility!

Planning
In-Progress
Done

KEM-497AAA Pin Out Analysis

OPU_Driver PCB rev0.1 CAD capture

Firmware Development (need to break up into tasks)

for $500

Build
this document
Patterning SOP
Patterning SOP
Stepper V2
Rapid Order
this repo
Adapter plate
Stage
custom
GRBL
V2.1 CAD
V2 CAD
here
LightCrafter GUI software
this page
CAD
stepper software repository
here
Sam Zeloof
Huygens Optics
Patterning SOP
Link to spreadsheet
second sheet
third sheet
ThorLabs Upload Cart
Link to GitHub repository
projector coupler
_optics_assem.sldasm
cage cube
filter holders
C-mount flange focal distance
TTL-200A
UV-pass hot mirror
manual XYZR stage
projector coupler
cube adjuster
cage cube
this link
patterns
lens tube coupler
UV-blocking glasses
https://www.klayout.de/doc-qt5/programming/python.html
https://www.klayout.de/doc/manual/basic.html
https://mycourses.aalto.fi/pluginfile.php/897248/mod_resource/content/2/KLayout%20Guide.pdf
Onshape
on Discord
DLPDLCR471TPEVM
DLPDLCR230NPEVM
FLIR camera
UV-blocking glasses
Build guide

Deposition

  • uniformity

  • deposition rate

  • deposition precision (between runs)

Mouser
Thorlabs
Edmund Optics
Basler
Amazon
Amazon
Amazon
Amazon
Amazon
Amazon
Amazon
Amazon
Amazon
Digikey
Digikey
Amazon
Motor and Sensor Mounts
Base V2.1
Motor and Sensor Mounts
Z Coupler
Motor and Sensor Mount
s
Amazon
ThorLabs
McMaster
McMaster
AmScope
Amazon
Base.SLDPRT
Projector back plate.SLDPRT
Triangle bracket .SLDPRT
Support arm .SLDPRT
Cube adjuster .SLDPRT
Bracket_60mm.SLDPRT
Bracket .SLDPRT
Bracket_adj .SLDPRT
Projector coupler .SLDPRT
Projector assembly .SLDASM
ViewSonic documentation
_optics_assem .SLDASM
thorlabs.com
here

Etching

  • etch rate

  • selectivity

  • uniformity

  • anisotropy

  • effect on photoresist?

Other Processing Machines

Filling in the Gaps - Background Resources

Semiconductor research has been around for decades, which means there are many people who can explain concepts better than we can. This is a collection of our favorite resources we've found.

Links and Videos

  • Nearly identical to what we do

  • What our work was based on

  • Electrons, bandgap, etc.

  • Then we moved to silicon

  • Extremely well told story of the man who figured out how to manufacture blue LEDs

  • We are not the first people to claim that innovation in the semiconductor industry requires intimate knowledge of the fabrication tools

  • A fantastic tool being developed by friends at MIT. Overview of many processes, with each being a linear recipe

  • Make an account, and go to “fabubase” in menu

  • Check out our Hacker fab process, as well as others

  • Go through and try to recreate our process from scratch without cheating. See how far you get, and write down things that don’t make sense (1 hour)

How do these things even make computers?

  • Application Specific Integrated Circuits

Not all transistors are created equal

Below: ideal transistor IV curve vs. our first curves.

These both exhibit transistor-like characteristics. Looking back at the Veritasium video about how the first computers were made with lightbulbs - a transistor really boils down to a repeatable switching action. When we look at our curve on the right, we see multiple issues:

  • The curves don’t go through the origin, they start with a voltage offset

    • This means that when we apply a voltage to the gate (open the valve to allow current through), current doesn’t run through the drain to the source until we apply ~3V to the drain/source connection.

  • The lines are all squiggly?

In reality here is what it is saying:

Put simply, we just directly connected an electrical characteristic (IV curve) to a physical process parameter. We now have an exact experiment to try over the next week:

  • Less metal annealing

  • More Si02 etch before metal deposition (to ensure metal contacts Si instead of SiO2)

Right now it takes about 8 hours of work + waiting overnight to turn a blank wafer into one with NMOS transistors on it. Then we go to the probe station, test it, organize the data, look at the graphs, and think. That’s how long it takes to verify each new experiment. With each machine, script, or management tool we create, we push to significantly decrease this iteration cycle.

Each unique device can also use different materials entirely, which requires different machines.

  • What metal are we depositing?

  • What does the doping profile look like?

  • etc.

Spin Coater V1 Build (to do)

  • Collect all necessary measurements of the current spin-coater to create the new 3D mode.

  • Finalize an updated 3D model that includes the servo mount and any necessary adjustments to the lid design.

  • Order required components, including a servo motor, necessary mounting brackets, and plastic material for a redesigned lid.

  • Cut and prepare the new lid, ensuring proper fit and clearance for rotation

  • Assemble all components and build the initial prototype.

  • Conduct preliminary functionality tests, focusing on servo movement and integration with the claw mechanism.

  • Optimize servo rotation angles and positioning to maximize clearance while minimizing occupied space.

  • Conduct final system tests to verify smooth automation and reliable lid operation.

  • Implement necessary refinements and finalize the design for long-term use.

Spin Coater V2 Build (work in progress)

  1. Only requires a 3D printer (no machining)

  2. Only requires vacuum pump 1/5th the size

  3. 1/2 the height

  4. Easier to assemble

  5. More reliable excess liquid collection

    1. Easier cleaning

    2. Less motor stalling from dried residue

    3. Less residue on window for better visibility

  6. Better user interface

    1. Replace touchscreen with potentiometers

    2. Put power button on top so entire operation with 1 hand is possible

    3. Top swinging window becomes flush with side wall and snaps into place

Electroless Nickel Plating

Working Docs

Links to work in progress notes from individual contributors - add your link here with a pull request

Lithography Stepper V2 Build

Hardware Specs

Cost
$3,015.44

Approximate Build Time

6 hours

Optical Resolution

2 µm

Developed Resolution

2 µm

Tiling Alignment Accuracy

5 µm

Overlay Alignment Accuracy

5 µm

Reticle (Exposure) Dimensions

1.04mm by 0.58mm

Exposure Time

8 seconds

Mechanical Step Size

1.5 µm

Mechanical Repeatability

5 µm (to verify)

Maximum Wafer Size

2 cm by 2 cm

Tool Size

30 cm x 36 cm x 20 cm

Hardware Description

Stepper version 2 has greatly improved optical and mechanical performance over V1 while using the same DLP chip from Texas Instruments. Several factors led to this improvement:

  1. By swapping to a finite conjugate microscope objective, the optical path length is reduced from ~250 to 160 mm. This reduces the moment of inertia of the optics subassembly, therefore also reducing vibration.

  2. Mounting the projector horizontally means less structure is needed.

Tools Required

  • M3 and M4 taps

  • 3D printer

  • Solder paste (preferably a syringe)

  • Tweezers or pick and place machine

  • Reflow oven

  • Calipers

Bill of Materials

Total Cost: $3,015.44 or** $3106.44 (excluding computer & peripherals) (last updated March 16, 2025)

Name
Qty
Total
Link

TI DLP Evaluation Module

1

$999

Assorted Optics

1

$736.52

10X Din Plan Objective

1

$159

Basler acA1920-40uc w/ Sony IMX249 (recommended), or** FLIR Blackfly S Camera w/ Sony IMX183

1

$609.00 or** $700.00

USB Type A to Micro B locking cable

1

$25

19V 4.74A Projector Power Supply

1

$17.99

XYZ Stage 40mm

1

$125

Rotation Stage

1

$69.34

NEMA 28 Steppers

4

$71.96

Arduino Uno (Elegoo)

1

$16.99

CNC Shield for Arduino V3.0

1

$9.99

Stepper Motor Drivers

1

$22.99

Shield Power Supply 12V

2

$23.98

2.5mm Barrel Connector

1

$7.99

Vacuum pump for chuck

1

$26.52

M2.5 Screw Assortment

1

$30.56

Collapsible Magnetic Tray for Vibration

1

$21.99

410nm Lumiled LED

4

$40.20

Pico-spox 10pos Vertical Connector

2

$1.42

*Upload this CSV file to Thorlabs for all the optomechanical parts + beamsplitter.

**The Basler camera and FLIR camera are mechanically interchangeable, but our software implementation for the Basler camera is more reliable and freely accessible (FLIR code distribution is restricted). For software installation simplicity, we recommend using the Basler camera.

Design File Summary

Note: the OnShape folder is organized poorly because it was our first time using it. Won't happen again, we promise!

File Name w/ link
Description
QTY
Tools Used

Reference for assembling optical components

1

Driver kit

1

Water jet/ Online CNC shop/ 3D print

Structural base for aligning the micropositioning stage to the projector and optics.

1

Manual mill/ Online CNC shop/ Water jet

Three parts that connect stepper motors to the micropositioning stage x , y and z axes.

1

3D printed

Press fits onto micrometer and slides on motor D-shaft.

3

3D printed

Tiny part for offsetting micrometer stop on Y axis

1

3D printed

Mounts the theta stage at a right angle to the rest of the stage.

1

3D printed

Connects to a vacuum hose to hold the chip. Corner jig aids alignment.

1

3D printed

Python script for controlling the projector. Check for recent version.

Laptop

Firmware for stage microcontroller.

Arduino Uno, IDE, Laptop

Build Instructions

Building the Stepper V2 requires some simple CNC machining, PCB soldering, 3D printing, and other assembly steps, followed by software installation.

Get the Metal Parts Made

Option 1: Water Jet

The Base Plate is 15" long, so double check that your water jet is large enough.

When downloading the Adapter Plate DXF for water jetting, go to Config > Water jet to get the hole sizes right for tapping. The 2.2mm holes are clearance for M2, and the 2.5mm holes are M3 tapped and countersunk.

Option 2: CNC Shop

Option 3: Manual Machining

Adapter plate: This should be manually machinable but we haven't tried.

Solder the UV LED PCB

We used 410 nm UV LEDs on this PCB. We found that two LEDs in series is sufficient to produce enough UV light for patterning. We also found connectors that are compatible with the cable in the TI DLP dev kit.

When assembling the UV LED PCB, it is easiest to use a solder syringe to carefully deposit the paste onto the LED pads and connector pads. If you try to use a stencil mask, it is very easy to smear the paste, so this is not recommended.

Once the paste is applied, align the components with their pads (i.e. using tweezers or a pick and place machine). Keep in mind that you need to use a nozzle that is small enough to pick up the LEDs. Finally, you can put the PCB into a reflow oven to solder the components to the board.

You can test by applying 6V (limit to 1A) across the LED leads, but be sure to wear UV-protective glasses, as the LEDs will be bright! Once you are confident that the PCB works, you can now replace the blue LED PCB in the TI DLP dev kit with our new UV LED PCB. To see the UV light, simply look at the leds through your phone's camera, as the sensors see it as purple light.

Disassemble the TI DLP dev kit

Taking pictures after every step is key to ensuring you can put it back together properly.

  1. Test the projector before we completely take it apart :)

  1. Unplug all the connectors and remove the top PCB by unscrewing the standoffs.

  1. Remove the side PCB.

  1. Unscrew and remove the shroud by sliding it away from the rest of the optics.

  1. Unscrew and remove the heatsink for the front-most LED, which should be the blue one.

  1. Disconnect the LED PCB from the cable. Heat it slightly on a hot plate or with a hot air gun to soften the adhesive and remove the black plastic housing.

  2. Glue the black plastic piece to the DIY UV LED PCB, connect it to the blue cable, and reattach it to the optics housing. Put the heatsink back as well.

  1. Unscrew the projection lens. That one makes things bigger, but we're trying to make things smaller. It's got to go.

  1. Screw on the adapter plate with four countersunk M2 screws.

  1. Reassemble the rest of the projector, including the shroud and the PCBs.

Assemble the Optics

  1. Start with the beamsplitter cube. Unscrew the set screws, remove the holder, and clip in the beamsplitter. The text ("Thorlabs") should be facing the microscope objective and camera when the holder is reinserted. Keep track of this during assembly and fix it later if necessary.

  1. Assemble the DLP tube. From left to right, the parts in the first picture are 0.3" lens tube (SM1L03), 0.5" lens tube coupler (SM1CPL05), 0.5" adjustable lens tube (SM1V05), and 0.5" lens tube (SM1L05). You may want to remove any internal lens rings. The adjustable lens tube allows axial length adjustment and the coupler allows rotation about the optical axis.

  1. Screw the DLP tube into the beamsplitter cube. The correct orientation is shown above, and the arrow points to the side of the beamsplitter with the text (and optical coating).

  2. Assemble the camera tube, which similarly constructed. The parts are 1" lens tube (SM1L10), 1" lens tube coupler (SM1CPL10), 1" adjustable lens tube (SM1V10), another 1" lens tube (SM1L10), and C-mount SM1 adapter (SM1A9) (last two shown below).

  1. Screw on the C-mount SM1 adapter (SM1A9) to the camera and the 1" lens tube. Adjust the lens tube coupler to align the camera with the beamsplitter cube.

  1. Assemble the objective tube, which consists of a 0.5" lens tube (SM1L05), a 0.3" lens tube (SM1L03) an SM1 to RMS adapter (SM1A3), and the microscope objective.

  1. Temporarily loosen the top lens tube coupler in order to finally screw the entire assembly into the projector.

3D Print and Assemble the Stage

Print all of the parts in the table below. Black PLA is fine. You may need to re-orient them so they print well. The stepper mounts will all need small supports in the motor flange. The X and Y axes need other supports as well.

File Name w/ link
Description
QTY

Three parts that connect stepper motors to the micropositioning stage x , y and z axes.

1

Press fits onto micrometer and slides on motor D-shaft.

3

Tiny part for offsetting micrometer stop on Y axis

1

Mounts the theta stage at a right angle to the rest of the stage.

1

Connects to a vacuum hose to hold the chip. Corner jig aids alignment.

1

  1. Unscrew all the, micrometers, L-stops and stage locks from the micrometer stage. Separate the X, Y and Z axes. Throughout the assembly process we will be replacing the stock screws with ~4mm longer ones as we reattach the various components to the stage. All 3d printed mounts are 4mm thick at the screw holes. Have your M2.5 screw kit handy!

  1. Press fit the three sliding shaft couplers onto the three micrometer handles until the knurled surface is fully covered. They should fit with significant force and maybe gentle hammering. Be careful - the micrometer handles may have different diameters so you may need to modify the CAD and reprint to get a correct fit.

  1. The shaft couplers should slide on the motor shafts with zero slop. Modify dimensions and re-print if this is not the case. Graphite lubricant may help decrease sliding friction, and the fit will get looser after repeated axial movement as the steel deforms and smooths the plastic.

  1. Screw the motor, coupler, and micrometer into the X axis motor mount as shown. Doing this step before attaching to the rest of the stage takes advantage of the slop in the micrometer mounting screws and aids alignment.

  1. Slide the Y axis motor mount onto the Y axis. You will need to remove some screws and push the stage to allow it to slide on.

  1. Attach the motor. Don't screw down the micrometer mount yet.

  1. While pushing the stage so the micrometer isn't touching the stop, fasten the micrometer mount. This avoids preloading the micrometer/motor assembly and improves shaft alignment.

  1. Reattach the X axis micrometer stop as well. You may need to adjust the screw length to get it to fit.

  1. Insert the Z axis motor mount to the Z axis. The easiest way to do this is to insert it upside down from the opposite side, then flip it while pushing the stage up, then slide it back so the holes line up. Basically it takes some fiddling.

  1. As with the other stages, attach the motor first, then secure the mounts. Tighten the set screw at the green arrow. Make sure the micrometer is flush with the mount at the yellow arrow. Again pushing upwards at the red arrow eliminates prelaod from the spring inside the stage and helps alignment.

  1. Tighten down the Z axis mount.

  1. Attach the X axis motor mount to the stage with the screws at the red arrows.

  1. Add additional screws on the X and Y axes to make sure the mounts are solidly attached. Ignore the spring in the above image.

  1. Attach the right angle bracket to the theta stage and the top of the Z stage.

  1. Screw the chip vacuum chuck onto the theta stage. The stage is finished.

Mechanical Integration

  1. Bolt the XYZ stage to the base plate using short screws so they don't protrude out the bottom. Ensure the stage is aligned with the tapped holes by pushing it forward while screwing it down.

  2. Screw in the four alignment screws for the projector. They don't need to go in all the way.

  1. Push the projector and optics against the four screws to ensure alignment.

  1. Plug in everything: power for the projector, locking USB cable for the camera, USB cable for the stage, power for the stage, HDMI for the projector, power for the pump, and vacuum tube for the chuck. Do not power the stage arduino shield without the motors connected, or you will burn out the drivers.

Install Software and Flash Firmware (WIP)

To install and run the software, you will need a Windows system that has two USB ports. The rest of this section describes how to install the following dependencies:

  1. Arduino GRBL firmware

  2. Python version 3.10 and Python libraries

  3. Basler camera or FLIR Blackfly S Camera Drivers & Viewer

After these are installed, you may clone and instantiate the stepper repository on your device. Our GUI supports a live camera preview of the stage when using the Basler camera. Optionally, you can develop your own driver for using the FLIR camera instead. Instructions for such are included below as well.

Arduino GRBL Installation

  1. Install Arduino IDE.

  1. To test that the installation was successful, open Arduino IDE and open the serial monitor. You should see text indicating that a version of GRBL is running on your Arduino.

Python Version 3.10 (if using FLIR camera)

If you are using the FLIR camera, you must install Python version 3.10. This is because at the time of development, the latest Python version the Flir Spinnaker SDK supports is version 3.10. As such, you must install libraries and run the software for/from this version. If you are using the Basler camera, later versions of Python should be compatible with the GUI software.

Basler Camera Drivers & Viewer Installation (WIP)

If you are using the Basler camera, install its necessary drivers and its GUI for live camera output.

FLIR Blackfly S Drivers & Viewer Installation (WIP)

Stepper GUI Installation

Follow the steps outlined in the linked repository (recommended). Alternatively, follow the steps below.

  1. pen git terminal to the location where you want the Stepper GUI software to be downloaded. Then, run the following commands:

  • git clone https://github.com/hacker-fab/stepper .

  • cd stepper

  1. Install software dependencies listed in the requirements.txt file

  2. If you are using the FLIR camera and have access to the private FLIR camera submodule repository, then also enter the following commands:

  • git submodule init

  • git submodule update

    Otherwise, go to the stepper/config.toml file and toggle the necessary flags to select your camera (or disable it).

  1. Configure config.toml with the settings most appropriate for your Stepper build and camera configuration.

  2. Run gui.py with Python 3.10:

    • py -3.10 ./src/gui.py

Optional: FLIR Spinnaker SDK (for software developers)

The Stepper V2 build uses a Teledyne Flir camera and custom software written for it. The Stepper software uses the Flir Spinnaker SDK to integrate a live camera preview of the stepper's stage. Since the SDK and its derivative software are closed-source components, we currently do not possess the legal authority to grant access to our custom Flir camera driver to third parties. The following steps describe how to install the Flir Spinnaker SDK and how to develop your own driver. Please carefully review all terms, agreements, and licensing requirements. Follow the steps below.

  1. Decompress your download if necessary. Open the README.txt file in the (decompressed) download and follow the installation instructions inside.

  2. Test that the installation was successful by running an example program. To do this, first make sure your Flir camera is connected. Then, open git terminal in the "Examples" folder. Then, choose any example .py script and run it by entering py -3.10 NameOfYourScript.py. Ensure that the program output reports connection and communication with your FLIR camera.

    • def __init__(self)

    • def setStreamCaptureCallback(self, callback)

    • def streamImageReady(self); returns True if live image is available

    • def getStreamCaptureImage(self); returns a tuple of (numpy ND image array, shape of that array, and an image format string ("rgb888" or "mono8")), or False if the image is invalid

    • def isOpen(self); returns True if the camera is active

    • def open(self); returns True on success

    • def close(self); returns True on success

    • def startStreamCapture(self); returns True on success

    • def stopStreamCapture(self); returns True on success

    • a Flir image event handler

    We also suggest optimizing live preview performance by selecting a low-overhead color processing scheme and by displaying only the most recently acquired image (i.e. newest first). The Flir SDK code examples show how you might do this.

  3. In config.toml, select the FLIR camera. to an instance of your FlirCamera class.

Final Alignment (WIP)

Once the stepper is connected to a computer and the live camera feed is visible, proceed with final alignment. The goal is to adjust the tube length between the DLP housing and the beamsplitter cube such that both the projected image and the chip are in focus.

  1. Place a chip with a visible pattern on it. Cracked glass or extremely dirty chips are good options.

  2. Project a mostly red image with some fine marks for determining focus.

  3. Using the Z axis (focus) of the stage, focus onto the chip surface. Disregard the projected pattern for now.

  1. Loosen the clamp that connects the two parts of the DLP-beamsplitter tube so that they freely rotate. (update picture)

  2. Loosen the locking ring on the adjustable lens tube.

  3. Screw the adjustable lens tube in/out while periodically checking to see if the projected image gets more or less in focus. You may need to push the optics into the coupler to ensure planarity.

  4. Once both images are in focus at the same time, tighten the locking ring on the adjustable lens tune as well as the coupler. (insert image)

Safety

Appendix

Documentation

Project Specification

Datasheets

Thermal Evaporator V1 Build (WIP)

Vacuum Chamber Assembly

1. Assemble the chamber frame and plates

(i) Wrap an O-ring around each plate to ensure the chamber has a tight vacuum seal.

(ii) Screw in each plate with 8 bolts into the frame as shown in the following image.

Note: Plan where you want each plate to be (i.e. top, bottom, side) depending on your setup

2. Attach feedthroughs and/or blank flanges

Each opening must be covered and sealed for the vacuum to exist. Therefore, each opening needs a feedthrough in it or a blank flange to cover it. Ensure that each part has the correct dimension to properly fit in its corresponding port.

(i) Pair up the feedthrough/flange with its matching O-ring and clamp.

(ii) Layer the parts in the following order. Starting from the bottom closest to the plate place the O-ring, flange/feedthrough, and clamp. Then attach all necessary screws tightly. Repeat this process for all openings.

3. Turn a face into a door and attach feet

(i) Screw in the hinge into two adjacent plates where you want the door to be.

(ii) Attach knobs on opposite side of hinge to open and close the door securely.

(iii) Attach feet to the bottom of the chamber to minimize vibration.

Final product

Pumping down the Vacuum Chamber

1. Attach the turbo pump to the chamber

Connect the turbo pump (Hi-Cube 80) to the KF-40 plate using the corresponding KF-40 flange and O-ring. Since the turbo pump has a lip that makes it difficult to tighten the screws, we recommend using hex shaped 10-32 x 5/8" screws and tightening with a wrench.

2. Connect the pressure gauge

The Pfeiffer MPT 200 Gauge has a KF-25 connection port. To optimize the 6 plates we chose, an adapter from KF-25 to KF-16 is needed to connect the pressure gauge to the vacuum chamber. Attach using a KF-16 flange to the plate and a KF-25 clamp to connect the adapter to the pressure gauge.

Implement Heating Parts

Heating the vacuum chamber is necessary for two reasons. First, high temperatures of approximately 1200˚C are needed to evaporate the aluminum and perform the thermal evaporation process. Second, heating the chamber allows it to bakeout, meaning that the water trapped inside evaporates allowing the vacuum to achieve a lower pressure.

Our setup consists of two parts: the crucible and the substrate heater.

Crucible Set-Up

The crucible is comprised of the following parts:

Next, connect a power supply to the external end of the power feedthroughs to heat up the crucible.

Finally, attach the thermal breakout board and arduino to the thermocouple to read the temperature values.

⚛️DIY ALD

HackerFab DIY Low-Cost Atomic Layer Deposition Tool - Progress as of Dec. 2024

Bill of Materials

Introduction

We are building a low cost Atomic Layer Deposition machine for the Hacker Fab to achieve improved gate dielectrics, which will help us achieve our goal of a 10 micron CMOS process as well as improve our capability in performing thin-film research. Our design work on it will be all open source, and we hope other labs can use our work to make their own ALDs at a fraction of the cost of commercial alternatives. We are building our ALD to fit 4" wafers so that it can be brought into the nanofab, which will help us lower the barrier to entry for researching thin film deposition and new materials. Although 4" is much larger than anything we are currently using in the Hacker Fab at CMU, this larger size will make it useful to a larger audience.

This document will present the current proposed machine design plan and the work completed to date for our vertically aligned, cold-walled reaction chamber ALD machine for the Hacker Fab.

Precursor Selection

Oxide of interest

For the current system we aim to deposit Indium-Tin Oxide. Indium Tin Oxide (ITO) is a versatile material widely recognized for its excellent electrical conductivity and optical transparency. These properties make ITO a promising candidate for advanced applications, particularly as a channel material in thin-film transistors (TFTs). Its high carrier mobility and tunable electrical characteristics offer significant potential for improving TFT performance in display technologies and flexible electronics. Additionally, ITO thin films are of great interest in materials and thin-film research due to their unique combination of metallic and semiconducting properties. This makes them an ideal system for exploring novel deposition techniques, optimizing film uniformity, and investigating structure-property relationships.

The precursors for the metals were chosen based on their feasibility to react with water vapor as the oxidizer. The precursors chosen are Trimethyl Indium (TMIn) for Indium and Tetrakis(dimethylamino) Tin (TDMASn) for Tin with Nitrogen carrier gas. They have been shown to be used for ALD and CVD processes with water as the oxidizer in literature. As a starting point our aim would be to reproduce the results achieved in [Zhang et al.]. The process parameters highlighted in the paper are as follows (substrate temperature: -225C):

Safety Considerations

Most precursors and specifically metal organic precursors used for CVD and ALD processes tend to be pyrophoric (i.e. thermally unstable and spontaneously ignite on exposure to air) thus necessitating safety measures.

Material Considerations

Compatibility with the precursors and byproducts produced during reaction are important to consider when selecting components for the delivery system. For our given precursors the chemical groups for which we checked compatibility are: 1) ability to handle pyrophoric materials, 2) ability to resist corrosion due to water vapor, 3) compatibility with methane (by product of TMIn reaction with water) and dimethylamine gas (by product of TDMASn reaction with water)

Specific choices:

  • Stainless Steel Tubing

  • Aflas O-rings - conventionally used Viton O-rings are incompatible with dimethylamine

  • Aluminum vacuum chamber

  • Stainless steel bellow hose

  • Vacuum pump - Although the vacuum pump manufacturer warns against using the pump with pyrophoric gases, this caution can be safely disregarded in our case. Since we will be working with extremely dilute concentrations of these gases, the risk of combustion or hazardous reactions is significantly minimized. The low concentration ensures that the gases remain well within safe limits, allowing for the pump's use without compromising safety or performance.

Sourcing Precursors

DIY Substrate Heater

The goal of the DIY substrate heater is to develop a cost-effective, replicable ALD wafer heater to support thin-film deposition processes for materials research. Commercial solutions for wafer heating are often prohibitively expensive, making this tool an accessible alternative for Hacker Fab and other researchers. Existing solutions do not meet specific size, temperature, or vacuum compatibility requirements at an affordable price. By designing this tool, we contribute an open-source option tailored for ALD processes. This supports the open-source nature of Hacker Fab by enabling other researchers or users to replicate and build their own wafer heaters. It allows for a more cost-effective approach to ALD, contributing to the open-source knowledge base by providing detailed, replicable build instruction.

Heating Element Setup

  • Use 22-gauge nichrome wire to create a heating coil.

  • Arrange the wire in a zigzag pattern to cover the area of the heating plate (approximately 4.5-inch diameter).

  • Place the nichrome wire between two boron nitride plates (each 0.1-inch thick). Boron nitride provides electrical insulation while allowing efficient heat transfer.

Construction of Heating Plate

  • Mount the heating element (nichrome wire and boron nitride assembly) onto an aluminum disk (4.5-inch diameter, 0.1-inch thick). The aluminum disk acts as a heat spreader, ensuring uniform heat distribution to the wafer.

  • Secure the boron nitride plates with aluminum bolts to ensure tight contact and structural integrity.

  • Ensure that the wire ends extend outside the assembly for electrical connections.

Assembly and Connections

  • Position the aluminum plate so that it faces upward, serving as the surface for the wafer.

  • Connect the nichrome wire ends to a DC power supply. This power supply should allow adjustable voltage (up to 30V), which will control the current and regulate the temperature of the nichrome wire.

  • Attach a thermocouple to the aluminum plate for temperature monitoring. This will help ensure the wafer reaches and maintains the target temperature (300°C).

Operation

  • Gradually increase the voltage on the DC power supply to heat the nichrome wire. Use the thermocouple reading to fine-tune the voltage for achieving the desired temperature.

Specifications

  • Temperature Range: 300°C to 500°C

  • Material Compatibility: The heating element is designed to be compatible with a 4-inch wafer and is placed between aluminum and Boron Nitride plates.

  • Voltage: The heater operates with a maximum input voltage of 30V.

  • Power Requirements: The heater needs a stable DC power source capable of delivering sufficient current to reach the target temperature.

  • Thermal Uniformity: The temperature should be uniformly distributed across the wafer, verified using a laser thermometer to ensure consistent heat application during ALD processes.

  • Size: The heating element is sized to fit a 4-inch wafer, ensuring full coverage.

Voltage and temperature data

Select Vacuum-Compatible Feedthroughs

Feedthroughs are specialized components designed to pass electrical, thermal, or other signals through a vacuum boundary. For your heater, an electrical feedthrough is required.

Key Features:

  • Vacuum Compatibility: Ensure it is leak-tight, rated for the vacuum level (e.g., high vacuum or ultra-high vacuum).

  • Temperature Compatibility: The feedthrough must withstand high temperatures near the heater.

  • Electrical Capacity: Rated for the current and voltage requirements of the nichrome wire.

Common Materials:

  • Metal-to-ceramic seal feedthroughs: These use materials like stainless steel and alumina ceramics for high durability and vacuum compatibility.

  • Glass-to-metal seals: Suitable for lower voltage and current applications.

Vendors:

Feedthroughs are available from companies such as:

  • MDC Vacuum

  • Kurt J. Lesker

  • Conax Technologies

  • Allectra

Mounting the Feedthrough:

  • Install the feedthrough into a flange on the vacuum chamber (e.g., CF, KF, or ISO flange systems).

  • Use O-ring seals (Viton or Buna-N) for lower vacuum applications or indium gaskets for ultra-high vacuum.

Wire Connections

  • Inside the Chamber:

    • Connect the nichrome wire to the internal terminals of the feedthrough using vacuum-compatible connectors (e.g., nickel or stainless steel).

    • Ensure insulation with high-temperature, vacuum-compatible materials such as ceramic or polyimide.

  • Outside the Chamber:

    • Connect the power supply to the external terminals of the feedthrough.

    • Use shielded cables if electromagnetic interference is a concern.

Detailed Instructions for Assembling the Substrate Heater Component

Materials Required

  • Nichrome wire (22-gauge)

  • Boron nitride plates (2, 4-inch diameter, 0.1-inch thick)

  • Aluminum disk (1, 4-inch diameter, 0.1-inch thick)

  • Thermocouple

  • Bolts and nuts (compatible with boron nitride and aluminum plates)

  • Insulating washers (if needed, for vacuum compatibility)

  • DC power supply

  • Wire connectors

  • Heat-resistant adhesive (optional for securing wires)

Assembly Steps

Step 1: Preparation

  • Cut the wire to the appropriate length (as per your design, typically around 14 inches).

Step 2: Setting up the Heating Element

  • Wire Arrangement:

    • Lay one boron nitride plate flat on a stable surface.

    • Arrange the nichrome wire in a zigzag pattern across the surface, ensuring even coverage. Leave wire ends long enough to extend outside the assembly for electrical connections.

  • Layering:

    • Place the second boron nitride plate on top of the first, sandwiching the nichrome wire between them. Ensure the plates align perfectly.

Step 3: Mounting onto Aluminum Plate

  • Place the boron nitride and nichrome assembly onto the aluminum disk.

  • Align the pre-drilled bolt holes in all three layers (aluminum, boron nitride plates).

  • Insert bolts through the assembly, using insulating washers if needed to maintain electrical isolation.

  • Secure the bolts with nuts, tightening evenly to ensure good thermal contact without over

Step 4: Electrical Connections

  • Attach the thermocouple to the aluminum plate using thermal paste or tape for accurate temperature monitoring.

  • Use a multimeter to check for electrical continuity and verify there are no short circuits.

  • Attach the nichrome wire ends to the wire connectors and connect them to the DC

Step 5: Final Assembly

  • Seal the feedthroughs to maintain vacuum integrity.

  • Route wires for the power supply and thermocouple through vacuum chamber feedthroughs.

  • Use vacuum-compatible connectors.

  • Position the entire assembly inside the vacuum chamber

Future Testing Tasks

  • Initial Power Testing:

    • Gradually increase the voltage while monitoring the temperature using the thermocouple.

    • Record the time required to reach target temperatures (e.g., 400°C, 500°C).

  • Thermal Uniformity Testing:

    • Use a thermocouples to verify uniform heat distribution across the aluminum plate.

  • Vacuum Compatibility:

    • Test the system under vacuum conditions to ensure no leaks in the feedthroughs and proper operation of the heater.

  • Optimization of Wire Length and Voltage:

    • Experiment with different lengths of nichrome wire to find the optimal balance between power efficiency and heating uniformity.

  • Long-Term Durability Testing:

    • Run the heater for extended periods to evaluate its stability and reliability.

  • Temperature Controller Integration:

    • Test the system with a PID temperature controller to automate heating and maintain stable temperatures during operation.

  • Documentation of Results:

    • Plot temperature vs. time, power vs. temperature, and voltage vs. temperature graphs based on experimental data.

    • Note any issues or observations to refine the design.

Challenges

  • Wire Placement: Achieving uniform heating is dependent on precise placement of the nichrome wire.

  • Vacuum Constraints: The vacuum environment imposes limitations on assembly and temperature uniformity

  • Optimization of Power and Heating Time: There is a need to balance the wire length for optimal performance. A longer wire enhances heating uniformity but consumes more power and increases the time required to reach the target temperature.

Future Improvements

  • Alternative Materials: Testing circular mica heaters or other heating elements for improved thermal response times.

  • Optimization Studies: Verifying whether the aluminum disk is essential. Direct placement of the wafer on boron nitride could simplify the design without compromising functionality.

  • Enhanced Efficiency: Refining nichrome wire routing to minimize heat loss and enhance system efficiency.

  • Parameter Tuning: Finding the sweet spot between nichrome wire length and power consumption to maximize performance while minimizing energy usage and heating time.

Delivery System

System Design

For the delivery system we chose VCR connections for the gas lines in our vacuum system to ensure a reliable, leak-tight seal, essential for maintaining system integrity. These metal-to-metal sealing connections are ideal for ultra-high vacuum (UHV) and high-purity gas applications, reducing the risk of leaks, outgassing, and contamination. Their robust design and reusability also made them a practical choice for our setup, where frequent assembly and disassembly are required. We use a two-stage regulator at the carrier gas cylinder as it ensures consistent and precise pressure control, reducing the high-pressure gas from the source to a stable, manageable level for downstream components. This stability is essential for maintaining uniform gas flow in the system. The gas at the correct pressure is then delivered through a mass flow controller that regulates the flow rate of gases entering the system, providing precise control to meet process requirements. It ensures accurate delivery of gases to the precursor manifold. We are receiving a precursor manifold having three Swagelok ALD3 valves donated by the Claire & John Bertucci Nanotechnology Laboratory at CMU. The precursor manifold serves as a distribution hub, directing gases to valves. It includes multiple inlets for the precursor bubblers and an outlet to lead to the chamber, enabling the mixing or isolation of various precursors before delivery to the reaction chamber. The ALD valves in the manifold are high-speed, precise valves that control the pulsed delivery of precursors into the vacuum chamber. These valves are critical for achieving the sequential gas flows required in ALD processes. The line finally leads to the vacuum chamber designed to be a cross-flow reactor.

Components requiring connection for delivery line:

  • Chamber precursor inlet: KF25 flange fitting

  • Precursor Manifold:

    • Inlet: ¼” female VCR

    • Outlet: ¼” male VCR connector

  • MFC inlet and outlet: ⅛” NPT female connectors

  • Dual stage regulator: reduces cylinder pressure (~2000 psi) to operating pressure for Mass Flow Controller (<70 psi)

Control Systems

Components/Hardware Requiring Control

Parts to be controlled:

  1. Mass Flow Controller - Controls the amount of carrier gas flowing through the tubing per time. Requires an analog signal 0-10Vdc and power supply of 12-24 Vdc, 250mA

  2. ALD valves - Controls the duration for which precursors are open to the carrier gas line. Works on a pneumatic valve that is actuated by solenoids. Requires N2 gas input for pneumatic actuation and square wave signal of 24 Vdc with wave width equal to valve open time.

  1. Delivery line and substrate heaters - Controls the temperature of the gas lines and substrate holder surface. Requires control of voltage and current being delivered to the heating element to modulate based on reading from the thermocouple.

  2. Throttle Valve - Controls the pressure of the vacuum chamber by modulating the evacuation rate of the pump based on current pressure.

Outline of controls

Control parts using LabVIEW and RaspberryPi (given the number of different signals and components we decided to use a Pi instead of using an Arduino)

RaspberryPi is great for handling low-level hardware tasks, such as controlling valves, relays, and sensors. It can read analog or digital signals, control actuators (e.g., motors or heating elements), and interact with sensors that LabVIEW can’t interface with directly.

Progress

The ALD valves are controlled based on their status in a truth table, where each row corresponds to a specific step of the ALD cycle. The truth table defines the ON/OFF state of each valve, with True indicating the valve is ON and False indicating it is OFF. The appropriate row of the table is accessed dynamically, depending on the current step of the cycle.

To implement this control, a relay board is used to interface the ALD valves with a 24V DC wall adapter. The relay board switches the power supply to the valves according to the truth table commands, ensuring precise timing and coordination for each step of the ALD process. For depositing Indium Tin Oxide (ITO), which requires two metal precursors, the ALD valve operation is determined by the desired ratio of the two precursors. To achieve this, a sequential block is used to calculate the current cycle number in the ALD process. Based on the cycle number and the specified precursor ratio, the sequential logic selects which metal precursor valve to open. This setup allows for reliable and automated control of the gas delivery system during operation.

To control the heating elements, temperature data is collected from thermocouples at a specified sampling rate and frequency using a DAQ (Data Acquisition) system. The measured temperature readings are averaged to calculate a mean temperature, which provides a stable input for feedback control. The mean measured temperature and the target temperature are then fed into a PID (Proportional-Integral-Derivative) controller. The PID computes the required voltage adjustment to maintain the target temperature by supplying the appropriate voltage to the resistive heating elements. This feedback loop ensures precise temperature control, critical for maintaining process stability and uniformity during operation.

We are still in the process of testing this and are currently figuring out how to use DAQ hats on Raspberry Pi to collect the data at a given frequency.

Challenges

Vacuum Chamber + Vacuum Pump

Motivation

The vacuum chamber and the vacuum pump are the foundation of the ALD machine, providing the controlled environment necessary for thin-film deposition on the 4 inch diameter wafer. Initially, the idea of machining the vacuum chamber in-house was considered, but quickly decided against due to the precision needed to manufacture a reliable vacuum chamber, and given that the ALD machine project is on a quickly-moving timeline, This project addresses these gaps with a cost-effective and adaptable design, which was easily outsourced and purchased, for academic and research settings.

Technical Requirements

  • Vacuum Pump Range: The vacuum pump and chamber should be able to reach mTorr levels of vacuum to reach precursor baseline pressures.

  • Temperature Requirements: The vacuum chamber should be able to withstand temperatures up to 500°C, in order to align with precursor pressures and thermal evaporation benchmarks, and to keep the wafer at 300°C

  • Vacuum Chamber Material: Aluminum for affordability and compatibility with high vacuum and temperature conditions.

  • Port Configurations: Modular design to accommodate multiple gas inlets and precursor integration.

Design Process

With the technical requirements in mind and once the precursors were selected (and ITO was decided upon), the design process for the vacuum pump and vacuum chamber evolved quickly over the first half of the semester. Originally, the vacuum chamber had a technical requirement of being made of only stainless steel, avoiding aluminum due to concerns about compatibility with the gases. Eventually, aluminum was reconsidered to be a vacuum chamber material option, after double-checking its compatibility with the gases.

Vacuum Pump Selection + Design Choices

For the vacuum pump, extensive research was conducted to identify a pump capable of maintaining the desired vacuum range without overloading the budget. It was necessary to ensure compatibility with the fact that it would be used with gases as well. Despite initial hesitation due to the high cost of some components, we finalized the order for the Edwards nXDS6i Dry Scroll Vacuum Pump, as it has been used for other DIY ALD machines in the past and is known to be reliable for these purposes. This step was crucial to ensuring the entire vacuum system could function as intended without compromising the ALD process's precision.

Vacuum Chamber Selection + Design Choices

A major milestone was sourcing the 9x9x9 modular vacuum chamber from Ideal Vacuum, initially inspired by using the 6x6x6 Ideal Vacuum chamber that’s used for the thermal evaporator. We noticed that the inside temperatures of the thermal evaporator reach even higher temperatures than needed for ALD, even though on the Ideal Vacuum site, the specs say it isn’t rated for that high of a temperature. This milestone, though, was guided by its versatility, as the modular port placements allowed for customizable configurations. Additionally, this chamber offered a practical balance between cost and performance, addressing both budget constraints and functional needs. To further refine this selection, the 9x9x9 pre-selected component kits were compared with the individual necessary components (with itemized lists of those individual components), weighing the trade-offs between cost savings and assembly complexity. All individual components ordered are listed in the BOM shown in the Appendix.

As shown in the BOM for vacuum chamber components, the 6 sides to the modular vacuum chamber from Ideal Vacuum which were ordered, with reasoning as to why, were:

  1. One (1) plate with a viewing window and door hinge, to easily place and remove the 4” diameter wafer.

  2. One (1) plate with four (4) KF16 inlets in order to connect the pressure gauge, temperature probe, and electrical lead. Each of those three components connected to the ALD account for one KF16 inlet, leaving a single KF16 inlet covered by a blank flange, and reserved for if future leads are needed.

  3. Two (2) plates with single, centered KF25 inlets, to be placed on the top and bottom of the cube, with the top inlet being the gas inlet, or the gas entering the vacuum chamber, and the bottom outlet being the vacuum chamber’s connection to the dry scroll vacuum pump and throttle, or where the gas will exit the chamber. This top-to-bottom placement is to prompt laminar flow of the gases and increase chances of even deposition throughout the wafer. The gas flow is depicted below.

  4. Two (2) blank plates

Vacuum Chamber + Vacuum Pump Baseline Test

As of the end of the Fall 2024 semester, the vacuum chamber has been fully assembled, using only parts provided by Ideal Vacuum including Viton o-rings and o-ring fittings, and connected to the pressure gauge and vacuum pump. It’s important to note that this vacuum chamber assembly is only temporary, as Viton is not compatible with the gases used for the Hacker Fab ALD machine. A baseline vacuum test was conducted with the Viton o-rings overnight to see how much of a vacuum could be achieved with the standard assembly, and a rough vacuum of <100 mTorr was achieved. There are numerous reasons as to why the vacuum chamber wasn’t able to reach the single digits of the mTorr range during this baseline test, such as the fact that the pressure gauge we used was powered by a cord rated for half of the required voltage to power the pressure gauge.

Vacuum Chamber O-ring Material Compatibility

Since incompatible Viton o-rings were included with the hardware kit for assembling the Ideal Vacuum chamber, Aflas is currently being considered as a possible replacement option, due to its compatibility and temperature rating. Extreme Viton could also be considered, as it’s also compatible, but for o-ring replacement testing, only Aflas materials have been ordered. Since the extra large o-rings that are used to seal the vacuum chamber plates themselves (not the feedthrough ports) are so specific in dimension that they would need to be custom-made, which is a costly to schedule and budget, Aflas cording with similar thickness was ordered and can be cut to size. Aflas o-rings for KF16 and KF25 fittings were also ordered from McMaster to eventually replace in the vacuum chamber. The efficiency of replacing the Viton seals with Aflas cording and slightly smaller Aflas o-rings has yet to be determined and tested.

Next Steps

  • Replace incompatible Viton o-rings with Aflas o-rings to ensure compatibility and improve system reliability.

  • Conduct a new baseline vacuum test using Aflas o-rings for comparison with initial tests conducted with Viton o-rings.

  • Install a KF25 elbow-shaped connector to reduce the tubing bending radius and prevent stress on connections.

Future Improvements

  • Design some type of stand below the vacuum chamber to incorporate additional space beneath it, allowing better accommodation of stiff tubing leading to the vacuum pump, if KF25 elbow connector still leaves a tight fit.

  • Explore alternative compatible sealing solutions or materials to simplify the process of replacing the Viton o-rings, if the Aflas cording and current Aflas o-rings are insufficient in reaching vacuum specs.

  • Optimize the vacuum chamber setup to ensure sustained performance at rough vacuum levels (<100 mTorr).

Precursor Delivery Storage

Motivation

Safe and efficient storage and handling of ALD precursors are critical to ensuring consistent thin-film deposition. An existing precursor storage solution for the specific requirements of Hacker Fab’s ALD machine doesn’t exist on the market, at least not at any reasonable price point. While other DIY ALD machines don’t include any housing for the precursor ampoules at all, and are simply attached to only the ALD valves and tubing themselves, those same DIY ALD machines normally don’t handle pyrophoric precursors. Since the Hacker Fab ALD Machine is for ITO deposition purposes, and the precursors aren’t as inert, designing a precursor delivery storage, which the gases can travel through, and be directly connected to an exhaust, is a good preventative measure to take (to minimize risk with possible combustion/flames).

Technical Requirements

  • Storage Capacity: Holds the precursor manifold with three ALD valves and three gas ampoules. Potentially has room to store the mass flow controller at some point when incorporated:

  • Inlets and outlets: Contains holes to attach proper fittings for an exhaust connection, carrier gas inlet, and a gas outlet.

  • Materials: Made out of aluminum for precursor compatibility.

  • Miscellaneous: Ampoules should be easy to access in order to for simpler replacement when necessary.

Design Process

The precursor storage design process began by defining the requirements for safely and efficiently housing three precursors, each with dedicated gas lines and secure connections to the vacuum chamber. Aluminum was selected as a precursor delivery storage material for its corrosion resistance and ease of machining, ensuring compatibility with the chemicals and the system's operational conditions.

The initial design concepts, shown below, were sketched to visualize how the ampoules would be held and integrated into the vacuum chamber setup. These sketches evolved into more detailed CAD models (shown below), created in SolidWorks, with a focus on designing for sheet metal fabrication, since that would be the most cost effective. The flat pattern designs incorporated fold lines for easy assembly, allowing the components to be cut using waterjet or manual machining methods.

Initial conceptual design sketches of the precursor delivery storage system

Initial CAD screenshots of the precursor delivery storage system assembly (left), and an example of one of the components from the assembly folded and unfolded (right)

Since the TechSpark makerspace's water jet was out of order, we considered outsourcing the water jetting for the sheet metal. An initial quote from Atomatic for waterjet cutting parts at $130 per piece (ridiculously overpriced) prompted a pivot to sourcing 5052 Aluminum sheet metal with a thickness of 0.05”, from McMaster-Carr, since 5052 Aluminum is an easy-to-bend metal. I was able to begin the fabrication and assembly process and complete fabrication of 3 components, leaving the door and manifold shelf to be fabricated and assembled next semester. Using the CAD designs as a rough guide, and adding a few extra inches in every direction to ensure there was enough space, I cut the sheet metal to size using either the shearer or the bandsaw. I then bent right angles where necessary using the bending machine at Techspark, and then holes were drilled and parts were riveted together manually using aluminum rivets. While this reduced costs drastically while maintaining functionality, the fabrication and assembly process (mainly the manual riveting) was extremely time consuming and physically exhausting.

Images of the fabrication and assembly process of the first few components of the storage assembly

Due to time constraints, we weren't able to complete the entire assembly, but believe that this is for the best, as I’m sure many design improvements will be implemented next semester. One example of this is for redesigning the shelf which holds the manifold and ampoules. Next semester’s ALD team should consider whether or not the heating block is either usable (we don’t know if it’s programmable currently), or if heating tape would suffice. Due to the heating block’s heft (it’s made out of solid metal), it would be beneficial to consider removing it if possible. Shown below are a few quick sketches of possible shelf redesigns depending on if the manifold’s heater block is incorporated or not.

Conceptual sketches displaying the various options for shelving manifold, ALD valves, and precursor ampoules

Next Steps

  • Complete the remaining assembly for the precursor delivery storage system, addressing any precision or alignment issues from the manual fabrication process.

  • Evaluate the usability and efficiency of the manifold's heating block in the current setup to determine its suitability for sustained operation.

  • Investigate alternative heating solutions, such as heating tape, to replace the manifold's heating block if it proves impractical due to its weight or solid metal construction.

Future Improvements

  • Refine the design for easier replication and modularity, considering lessons learned during manual fabrication.

  • Reassess shelf configurations in the precursor storage system to accommodate potential design changes stemming from heating block decisions.

  • Incorporate design elements that improve manufacturing precision and reduce the labor-intensive nature of assembly.

References

Z. Zhang et al., "Atomically Thin Indium-Tin-Oxide Transistors Enabled by Atomic Layer Deposition," in IEEE Transactions on Electron Devices, vol. 69, no. 1, pp. 231-236, Jan. 2022, doi: 10.1109/TED.2021.3129707.

Sputtering Chamber

Sputtering deposition involves using an RF or DC capacitively coupled plasma to bombard a target material with ions fast enough for pieces of the material to fall down onto a chip below for thin film.

Version 2

Below are pictures of the current V2 sputtering chamber. This test was conducted just last week, so documentation for construction, BOM, operation are forthcoming.

The huge improvement is the completely redesigned sputter head, which allows for much strong magnets to confine the plasma to a small ring at the target. This makes it our first sputtering chamber capable of both RF and DC metal and oxide deposition at highly performant speeds. bleow is evidence of sputtering for aluminum.

documentation for construction, BOM, operation are forthcoming.

Version 1

Metrology / Characterization

FabuBlox

(5 min)

(5 min)

(30 min)

(18 min)

This stuff is regularly communicated as complex , and requires the permission of to work on it. We are starting from 1960’s level complexity and working our way up to modern complexity.

(30 min)

(∞)

(13 min)

Transistor → → basic logic circuitry (timers, counters, latches, shift registers, etc.) → → CPU

So we try to debug this by finding literature that debugged something similar, or often we simply design and run more experiments. Skim through pages 172-176 (bottom corner number, not pdf page number) of . Their transistors have very similar issues to ours. When you read this document, the answers are behind a huge layer of jargon and acronyms that make the barrier to entry for understanding extremely high.

Our source-drain is dominated by an aluminum metal-to-silicon instead of doping

We've only made NMOS devices so far, but there are to be made. That means our process data corresponds to NMOS only, but most process steps can be generalized to any process if documented properly.

Here is a of our most recent spin coater V1 build. More info to come soon!

List of improvements over

Shared, more concise notes live here on Gitbook. See

If you already have a stepper built and you're looking for information on how to operate the tool, check out our !

Our design was based on and ’ versions of this tool, which is essentially a projector connected to a microscope. We use a 10x objective for demagnification and a mechanical XYZ stage for positioning.

Instead of an off the shelf projector with a flimsy plastic housing, we switched to the . This allows for a more robust physical connection to the projector housing, thus eliminating vibrations. It also has much better documentation.

Swapping to LEDs instead of the broad spectrum mercury lamp removes the need to constantly swap filters, which introduced random perturbations from touching the optics. We replaced the stock blue LED with a 410 nm LED mounted on a custom PCB. The PCB design files can be found .

*

or**

Connects the optics to the projector. Matches hole pattern on DLP housing and .

(link to )

There are several options for fabricating these two parts: the Base Plate and Adapter Plate. If you have access to a water jet, you may cut these parts from 1/4" aluminum plate, available on . Otherwise you can order the parts from , or another online CNC shop.

shopping cart with the parts already uploaded and configured. This has not been tested yet.

Base Plate: for a drawing to have open while drilling all the holes. Start with a center drill then use an appropriately sized drill bit for M4 and M6 holes. You may also switch to 8-32 and 1/4-20 if you already have the taps for those, and no other parts will change if you do so.

The PCB Gerber files for our UV LED can be found . We provide a screenshot of the layout in Altium and a 3D render of the PCB below.

You can order it through your PCB manufacturer of choice (we used JLCPCB). However, note that the PCB is . This is because the LEDs draw several amps of current in operation. To ensure that the PCB doesn't melt, you should use copper core to facilitate better heat flow. When ordering the PCB, the manufacturer might send you an email asking about a missing heatsink file. In this case, please respond that this project does not include a direct heatsink, as the copper core PCB itself is designed to handle the thermal management.

Below is a completed version of the PCB - note the polarity! This image shows the correct orientation of the LEDs (credit to University of Utah for the photo). If you have it flipped, then the projector will project an image briefly before shutting itself off:

Plug in the projector over USB and use the to set the LED current to 150mA.

t

See for interactive assembly help (select option 3)

Make sure this camera tube is 82.3 mm long. We calculate this number by subtracting the various component lengths from the standard microscope objective back focal length of 160mm: 160 - 17.5 (c-mount camera) - 22.1 (objective tube) - 38.1 (beamsplitter cube). (NOTE: The calculation here is done incorrectly, but we have successfully been using it without major issues. The correct back focal length is 150mm, see )

(link to )

Flash the Arduino with GRBL following the instructions in the below (it may display as "Not found", but we have found that the link works anyway). For more info about the CNC shield, see the original designer's page below.

We highly recommend using a Linux-based terminal on your Windows system for installation. One option is the . The following instructions assume you are using this terminal environment.

Open git terminal. Check if you have Python 3.10 already installed on your system by running py -3.10 -V. If no installation is present, download and install Python 3.10 from the .

Install necessary software dependencies. Follow the instructions on the for instructions on how to set up a Python virtual environment for this purpose.

If you are using the FLIR camera, install FLIR camera drivers. Also install the FLIR Spinview GUI to view camera output. For integrating this within the GUI, follow the instructions in

For instructions on how to use the Stepper GUI software (including troubleshooting), please see the .

Create an account on the Flir website (), or, if you already have one, sign in.

Download the Flir Spinnaker SDK () for Windows.

To write a Flir camera driver compatible with the rest of the software, you must conform to the stepper's . Within your custom "FlirCamera" class, which should be defined as a subclass of CameraModule and a Flir event handler, we recommend implementing the following functions:

Wear whenever light leakage from the projector is possible.

Reference Datasheets
  1. ToF Laser diode driver

  2. Blu-Ray Laser Diode Driver

  3. Blu-Ray Laser Diode

  4. Photo Detector IC

  5. CMOS to LVDS Driver

After purchasing and receiving all parts outlined in the , follow the step-by-step process to assemble the vacuum chamber.

After assembling these parts together, connect the copper power feedthroughs to either end of the tungsten filament using an .

can be used to safely insulate the metal and prevent electrical misconnections.

For a description of what the team at CMU is working on in Spring 2025, check out !

A complete list of parts and components used in making the DIY ALD system can be found .

Our work thus far has been focused on machine design, largely drawing from two papers on “DIY” ALD machines; ” by Michael Lubitz, and “” by Pamburayi Mpofu. Each of these papers describes their machine design followed by some process development where they describe the settings (ie. temperatures and precursors deposition times) used in their initial depositions.

The compatibility of o-ring materials was checked on the following sources:

Given the safety considerations involved in handling the pyrophoric precursors, the sourcing of materials for ITO deposition is managed by the Claire & John Bertucci Nanotechnology Laboratory staff. They ensure that all necessary precautions are taken during the procurement, handling, and storage of the chemicals. The required precursors have been ordered from Strem Chemicals, a trusted supplier known for providing high-quality materials for advanced research and industrial applications. ,

is a graphical programming environment designed for system control, data acquisition, and automation. Easy to use for engineers and it provides the ability to quickly prototype control systems for complex setups.

RaspberryPi 5 does not come with Python 2; hence, getting LabVIEW to run on it is still something we are figuring out. ()

: This document explains the initial thought and design process for this delivery storage.

: This folder contains all SolidWorks CAD files and assemblies used to plan the storage design more accurately, get outsourced water jetting quotes, and to begin the in-house fabrication process.

: This folder contains screenshots of the outsourced waterjet quotes from Atomatic, which we decided not to go through with, but are reference points as to why we decided to attempt manufacturing in-house.

” by Michael Lubitz

“” by Pamburayi Mpofu

Refer to . Note some conclusions made about power supply specifications and chamber problems have been resolved in v2 assembly and experimentation.

For a description of what the team at CMU is working on in Spring 2025, check out !

Simple MOSFET intro video
Sam’s Youtube video overview
Device Physics Overview
Before we had transistors, we had lightbulbs
magic
billionaires
The creation of the blue LED
Fabublox
How we turn sand to intelligence
Making logic gates from transistors
logic gates
architecture abstractions that people made up over decades
TinyTapeout Video Example: Making ASIC
this document
Schottky junction
so
many
more
things
BOM
Spin Coater V1
SOP
Sam Zeloof
Huygens Optics
TI DLPDLCR471TPEVM evaluation board
here
McMaster
SendCutSend
Xometry
Click here for a SendCutSend
Click here
here
copper core
LightCrafter GUI software
CAD
this page
Link
official git terminal
official download link
GitHub repository
Standard Operating Procedures
https://www.flir.com/
https://www.flir.com/products/spinnaker-sdk/
CameraModule API
UV-blocking glasses
https://www.infineon.com/dgdl/Infineon-IRS9102C-DataSheet-v01_00-EN.pdf?fileId=8ac78c8c919c9f9d01923335dc1b43c5
https://www.renesas.com/en/document/sds/isl58797-data-short?r=506001
https://www.renesas.com/en/document/dst/isl58792-datasheet
https://rocelec.widen.net/view/pdf/eyrlshzeil/ATMLS04748-1.pdf?t.download=true&u=5oefqw
https://media.digikey.com/pdf/Data%20Sheets/Sharp%20PDFs/GH04P21A2GE.pdf
https://www.digchip.com/datasheets/download_datasheet.php?id=3143605&part-number=MLX75012
https://www.analog.com/en/products/adn4661.html
home page for info
Optional: FLIR Spinnaker SDK (for software developers)

Oxide

Bubbler temperature

Pulse time

Co-reactant pulse time

Process pressure

Purge time

In2O3

60oC

0.625s

0.75s

100 mTorr

10s

SnO2

60oC

2s

1s

100 mTorr

30s

Parameter

Value

Wafer Diameter

4 inches

Temperature Range

300°C-500°C

Power Supply Voltage

30V (max)

Heater Material

Nichrome wire (22 gauge)

Heat Transfer Medium

Boron nitride

Structural Material

Aluminum disk

Wire Length(in)

Temperature(C)

Voltage(V)

Time to reach temp(s)

14

650

14

35

14

295

7

30

14

300

8.5

30

14

400

8.5

40

Cleaving Jig

Tube Furnace

TI
Thorlabs
Edmunds
Basler
Edmunds
Edmunds
Amazon
Amazon
Amazon
Amazon
Amazon
Amazon
Amazon
Amazon
Amazon
Amazon
Amazon
Amazon
Digikey
Digikey
Stepper V2 Assembly
Adapter plate
Thorlabs flange
Base Plate
40mm Stepper Mount
SW
Sliding Shaft Coupler
Spacer
60mm Theta to 40mm XYZ Bracket
Vacuum Chuck
Stepper Software
GRBL Arduino CNC firmware
40mm Stepper Mount
SW
Sliding Shaft Coupler
Spacer
60mm Theta to 40mm XYZ Bracket
Vacuum Chuck
Evaporator Bill of Materials
Tungsten Filament
Alumina Thermal Crucible
Insulating Bucket
inline barrel connector
Ceramic beads
this document
here
“Design Of Atomic Layer Deposition Reactors For The Deposition Of Nanoparticle Embedded Thin Films
Homebuilt Reactor Design and Atomic Layer Deposition of Metal Oxide Thin Films
(1)
(2)
TMIn
TDMASn
LabVIEW
link
Precursor Case Ideation Document
ALD-precursor-storage
Atomatic quotes
“Design Of Atomic Layer Deposition Reactors For The Deposition Of Nanoparticle Embedded Thin Films
Homebuilt Reactor Design and Atomic Layer Deposition of Metal Oxide Thin Films
this documentation
this document
Logo

Aluminum

  • get pure aluminum

  • mixed with SI

  • need thermal evaporator

Chemicals / Materials

Semiconductor Parameter Analyzer

  • high level: we can relate all the process parameters to electrical characteristics

  • all the tests we can do

    • what they tell us, how many probes needed, etc.

    • example pictures, resulting curves

  • lots of great diagrams from Anirud, Icey, Ahmet, Joel working docs we can update with


Semiconductor Parameter Analyzer

Not all transistors are created equal. There is an immense amount of information within the electrical characteristics of the device that helps with optimizing the manufacturing process (Read Peter Van Zant Chapter 14). Below is an example of an ideal IV curve from a textbook, and the first IV curves taken in the Hacker Fab. While our curves aren’t perfect, they do exhibit transistor-like-characteristics 🙂.

IV curves are not the only tests that can be done with a parameter analyzer. With enough data, trends in these different curves can be directly associated with process parameters.

Probe stations are traditionally heavy desktop machines that hold probe manipulators. The purpose of the probe station itself is to precisely move the tungsten probe in order to make contact with the contacts of the device. This typically means moving 3 individual probes to the gate, source, and drain contacts, and another to contact bulk.

Probe Station + simple diagram of contact locations

These probes are attached to the back of the Semiconductor Parameter Analyzer - precision instruments consisting of multiple SMUs (Source Measure Units) and a built-in computer to control them and store readings. Source Measure Units are glorified power supplies with built-in voltmeters and ammeters - they are very precise instruments that are able to supply voltage or current through the probes, and simultaneously read voltage or current.

CV Measurements

Equipment

  • Capacitance-voltage meter (i.e. Keithley 4200-SCS Semiconductor Parameter Analyzer)

Procedure

Prepare the Transistor:

  • Ensure that the transistor surface is as clean as possible to minimize probe-to-pad contact issues. It is helpful to have another user with you to properly align and contact the pads without damaging other probes or the transistor surface.

  • Ensure that the transistor is properly connected and biased for C-V measurements (i.e. for an NMOS transistor, ground the bulk and source contacts, apply voltage from the gate or drain depending on the type of measurement).

Measurement Setup:

Voltage Sweep:

  • If using an NMOS transistor with 3 terminals (i.e. no bulk contact), turn off the bulk probe on the KITE interface, ground the source pad, apply a small-signal AC voltage to the drain pad (constant frequency ideally above 100 Hz, low frequency measurements will be performed later), apply a large-signal DC voltage sweep to the gate pad (-8V to +8V for our case). Measure the total capacitance from the gate pad as well. If your NMOS transistor has a bulk pad as well, it is possible to modulate the bulk potential and model threshold voltage dependencies. For regular use, grounding the bulk and/or at least having it at the same potential as the source pad is ideal.

  • It is also possible to model the MOSFET as a MOS capacitor instead by connecting source and drain to the ground and only by sweeping the gate voltage. This “topology” may be deemed ideal to extract capacitive parasitics from the measured total gate capacitance:

    • When in accumulation (VGS < 0), mobile holes from the p-type substrate form a dielectric region due to being attracted under the gate. The total gate capacitance is the sum of the gate-source and gate-drain overlap capacitances, along with the gate-bulk capacitance.

    • When in depletion (VGS is a small but positive voltage), some number of mobile electrons are attracted under the gate but not enough to fully invert the net channel charge, therefore the region under the gate simply becomes devoid of mobile charges, but becomes more negative as the gate voltage is increased. Total capacitance is the sum of the overlap capacitances (which are often neglected due to their small magnitude) and the oxide capacitance (between the gate oxide and the induced weak negative channel) in series with the depletion region capacitance. This parallel topology decreases the total capacitance.

    • When in inversion (VGS >> 0, much larger than the threshold voltage required to “turn on” the MOS), a substantial number of electrons are attracted under the gate such that a strong conduction channel forms. The conduction channel forms the bottom plate of this virtual capacitance, and the distance between this bottom plate and the gate decreases as the channel inversion becomes stronger (with increasing gate-source voltage), increasing the total capacitance. Apply a DC voltage sweep to the transistor, typically from negative to positive bias (usual measurement range is from -8V to +8V). Measure the capacitance at each bias voltage.

Plotting CV Curves: Plot the measured capacitance as a function of the bias voltage. Below is an example of a measured capacitance versus applied voltage (C-V) curve. Note the decrease in the total capacitance as the mode of operation changes from accumulation in the deep negative voltages to depletion as the capacitance decreases significantly. There is no bulk contact in this measured NMOS transistor, and therefore the inherent and uncontrollable modulation in the bulk potential may be preventing the change of the mode of operation from depletion to inversion (note the lack of increase in the capacitance as the gate potential approaches +8V).

Analyzing C-V Curves: The shape of the CV curve will provide information about the doping concentration in the silicon substrate.

  • Dopant Concentration (ND): To measure the concentration of the deposited donor atoms, either the source or the drain terminal of the NMOS is used with respect to the bulk. If the drain and the gate are grounded, the subsequent capacitance measurements will be done between the bulk and the source terminals. Since the source and the bulk regions are oppositely doped, they form a p-n junction with a depletion region in between. This structure presents inherent diode and capacitive properties, which is ideal for doping concentration and profile measurements. The average doping should be extracted to later calculate the Debye length (in plasma physics, the distance at which a charge (among a sea of other charges) is shielded against electrostatic forces of a charged plane, such as that of a capacitor), flat band capacitance and bulk potential.

  • Flatband Voltage: Flat band voltage is the voltage that must be applied to the gate terminal at which the metal-oxide-semiconductor interface potential becomes equal in magnitude to the built-in potential, making the surface potential zero. Since the presence of a flat band condition affects the accumulation of charges for accumulation or inversion channel formation, it is an important parameter to extract for the modeling of the threshold voltage. VFB is usually interpolated from the C-VGS curves, if and only if the doping profile is assumed to be uniform over the region and interface trap state density is large. Otherwise, measuring the flat band voltage is finicky at best and extremely difficult at worst due to our fabrication methods.

  • Metal-Semiconductor Work Function Difference: The work function difference is a key parameter in determining the threshold voltage of the MOS transistor since the WMS forms a potential barrier against the inversion of the channel. The bulk potential, which is extracted using the doping profile, is an input to WMS.

Model Fitting: As a general rule of thumb, for long-channel devices such as ours, 1 MHz is the frequency at which high-frequency measurements are performed, while low-frequency measurements are generally performed at and below 100 kHz, down to 1-10 Hz.

Use semiconductor device simulation software or a theoretical model to fit the experimental CV curve to theoretical curves, which depend on the doping concentration. This can provide a more accurate estimation of the doping concentration. See the ideal CV curve below:

Future Work

Reference Sources

Base Principles

This page contains topics that are good to know if you want to contribute to this project.

Optical

Minimum Feature Size

The minimum feature size in transistors, often referred to as the "technology node" or "process node," represents the smallest dimension of a transistor on a semiconductor chip. This size is measured in nanometers (nm) and dictates how densely transistors can be packed on a chip, which in turn influences the chip's performance, power consumption, and overall size.

Transistor sizes through the years (needs to be corrected)

Year
Node Process
Width (nm)
Length (nm)

1968

20,000 nm

100 nm

20,000 nm

1971

10,000 nm

100 nm

10,000 nm

1974

6,000 nm

100 nm

6,000 nm

1977

3,000 nm

100 nm

3,000 nm

1981

1,500 nm

100 nm

1,500 nm

1984

1,000 nm

100 nm

1,000 nm

1987

800 nm

100 nm

800 nm

1990

600 nm

100 nm

600 nm

1993

350 nm

100 nm

350 nm

1996

250 nm

100 nm

250 nm

1999

180 nm

100 nm

180 nm

2001

130 nm

100 nm

130 nm

2003

90 nm

100 nm

90 nm

2005

65 nm

100 nm

65 nm

2007

45 nm

100 nm

45 nm

2009

32 nm

100 nm

32 nm

2010

28 nm

100 nm

28 nm

2012

22 nm

100 nm

22 nm

2014

14 nm

100 nm

14 nm

2016

10 nm

100 nm

10 nm

2018

7 nm

100 nm

7 nm

2020

5 nm

100 nm

5 nm

2022

3 nm

100 nm

3 nm

Mechanical

Mechanical Resolution - Step size

The minimum needed step size can be determined by the perimeter of the writing area and the minimum spot size

  • For the largest radius (58mm) the perimeter is 364mm

  • For the smallest radius (23mm) the perimeter is 144mm

From there number of steps is calculated by:

Assuming a 290nm spot size:

  • For the largest radius (58mm) the number of steps is 1.256M

  • For the smallest radius (23mm) the number of steps is 498k

Mechanical Resolution - Repeatability

The planned approach for repeatability is closed loop control. Since the blu-ray system works on reading concentric circles each disc will have a pattern written along the ring perimeter that identifies what is the current ring radius. It will also be used to help identify the start position on the perimeter.

Maximum Wafer Size

Since this project plans to use a blu-ray drive, the working area is basically the entire readable area of a disc (including table of contents).

  • The start of the writing area for a disc is 46mm in diameter or 23mm in radius.

  • The end of the writing area for a disc is 116mm in diameter or 58mm in radius.

Therefore the writing radius is about 35mm.

Maximum Symmetrical Die

5x Symmetrical dies can fit on a disc assuming 30mm x 30mm (900mm^2)

Maximum Asymmetrical Die

4x Asymmetrical dies can fit on a disc assuming 25mm x 50mm ( 1,250mm^2 )

Disc Revolution Speed

To calculate how fast the disc needs to spin we first need to know how fast the spot we need to image is moving. the speed is dependent on how far we are from the center of the disc.

If we assume a random rotational speed in revolutions per minute (rpm), we can use the following steps to calculate how fast the imaging spot is moving:

  1. Convert rpm to revolutions per nano-second (rpns):

  1. Calculate the linear speed in nano-meters per nano-second (nm/ns):

Assuming the disc is spinning at 500rpm:

  • The smallest inner radius of the disc (23mm) is moving at roughly 1.24nm/ns

  • The largest outer radius of the disc (58mm) is moving at roughly 3.03nm/ns

Material

Positive and Negative Photo-resist (TBD)

Minimum Developed Spot Size (TBD)

Relevant Works

Blu-Ray Specifications

White Paper Blu-ray Disc Format General

White Paper Blu-ray Disc Format BD-R

White Paper Blu-ray Disc Format BD-RE

Laser Scanning Microscope (Doctor Volt)

This is a 3 part video series where Doctor Volt dissects a Blu-ray player to figure out how to make a laser scanning microscope out of it.

PT1. Blu-Ray laser tear-down

PT2. Mechanical Assembly

PT3. SW and Resolution Improvements

DVD Laser Assembly Tear-down (tsbrownie)

Functional walk through of laser head assembly

Edwin Hwu's Research Hacking Blu-Ray

Hacking Blu-ray for High-Resolution 3D printing

Hacking Blu-ray for High-Throughput 3D printing

#Paper

#Video

Hacking CD/DVD/Blu-ray Optical Pickup Unit (OPU) for Fun and Scientific Research

Hacking CD/DVD/Blu-ray for Biosensing

Tear-down of PHR-803T Laser Module (diyouware)

Future Improvements

STED Lithography (reaching 100nm and below)

IC Packaging

Hacker Fab DIY IC packaging documentation - as of May 21st, 2025.


Links


Bill of Materials

The overall cost of the package itself is $108.10, the total R&D cost of $195.09.


Motivation

Hacker Fab currently utilizes the probing station available at CMU for electrical characterization of its ICs, but these machines have proven difficult to both access and operate. Consequently, the team is developing a DIY probing station at a much lower price in hopes of bringing this capability in house. However, as our ICs eventually get more complex and start to increase in IO counts, characterization with a probing station will also require more time and effort.

In anticipation of this challenge, we are also developing a process for packaging our ICs with the EDA team in order to accommodate for the increased IO counts in order to further close the loop on the team’s process steps, and decrease the time to test more complex ICs in the future.


Introduction

The main purpose of packaging is to protect the IC from the outside world while still making proper electrical connections to other devices. Packages are often standardized into different form factors for different IO counts and applications.

Many packages in industry are designed for protection against environmental factors such as moisture as to prevent damage to the IC. Materials choices are also important especially for high performance ICs that have high heat dissipation. This means that materials used must have compatible coefficients of thermal expansion in order to prevent thermal stress from damaging the package and chip. They must also be designed to reject sufficient heat from the chip in order to prevent thermal runaway.

The varying requirements for different applications have led to many different packaging technologies in the packaging industry that each have trade offs with each other. In recent years, as the semiconductor industry encounters technical and economic limitations to higher performance gains on the ICs, advanced packaging technologies have emerged as a way to continue improving overall device performance while maintaining economic viability.

With all that said, packages being developed at Hacker Fab will have much less technical requirements due to simpler devices on our ICs and our goal of creating easily replicable solutions.


Technical Requirements

Metric

Requirement

Mechanical strength

Withstand regular handling

Signal integrity

Minimize parasitic resistance between IC and package

Portability

Adaptable to different ICs and ease of package replacement

Integration

Successfully connect to Analog Discovery 3 analyzer

Replicability

Minimize hard to access material and processes

Cost

Minimize cost where possible


Packaging Methods

Typical semiconductor packaging process goes through the following steps:

  • Wafer-level probing for known good die (KGD)

  • Wafer back grinding

  • Wafer dicing

  • Die pick & sort

  • Die attach to package

  • Wire bonding or flip chip bonding

  • Package encapsulation

  • Packaged die test

  • Final assembly onto printed circuit board (PCB)

(Hacker Fab: Packaging, Robert M. Radway, 2024)

Due to our aim for simplicity and replicability, we will not need all the steps to this process flow, and the packaging method will determine how many process steps are needed for packaging.

Two main candidates were considered for Hacker Fab:

Chip on Package

Chip on package is a standalone package that uses leads to electrically connect to the outside world. Most of the ICs we use during PCB design are packaged this way. It is consisted of the following:

  • Leadframe: Piece(s) of conductive metal that makes electrical connections from the IC to the outside world.

  • Wire bonds: Thin wires (usually gold or aluminum) that connect IO pads on the IC to the lead frame.

  • Encapsulation: Usually made of a polymer like epoxy (though not limited) that provides structural support and protection to the package by enclosing the IC, wire bonds, and leadframe.

For Hacker Fab, a chip on package will have the following manufacturing process flow:

  1. Lead frame manufacturing

  2. Chip attach to lead frame

  3. Encapsulation manufacturing

  4. Lead frame attach to encapsulation

  5. Wire bond from lead frame to chip

  6. Final chip encapsulation

  7. Possible soldering onto PCB

  8. Test with analyzer

Chip on Board

Chip on board is a package that directly makes electrical connections to pads on a PCB, consists of the following components:

  • PCB: A piece of PCB that has pads around the IC footprint for wire bonding.

  • Wire bonds: Thin wires (usually gold or aluminum) that connect IO pads on the IC to the lead frame.

  • Encapsulation: Usually made of a polymer like epoxy (though not limited) that provides structural support and protection to the package by enclosing the IC and wire bonds right on the PCB.

For Hacker Fab, a chip on board will have the following manufacturing process flow:

  1. PCB manufacturing

  2. Chip attach to PCB

  3. Wire bond from PCB to chip

  4. Encapsulation manufacturing

  5. Final chip encapsulation

  6. Test with analyzer

After evaluating the tradeoffs and benefits between the two methods for packaging, we settled on chip on board mainly due to its less complex manufacturing process and better replicability.

The design matrix for this choice is outlined below:

Complexity

Manufacture Time

Chip Protection

Damage Risk

Portability

Total

Chip on Package

0

0

1

0

1

2

Chip on Board

1

1

1

1

1

5

The major concerns regarding manufacturing complexity is mainly due to the lead frame and encapsulation. With a chip on board, the lead frame can be eliminated, reducing the step of machining small patterns on a piece of thin metal. The encapsulation is also made easier by the fact that the PCB board itself can be used as the bottom part of the encapsulation, requiring only a cap to protect the chip.


Design Process

Package Architecture

Working with the EDA team, we first had to decide the IO counts that the prototype package will accommodate. This was ultimately locked down at 16 pins due to its potential for two main tests that we would like to run:

Resistance Test

The first test we would like to run are wire bond resistance tests. The goal of this test is to determine the combined contact resistance from the wire and bond joints. The data from this test will help inform the team how much resistance our package introduces between the analyzer and the IC, allowing us to more accurately characterize our devices.

The 16 pins will be used to test 8 rows of resistance paths with varying widths of doped silicon. The IV curves will provide a correlation between width and resistance that will be used to determine total contact resistance of the circuit.

NMOS Characterization

The second test we would like to perform is with NMOS transistors designed by the EDA team.

The 16 pins will allow us to test 5 transistor devices at once with the analyzer (5x3 terminals per MOSFET + 1 GND). This will allow us to validate our package design’s viability for testing devices in Hacker Fab.


Wire bonding

As explained before, wire bonding connects the IC’s IO pads to metal pads on either the PCB or leadframe, but how is this done?

There are two main methods for wire bonding:

Wedge Bonding

Wedge bonding is achieved first by pressing the wire onto the bond substrate using a fine metal tip, then ultrasonic energy is applied to make the bond. The ultrasonic energy both helps rub off contaminants and oxides as well as facilitating intermetal diffusion, allowing the wire to fuse with its substrate. After the bond is achieved, the tip is then moved to make the next bond, or to break the wire, leaving a wedge shape on the substrate.

Ball Bonding

Ball bonding is achieved with a fine metal tip pressing the wire down on the substrate as well, but the bond is formed by applying heat to the tip, causing the wire to deform then bond to the substrate. This is called thermocompression. When moving the tip away to break the wire after bonding is finished, the tip will leave a ball shape at the first bond and a crescent at the second bond.

We are planning on using wedge bonding for our packaging due to its higher availability on campus and smaller bond footprint allowing for more margin of error during bonding.

The wire material we are planning to use is aluminum for a number of reasons. Since the team has the most experience with aluminum thermal evaporation, using aluminum wire to bond to aluminum pads on the IC will pose the least risks to defects, especially given our uncertainty of potential failure modes on the IC side. Wedge bonding with aluminum also has much higher mechanical reliability than gold and requires lower temperatures, thus further lowering the failure risk.

Based on recommendations from the lab, we have given some IO pad design parameters as well. The aluminum bonding pads are set to be at least 200µm by 200µm and at least 3µm tall, with about 300µm to 500µm spacing between pads. The EDA team has also designed the resistor pattern with multiple sizes of bond pads to determine the size that will yield the most performance for our team.


Package Design

The package itself is a smaller piece of PCB with the aforementioned 16 IO pins + 4 GND pins in a dual-inline configuration. The IO pads are also dual-inline on either side of the chip footprint.

The encapsulation was planned to be a 3D printed cap secured with bolts to ensure protection of the IC and wire bonds. The bolted connections will allow for easy removal of the cap to inspect for defects and wire bond failure, as well as giving us the option to redo any failed wire bonds. Since we do not expect to use the test chips for extended periods of time or in harsh conditions, moisture protection with hermetic sealing is not considered within scope.

Chip on Board Footprint

Starting with the footprint design, I referenced common aluminum wire bonding design rules to determine how far the IO pads should be from the chip itself, which should be at least 1.5X the thickness of the chip. With our chips being 0.525 mm, the minimum gap should be 0.7875 mm.

Due to the manual method of chip dicing, I set a conservative estimate of chip size ranging from 10 mm to 14 mm on each side. With both of these dimensions in mind, I was able to roughly plan the footprint layout and confirm with the EDA team:

These PCB IO pads will need to be as small as possible while still falling within manufacturing limits in order to minimize the wire bond lengths. This is important for both reducing wire failure and parasitic resistance.

I set the PCB pads to be 0.5 x 1.5 mm with 0.5 mm gaps, which are slightly larger than the recommendations given by a graduate student who has worked on chip on board packaging before:

With these constraints in mind, I followed by creating a custom footprint for the chip in Altium Designer. At this stage, I added more tolerances to the chip gap due to lack of familiarity with the process, resulting in a gap of 1.226 mm from the largest anticipated chip size of 14x14 mm.

In addition to the footprint, I also created a custom schematic symbol for the resistor chip that contains proper pin labeling.

Schematic and Layout

Moving on to over schematic design, I connected the chip pins to two female headers with 10 positions each, leaving the last 4 for ground connections.

I also added 0603 decoupling capacitors (tentatively set at 0.1 uF) to each pin as an option for future chips that may be used for the package.

Next is layout, which uses a two layer board due to the lack of complexity and has the ground plane on the bottom layer. There are also 4 mounting holes for encapsulation mounting.

Finally, I exported the board design and designed a 3D printed cap around the chip. The cap uses four M2 screws and nuts for mounting and has 7.5mm of of vertical space for wire bond loop heights.

For the sake of simplicity and cost, we will be using readily available adhesives to perform the chip attach to board step. This should not pose major concerns especially due to the fact that these test packages are not expected to encounter significant thermal loading and since the team is not planning on doing the wafer thinning step, risk of chip cracking is minimal.


Motherboard Design

The motherboard is a larger PCB that can accommodate two packages by accepting them with female breadboard headers. Has a 30 pin connector to meet the IO needs of the Analog Discovery 3. This approach will allow us to easily swap out packages without having to spend extra time redoing all the connections to the analyzer.

Schematics and Layout

Due to time constraints, the motherboard was designed to house two packages.

Each package slot has two male headers with 15 positions each.

Each pin has an optional pull up and pull down resistor for eventual switching functions on chip in mind. The pull down resistors can also be used with a 0 Ω jumper to short the pin to GND, and the pull up slot can also use the same jumper when the function is not needed.

Additionally, each of the output pins has an option for decoupling capacitors.

Like the package, all components are standardized to 0603. Also due to time constraints with assembly, additional jumpers for the pull up and pull down connections were not added.

Due to the number of pins that need to be routed, the board has four layers.

Once the board was finished, the step file was imported into CAD, and 4 M3 screw mounted bumpers were added as well.


Sourcing and Manufacturing

Initially the PCBs were planned to be milled in house, but this was later changed to outsourcing for the following reasons:

  • Better replicability and access for others, PCB mill is not accessible to everyone

  • Reasonably low cost to outsource PCB manufacturing

  • More design freedom, not limited to to two layers and can add vias

  • For Al wire bonding, PCB bonding pads with ENIG (Electroless Nickel Immersion Gold) plating is recommended for high bonding quality

Thus we outsourced board manufacturing to JLC PCB.

The encapsulation was able to be printed in house out of ABS easily.

The remaining components were sourced from Digikey and McMaster-Carr.


Assembly

Once the PCBs arrived, a combination of solder reflow and hand soldering was used to connect all the components.

Finally, the resistor chip #656 from the EDA team was adhered with double sided tape and wire bonded to the package board. Due to time constraints, the other resistor chip #657 was not wired. The NMOS chip was not fabricated in time.

Due to manufacturing errors, only four resistors on the chip were good for wire bonding for resistance testing.

We found that setting the bonding power to 300 yielded good results. Due to the asymmetry of chip pad placement the two sides don’t have identical wire lengths (~5mm vs ~7mm).

During the wire bonding process, there were multiple issues:

  • PCB pads are too far away from the chip

    • Longer bonds are much more difficult to do

  • PCB pads are also too spaced out compared to the chip pads, leading to longer wires and mismatch in intended pinouts

  • Bonds should’ve been made before putting in the headers for more rigid fixturing

    • Lack of rigidity results in loss of ultrasonic energy

    • Double sided tape is also not ideal for the same reason

Lastly, the encapsulation and hardware are installed, completing the package.


Testing and Validation

Wire Bonding Test

While waiting for the PCBs to arrive, I did a few wire bonding tests with spare chips from the lab to identify likely failure points in the wire bonding process

Conclusions from the test:

  • Confirmed that thin and small aluminum pads are very susceptible to flaking off the chip

  • The most likely failure points were at the wedges where bonding occurs, likely due to the sharp geometry creating high stress points


Resistance Test

While the original goal was to get IV curves with the Analog Discovery 3, we were not able to do this in time due to needing a specific current-power adapter. As a result we took resistance measurements with a multimeter on the four resistors and used those values for analysis.

For this set of resistors, the chip pads are 400 x 250 x 3 um in dimension, and the n-channel resistors have widths of 75, 150, 225, and 300 um.

Width

Resistance

75 um

1168 Ω

150 um

579 Ω

225 um

408 Ω

300 um

311.5 Ω

Using this data, I was able to plot measured resistance to the reciprocal of channel width to observe a linear relationship. The intercept represents the total parasitic and contact resistances from the wire bonds and chip pads:

Additionally, the pure contact resistance from the bond points and chip pads can be extrapolated by subtracting the parasitic resistance from the Al wires:

The resistance plots are as follows:

From the analysis, the following is concluded:

  • Total parasitic resistance per connection: 11 Ω

  • Contact resistance per connection: 10.6755 Ω

  • Total aluminum wire parasitic resistance: 0.649 Ω


Conclusion and Future Plans

The project has proven successful over the course of the semester. Despite not all the initial project deliverables being met, I was able work towards a successful packaging solution for Hacker Fab and prove its functionality.

Below are actions and improvements for future semesters:

  • Wire bond chip #657

  • Obtain IV curves from both resistor chips with the Analog Discovery 3

  • Package NMOS chips and verify their characteristics with the Analog Discovery 3

  • Modify Altium footprint to close the gap between chip and PCB pads for easier wire bondin

Additionally, below are potential projects to look into for future semesters:

  • DIY wafer dicer that allows for more accurate chip sizes

  • Revisit chip in package through metal plating on resin 3D prints

  • Flip chip on board packaging with nickel plated aluminum pads and solder reflow

This semester’s progress serves as a first step to packaging for metrology at Hacker Fab, and hopefully as we make progress toward more complex devices packaging can facilitate efficient testing for those devices.


References

Hacker Fab: Packaging, Robert M. Radway, 2024.


Automated Spin Coater

Automating our existing spin coater whilst integrating heating and liquid dispensing systems.

Lab Automation

Automating the Lab Process

What is Lab Auto?

Lab Auto's goal is to automate the steps of the NMOS process for Hacker Fab. This will take the form of a lab robot with integrated machines for each step of the process. Currently, we're focusing on an automated spin coater that will receive a blank chip and spin on HMDS and photoresist, with liquid dispensing and baking capabilities.

Specs

Our Subprojects

Probe Station

A step-by-step guide on working with the Probe Station

To learn more about the hardware and software involved, refer:


Software

Probing the Chip

Connections

  1. If not using the tester adapter, connect W2 to the Gate probe and W1 to the Drain probe.

  2. The Source and Body probes must be connected to GND.

  3. The +1 & -1 connections should be connected around the drain resistor.

  4. +2 should be connected to the Drain terminal.

To-do:

Add images with the connections, more specifics.

  • simple mechanical probe manipulator

  • needs 4 probes (show where each of them are used)

Piezo Nanopositioner (Stick Slip)

Based on Original Paper Found Here: https://www.sciencedirect.com/science/article/pii/S2468067222000621


Background

In this Document

At its fundamental level, a piezo inertia actuator might seem quite simple: two contacting surfaces one of which alternates between moving slowly and quickly in alternating directions which, in turn, causes displacement on the other surface. However, there are many variables at play, all of which have significant effects on the efficacy of a piezo inertia actuator.

There is no single optimal solution to each individual variable, rather different combinations of variables function well together given specific piezo inertia actuator assemblies. Understanding the most impactful variables and their effects can simplify this process.

This document includes a list of specific variables broken down as closely to first principles as possible + a specific configuration that resulted in a working piezo inertia actuator.

Background

Piezo actuators are tiny stacks crystals that respond to voltage by physically expanding in a very repeatable way. The simplest of these crystal stacks simply expands and contracts in one direction. The magnitude of this expansion can range from single nanometers to multiple microns.

Actuator assemblies have been made utilizing this crystal stack by amplifying it's small expansion. This can be taken a step futher - by applying a sawtooth wave function to the piezo crystal, it can be made to expand slowly, but contract quickly. This, in tandem with some clever friction interfaces and dynamics, can be utilized to make a separate stage move much more than just the short range of the piezo draw (expansion) distance. It can effectively be used to move an infinite range.

  1. Friction between A and B

The friction force between A and B is determined by the material choice, cleanliness, as well as the preload force Fa.

Having too much friction makes it harder for the slip phase of the stick-slip cycle to work. When the friction force is too strong, the inertia of A is no longer enough to overcome the higher friction force and the and surfaces do not slip; the assembly simply vibrates back and forth.

However, when the friction force is too weak the contact between both surfaces becomes inconsistent. This can also result in the stick phase being only a fraction of the draw distance of the piezo. Similarly to when there is too much friction, the assembly mostly just vibrates. This makes this hard to diagnose the issue.

It is also desirable for the surfaces of A and B to be hard.

As the piezo expands a very small amount (microns) any imperfections or change in angle between the A and B surfaces can cause the stick-slip cycle to fail and the actuator to get stuck. Therefore, having smooth surface finishes is desirable and increases reliability. Keeping the surfaces clean from debris has the same effect and also prolongs the lifetime of the surfaces.

Having a preload force between the and surfaces is paramount. If there were none, we would be relying on perfect alignment between the A and B surfaces throughout its range of motion.

Having a preload ensures that even if both surfaces are not perfectly aligned they maintain contact with each other. This preload force also and gives us control on the friction between A and B.

  1. Planarity of A and B surfaces

If the piezo element is mounted on the chassis, and not the stage itself, then any slop in the stage mounting will propagate as the stage moves throughout its range of motion. This can increase or decrease the force between the magnet and the stage, as well as wedge the magnet's corner against the stage.

This is very unpredictable for the stage dynamics. Making more precise mounting for the stage is also desirable for other reasons, such as wanting a very linear range of motion (assuming that the magnet interface is operating properly to begin with). This can be expensive however, as the tolerances are on the order of microns.

A poorly mounted stage can be calibrated out when using a 3-axis system, curbing the finicky precise mounting and tolerancing.

  1. Mass of A (Inertia)

The entire concept of a piezo inertia actuator relies on the fact that the momentum of the stage during the stick phase will continue and overcome the friction force between A and B during the slip phase. In other words, the piezo pushes the mass A some amount then quickly pulls back. Without sufficient A mass, the slipping phase becomes very difficult to achieve.

Piezos can exert very high forces when expanding (stick phase), so increasing mass does not put significant strain on the piezo actuator itself. During the slip phase, we only require enough force to overcome the friction force between and B.

  1. Slew Rate of Driver

The rate at which the piezo can slip is just as important as the momentum of the stage. This is dictated by the capacitance of the piezo stack itself, but we have found that the more impactful variable at play is the slew rate of the driver. A proper driver that can pump or deplete voltage from the piezo in a matter of microseconds is critical to get consistent slipping action.

This can also dictate the frequency at which you can drive the stage, defining the maximum speed the actuator can move.

  1. Waveform driving the piezo

Though a linear saw-tooth waveform is able to produce movement of the piezo inertia actuator, it is far from optimal. Using a linearly increasing or decreasing waveform is not ideal for the sticking phase, as the sharp changes in direction can make the stage slip before sticking action occurs.

Using a gradually increasing waveform like the ones seen below is a more optimal solution.

The velocity of the waveform starts off slowly and gradually increases speed, which allows it to reach higher driving frequencies without slipping and even a greater velocity at the end of the sticking phase – which increases the momentum of the surface A.

Let Fcr be the maximum driving frequency at which there still is sticking: it is desirable that the rapidly changing portions of the signal (slipping phase) be 4 times faster than Fcr and that the slowly changing portions of the signal be 4 times slower than Fcr.

  1. Stiffness / stability of the entire assembly

Vibrations are naturally created by the piezo element. They are undesired and indicate lead to inefficiencies.

Manufacturing the chassis assembly out of a stiffer and heavier material and fixturing the assembly to a stable base reduces said vibrations and greatly increases the efficiency and reliability of the machine.

This is especially critical for stages with more than one axis stacked on top of one another. This is yet to be tested.


PCB Files on Github

PCB files above are the 2nd iteration on a custom board, with higher resolution ADC

Example Configuration that Works

  1. Friction between and

We have a 3 mm square nickel-coated neodymium magnet and a precision ground stainless steel linear rail as the two surfaces causing friction.

  1. Preload

We are using a 3mm square nickel-coated neodymium magnet that has 0.28kg pull and the magnetic attraction between the stainless steel linear rail and the magnet acts as the preload force.

  1. Finish & consistency of and surfaces

We are using a 3mm square nickel-coated neodymium magnet as the surface and a stainless steel linear rail as the surface. The linear rail was chosen as the surface because it is precision ground and has an excellent surface finish and for the surface we are using the smoothest looking face of the magnet. Furthermore, both surfaces are handled with care to avoid scratches and burrs, kept clean, and cleaned with isopropyl alcohol.

  1. Mass of A

The design starts performing the best when there is over 50g of mass on top of the carriage. If you are prototyping and just put something heavy on top of the carriage to test, certify the weight is properly fixed to the carriage and can’t move freely – which would just cause vibrations and a poor performance.

  1. Waveform driving the piezo

BD150 slew rate = 12 V/us

PDu150 slew rate = 38 V/us

  1. Stiffness / stability of the entire assembly

The most significant way this was handled was by attaching the piezo directly onto the linear slide and the magnet touching the rail. This ensures that all movement is directly transferred onto movement of the slide and less is lost due to compliance on other parts of the assembly.

Machining the main body of the actuator out of aluminum works well, however it is also working with a 3d-printed chassis out of PLA. Taping – or even just pressing down with your fingers – the assembly to a stiff plate or table solves vibration related problems.

  1. Piezo element

  1. Linear rail and carriage

SMU - Analog Discoveries

A guide on Analog Discoveries and Waveforms Software

A portable USB-powered test and measurement device, also known as the AD3, is a digital oscilloscope, logic analyzer, waveform generator, pattern generator, and much more. Digilent WaveForms software makes it easy to acquire, visualize, store, analyze, produce and reuse analog and digital signals.


Hardware Specs

Total Cost:

Setup Time:


Technical Specs

  • Output Voltage Range: ±5 V

  • Accuracy:

    1. ±10 mV ± 0.5% (│Vout│ ≤ 1.25 V)

    2. ±25 mV ± 0.5% (│Vout│ > 1.25 V)

  • Number of channels: 2 (custom channels feature available)

  • DC Current Drive: 30 mA maximum


Setting up AD 3

  1. Run the .exe installer

  2. Plug the Analog Discovery 3s into the laptop and open up the Waveforms software.


Circuit Setup

Set up the circuit that connects the Analog Discovery 3 like this circuit diagram:

The actual circuit will look something like this:

Manual Testing with Waveforms GUI (not sdk)

  • For our purposes, click on Tracer (for IV Characterization).

  • Click on drop down to select transistor type.

  • Select “No Adapter”

  • Select “Measure Id/Vgs” and set the ranges for the Vgs and Vds.

  • Select step-size/no. of steps for both voltages.

  • Click play (in the top right corner) and watch the magic!

  • I-V Curve for ZVN3310A Transistor on Curve Tracer (replace this image with our chip curves).

Suggestions:

  • Can adjust current compliance for Gate if needed. (below the main toolbar, right above the graph).


Automated testing with Waveforms SDK

Get the code from github by typing in terminal

Cd into this directory then run the below Python script in any environment where Python is installed by typing in terminal

If this is the first time being run in this environment, make sure all dependencies are installed by typing the following command in terminal:


CMU Fab

Vacuum chamber connected to turbo pump.
A schematic of a general system overview of the ALD machine’s subsystems and components
Heating module assembly
Annotated view of Heating module assembly
Exploded view of module assembly
Drawings for Aluminum and Boron Plate( Both have the same dimensions, change size of hole to ¼”)
Heating test set-up
Block diagram of ALD valve control
Block diagram of PID control for heating elements
A conceptual sketch of the vacuum chamber when a cooling system for a successful cold-walled reactor was considered
A picture of the fully assembled Ideal Vacuum 9x9x9 chamber
A schematic displaying the laminar, top-to-bottom gas flow and even dispersion on the wafer in the vacuum chamber, and feedthrough port connections
Arduino CNC Shield – 100% GRBL CompatableProtoneer.co.nz

is a powerful technique for characterizing semiconductor materials and devices, especially the transistors that we build in our fab. The shape of the CV curve will provide information about the doping concentration in the silicon substrate. On this page, we will detail how to take CV measurements of your devices.

Probe station (see for standard operating procedure)

Set up the CV measurement equipment, we use a Keithley 4200-SCS Parameter Analyzer as our test equipment and Probe Station for circuit connections. Please follow the steps given in the to ensure proper probe-to-pad contact with the transistor.

Extract Parameters: From the fitting or analysis, extract parameters such as doping concentration, and threshold voltage using known parameters such as oxide thickness. See page 10 of for a detailed explanation of the relevant equations. has an implementation of those equations in MATLAB.

As of June 2024, we are currently working on our own custom probe station and source-measurement unit, as described . Once this is complete, we will be able to use our new setup to take CV measurements. We will update this page accordingly once this is done.

Minimum Spot Size (Rayleigh Criterion)

The Rayleigh criterion is a measure of the limit at which two points of light can be distinguished as separate. It states that two points are resolvable when the principal diffraction maximum of one image coincides with the first minimum of the other. In simpler terms, it defines the smallest angular separation at which two light sources appear distinctly separate rather than as a single blurred point. This criterion helps in understanding the resolving power of optical instruments. When the Rayleigh criterion is expressed in terms of the numerical aperture, the equation becomes:

d=0.61λNAd =\frac{0.61λ }{NA}d=NA0.61λ​

where:

  • d is the minimum resolvable spot size,

  • λ\lambda is the wavelength of light,

  • NA is the numerical aperture of the lens.

For blu-ray the wavelength is 405nm and the NA is 0.85 resulting in a spot size of 290nm.

Source/Reference

  1. Video explanation of resolution in optics (relevant info starts at 27:15 but the entire video is a great introduction to optics)

OPU Architecture

Note: It is recommended to keep the cover layer, whose thickness depends on the operation wavelength, in front of the OPU objective lens to guarantee optimal laser focusing. Microscopy cover glasses provide a similar refractive index (1.47 to 1.5) as the cover layer or one can simply use the disc hard-coat polycarbonate cover layer. Furthermore, the cover layer can be used for sealing microfluidic channels. OPU-based imaging or sensing through different media, such as liquid or gas, demands the optimization of the distance between the cover layer and measurement target

Source

Photo-diode Auto-focus

Optical pickups focus on disc using the so called astigmatic method. This method is based on the deformation of the roundness of the laser beam when it is unfocused. The pickup has a series of lenses that lead the reflected ray to a photodiode array which generates four signals (A,B,C,D). Using them it is possible to deduct if the laser is unfocused and move the lens to focus it correctly.

Once you know the A,B,C,D signal pins, implementing the auto-focus algorithm is easy: just add A+C and subtract B+D from the result. The pickup returns those signals in the form of minimum current variations that depend on the laser light received by each photodiode. The photodiodes are arranged in a square (see following figure).

As you can see, it is possible to infer the focus level checking if the result is less than 0 (too close) equal to zero (focused) or greater than zero (too far) and with this information move the lens until the laser is focused.

Sources

perimeter=2∗π∗radiusperimeter ={2 * π * radius}perimeter=2∗π∗radius

steps=perimeterminspotsizesteps = \frac {perimeter}{min spot size}steps=minspotsizeperimeter​

rpns=rpm60∗109rpns =\frac{rpm }{60*10^{9}}rpns=60∗109rpm​

Linearspeed(nm/ns)=radius(nm)×2×π×rpnsLinear speed (nm/ns)=radius (nm)×2×π×rpnsLinearspeed(nm/ns)=radius(nm)×2×π×rpns

STED Microscopy

Two-beam OBL utilizes a doughnut-shaped inhibition beam to inhibit the photopolymerization triggered by the writing beam at the doughnut ring leading to reduced feature size and improved resolution

Super-resolved critical dimensions in far-field I-line photolithography

Possible STED Architecture Diagram of BSM. The fluorescence signal passes through multimode fiber B7 and is collimated by collimator lens B8 and narrowband emission filter B9. D1, laser diode; D2, beam splitter; D3, collimator lens; D4, dichroic filter; D5, photodiode; D6, objective lens (NA: 0.6); D7, Al-coated address pattern; B1, blue laser diode; B2, B3, beam splitters; B4, collimator lens; B5, dichroic filter; B6, 4.34 mm focal lens; B10, objective lens (NA: 0.85); B11, lens holder. B12, cover glass; B13, collimator astigmatic plate; B14, photodetector. ()

The table below is the BOM packaging, which can be found here:

Figure 1: Hacker Fab package

The main use for packages made this semester will be to use the analyzer to perform tests on IC devices, and so all packages will be designed to port to the analyzer.

Figure 2: Analog Discovery 3
Figure 3: Example of chip on package
Figure 4: Example of chip on board
Figure 5: Resistor lab chip mask design (courtesy of the EDA team)
Figure 6: NMOS chip draft (courtesy of the EDA team)
Figure 7: Wedge bonding process
Figure 8: Ball bonding process

The machine we are planning to use is the manual wire bonder in the CMU MEMS lab (). This is the wire bonder in the lab that is the easiest to train on, but if more precision is needed we may pivot to other wire bonders in the lab that offer semi automatic operation. Though the use of lab equipment on campus harms the replicability of this project, the team is hoping to use experience gained from our DIY Probe Station to eventually develop a DIY wire bonder at a much lower cost than on the market.

Figure 9: West Bond Wire Bonder in HH1212
Figure 10: CAD Views of initial package concept
Figure 11: Design rules for Al wire bonding
Figure 12: Initial planning for footprint layout
Figure 13: Recommendations for PCB pad sizes (Credit: Chengyu Fan)
Figure 14: Altium footprint and relevant dimensions
Figure 15: Altium schematic symbol for resistor chip
Figure 16: Final resistor chip package schematic
Figure 17: Resistor chip package layout
Figure 18: Resistor chip package 3D top view
Figure 19: Resistor chip package 3D bottom view
Figure 20: Resistor chip package CAD with cap
Figure 21: Top level motherboard schematic
Figure 22: Analog Discovery 3 connector schematic
Figure 23: Package slot schematic
Figure 24: Resistor and capacitor sub blocks
Figure 25: Motherboard final layout
Figure 26: Motherboard 3D top view
Figure 27: Motherboard 3D bottom view
Figure 28: Motherboard CAD with packages

Source:

Figure 29: Soldered package
Figure 31: Wire bonded chip on package
Figure 32: Annotated pinouts for resistor chips
Figure 33: Package on motherboard
Figure 34: Test wire bonds
Figure 35: Multimeter measurement
Figure 36: Total resistance plot
Figure 37: Adjustable resistance plot

Chapter A: Wire Bonding, Nanoscale Research Facility, University of Florida, 2021.

Capabilities: ENIG Plating for Aluminum Wedge Wire Bonding, PCB Trace. (figure 11)

CHIP ON BOARD / WIRE BONDING, Würth Elektronik eiSos GmbH & Co. KG.

Analog Discovery 3, Diligent. (figure 2)

The power of packaging, Texas Instruments. (figure 3)

The Mystery Behind The Globs Of Epoxy, HACKADAY. (figure 4)

Fatigue Design Criteria, Encyclopedia of Materials: Science and Technology, R.I. Stephens. (figure 7)

High precision capillary produced with by HIP processing and polishing technology, Orbray. (figure 8)

West Bond Wire Bonder, Carnegie Mellon ECE Department. (figure 9)

Metric
Goal
Notes

with a regular STM32 ADC was used for the testing below

The piezo element is driven with an 8 bit DAC and a piezo driver. The waveform used is the same shown in the images in section “5. Waveform driving the piezo”, it has a peak voltage of 120V and a driving frequency of 1,400 Hz.

Previously, we used the driver, however, its slew rate was extremely low and the upgrade to the driver showed very significant improvements.

We used 4.6um draw distance piezo stack.

We are using these and from McMacter.

Product
Cost (each)
Quantity

Download the Waveforms software:

https://drive.google.com/drive/u/2/folders/1o5fxdsvbNqkaUjlJolox5KOtbqi4PFFn
Capacitance-voltage (CV) profiling
here
Probe Station Manual
this document
This file
here
C-V Testing for Components and Semiconductor Devices
Making Optimal Capacitance and AC Impedance Measurements with the 4200A-SCS Parameter Analyzer
http://educypedia.karadimov.info/library/general_bluraydiscformat-15263.pdf
https://blog.ligos.net/images/The-Reliability-Of-Optical-Disks/BD-R_physical_specifications-18326.pdf
https://blog.ligos.net/images/The-Reliability-Of-Optical-Disks/White_Paper_BD-RE_5th_20180216.pdf
https://www.youtube.com/watch?v=liGuhbFh4IQ
https://www.youtube.com/watch?v=Hkialty_8K4&t=267s
https://www.youtube.com/watch?v=xfuWbnMYOos&t=72s
https://www.youtube.com/watch?v=-7IRB7lb9lQ
https://backend.orbit.dtu.dk/ws/files/239879723/SSDM2020_Abstract_Edwin.pdf
https://www.spiedigitallibrary.org/conference-proceedings-of-spie/11677/116770A/Hacking-blu-ray-drives-for-high-throughput-3D-printing/10.1117/12.2576491.short
https://www.youtube.com/watch?v=Fw8r5FBaPTI&t=1281s
https://www.youtube.com/watch?v=5bqujaldaCQ
https://pmc.ncbi.nlm.nih.gov/articles/PMC6066758/
http://www.diyouware.com/node/161
https://www.youtube.com/watch?v=1pgpzHao1c0
https://www.nature.com/articles/ncomms3061
https://www.spiedigitallibrary.org/journals/journal-of-micro-nanolithography-mems-and-moems/volume-18/issue-1/013505/Super-resolved-critical-dimensions-in-far-field-I-line-photolithography/10.1117/1.JMM.18.1.013505.short
https://github.com/hacker-fab/packaging
https://cad.onshape.com/documents?nodeId=a41742eaad18f4b65bb1ceb5&resourceType=folder
https://docs.hackerfab.org/home/working-docs/cmu-updates/james-lin
Packaging BOM
Analog Discovery 3
West Bond Wire Bonder
https://pcbtrace.com/enig-plating/
https://nrf.aux.eng.ufl.edu/_files/documents/3201.pdf
https://pcbtrace.com/enig-plating/
https://www.we-online.com/files/pdf1/design-rules-wire-bonding-cbt-en.pdf
https://digilent.com/shop/analog-discovery-3/
https://www.ti.com/about-ti/newsroom/company-blog/the-power-of-packaging.html
https://hackaday.com/2016/08/25/the-mystery-behind-the-globs-of-epoxy/
https://www.sciencedirect.com/topics/physics-and-astronomy/metal-fatigue
https://orbray.com/en/product/jewel/product/capillary.html
https://research.ece.cmu.edu/~mems/resources/HH1212/bonder.shtml

Footprint (cm³)

35 x 35 x 50

L x W x H

Reliability (%)

99%

Amount of chips sucessfully processed

Clearance (cm)

15

Room for users to access chips

Heating (°C)

100

Internal Temperature (°C)

+15

Temp. above Room Temp.

Dispense Time (sec)

2

Time per drop dispensed

Open/Close Time (sec)

10

Time taken to open/close lid

Analog Discovery 3

$379

3

Jumper Cables set

$6.98

1

Micropositioners

TBD

4

>>> git clone https://github.com/joshna-ii/HackerFabSMU
>>> python3 smu.py
>>> pip install -r requirements.txt
Automated Spin Coater
Gantry
Gripper
Liquid Handling
Tube Furnace
Wafer Cleaver
SMU - Analog Discoveries
PDu150
VIDEO OF THE STAGE MOVING
OLD DRIVER BUT A BUNCH OF WEIGHT
PDu150
BD150
PDu150
VIDEO OF 3D PRINTED VERSION – SIDE MOUNTED MAGNET
VIDEO OF 3D PRINTED VERSIon – TOP MOUNTED MAGNET
this
rail
carriages
https://digilent.com/shop/software/digilent-waveforms/
Logo

Database

Overview

The database was created in Spring 2024 with the ability to create new chips, add process parameters to each chip, and query back results from the database. The front-end had simple styling, although they were not reflected in the production website due to issues with certification. The motivation for our improvements in Fall 2024 was increasing the intuitive usability of the website, as well as adding more functionality for the user. hi

Design Choices

Web Hosting Platform

The website hosting options up for consideration were Amazon Web Services (AWS), Google Cloud Platform (GCP), and Microsoft Azure. AWS was ultimately chosen because it had the longest free period and we had the most experience working with it. We use EC2 because it has the most flexible options and high availability in many geographic regions. The website is not very compute-heavy, so we chose a small instance to keep costs down.

Model/Schema Changes

User Interface

We identified that a non-intuitive workflow and lack of visual cohesion were affecting the usability of our website. One major change was the inclusion of “chip pages” that show every process done to a chip and eventually will allow for edits to the data associated with it. Previously, the only way to see that data was to search the database by chip number. This process was not intuitive because users are usually working with a single chip at a time, so it made more sense to have a centralized location to view that relevant information.

A change for the search page was the use of horizontal tables to display data for a process. In other words, for a single entry, each column represents a certain field in that entry, and each row is a distinct entry (previously, the first column was the field name, the second column was the value, and additional fields for a given entry were displayed in their own row). The horizontal table display makes it much easier for users to distinguish between different entries for chip information and process parameters. Furthermore, we modified the search page to display all filter categories to the user under an umbrella “Advanced Search” dropdown. This allows the user to see all the search options at once instead of having to submit a process. Lastly, to make it easier for users to interpret the data that is presented to them in the search page, we added functionality that allows users to group the search results either by the process types they have selected, or by the chip number.

The chip creation page will also have the option to use a “chip profile” or “chip default” that prefills parameter values associated with an established process, such as the NMOS process we use for class labs.

An important addition to the Patterning process in particular is the ability to add multiple patterns in the same step and click on a gray rectangle to approximately note the location of that pattern. This way, it is easier to record the application of multiple patterns at the same time as well as locate a specific pattern when returning to the chip.

Main Controller

Main Controller: Querying Data

As our website serves to display database entries to our users, a crucial functionality is querying data (related to process parameters and chip information) and rendering it on the page. These are the different pages where data querying is critical:

Page Name
Page Address
Controller (Function Name)

Search Page

/search

search_page()

Central Chip Page

/central

central_action()

Chip Page (for a single chip)

/chipnum/<chip_id>

display_chip()

!!!!!!!!!!!!!!!!!!!!!!!!!! System architecture for interfacing with tools (the spincoater for now) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

SEE this link for better formatting: https://docs.google.com/document/d/1SrD66bqmS1xxs2jt_WWSY7eLr6vyDJxIB4dbMdbxkws/edit?tab=t.0#heading=h.ai1m6262yla9

Spin on Glass/Diffusant SOP

Process Parameters


Total Time

15-35 minutes

Spin Speed

4000 rpm

Spin Time

20s

Anneal Temperature Profile [temp 1, time 1, temp 2, time 2...] [°C, min]

700B: [400, 20-30], P504: [200, 10-15], B154 [200, 10-15]


Purpose

Three types of "spin on glass" are currently used in the Hacker Fab. 700B, P504, and B154, all three sourced from Filmtronics. Each of these begin as liquids, which are spun onto the surface of the chip, then annealed to form solid thin films. This is known as a sol-gel process.

700B becomes an undoped thin film of SiO2, but with lower density than a thermally grown SiO2. After high temperature exposure (~1100C) this thin film densifies to the density of a thermally grown oxide.

P504 becomes a thin film of SiO2, with a small amount of Phosphorous in it, also with lower density than a thermally grown SiO2. This is also referred to as a "spin on diffusant." After high temperature diffusion (~1100C) this thin film densifies to the density of a thermally grown oxide.

B154 does not have SiO2 precursors like 700B and P504, but becomes a solid thin film with a small amount of Boron in it. The composition of this solid film after relatively low temperature exposure (~200) is not clear, since the formula is proprietary, but it is believed to be some sort of polymer. Upon diffusion (exposure around ~1100C) the B154 thin film becomes SiO2 of thermally grown density.

These spin on glass films are often etched with a dilute HF solution, or BOE (HF + NH4F) due to the high selectivity with Si. However, the etch rate of spin on glass annealed around 400C is much faster than that of spin on glass that has been densified at around 1100C. Additionally, the B154 film that has been annealed at 200C is not effectively etched with HF, but is effectively etched with HF after diffusion at 1100C.

As indicated above, the purpose of the P504 and B154 deposition is to create a dopant source at the surface of the silicon, which can be diffused into the silicon substrate. 700B is used as a diffusion barrier, or a dielectric layer to fabricate metal interconnects on top of.

Defects

The main concern with spin on glass, is its tendency to crack (extent of cracking varies, but full shatter can occur leading to flake off), have variation in uniformity, and have pinholes. Cracks and pinholes can lead to uneven doping across the surface, failure of 700B to act as a diffusion barrier, or metal interconnects shorting to the Si below. Factors like humidity, annealing temperature profile, particulate contamination, and shelf life of the spin on glass solution.

However, the CMU Hacker Fab has found particulate contamination to be the number one cause of defects, and this issue has been mitigated greatly by using filtered syringe tips during deposition, as seen below in the procedure.


Tools

Materials

  1. Filmtronics 700B, P504, or B154.

  2. Acetone

  3. Isopropanol


Procedure

Wafer Cleaning

  1. Check that the working volume of spin on glass is labeled with the date it was poured. For 700B and P504, ensure that the solution has not been out for more than a month (main bottle is stored at 5C).

    1. If you are pouring a new working volume of P504 or 700B, let it come to room temperature before using it (ideally, wait 24 hours).

  2. In the fume hood, hold the wafer with tweezers over the sink.

  3. Rinse the polished side of the wafer thoroughly with acetone, then isopropyl alcohol.

    1. The acetone leaves a residue that must be removed by the isopropyl alcohol rinse.

  4. Blow the wafer dry with the nitrogen gun by pressing the wafer against a cleanroom wipe on the table to ensure it does not fly away. Get a good grip on it with your tweezers.

    1. Even when the wafer appears dry, there may still be moisture on the edges, so dry both sides liberally for ~20 seconds

    2. if there is visible acetone residue after drying, repeat steps 2-3

Prebake

  1. Place the wafer in the center of the hotplate for 20 seconds

    1. Be sure to handle the wafer with tweezers that can handle high temperatures (metal tweezers)

    2. No need to turn the hotplate off since annealing will require 100°C initially as well

Spin Coat

  1. Open the SOG container while keeping the bottom resting on the table

    1. Never open containers up in the air or outside of the fume hood

  2. Pipette 1-2 drop of SOG using Luer Lock filtered syringe:

    1. Take a clean syringe and draw it up ~½ to create an air pocket in the tube

    2. Suck up SOG about halfway up the syringe. This is a lot more than you need for 1 drop, because the filter needs to be wetted by the excess solution before drops are released.

    3. Twist on a syringe filter

    4. Release 2 drops back into the SOG container

    5. Apply 1 or 2 drops to your chip, make sure the chip is completely coated in solution but do not use more than 2 drops

    6. Dump any remaining SOG in the syringe back into the SOG container

    7. Dispose of the syringe and the filter in the waste bucket

  1. Spin coat the wafer (Remember to switch on the vacuum!)

    1. After spin coating, the SOG application should appear even. (See pictures below)

  2. Immediately move onto annealing

Hot Plate Annealing.

  1. The hot plate should already be at 100C

    1. Be sure to handle the wafer with tweezers that can handle high temperatures

  2. Set the hotplate to the desired annealing temperature (200C for P504 or B154, 400C for 700B)

  3. After the desired anneal time has passed (10-15 minutes for P504 and B154, 20-30 minutes for 700B), use metal tweezers to remove the chip. Be careful not to burn yourself.

Tube Furnace Anneal/Diffusion P504

Inspection

Safety

Be sure to work under fume hood when working with SOG. The SOG can give off toxic vapors (especially during annealing)

DO NOT touch the hot plate during operation. A 400 C hot plate will cause severe burns. (Reminder: 400 C = 752 F). The same is true of the glass cover, which is why it is important to ramp down before touching.


Photoresist Strip SOP

Parameters

Total Time

1 minute

Acetone Spray Time

20 seconds

Isopropyl Alcohol Rinse Time

10 seconds

Nitrogen Blow Dry Time

10 seconds


Purpose

Stripping removes all photoresist from a chip. This is typically done after an etch step is completed, though it can also be used to remove resist before etching if you need to redo patterning.


Tools

  1. Fume Hood with Sink

  2. N2 gun

Materials

  1. Chip with photoresist

  2. Acetone

  3. Isopropanol


Troubleshooting and Best Practices

Chip flying out of tweezers during nitrogen blow drying

Lie the chip flat on a cleanroom wipe surface while still holding it with the tweezers.

Only apply nitrogen normal to the surface of the chip, so it presses against the cleanroom wipe instead of lifting it up.


Procedure

Stripping

  1. Spray the entire chip with acetone

  2. Rinse with IPA

    1. IPA must always be used after acetone to remove any acetone residue

  3. Dry with nitrogen gun until the surface is entirely dry

    1. This requires you to blow dry the back of the chip as well. Surface tension tends to pull the liquid towards the back

Safety

Be sure to spray the chip over a sink. Do not use near source of high heat.

Vacuum Spin Coater SOP

Purpose

To apply a thin layer of wet chemicals to the surface of the chip, with sub-micron control.


Troubleshooting and Best Practices

Spin Coater is Stuck, the chuck tries to move but it stays in place
  1. Remove the outer plastic vase that holds the residual photoresist and chemicals

  2. Wet a cleanroom wipe with acetone and wipe the outside of the chuck and the inside of the plastic vase clean

  3. Attempt to run the spin coater again

  4. If the problem persists, run the spin coater without the plastic vase or any chip present, then press the acetone covered wipe against the chuck as it is spinning to get a thorough clean


Procedure

  1. Plug in the Spin coater and the vacuum pump (if either is not able to power on try hitting “reset” on the outlet)

  2. Use the arrows on the touch screen to set the spin time and rpm

  3. Use tweezers to place wafer onto the o-ring so that the chip completely covers the o-ring and will seal onto it

    1. Also attempt to center the chip on the o-ring as best you can. This will minimize the chances of it flying off.

  4. Use a pipette to apply liquid on top of the wafer while it is seated in the spin coater. You only need a couple drops in the pipette, don't suck up extra.

  5. Close the HMDS/photoresist/SOG lid.

  6. Close the spin coater lid

  7. SWITCH ON THE VACUUM PUMP!

  8. Press “begin”

    1. This will begin a pre spin at 600 rpm

  9. Press “coat”

  10. When the spin time has been reached, the coater will automatically ramp down to rest

  11. Open the lid and remove the wafer with tweezers

Side Notes

If you hear the spin coater constantly beeping, this is normal. It does this because we are using a drone motor ESC, so it is programmed to make a noise after being at rest for a few minutes. It’s trying to help you find it 🙂

Feel free to turn it off using the switch in the front so the noise goes away.

Hot Plate SOP

Purpose

Soft baking photoresist and annealing spin on glass.


Troubleshooting and Best Practices


Procedure

Heating

  1. Plug in the hot plate, it should beep, light up the screen, then go dark.

  2. Switch the hot plate on, it should light up and display both current temperature, and a pending set temperature.

  3. Turn the knob until the desired set temperature is present, hold the knob down until it beeps to set the desired temperature.

    1. A small green circle should appear at the set temperature

  4. The screen should alternate between set temperature and current temperature, ensuring that the current temperature is increasing.

Increasing Set Temperature While Operating

  1. Hold the knob down until the set temperature is canceled.

    1. The small green circle should turn off.

  2. Turn the knob to your new desired temperature, hold the knob down until it beeps to set the desired temperature.

    1. A small green circle should appear at the set temperature

  3. The screen should alternate between set temperature and current temperature, ensuring that the current temperature is increasing.

Shut Down

  1. Hold the knob down until the set temperature is canceled.

    1. The small green circle should turn off.

  2. Switch the hot plate off.

  3. Unplug the hotplate.

Plasma Etcher SOP

This SOP is specifically for etching 300nm of polysilicon in the NMOS process

Parameters

Total Time

15 min

SF6 flow rate

10 sccm

Etch time

60s

RF Power

100W

For more detaild process parameters:


Purpose

This first etch step creates the transistor’s gate by etching away almost all of the polysilicon and gate oxide, except for the islands covered by patterned photoresist. We use plasma etching (AKA dry etching) for two reasons:

  1. Plasma is capable of etching silicon, whereas HF is not.

  2. The anisotropic (vertical) etch profile is capable of transferring smaller patterns than isotropic etches.

The plasma etcher breaks down the normally inert SF6, creating a fluorine ion containing plasma on the surface of the chip. A combination of physical bombardment and chemical reaction removes material from the surface. Physical bombardment occurs when the pressure is low (<~.1 Torr) and results in an anisotropic (vertical) etch. This allows for precise transfer of a photoresist pattern onto the underlying material. Chemical etching dominates at higher pressures and results in an isotropic etch. Fluorine reacts more quickly with Si than SiO2, resulting in high selectivity.


Tools

  1. PE-25 Plasma Etcher

Materials

  1. Chip with patterned resist on Si

  2. Acetone

  3. Isopropanol


Procedure

Preparation

  1. Turn on the etcher via the switch on the back panel.

  2. Turn on the laptop and open the Plasma Etch app.

  3. Turn on the RF power supply on top of the etcher.

  4. Open the chamber and place your chip in the middle of the rack. Close the chamber.

  5. Set O2 flow, SF6 flow, power, time, vacuum setpoint in Sequence screen. Save your sequence.

Etching

  1. At the top menu bar, go to power and turn on RF and vacuum. The pump will start.

  2. Wait until the pressure (the number next to "vacuum") is below .1 Torr.

  3. Go to commands > cycle off. This will purge the chamber for three seconds with nitrogen in order to remove H2O. If any water is in the chamber during the plasma it will react with fluorine to make HF. Very bad.

  4. Commands > standby. This will start the pump again.

  5. Repeat steps 2-4 to purge again. This makes sure no water is in the chamber.

  6. Open the valve on the cylinders of gas that you are using. Lefty loosey.

  1. When you are ready to start etching, select commands > plasma.

  2. During the etch, monitor the pressure on the screen (should be at your setpoint) and the outlet pressure on the regulator (should be around 5-15 psig). Look in the window for pretty plasma!

  3. SHUT THE GAS CYLINDER. RIGHTY TIGHTY

  4. At the end of the cycle, the etcher will purge itself once, pump down, then purge again. To be safe we’ll purge a third time:

  5. Commands > standby. This will start the pump again.

  6. Wait until the pressure is below .1 Torr.

  7. Commands > cycle off. Lets gas in for 3 seconds

  8. Commands > standby.

  9. Wait until the pressure is below .1 Torr.

  10. Commands > shutdown. The chamber will come to atmosphere in 30 seconds, at which point you can open it.

O2 Plasma Cleaning

The procedure is the same as for silicon etching, but you may skip a purge before and after the plasma. This is because

Total Time

6 min

O2 flow rate

10 sccm

Etch time

120s

RF Power

100W


Safety

SF6 is not toxic, but fluorine is. By purging before and after the plasma, we’re trying to prevent two things:

  1. Purging before removes all water from the chamber. This prevents any HF from being formed, which would otherwise corrode the pump and exhaust. If the exhaust hose connected to the pump turns green, this is an indication that HF is being formed.

  2. Purging after removes all reaction products from the chamber. This includes SiF4 and various other sulfur oxides.

Patterning SOP - Stepper V2

Parameters

HMDS Prebake Temperature

100°C

Resist Bake Temperature

100°C

HMDS Prebake Time

60s

Resist Bake Time

90s

HMDS Amount (Drops)

2

Exposure Pattern

link

HMDS Spin Speed

4000 rpm

Exposure Source

Stepper V2

HMDS Spin Time

20s

Exposure Time

8s

HMDS Bake Temperature

100°C

Exposure Dose

HMDS Bake Time

20s

Developer Type

AZ-400K

Resist Amount

2 drops

Develop Time

60s

Resist Spin Speed

4000 rpm

Developer Temperature

20°C

Resist Spin Time

30s

For More Detailed Process Parameters:


Purpose

Patterning is the core of any micro/nanofabrication process, as it is used to mask etch and deposit steps. First we spin coat photoresist to deposit a thin layer. Then we use our maskless lithography stepper to expose our pattern in the resist with light. Finally we wash away the exposed region with developer. This leaves behind a resist pattern that is resistant to many types of acid and plasma etches. It can also be hard baked and used as a dielectric, or metal can be deposited on top of it for a lift off process. The procedure described here uses a positive resist, AZ-P4210, but negative resists also exist where unexposed areas become soluble.

See the appendix for useful resources about spin coating, our resist, and developer.

Safety

  • Harm to your eyes/eyesight is possible if you do not wear the right protective equipment. To shield your eyes from harmful UV-rays, everyone working with or near the stepper should wear UV-blocking goggles/glasses.

  • HMDS is a toxic, volatile chemical that should only be used in the fume hood.

  • Photoresist, while not as bad as HMDS, contains some nasty solvents and should be cleaned with acetone if it gets on anything other than chips and the spin coater.

  • AZ-400K developer is a strong base containing KOH. Use the appropriate precautions for working with bases. Only agitate the developer inside the fume hood to reduce the chance of droplets.


Tools

  1. Flashlight Jig or Maskless Lithography Stepper

Materials

  1. AZ-400K Developer

  2. Acetone

  3. Isopropanol

  4. Deionized water

  5. Evaporating dish


Procedure

Preparation

  1. Dust off the wafer with the nitrogen gun

Wafer Cleaning

  1. In the fume hood, hold the wafer with tweezers over the sink.

  2. Rinse the polished side of the wafer thoroughly with acetone, then isopropyl alcohol.

    1. The acetone leaves a residue that must be removed by the isopropyl alcohol rinse.

  3. Blow the wafer dry with the nitrogen gun.

    1. Even when the wafer appears dry, there may still be moisture on the edges, so dry liberally.

  4. Inspect with the naked eye and note any marks on the wafer.

    1. Marks present after cleaning are likely scratches that need to be documented so we observe their effect on the process.

Spin Coat

  1. If previous steps required cleaning with solvents, pre-bake the wafer to dehydrate the surface.

  2. If patterning on silicon or glass, spin coat 2-3 drops of HMDS. Otherwise skip to 7.

  3. HMDS bake on the hot plate at 100°C for 60 seconds.

  4. Spin coat as much photoresist as needed to mostly cover the chip, normally 3-4 drops.

    1. If chip is having trouble sticking on o-ring either: try pressing top of chip while vacuum is on with some pressure to make a better seal (use plastic tweezers)

    2. Or, take o-ring off and clean then re-install.

  5. Soft bake on the hot plate at 100°C for 90 seconds.

Stepper Setup

  1. Power: Check that the projector, stage, and vacuum pump are all plugged in.

  2. Plug the HDMI cable for the projector, the USB camera cable, and the Arduino + CNC Shield USB into your computer.

  3. Set up the projector as an extended screen on your computer’s display settings (Win+P on Windows).

  4. Prepare your exposure, red align, and UV focus patterns.

    1. Your exposure pattern should be pure blue in the areas you want exposed, and black elsewhere. Include alignment marks for the next layer.

    2. Your red align image should be completely pure red except for alignment marks that match the previous layer.

    3. Your UV focus pattern should be completely black except for blue focus marks. Ideally these should be in a region that gets fully exposed. You may also use grayscale to avoid unintentional exposure.

    Note: If your pattern images have extraneous color components, the GUI has options to enable/disable different color channels for the red focus, UV focus, and exposure pattern. Use these at your convenience.

  5. Set up the patterning GUI util script

    1. In the source or scripts folder, find and open config.py in your text editor of choice. If your GUI has an integrated camera implemented, set RUN_WITH_CAMERA to True. If your GUI uses a motorized stage, set RUN_WITH_STAGE to True.

    2. Move the black full-screen window to the projector (on windows, this is shift + win + L/R arrow)

    3. Use the three import thumbnails to select the desired images, these can be changed whenever. Make sure they are correct using the small previews.

    4. For more information about the software and its usage, click the "help" button at the bottom right of the GUI.

  6. The GUI should appear similarly to below. If you do not see content on the camera preview yet, this is fine for now.

Expose Using Maskless Photolithography Stepper

If you're doing this for the first time, it is recommended to read through the full instructions before starting. You will need to move somewhat quickly because the stepper will begin to expose photoresist in about 1 minute.

  1. Make sure the correct pattern is loaded in the Lithographer GUI. See step 4.4 in Stepper Setup

  1. LYFT and move the projector to the left, out of the way of the small hole in the chip holding jig.

  1. Turn on the vacuum pump. Ensure vibrations are isolated from the rest of the stepper.

  1. Orient the chip over the hole with its squarest corner in the corner of the alignment jig. The vacuum will suck it against the jig. Push the chip into the corner. Doing this repeatably eliminates the need to adjust theta.

  1. LYFT and move the projector back into place. Ensure it is touching all four bolts. Be careful about not scratching the chip.

  1. Turn the Z knob on the stage or modify the GUI stage coordinates until the objective lens is ~2mm from the chip and the image on SpinView or the GUI is in focus.

  1. Move the X and Y axes manually, or by using the GUI. One arbitrary "step" is approximately equal to 1 micron. To avoid straining the motors/stage, test small step sizes (i.e. 1) before trying larger ones (i.e. 10 or more). The minimum reliable step size is about 8-12 microns.

  2. If this is your first layer, find an area with minimal contaminants, plan how many exposures you will do, and in which direction you will move. Otherwise, align to your previous layer using your pattern's alignment marks.

  3. Once you're ready to expose, move the Z axis by -54 steps (fine-tune if necessary). This will switch from focusing in red to focusing in UV.

  4. Set your exposure time to 8000 ms.

  1. Press show UV focus. You are now exposing the photoresist, so try to do this quickly. If necessary, make fine adjustments to the Z axis if any marks seem less in focus than others. The image above is well focused (all crosses look in focus).

  2. Press the big red "Begin Patterning" button. Avoid bumping the table while you wait for the exposure to finish.

  3. Press "Show Red Focus" and move in Z by +54 steps to switch back to red.

  4. Move on to your next pattern and repeat. A good spacing between patterns is 580 steps in Y and 1080 steps in X (assuming one step per micron). This will allow you to easily find your next pattern. Take note of where you started, which direction you're moving, and how many exposures you've done so that you don't miss any patterns.

  5. Once you're finished, press "Clear". Push the projector to the left again, and carefully hold your chip with tweezers while you turn off the vacuum.

Develop

  1. Refresh the developer if it has been out for more than 6 hours. Otherwise skip to step 2.

    1. Pour the used developer into the bottle labeled "developer waste"

    2. Rinse the evaporating dish with DI water.

    3. Pour about 30 mL of pre-diluted 3:1 AZ-400K developer solution into the evaporating dish labeled “AZ-400K 3:1”. For a sense of scale: in the dish above this should only be about 3mm tall of liquid (just enough to cover the surface of the chip)

    4. Fill another evaporating dish halfway with DI water.

  2. Start the timer at the same time as you drop the wafer into the developer, photoresist side up.

  1. 5 seconds before the end of the timer, pick up the chip and prepare to drop it into the water. The chip should hit the water exactly at 0 seconds. Rinse well for 10 seconds.

    1. Note that development time includes all the time that developer is touching the chip, not just during agitation

  2. Dry off the chip with compressed air.

Inspect

  1. Look at the chip with your bare eyes to help build an intuition for the process.

  2. Put the chip under the microscope. Connect to the camera with your laptop and take pictures of each developed pattern at 5x. If there are smaller interesting features or defects, you may take pictures at higher magnification or under dark field. Be aware that it's easy to get carried away with the microscope.

  3. If you want to measure the length of pitch in microns (μm) then you must use only the calibrated objective.

    1. This calibration converts pixels of the camera to microns using a calibration slide from the manufacturer. If you use a different objective, the measurement will be inaccurate.

    2. After this is selected, measure the pitch or any other length using the line tool

  1. Paste a link to the folder in the last column of the chip sheet.

  2. Put the chip away in a plastic box and label it with a serial number.

See below for examples of underexposure/development, overexposure/development, non-uniformity, and optical blurring.

Right side: thicker lines and blurry edges. Left side: thin lines and sharp edges.


Additional Resources

Alternative Exposure Technique: 365nm Flashlight

  1. Put on UV protection glasses.

  2. Before placing the chip under the exposure area, turn on the flashlight and adjust the position of the UV meter’s sensor head to maximize the reading.

    1. Depending on the battery level, this should be around 10 mW/cm2.

  3. Turn off the flashlight, being careful not to move it out of position.

  4. Place the chip on the plastic cap photoresist side up.

  5. Place the mask on the wafer. Gently press down to sandwich the two together.

    1. If the ThorLabs logo is correctly oriented then the chrome is facing you. Put that side face down towards the chip.

    2. Try not to slide the mask on the wafer because you’ll damage the photoresist.

  6. Place the cap with the wafer and mask on top of the UV sensor.

  7. Turn on the flashlight for the desired exposure time.

    1. Dose should be automatically calculated in the sheet based on exposure option used

Troubleshooting

If horizontal bands appear in Flir-based camera preview:

  1. Open the Flir camera viewer.

  2. Select the connected Flir camera model (Blackfly S) and select the green triangle. You should see a preview of the camera's output (it may appear black or grainy; this is okay).

  3. Update the camera settings so that Acquisition Frame Rate Enable, Acquisition Frame Rate, Exposure Auto, and Exposure Time have the same values shown below:

  1. Verify that the horizontal bands are no longer present across the camera preview. This may be easier when viewing the stage or a chip while illuminated with the projector.

Spin on Glass Defect Inspection

Pre Spin Coating

  1. Particulate/dust contaminating liquid SOG.

  2. Explanation: If disruptions to the surface tension of the liquid SOG are seen before spinning, then some type of particulate is in the SOG and this warrants restarting the test. There are three possible causes of this…

    1. Dust landed onto the wafer after the SOG was applied

    2. Dust already existed on the wafer from improper cleaning

Post Spin Coating

  1. Particulate/dust contaminating wafer surface.

    1. Often, after spin coating disruptions to the SOG evenness/thickness can be seen in localized spots on the wafer. There are possible causes of this…

    2. Some SOG has hardened inside the bottle creating fine flakes of SiO2. These flakes then get sucked up by the pipette and deposited onto the wafer with the liquid SOG. These flakes are clear and sometimes not visible pre spinning, and are then only visible after spinning.

  2. Particulate Landed on the wafer during spinning. Sometimes the spin coater can create turbulent air and kick up dust from inside the spin coater which then lands onto the wafer.

  3. The wafer had a preexisting scratch or mark big enough to cause surface tension issues which result in the liquid SOG “un-wetting” in that spot and exposing the substrate. These scratches are often caused by scratches that occur during cleaving, slipping across the wafer when using hard tip tweezers, or dropping the wafer.

  1. Radial variation in thickness/diffraction color

    1. Sometimes after spin coating, there may be a radial pattern of changing color on the wafer. The varying colors indicate variation in thickness since SiO2 is translucent so thin films diffract and appear different colors based on thickness. These variations are usually on the order of a few hundred Angstroms (A) (film thickness ~2000 A) and may not warrant restarting.

During Spin Coating

  1. Wafer flies off the chuck while spinning

    1. Sometimes either due to bad two sided tape adhesion (regular spin coater) or improper sealing onto the vacuum chuck (vacuum spin coater). The chip may fly off the chuck due to inertial forces. This usually warrants restarting since when the chip flies off it hits the side causing uneven spreading of the SOG or lands onto the SOG.

Post-Anneal

Identifying “defects” in the deposited SOG

Pinholes

Possible Causes

  1. Scratches or dust particles on the wafer Cause the liquid SOG to “un-wett” in some spots. This essentially creates a dip in the SOG layer that extends to the wafer surface below the SOG.

Particulate resting on top of the SOG

Possible Causes:

  1. Dust coming into the fume hood and landing onto the wafer after the SOG layer has solidified.

Machine Integration

Lab communication system for interaction between database website and individual tools

The goal of the Machine Integration project is to develop an extensible interface that can be used to communicate between the primary web application and each individual machine in the hacker fab.

Background information

The information in this section will explain some basics about web application design that will allow for a better understanding of the current machine integration system.

API:

An API is an application programming interface. For the purposes of this project, it is the abstraction of the interface between the server and client devices. The client devices can invoke GET, POST, UPDATE and other HTTP (Hyper Text Transfer Protocol) endpoints for a specific URL. We can send test API requests easily using POSTMAN. For those more familiar with linux networking, you could also use a CURL command.

Postman:

Postman is a user friendly way to send API requests to test endpoints. Note that in production, another program will call an API endpoint. Postman is just a way for us to easily test these endpoints. If you are familiar with the CURL linux command, you can use that instead.

Download POSTMAN from their website (do a google search). Below is a basic overview of the user interface.

Database fundamentals:

A database is a structured collection of data that enables efficient storage, retrieval, and management of information.

You can think of a single Table within the database as an excel spreadsheet. The entire database is like an excel workbook.

Each table has multiple column names (shown as the first row in the image below). One of these columns are dedicated to be the primary key. The primary key uniquely identifies a single row, or entry, in the database. The other columns are used to store information about that entry.

The entire structure of the database (names of all the tables, column names, etc) is referred to as the schema.

System Architecture Diagram:

Now moving onto the details of this project, here is a system level architecture diagram of the system.

High level overview:

  1. Web Application Frontend & Backend: This is the first two boxes on the architecture diagram above. This is how the end user will interface with the system. The user can create/edit/delete jobs. The exact details of how the web application frontend and backend work are covered in more detail in that section of the documentation (not on this page).

  2. Jobs Queue on AWS: This is where the list of jobs that the machines will need to run is stored. The jobs queue on AWS will have an API interface that is accessible to the web application (in order to take in new jobs) and the Raspberry PI (in order to complete jobs).

  3. Raspberry PI mini computer: This raspberry PI will be physically located near the tool that will be controlled (spin coater to start). The raspberry PI will be connected to the device using either USB or I/O pins on the raspberry PI. The raspberry PI will pull jobs from the jobs queue and run them on the device. There will also be a keyboard, mouse, and portable monitor connected to the Raspberry PI to monitor the status of the machine (these components will be optional, but provide additional redundancy).

  4. Device to be controlled: Will receive control signals from the raspberry PI. For this version of the project, we will be controlling the spin coater.

Data Flow Description:

Job Creation:

  • The primary way that jobs will be created is through the hacker fab website. The hacker fab website will call the appropriate API call to manage the jobs database. The implementation of this is out of the initial scope for my project. For testing purposes for this semester, I will use POSTMAN to send API calls to the AWS jobs database.

  • Users can also create new jobs directly via the Raspberry Pi UI. This allows for redundancy in the case that the machine needs to be controlled without the database.

  • There will be an option to run the job immediately or to send it to the database to be added to the queue.

Job Queue Management:

  • The AWS server maintains a centralized queue of jobs.

  • The Raspberry Pi fetches and dequeues jobs by querying the API. Only jobs for the specific machine are dequeued.

Job Execution:

  • The Raspberry Pi receives the job and displays it on the connected UI.

  • Upon user interaction (manual start) or automatically (if set), the job is run on the spin coater (or other device in the future)

Job Completion:

  • After execution, the Raspberry Pi sends the success/failure status to the AWS server, updating the job's record in the database.

Justification for Design choices:

1. Why do we need lab automation?

This will significantly automate the process of chip development. Our goal is to make basic chip tape outs like 3D printing.

2. Why do we need an additional full raspberry pi for each tool that we are controlling? This is much more expensive than having one raspberry pi that then communicates wirelessly with smaller arduinos for each tool.

Answer: KISS: Keep it simple stupid. Adding the additional communication step between a central raspberry pi to peripheral arduinos would significantly increase complexity of the system in multiple ways:

  1. Initial implementation time is significantly longer for an arduino solution. The additional communication link between the raspberry pi and arduinos is not trivial, especially considering issues with the CMU wifi.

  2. The user experience is significantly worse for the arduino solution. The user who is standing at the tool is completely reliant on the automation system in this case. By contrast, with my proposal, the user will still have direct control of the tool via the on-screen gui at the machine.

  3. A raspberry pi for each machine would be a significantly more robust solution, while still offering all of the potential for automation.

    1. Less complexity (removed additional wireless link)

    2. Tools can still easily be operated manually (using on screen gui) in case of issues with the website/database.

I will now go through the jobs queue and Raspberry PI mini computer in more detail, as these are the key innovations of the machine integration framework.

Jobs Queue on AWS:

The jobs queue is where jobs that are requested by the web application are stored before they are fetched by the appropriate tool's raspberry PI.

Other programs (such as the web application and the RPI) interface/communicate with the jobs queue via API calls. These are HTTP requests.

Job Queue API interface:

API Gateway Endpoints from AWS for raspberry PI:

  • GET /jobs/next: Fetch the next job from the queue.

  • POST /job_completion : Update job completion details.

  • POST /generate_download_url: Generates the download url for a file recently uploaded based on the s3 id key provided

API Gateway Endpoints from AWS for web application:

  • POST /jobs: Enqueue a new job. The request has the machine name, input parameters, priority. The response will have the job_id of the newly created job, or error.

  • GET /jobs_by_id: The request includes the job_id(s) for which you will get details. All data for that row of the table will then be returned. NOTE: you can pass a list of job_ids to get multiple rows of data at the same time.

  • GET /jobs_by_machine: The request includes the machine name. All jobs that are in the database (regardless of status) will be returned.

  • POST /generate_upload_url: Generates the upload url to then upload a file to s3 storage. It also returns the s3 key, which can be used to retrieve the uploaded file.

Job Queue Table Schema:

  • job_id (Primary Key)

  • machine (the machine to run the job on. E.g. spin coater)

  • status (Pending/In Progress/Completed/Failed)

  • input_parameters (JSON for variable parameters)

  • output_parameters (JSON for results from the machine)

  • timestamp (Queued timestamp)

  • priority (Optional for prioritized execution)

Job Queue implementation details:

AWS Configuration for jobs queue:

This is the jobs queue that the tools (right now only the spincoater) pull from. Jobs are enqueued from the primary web application.

The API gateway routes are configured as follows:

The dynamo DB is configured with default settings. job_id is the primary key.

I am currently using a free tier AWS account from hacker fab. This takes care of all licensing requirements for this project.

The majority of the logic is in the lambda function. The lambda function is the code that runs on AWS servers that processes API requests to the database. The python code is as follows (up to date as of 4/10/2025):

This code scores a 9.31/10 on pylint (google code guidelines). The failures are described in comments and are intentional, or are due to import statements not being found (since this code runs on AWS, not locally).

Other AWS resources (File Transfer):

S3: S3 is amazon's blob storage service. When a file is uploaded to the upload link from the generate_upload_url, it is stored here. It is setup with default configurations.

IAM management policy. This policy must be added to allow the Lambda script to access the S3 data. This is needed to generate the upload and download URLs.

To add the policy, go to IAM from the AWS panel, then roles, then create role.

{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Effect": "Allow",
			"Action": [
				"s3:PutObject",
				"s3:GetObject"
			],
			"Resource": "arn:aws:s3:::job-queue-files/uploads/*"
		},
		{
			"Effect": "Allow",
			"Action": "s3:ListBucket",
			"Resource": "arn:aws:s3:::job-queue-files"
		}
	]
}

Here is an automated test script to run that will test all endpoints except /generate_download_url and /generate_upload_url. Run this script locally on your PC. The script should pass if the AWS database is configured correctly. You may need to change the base URL.

The following python script tests the functionality of the s3 file upload and download system. Note you made need to change the base URL to the current AWS instance.

Raspberry PI mini computer

The raspberry PI pulls job requests from the AWS jobs queue

Basic raspberry PI hardware setup:

Raspberry PI 5 with case and heatsink. There are two ways the RPI can connect to tools to control. The first method is using jumper wires to connect GPIO pins to external device. See image attached. The device could also interface with the raspberry PI over one of the Raspberry PIs USB ports. This is the approach that is used for the spincoater

To control the Raspberry PI 5 GPIO ports, use the gpiod python package (see screenshot below). It is critical to use gpiochip4. If you are interfacing with the device over USB, the exact setup instructions will depend on the device you are controlling. I will detail how to interface with the spincoater in this guide.

Here are the reasons why we are using UART over USB instead of using the GPIO TX and RX on the rasperry PI and arduino. Keep this in mind if you are integrating future devices other than the spincoater.

The raspberry PI runs on 3.3V while the arduino runs on 5V. This presents a problem for the signal from the arduino to the RPI. We have to use either a level shifter or a voltage divider. I didn't have a level shifter on hand, so I tried building a voltage divider using a 20k (on the bottom) and 10k resistor (on the top). This filtered the voltage as needed, but it's possible this was part of the issue. Here is an image of the basic voltage divider I tried.

I also attempted to bitbang a UART connection between the RPI and arduino. This was also unsuccessful. After a bit of research, it looks like this is because Raspberry PI OS is not a RTOS (real time operating system), so the timing is not precise enough to bitbang a UART connection. Keep this in mind before trying this approach for a new tool.

At this point I was pretty stumped, so I searched around the internet a bit. I then realized it would be MUCH MUCH easier to simply use UART over the USB connection between the two devices. The reasons why I settled with this approach are as follows:

  1. I was able to get UART over USB from RPI to arduino working, but I was not able to get it working using the GPIO UART module.

  2. This solution is more scalable as we can have multiple arduinos that control individual devices plugged into one raspberry PI as the RPI only has one UART TX/RX vs multiple usb ports.

  3. We can leverage existing consumer grade USB extension cables and hubs

  4. The USB cable is physically studier than the multiple thin GPIO cables. Also, there is only one cable to deal with.

This is the code running on the raspberry PI. I'll first show it from the user's perspective:

When the machine is IDLE, the monitor connected to the RPI just displays a message that we are waiting for the next job

If autorun is not turned on, you'll need to manually approve the job

Next, the job will be run

Finally, the user can type in input for the final job status (this will vary based on the machine automated)

The user can also create a job from the RPI gui itself. If the RPI is connected to the internet, it will upload the job details to the database. Otherwise, the job will run completley offline. This is a intentional redundancy feature.

  1. Fetches jobs from AWS jobs queue

  2. Displays the currently running job on the GUI. Also allows users to control whether jobs run automatically or require manual confirmation.

  3. Runs the job on the device

  4. Sends completion details back to the AWS jobs queue.

I will now detail three important pieces of the code. These three parts should be the only parts of the code that you need to modify when integrating a new tool.

Note that the three sections that you need to edit to integrate a new tool begin with the comment

########################## EDIT HERE: block name ##############################

The first portion is an initialization block. In this case, it just opens the UART port to communicate with the Arduino. In general though, put any code here that needs to run once when the raspberry PI starts up.

########################## EDIT HERE: PERIPHERAL CONFIGURATION ##########################
#### INSTRUCTIONS: ######
### Add whatever code you need here to inintialize your peripherals so that they can begin to accept jobs. ###

#### UART OVER USB SERIAL TO ARDUINO ####
# This may be different on a different RPI
USB_PORT = "/dev/ttyACM0"  # Adjust this based on your device
BAUD_RATE = 115200  # Must match Arduino

# Open Serial Connection
try:
    ser = serial.Serial(USB_PORT, BAUD_RATE, timeout=1)
    time.sleep(2)  # Allow time for connection to stabilize
    print("Connected to Arduino over USB Serial!")
except serial.SerialException:
    print("ERROR: Could not open serial port. Check USB connection!")
    sys.exit()

#########################################################################################

The second portion sends the command to the arduino. Note that it is a self-contained method for this new device. To add this device to the code, all we needed to do was add the peripheral config and write this method.

This method also reads out the debugging messages from the arduino. Once we actually get the spincoater working, this could be messages if the spincoater is malfunctioning.

Note that I show two methods: one for run_led and another for the spincoater. In the next section, you'll select which you want to run when a job is recieved.

 ########################## EDIT HERE: PERIPHERAL CONFIGURATION ##########################
    ##### INSTRUCTIONS #######

    ### Write a function in this locaiton that will run the job. ###
    ### This function will be called when the job is approved. ###
    ### The function will be passed the job input parameters. ###

    ### to get started, copy the run_led function and edit it to run your job. ###
    ### only edit the code in between FIRMWARE START and FIRMWARE END ###
    ### This is where you will write the code to run your job. ###

    ### If you want the user to type in a response, leave the following two lines for gathering the response. ###
    ### If you don't want the user to type in a response, remove the two lines. ###

    #### This is the function that will be edited to integrate new tools #####
    def run_led(self, job_input_parameters):
        """Run the LED job."""

        ### FIRMWARE START: This is where you write the firmware code to run the job. ##
        line.set_value(1)  # Turn on GPIO
        self.set_job_status_label("Job Status: GPIO: ON")

        duration = job_input_parameters.get("time", 5)
        for i in range(duration, 0, -1):
            self.set_job_status_label(f"Job Status: GPIO: ON, Time remaining: {i} seconds")
            time.sleep(1)

        line.set_value(0)  # Turn off GPIO

        ### FIRMWARE END ###

        ## Gather the user response [Optional, you can remove]##
        self.set_job_status_label("Job Status: GPIO: OFF. Please type in response.")
        self.get_user_output_response()

        ## Submit the data back to the server ##
        final_output_parameters = {"response": self.output_text}
        self.submit_completed_response_to_server(final_output_parameters)

    def run_spincoater(self, job_input_parameters):
        """Run the spincoater job."""

        print("Job input parameters:", job_input_parameters)

        ### This is where you write the firmware code to run the job. ##
        rpm = job_input_parameters.get("rpm", 1000)
        duration = job_input_parameters.get("time", 5)

        # Send RPM command
        rpm_command = f"RPM:{rpm}\n"
        print(f"Sending: {rpm_command.strip()}")
        ser.write(rpm_command.encode())
        time.sleep(0.5)  # Small delay to ensure command is processed

        # Send Time command
        time_command = f"TIME:{duration}\n"
        print(f"Sending: {time_command.strip()}")
        ser.write(time_command.encode())
        time.sleep(0.5)  # Small delay to ensure command is processed

        # Send Start command
        start_command = "START\n"
        print(f"Sending: {start_command.strip()}")
        ser.write(start_command.encode())

        run_result = "JOB FAILED"

        # Read response from Arduino
        while True:
            response = ser.readline().decode('utf-8').strip()
            if response:
                print(f"Arduino: {response}")
                if ("**SPIN JOB COMPLETED SUCCESSFULLY**" in response):
                    run_result = "JOB COMPLETED"
            else:
                break  # Stop reading when no more data

        ### End of firmware code. ###

        ## Submit the data back to the server ##
        final_output_parameters = {"response": run_result}

        self.submit_completed_response_to_server(final_output_parameters)


    ##########################################################################################

The last section that needs to be reconfigured when adding a new device sets parameters for the GUI and main action of the program.

The editor will specify a default job param template (needed to construct the GUI automatically), the name for the machine (so it knows what jobs to grab from the server) and the name of the function to run when a new job is fetched.

########################## EDIT HERE: JOB OBJECT FORMAT ######################################
#### INSTRUCTIONS: ####
### In this section, to integrate a new tool, you must create three new variables ###
### These will be used to know which function to call when the job is run. ###
### The variables are: ###
### 1. JOB_PARAM_TEMPLATE: This is the template for the job parameters. ###
###    It should be a dictionary with the same keys as the job parameters. ###
###    The values should be the default values for the job parameters. ###
### 2. JOB_NAME: This is the name of the job. ###
###    It should be the same as the name of the job in the server. ###
###    It will be used to identify which jobs to fetch from the server###
### 3. JOB_FUNCTION: This is the function that will be called to run the job. ###
###    It should be the function that you wrote to run the job. ###

#### It is imperative that the job object format matches the server's object format ####

#### SPINCOATER JOB ####
SPINCOATER_JOB_PARAM_TEMPLATE = { "time": 12, "rpm": 1100 }
SPINCOATER_JOB_NAME = "spincoater"
SPINCOATER_FUNCTION = JobGUI.run_spincoater


#### LED JOB ####
LED_JOB_PARAM_TEMPLATE = { "time": 5 }
LED_JOB_NAME = "led"
LED_FUNCTION = JobGUI.run_led


### Edit the following variables to match the job type you are integrating ###
JOB_PARAM_TEMPLATE = SPINCOATER_JOB_PARAM_TEMPLATE
JOB_NAME = SPINCOATER_JOB_NAME
JOB_FUNCTION = SPINCOATER_FUNCTION

##########################################################################################

Embedded Firmware

Whoever is extending this software to a new tool will need to write firmware for the ardunio or other microcontroller that controls the final device. For example, the spincoater has an internal ardunio that acts as a microcontroller. The RPI talks to this microcontroller over UART.

Here is the code that will run on the arduino FOR THE SPINCOATER INTEGRATION. Notice that only a section was added for the USB UART interface.

Example embedded firmware: Spincoater

The spin coater's motor must be powered by an AC 120-V power supply. The spin coater also needs to be connected to an Air Compressor, which is also AC powered.

The AC power to the air compressor and the spin coater are connected to the "normally off" outlets of the relay switch. GPIO pin 17 of the Raspberry PI is connected to the positive terminal of the relay switch DC input. The ground pin of the Raspberry Pi GPIO pins is connected to the negative terminal of the relay switch.

Example embedded firmware: Stepper

In this section, I will explain how the lab communication system was used to successfully connect the stepper to the database website with minimal changes to the system architecture.

There are two main differences between the spincoater and stepper when considering their integration with the lab com system.

  1. The stepper solution already has a control PC. This eliminates the need for the RPI, as we can just run the lab_com software directly on the control PC.

  2. The stepper needs to have an image sent from the website to describe the image to pattern. Although it is theoretically possible to encode this within the existing input_params JSON, this is not a robust solution. We will need to develop a file transfer system to transmit images from the website to the stepper. This file transfer system will be soley used for images here, but it can be used with other types of files when connecting other devices to the lab_com system.

The diagram below shows the overall dataflow for the interaction between the website and the stepper.

The website first adds a job to the job queue to start the spincoater. For testing purposes, we will use a simple web gui as shown in the image below.

After the user hits submit, the image is uploaded to AWS S3 blob storage. AWS S3 blob storage is a service that allows shorter-term storage of files as part of a web application.

As a result, the jobs queue database will then have the following entry added. It is shown here in JSON where the keys are the column names and the values are the values within this specific row of the table.

{"input_parameters": {"x": "9000", "image_s3_key": "uploads/129f420c-ac04-46af-a935-a1ded153de1c", "y": "8000"}, 
"machine": "stepper", 
"status": "In Progress", 
"timestamp": 1745800143, 
"output_parameters": {}, 
"priority": 2, 
"job_id": "3891b3b4-9cca-476d-b55e-874b92cdf663"}

Note that the table schema (names of the columns) did not change for the stepper. It is the same as the table schema for the spincoater. All jobs are stored in the same table. We are able to differentiate between jobs for each type of machine by the "machine" column (as seen above).

The file that stores the pattern to image is not stored directly in the jobs queue database, but is instead stored in AWS S3 storage. Within the jobs queue database table, the input parameter stores a key to access the specific file uploaded for this job. For the job above, the key is: "image_s3_key": "uploads/129f420c-ac04-46af-a935-a1ded153de1c"

The job is now stores in the queue and ready to be fetched and run by the stepper.

At this point, the stepper has all of the data needed to complete the patterning job. The patterning job is run, and the job_completion endpoint is called on success.

Error Handling & Reliability

This system was designed on the ground up from both the macro and micro-level for robust operation.

The main high level design principle that ensures robust operation is redundancy. The lab_com system for this semester is not intended to fully operate with no human intervention. Although the infrastructure is now in place for operation without human intervention, we will have a human in the loop for the short to medium term. For example, the current spin coater requires a human to place the chip on top and line it up before the spin can begin. So, the current system includes a GUI control attatched to the RPI that allows the user of the spincoater to approve or deny jobs sent from the website. Furthermore, the GUI also allows the user to manually start a local job in case the lab_com system goes completely offline. Last, the physcial buttons are still present on the spincoater and will override any automated controls.

A related high level design principle that has been employed to increase reliability is the KISS principle: Keep it simple stupid. In practice, this has meant using the HIGHEST possible level of abstraction for hardware and software tools. This not only reduces design complexity substantially, but it also improves design reliability as we are using tools and systems that have already been validated by others. The main example of this is using HTTP API requests instead of opening sockets for network communication. HTTP requests are the foundation of all web-based traffic. There are countless resources available for developing, debugging, and testing HTTP requests. The barrier to entry for future students working on this project will also be much lower.

def send_job_completion(job_id, output_parameters):
    """Send job completion data to the server."""
    endpoint = f"{BASE_URL}/job_completion"
    data = {
        "job_id": job_id,
        "status": "completed",
        "output_parameters": output_parameters
    }
    try:
        response = requests.post(endpoint, json=data)
        response.raise_for_status()
        print("Job completion posted successfully.")
    except requests.exceptions.RequestException as err:
        print(f"Error posting job completion: {err}")

Spin on Glass Storage and Preparation

Short term Storage/ preparing small amounts for use

Replace Every 2 weeks

  1. Use a small plastic container (insert pic) to store a small amount ( < 10 ml) of SOG. Label the container as “700B” (undoped) or “P504” (dopant) and label the date that it was transferred from the bulk supply.

  2. Store this bottle of SOG at room temperature under the fume hood where SOG spin coating and annealing is performed.

  3. Allow the SOG to come to room temperature prior to use

    1. Filmtroonics recommends to allow the SOG to come to room temperature for 24 hours but this can be shortened to just a few hours if < 5 ml of SOG is in the bottle

Tube Furnace SOP

Parameters

Temperature

generally 1100°C

Diffusion time

generally 30 min for defining source/drain regions


Purpose

The primary use of the tube furnace is for diffusion of dopant atoms into silicon. The incorpoation of dopant atoms into the Si lattice creates defects in the electronic structure, which are charge carriers, increasing the conductivity of the diffused region and making it either N or P type. Diffusion of a solid into another solid is quite slow, so high temperatures and long times are needed, hence the high-temperature tube furnace.

Our process uses spin on glass containing phosphorus for N doping and boron for P doping.


Tools

  1. Quartz rod

  2. Quartz microscope slide, or Fused silica boat

Materials

  1. Chip with glass containing phosphorus or boron.


Procedure

Pre-heating the Furnace

  1. Turn on the furnace.

  2. Press and hold “set/ent” for three seconds until “mode res” is showing. Press the up arrow twice until mode “LCL” is selected. Press “enter” once. Now the furnace will hold the temperature shown. Use the arrow keys to adjust and press “enter” once to set the setpoint.

Inserting chips

  1. Put the Quartz microscope slide in the entrance of the tube. Do not use a regular borosilicate microscope slide, or it will melt inside the tube. The edge of a fused silica slide is pure white, while borosilicate is a little bit green.

  1. Place your chips on the slide.

  2. Put on the heat resistant gloves.

  3. Use the glass rod to push the slide into the center tube, being careful to not scratch the inside of the tube too much

    1. Measure out how far the glass rod needs to be pushed in to place the chips atthe center of the tube furnace.

  4. The rod is extremely hot, and will auto ignite what it touches, or burn through flesh. carefully place it a top the tube furnace

Removing chips

  1. Use the glass rod to push the slide to the other end of the tube.

  2. Wait a few minutes for the slide to cool down.

  3. Use metal tweezers to take the slide out. place it on the upside down beaker to allow it to cool further

  4. Wait 3 minutes before handling the chip.


Safety

The furnace is obviously very hot. Keep away from any hot parts of the furnace. The rod will heat up in the few seconds that it is inside the tube, so when removing it, only hold it by the colder end.

The rod and tube also channel heat out of their ends via internal reflection of radiation.


Spin on Glass Thickness Measurement

*This only works with SoG on pure silicon and NOT polysilicon. Should work for both 700B/P5O4

Purpose

The main purpose of this SOP is to describe a method that we can use to approximate the thickness of SoG. This is especially important in certain plasma etching processes, where removal of SiO2 is needed.

Tools

  • Spectrometer

  • Spectrogryph opened on computer connected to microscope view

Picture of Spectrometer Below:

Materials

  • Silicon Chip with 700B/P5O4 SOG

Steps

Setting up the software + obtaining spectrometer data

First, ensure that the spectrometer is connected to the computer.

In addition, place SoG on silicon chip sample on the slide under the microscope.

  1. Open Spectrogryph software on Computer

  2. Under Plot/Views, select “New Acquisition View”

After which, you should see something that looks like:

  1. In the upper left corner, select “Device Type” and select ASEQ. Then press connect.

  2. Change exposure to 5000 ms (or more, if you want less noisy data)

  3. Select single shot or continuous

    1. Use Single Shot if you want to get one graph that is taken after 5 seconds of exposure

    2. Use Continuous if you want a graph that is constantly being recorded (hence changing)

  4. Pressing “Acquire” would start the readings. Before pressing “Acquire”, ensure that the probe is connected to the microscope (will need to press the probe against the microscope to get good readings, as shown in picture below).

7. Once a graph of Count against Wavelength is obtained, we need to normalise the counts. This is done by clicking on "Process" and "Normalise (Peak)".

  1. Once normalized, we can now save this spectral plot in file (save it in the .sgd format, so that you can re-open it in spectrogryph later)

Determining Thickness of SoG

  1. Create another New Acquisition View

You should see this:

The color of the graphs correspond to the actual observed colors of the glass. This can serve as a good benchmark as to what the thickness of your glass might be.

As seen, the SoG with the lowest thickness (190 nm) had the maximum peak at a wavelength of ~590nm. As the glass thickness increases from 190 nm to 255 nm, the wavelength at maximum peak increased accordingly. Following that, from 255 nm to 276 nm, it can be seen that a second peak is starting to form (at a wavelength of around 480 nm). Finally, from 276 nm to 314 nm, the peak at 590 nm disappears, and now the peak at 480 nm becomes more distinct.

  1. Lastly, drag the .sgd file that you previously saved in Step 7 into the plot above.

  2. Determine which shape your graph most closely resembles to determine SoG thickness.

Also note that the color of your glass is a pretty good indicator of what thickness it will be. So for instance, if your chip looks pink, just by looking at the calibration graphs, we can determine that thickness is around 270 nm.

Useful Links

DIY Thermal Evaporator SOP (CMU Version)

Purpose

Deposit thin films of Aluminum onto the chip so that we can make electrical contact with doped Si and make interconnects between those contacts.

Materials

Procedure

  • Put on nitrile gloves.

  • If the Pfeiffer turbo pump is on, power it off by pressing the button pictured below.

  • Use the arrows to scroll to parameter 309, which show pump speed.

  • wait until the pump speed is at 0Hz

  • Slowly vent the chamber by unscrewing the vent screw located on the turbo pump (behind the chamber)

    • Try to increase 1 order of magnitude every 10 seconds

  • Wait until the pressure is at 1E3 hPa or greater (pressure is given by parameter 340).

  • Unskrew the two black knobs pictured below (B), then lift the chamber lid.

  • Turn the two black knobs on the top of the blue box as shown in Figure 1, and open the lid.

  • Make sure youre wearing nitrile goves.

  • The tungsten filament is secured with two barrel connectors piuctured below (B). The filament can be removed by slightly loosening the screws closest to the filamnet.

  • Tightly wrap aluminum around the Tungsten coil. The filament becomes brittle after evaporation, so be careful not to break it. if you do break it, use a new filament

  • Place the tungsten filament back and screw it in. Make sure it is straight.

  • Place ~ 1 inch of poly ide tape on the substrate holder shown below (A), then peel off the clear layer on top of the tape. Since aluminum often covers the square box, when you put the tape on, aluminum might stick to it and flake off. Just continue attempting to apply tape until it stick without flaking off.

Evaporation

  • Place your chip on the yellow tape, and use tweezers to gently press down on the corners of the chip.

  • Double check that the metal sheet at the back is not bent and still covering the vacuum.

  • Double check that the wire and barrel connectors are suspended and not touching anything conductive as to short them.

  • Use a multimeter to ensure no continuity between the power and ground wire going into the chamber.

  • Close the blue lid and screw the black knobs all the way.

  • Close the vent all the way (hand tight)

  • Turn on the pump.

  • Screw the black knobs more since they tend to loosen after the pump turns on.

  • Wait for the pressure to reach at least 6E-5 hPa. This will take 10+ minutes depending on how clean the inside of the chamber is, and how well it is sealed.

  • Turn on the power source as shown below (A)

  • Press start on the STM software

  • Slowly turn up the current on the power source until ~30 Angstrom/s is reached (do not exceed 45 amps). Keep adjusting the current to keep the rate between around 30 Angstrom/second until the thickness hits 5 kÅ, or you can no longer sustain the rate.

    • If you click the dial, you can change the digit.

    • The voltage and power will automatically change as you adjust the current, so you do not need to worry about it.

    • The pressure might increase during evaporation.

  • After the thickness hits 5 kÅ, TURN THE CURRENT BACK TO 0 AMPS BEFORE TURNING OFF THE POWER SUPPLY.

  • Press stop on the STM software.

  • Turn off the vacuum pump. WAIT until parameter 309 shows 0 Hz.

  • Slowly vent the chamber by unscrewing the vent screw located on the turbo pump (behind the chamber)

    • Try to increase 1 order of magnitude every 10 seconds

  • Open the chamber, and peel the tape off with your chip.

  • Use polymer tipped tweezers to grip the sides of teh chip, then use separate pair of tweezers to peel the tape off the chip.

Glass Acid Etch SOP

THIS IS NOT A COMPREHENSIVE GUIDE FOR HF ETCHING. THIS IS A RESOURCE TO COMPLIMENT IN PERSON TRAINING

Same process for Doped SOG:

Parameters


Purpose

You must complete Hydrofluoric Acid training before using Hf for etching.

The HF/BOE etch is used to do one of the following.

  • To etch holes through a layer of glass to open up areas for electrical contact to to doped Silicon.

  • To etch holes through a layer of glass being used as a diffusion barrier to open up regions for doping.

  • To etch way specific areas of doped glass to control where dopant diffusion will occur.

  • To strip a chip of leftover doped glass that needs to be removed for subsequent processing.

  • To strip native oxides, thermally grown oxides that may have formed during drive in diffusion.

  • To etch gate oxide layer left over after plasma etching of polySi with a plasma etcher in the original NMOS process.

Each of these conditions may require different etch times, and require different amounts of temporal precision for when to stop the etch. Regardless, you need to have an understanding of the density and thickness of layers you're etching, and the device you're processing to understand what etching parameters to use.

Spin on glass/diffusant should be patterned with HMDS to enhance adhesion between the photoresist and SOG layer during etching. Otherwise the photoresist is prone to peeling.

Relevant reaction:

SiO2 + HF → H2SiF6 + H20


Tools

  1. Fume hood

  2. Appropriate container for acid (polypropylene)

  3. Nitrile Gloves (under)

  4. Neoprene Gloves (over)

  5. Nitrile Splash Apron

  6. Face shield

Materials

  1. Hydrofluoric Acid or Buffered Oxide Etch

  2. DI water


Procedure

Preparation

  1. Put on PPE, including splash apron and face shield, where the over neoprene gloves when handling items in the fume hood

  2. Never remove tweezers from the fume hood. Once a tweezer has been used in the fume hood, it must remain there.

  3. Place your chip on the cleanroom wipe taped to the inside of the acid hood.

  4. Open the three small jars, labeled BOE, R1 (rinse 1), and R2 (rinse 2). Keep them in the orientation pictured below to minimize the chances of spilling, have them in the correct sequential order, and ensure that if a spill occurs it stays within the fume hood.

  5. Keep them in the black 3D printed tweezer guide.

  6. R2 should be filled higher than R1, and R1 should be filled higher than the BOE.

Etching

  1. Use the modified tweezers to pick up and hold your chip.

    1. These are self-locking tweezers, once it has a good grip you can hold the tweezers by the metal wire handle on top

  2. Start the timer and place your chip in the BOE, letting the tweezer dongle rest on the 3D printed etching stand

  3. When the timer is up, move the chip to R1, and jiggle it in R1 for 30 seconds

  4. Move the chip to R2, and jiggle it in R1 for 30 seconds

  5. Hold the chip over a beaker and spray it with DI water thoroughly.

  6. Place the chip back on a new cleanroom wipe outside the fume hood.

  7. Place the modified tweezers back in the fume hood where you found them

  8. Remove your gloves first, keeping them in the fume hood where you found them

  9. Remove the rest of your PPE

  10. Now take a pair of tweezers from outside the fume hood and pick up your chip

  11. Rinse the chip using a DI water squirt gun over the sink for 20 seconds, or hold it under the DI water tank.

  12. Dry your chip off with a nitrogen gun.


Inspection

Incomplete oxide etch looks like rainbow patterns at the bottom of holes.

Complete etch looks like flat white reflective Silicon

Inspect before stripping the photoresist


Safety

This document is an operating procedure for our specific lab, and is a reference for students to know how to consistently complete a successful etch.


Dry Oxide Growth SOP

SOP for dry oxide growth of 10nm SiO2

Parameters

Purpose

The oxidation growth of the silicon layer creates a layer of insulation to prevent direct flow from the conducting MOSFET layer to the metal gate.

  1. Fused silica rod

  2. Fused silica microscope slide

Tools

  1. Fused silica rod

  2. Fused silica microscope slide

Materials

  1. Pure silicon chip (not pre-deposited)

Procedure

Pre-heating the Furnace

  1. Turn on the furnace.

  2. Press and hold “set/ent” for three seconds until “mode res” is showing. Press the up arrow twice until mode “LCL” is selected. Press “enter” once. Now the furnace will hold the temperature shown. Use the arrow keys to adjust and press “enter” once to set the setpoint.

  3. Wait ~15 min for the furnace to come to temperature.

Inserting chips

  1. Put the fused silica microscope slide in the entrance of the tube. Do not use a regular borosilicate microscope slide, or it will melt inside the tube. The edge of a fused silica slide is pure white, while borosilicate is a little bit green.

  1. Place your chips on the slide.

  2. Use the glass rod to push the slide into the center of the tube, being careful to not scratch the inside of the tube too much. Start the timer.

  3. Place the rod on top of the tube furnace (it will be hot).

Removing chips

  1. Use the glass rod to push the slide to the other end of the tube.

    1. Push the slide all the way to the end until it is reachable.

    2. Put the rod on top of the tube furnace (it will be hot).

  2. Wait a few minutes for the slide to cool down.

  3. Use metal tweezers to take the slide out. Don't use the orange ones because they don't close all the way.

  4. Put the slide on a heat resistant surface and wait 5 minutes before handling the chip.

Safety

The furnace is obviously very hot. Keep away from any hot parts of the furnace. The rod will heat up in the few seconds that it is inside the tube, so when removing it, only hold it by the end.

The rod and tube also channel heat out of their ends via internal reflection of radiation.

Aluminum Etch SOP

Parameters


Purpose

After thin films of Aluminum are deposited (whether it be Thermal Evaporation, sputtering, etc) onto the chip, we want to define isolated contacts to certain pats of the device, and define interconnects between those contact. To do this, the contacts and interconnects are patterned on top of the Aluminum surface with photoresist, and then wet etched. The contact pads that are left allow us to probe the device, or package it.

How It Works

Alumina etchant contains Phosphoric Acid, Nitric Acid, and Acetic Acid (all in one solution). The Nitric Acid Oxidizes the Aluminum, then the Phosphoric Acid etches the Aluminum Oxide, and the acetic acid lowers surface tension to help the etchant wet the surface.

Disclaimers

Phosphoric and Nitric Acid are extremely Hazardous, be sure to review the SDS for the Al etchant, and wear the proper PPE (Lab Coat, Splash Apron, Nitrile gloves (under), Neoprene gloves (over), Face shield)

If under etching occurs, then all contacts will be shorted to each other. Over etching could result in less feature resolution, or Aluminum peeling off the chip.

Aluminum etch has proven difficult to keep consistent. There are many problems with peeling and bad adhesion of both photoresist on top and aluminum to the layers below.

Best practice is to calculate how long you should etch for, then etch for 30 seconds greater than that amount of time, then inspect, then etch longer if the etch looks incomplete.


Tools

  1. Fume hood

  2. Hot plate with magnetic spinner

  3. Magnetic stirrer

  4. Glass beaker

  5. Appropriate container for acid (polypropylene)

  6. Nitrile Gloves (under)

  7. Neoprene Gloves (over)

  8. Nitrile Splash Apron

  9. Face shield

Materials

  1. Aluminum etchant (16:1:1:2 phosphoric, nitric, acetic, DI water)

  1. DI water

Procedure

Preparation

  1. Put on nitrile gloves

  2. Place your chip on the cleanroom wipe taped to the inside of the acid hood. Do not leave the tweezers inside the fume hood.

  3. Put on a splash gown.

  4. Put on a face shield.

  5. Put on the neoprene gloves. Avoid touching the outside of the gloves.

  6. Pre-heat the hot plate.

  7. Fill the beaker to about 1 cm with Aluminum etchant

  8. Once the hot plate has reached the desired temperature, place the evaporating dish on the hot plate slightly off center so that the magnetic stirrer is on one side. turn on the stirrer.

Etching

  1. After the acid has had 5 minutes to come to temperature, use DI water to rinse the black plastic tweezers and pick up the chip, then put it in the dish on the opposite side from the stirrer, then start the timer.

  2. Rinse tweezers with DI water after.

  3. Prepare to take the chip out 30 seconds before the timer is up. It can be tricky to grab the chip, so start early and drop it into the DI water when the timer expires.

  4. Swish the chip around a couple of times and then take it and rinse further with the DI squirt bottle out and let it dry on the wipe.

  5. Turn off the hot plate.

  6. Take off the Neoprene gloves, Splash apron, and face shield.

  7. Use your outside tweezers to pick up the chip and dry it off with the nitrogen gun.

Inspection

Incomplete aluminum etch looks black and rough.

Complete etch should look like the layer you were trying to etch down to

Peeling is very obvious as well.


Safety

While the acids involved in this step are not as aggressive as hydrofluoric acid, there are still many overlapping safety protocols to be followed. This document is NOT qualified to teach you all the required safety protocols and correct operating procedures - please refer to an SOP and more disposal and safety resources.

This document is an operating procedure for our specific lab, and is a reference for students to know how to consistently complete a successful etch.


Probe Station SOP

Purpose

After fabrication, the chip must be tested to demonstrate the functionality of the design. Additionally, variations and errors in fabrication may result in differences in device characteristics which are useful to document when these variations cause the device to fail.

To enable precisely controlled experiments on microscopic chips, we currently use a probe station to contact the device using sharp probes which supply and measure voltages for calculation of various device characteristics such as I-V curves, which are explained in this SOP.

Tools

  • Probe station setup

    • Probe station - Karl Suss PM5

    • At least 4 probes, manipulators, and coaxial cables

  • Microscope setup

    • Camera - AmScope MU1000-HS and AmScope viewing software

    • Light – MI-150 Fiber Optic Illuminator

  • Keithley semiconductor analyzer system

    • Keithley 4200-SCS Semiconductor Parameter Analyzer

    • Keithley 2636a Sourcemeter

    • Keyboard and mouse

Materials

  • Devices under test – typically a finished chip with pads for probing

  • Flash drive for data transfer

Procedure

General setup and cleanup

  1. Place the chip in the center of the stage and turn on the vacuum.

  2. Turn on the microscope light, which appears as a spot of light on the stage.

  3. Connect the microscope camera to your computer and select the camera MU-1000HS on the AmScope viewer software, which should summon the camera view. The Keithley semiconductor analyzer has only two USB ports, which are currently occupied by a keyboard and mouse. Without WiFi or a USB hub, the camera view and data transfer are handled by another computer.

  4. Turn on the Keithley semiconductor parameter analyzer.

  5. Open the KITE software and the experiment of interest (see below sections).

  6. Using coaxial cables and connectors, connect each probe to the corresponding port on the Keithley semiconductor parameter analyzer.

  7. Raise the stage using the lever. Focus the stage and center the pattern of interest under the light source using the knobs below the stage.

  8. If the probe tips are not illuminated by the microscope light, carefully move the magnetically-attached manipulators such that the range of motion of the probe tips is within the spot of light.

  9. Using the knobs on each probe’s manipulator, lower the probes so that the tips are focused yet not touching the chip, then position the probe tips above their corresponding probing pads.

  10. Carefully lower the probe tips to touch the pads, which is generally indicated by resistance to movement when attempting to lower the tip further. The manual nature of this process means that the sharp probes can scratch the chip and damage the device beyond future usage, such as scratching the pads off.

  11. Press the green triangle in the KITE software to run the experiment.

  12. Once the experiment finishes, check the data for errors and repeat the experiment as necessary.

  1. Scale the graph such as by right clicking the graph and clicking Autoscale and save the data in a folder named chip### where ### is the chip number. To save the graph and data with a common name, type the name and click Populate, Save All, then Exit.

  2. Remove the probes from the chip and continue to the next device, either by lifting the probes or lowering the stage.

  3. After all experiments are finished, transfer the data to a flash drive and upload the data (such as to Google Drive).

  4. Raise the probes using the manipulator knobs.

  5. Lower the stage by turning the lever.

  6. Turn off the Keithley parameter analyzer.

  7. Disconnect the microscope from your computer and turn off the microscope light.

  8. Turn off the vacuum and remove the chip.

MOSFET I-V Curve

  1. Upon opening the KITE software, choose the vds-id test from under the section 4terminal-n-fet.

  2. Configure the probes and measurements using the following parameters. Make sure that the correct coaxial cable (SMU1, SMU2, GNDU) is connected to the correct probe.

  1. The I-V curve of the MOSFET and the gate leakage current should be plotted. Note the magnitude of the voltage and current measurements. Very low current in the range of nano-amperes or below can indicate an open circuit, and linear behavior can indicate a short circuit, which can arise from a fault in the device or improper probe placement.

Gate & Contact Resistance

  1. Upon opening the KITE software, chose the res2t test froom under the section 2-wireresistor.

  2. Configure the probes and measurements using the following parameters. Make sure that the correct coaxial cable (SMU1, SMU2) is connected to the correct probe.

  1. The I-V relationship between the two probes and resistance estimated from Ohm’s law should be plotted. An ideal resistor should have a linear relationship and constant resistance.


Wafer Cleaving SOP

Purpose

We pre-dice wafers in order to:

  • Limit the size of our DIY machines

    • Decreases the necessary movement range of nanpositioners

    • Other machines can be sized down

  • Increase experimental throughput

    • Decrease cost of each raw materials

    • Decrease risk of breaking chip

    • Ease chip handling

Best Practices

  1. Lay the wafer on a hard, steady surface

    1. If the surface has some give, it will act as a spring when pressure is applied from the scribe

  2. At an oblique angle, place the scribe tip at the edge of the flat side of the wafer

    1. Flat edge marks crystal orientation, cleaving should be easier along certain crystallographic directions.

  3. Push down, don't think too hard, cleave.

    1. It may also help to press down and drag the scribe tip 1 mm outwards to the edge of the wafer.

  4. Don’t move chip around with the diamond scribe to avoid scratches

MTI Evaporator SOP (No longer in use)


Parameters

Purpose

Figure from Microchip Fabrication (Van Zant, 2004)


Tools

  1. MTI Thermal Evaporator with Inficon Film Thickness Monitor

Materials

  1. Kapton tape

  2. 99.999% Aluminum wire

  3. Recommended: piranha solution


Procedure

Preparation

  1. Place the chip on a hot plate at 180°C for 90 minutes. Cover it to avoid surface contamination.

  2. Wear gloves while handling parts exposed to vacuum because oil from your hands will outgas.

  3. Use double sided kapton tape to attach the chip(s) to the center of the substrate holder.

  4. Put 20 cm of aluminum wire into the crucible.

Bakeout

  1. Carefully close the chamber.

  2. Check that the vent knob on the turbopump is fully closed by turning clockwise.

  3. Start the vacuum by pressing the on/off button on the pump.

  1. Wait for the pressure to get below 5E-5 hPa. You can also program the bakeout to have a long 0°C segment at the beginning.

  2. Make sure that the current knob on the side of the evaporator is in the “Auto” position.

  3. Press “Set” and “◀” to return to the standby state, then press and hold “▼” for 2 seconds to start the program. Press the green run button to enable current flow.

Evaporation

  1. Ensure the pressure reads less than 5E-6 hPa.

  2. Program the evaporator to ramp to 1125°C over 2000 seconds, hold for 500 seconds, and ramp down over 2000 seconds.

  3. Start the program. Set a timer for 28 minutes so that you open the shutter at the right time.

  4. Set up the film thickness monitor by plugging its USB cable into the laptop and starting the STM-2 software.

  5. When the evaporator reaches the target temperature, open the shutter using the knob at the top of the chamber and press “zero” on the STM-2 software.

  6. Monitor and record the pressure (should be below 5E-6 hPa) and deposition rate (should be greater than 5 Å/s) during the evaporation.

  7. When the temperature starts to drop, close the shutter.

  8. Wait for the temperature to drop below 350°C before proceeding

Vent

  1. Turn off the pump by pressing the same on/off button.

  2. Wait 10 minutes for the turbopump blades to slow down.

  3. Slowly turn the knob on the turbopump until the pressure starts to increase (<¼ turn). Don’t open it all the way or the rapid pressure increase will destroy the pump, which is still spinning really fast.

  4. Wait another 10 minutes.

  5. Once the pressure has increased to 1 hPa, open the valve a bit more. Wait until the chamber is at 1000 hPa (1 bar).

  6. Open the chamber and place the substrate holder face up.

  7. Use a utility knife blade to separate the chip(s) from the substrate holder.

  8. Peel/scrape off any tape residue left on the chip.

Anneal

400-500C


Safety

  1. As previously mentioned, don’t vent the chamber too quickly. Turbopumps supposedly have the kinetic energy of a car on a highway and can “grenade”... we don’t want to find out what that means.

  2. The sample holder may be hot. Be careful.

Appendix

Flash Evaporation Alternate Technique

Use this as a backup technique when the crucible/thermocouple are out of commission. No temperature control is used, instead we manually control the current running through a tungsten filament with aluminum wire wrapped around it. This is a quicker, less accurate technique. The deposition monitor can still be used to determine when the metal is depositing on the chip, though it may be less accurate due to the rate of deposition.

Preparation

  1. Use a 3-wire tungsten filament instead of a crucible. Wrap 20 cm of aluminum wire around it, keeping away from either end.

  2. Screw it into the terminal posts in the evaporator.

  3. Scrape/wipe off some deposited aluminum from the glass jar so that you can see into the chamber.

  4. Follow all other steps for pump down, except anything that mentions programming temperatures.

Evaporation

  1. Turn the switch on the right of the machine clockwise so it's set to manual mode.

  2. Use the knob above it to set current to 12A. The current is displayed on the front panel.

  3. Monitor the filament for ~5 minutes until it starts to glow. The aluminum will also melt and wet onto the filament.

  4. Increase the current to ~20A. It should start to glow white hot. If the deposition monitor is on, it should start to record some deposition. The walls of the chamber will also turn opaque from the aluminum. Hold for a couple minutes.

  5. Decrease the current to 10A, then 5A, then 0A to slowly cool the filament. Wait 10 minutes.

  6. Follow the vent procedure listed above.


Misc. notes that need to be organized:

Manually switch to evaporation procedure (based on evaporation data spreadsheet, using thickness monitor to determine when to stop)

Sam only evaporated for 1 minute, we are doing ~15?

Let it evaporate at 1100 for 3 min before moving guard to expose chip

This is because there is scum in the crucible and might be oxygen in the chamber at the beginning of evaporation that causes aluminum oxide to build on chip

  1. Evaporation is faster than sputtering (supposedly, it might be equivalent because evaporation operates at a much lower pressure than sputtering so pump down and bakeout take a whi

https://www.youtube.com/watch?v=sTa-Hn_eisw
https://pmc.ncbi.nlm.nih.gov/articles/PMC6066758/
http://www.diyouware.com/node/161
https://pmc.ncbi.nlm.nih.gov/articles/PMC6066758/
https://pmc.ncbi.nlm.nih.gov/articles/PMC6066758/
Waveforms Software
Tracer Window
Analog Discovery 3 - Digilent Reference

The Hacker Fab was built on the Django framework using Python, with HTML and CSS serving as the front-end. The code in this . The purpose of the database is to store data related to chip fabrication in our labs and use the results to refine our process parameters. It is crucial that we maintain a comprehensive and functional data store in order to develop new processes and to help new Hacker Fabs begin fabrication.

The code has a model-view-controller (MVC) structure. Each fabrication process is described as a model (in ), with each field representing a process parameter or documentation artifact. This translates to each process being stored as a separate table within the database. This semester, the models were updated to constrain parameters to specific data types in order to maintain consistency and correctness in the database. For instance, temperature was stored as a decimal value, duration as a positive integer, and material type as a string. Some models and fields were renamed as well in order to clarify their meaning. We worked closely with the process development teams to understand which fields should be included or what new models should be added. Relevant Django documentation:

In order to allow the user to interface with the database, there are input and search forms based on the models (in ). As of this semester, the input forms require certain parameters that are measurable and critical to the fabrication process, as well as prefilled default values for standardized parameters in our primary NMOS process. The search forms do not have any required fields, since we should be able to search process data for every chip and parameter value. This semester, the search forms were also updated with input fields that would provide users with the ability to perform searches given a specified range of values. The labels to these forms were also refined to be more readable and include units to aid in correct input. Relevant Django documentation:

The different web pages in our website are served by their own controller functions which are located in . We designed the backend architecture to have a separate function that serves each unique web page. This design allows us to modularize our backend logic and isolate functionality to those specific pages so that they can be as customizable as possible. If similar logic is used across different web pages, we put this logic in helper functions to avoid having duplicated code. The different controller functions for each page serve the main functionality of our website. Routes between the addresses to these pages and the functions that serve them are specified in . The controller links the different HTML pages together, performs the database operations, and interfaces with the backend. It determines what form to display based on what process the user selected, saves the form data and passes it to the database after cleaning, displays search queries by the user, and renders the web pages.

When a user performs a search for data, they can enter specific filters to narrow down their results. These filters are passed to our controller when the user fills out a search form filled with parameter values. In our controller, we use Django’s Q() objects from their to create and execute SQL queries. This simplifies the process of extracting data from our database since we just need to create a Q() object using the filters specified by the user then apply the filter on our models. This querying is done in the function . Data querying is one of the most computationally intensive components of our database; hence, it can be considered as a bottleneck. Querying data for a single model (i.e. process type, user profile, etc.) has a worst case complexity of O(M), where M represents the number of rows that exist for a particular model in our database (the total number of unique entries of that model stored in our database). In the search page, the user is able to conduct a search to retrieve data from multiple process types. In this case, the worst case complexity for the search is O(P*M), where P represents the number of different processes the user has selected, and M represents the number of rows that exist for a particular model in our database.

The code in is responsible for passing the data from the query result to the html files so that they can be displayed on the web page. There is an important detail that developers should take note of when implementing any functions that return queried results to users. We have implemented a specific data format to pass to the html page in order to standardize the design of the html pages and controller function outputs. When an html page is rendered, provides it a context, which contains data (variables) that are required by or will be displayed in the html page. The html page expects the queried data provided in the context to be an array of arrays of dictionaries. Since Django’s querying library returns the queried data to us in the form of a , we must convert the QuerySet into an array of dictionaries using Django’s model_to_dict() function found in their library. Each dictionary represents a single entry in the database. The keys correspond to the column names, which map to the corresponding value for that column. Each array of dictionaries within the outer array corresponds to a grouping of data. This enables us to group data based on the process types so that they can be displayed on the page with the correct column headers. This data structure is depicted below.

Diagram representing the data structure of the query results passed as a context to be rendered in the html

Preheat the to 100°C

Place wafer onto the chuck of the

Place wafer onto the center of the

If the next step requires higher temperatures, see the for details.

See document for a more detailed overview of failure conditions and possible causes.

DIY Vacuum Spin Coater Hooked up to Rotary Vane Pump
Mark a single location on hot plate to place chip throughout every experiment to minimize temperature variation

    1. Very inconsistent heating zones on most hot plates. These are not manufactured for 1cm^2 chip heating, original purpose is for heating of large beakers and liquids.

A 400C hotplate is barely warm on the edges

If you have already claimed a chip number, and opened its specific chip view data sheet, record your patterning data into that sheet. If you have NOT claimed a chip number, and have NOT begun recording data in a chip specific sheet, open this sheet, claim the next available chip number, open the blank chip view sheet for that specific chip number and record all subsequent process data into it.

AZ-4210 positive photoresist ()

If you have already claimed a chip number, and opened its specific chip view data sheet, record your patterning data into that sheet. If you have NOT claimed a chip number, and have NOT begun recording data in a chip specific sheet, open this sheet, claim the next available chip number, open the blank chip view sheet for that specific chip number and record all subsequent process data into it.

the Si wafer into a ~1 cm x 1 cm square.

See the . Remember to pipette an appropriate amount, close the lid, and turn on the vacuum.

Choose Time and RPM from

Choose Time and RPM from

Run the python script called Lithographer.py. You can do this by opening a terminal and running the command "py -3.10 Lithographer.py". Make sure you have all dependencies installed as described in . If the program does not run, see Troubleshooting.

If you do not have an integrated GUI camera implemented and you are using the Flir Camera, open SpinView, select BlackFly S, and press the green play button. If you see horizontal bands across the live camera preview, follow the corresponding steps in .

Agitate the developer

Agitate the chip in the developer solution with quick, small circular motions. Watch for proper technique.

In order to measure the developed pattern resolution, expose . The resolution is equal to the line pitch that is resolved in both light and dark field. Use AmScope to measure. The pitch is the distance between the center of two lines.

For each chip, batch save with the chip number as the first three characters in the file prefix. Do not change the folder. A script will upload to every 5 min.

Inspection image demonstrating non-uniform exposure

See this webpage for in depth spin coating theory:

Record the measured exposure time in the

Some SOG has hardened inside the bottle creating fine flakes of SiO2. These flakes then get sucked up by the pipette and deposited onto the wafer with the liquid SOG (Example picture above). This warrants preparing a new bottle of SOG based on document.

"""AWS Lambda handler module.

This module contains the Lambda function that runs the API endpoints
for the job queue system in AWS.
"""
import json
import uuid
import time
import logging
from decimal import Decimal
import boto3

### This code runs on the AWS instance as a lambda function for managing the API requests ###

# Set up logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)

dynamodb = boto3.resource("dynamodb")
table = dynamodb.Table("JobQueue")

def lambda_handler(event, context):
    """
    Handles API requests for different endpoints.
    """
    logger.info("Received event: %s", json.dumps(event, indent=2, default=decimal_serializer))

    # Extract HTTP method and route
    route = event.get("routeKey", "")
    method = event["requestContext"]["http"]["method"]
    body = json.loads(event.get("body", "{}"))  # Parse JSON body safely

    logger.info("Processing route: %s with method: %s", route, method)
    result = None
    # Routing based on the request
    if route == "GET /jobs/next" and method == "GET":
        result = get_next_job(event)
    if route == "POST /job_completion" and method == "POST":   # Ensure correct endpoint
        result = update_job_completion(body)
    if route == "POST /jobs" and method == "POST":
        result = enqueue_job(body)
    if route == "GET /jobs_by_id" and method == "GET":
        result = get_jobs_by_id(event)
    if route == "GET /jobs_by_machine" and method == "GET":
        result = get_jobs_by_machine(event)
    if route == "POST /generate_upload_url" and method == "POST":
        result = generate_presigned_upload_url(body)
    if route == "POST /generate_download_url" and method == "POST":
        result = generate_presigned_download_url(body)
    logger.warning("Invalid request received: %s", route)
    result = {"statusCode": 400, "body": json.dumps({"message": "Invalid request"})}

    return result

# **Helper Function to Convert Decimal to Native Python Types**
def decimal_serializer(obj):
    """
    Convert Decimal to native Python types.
    """
    if isinstance(obj, Decimal):
        return int(obj) if obj % 1 == 0 else float(obj)
    raise TypeError(f"Object of type {obj.__class__.__name__} is not JSON serializable")

# **Function to Update Job Completion (Completed or Failed)**
def update_job_completion(body):
    """
    Update job completion status.
    """
    job_id = body.get("job_id", "-1")
    logger.info("Received job completion request: %s", body)

    # **Check if job_id is missing, invalid, or set to "-1"**
    if not job_id or not isinstance(job_id, str) or len(job_id) < 8 or job_id == "-1":
        logger.error("Invalid job_id received: %s", job_id)
        return {"statusCode": 400, "body": json.dumps({"message": "Invalid or missing job_id"})}

    # Retrieve the job from DynamoDB to verify it exists
    response = table.get_item(Key={"job_id": job_id})
    if "Item" not in response:
        logger.error("Job ID not found: %s", job_id)
        return {"statusCode": 410, "body": json.dumps({"message": f"Job ID {job_id} not found"})}

    output_parameters = body.get("output_parameters", {})
    status = body.get("status", "").capitalize()

    if status not in ["Completed", "Failed"]:
        logger.error("Invalid status received: %s", status)
        return {"statusCode": 400, "body":
                json.dumps({"message": "Invalid status, must be 'Completed' or 'Failed'"})}

    timestamp = int(time.time())
    table.update_item(
        Key={"job_id": job_id},
        UpdateExpression="SET #s = :s, output_parameters = :o, #t = :t",
        ExpressionAttributeNames={"#s": "status", "#t": "timestamp"},
        ExpressionAttributeValues={":s": status, ":o": output_parameters, ":t": timestamp}
    )

    logger.info("Job %s updated to %s", job_id, status)
    return {"statusCode": 200, "body": json.dumps({"message": f"Job {job_id} marked as {status}."})}

# **Function to Add a New Job**
def enqueue_job(body):
    """
    Add a new job to the queue.
    """
    job_id = str(uuid.uuid4())
    machine = body.get("machine", "unknown")
    input_parameters = body.get("input_parameters", {})
    priority = body.get("priority", 1)
    timestamp = int(time.time())
    logger.info("Adding new job with ID: %s", job_id)

    # Ensure input_parameters are serialized properly (convert floats to Decimal for DynamoDB)
    def serialize_input_parameters(params):
        if isinstance(params, dict):
            return {k: serialize_input_parameters(v) for k, v in params.items()}
        if isinstance(params, list):
            return [serialize_input_parameters(v) for v in params]
        if isinstance(params, float):
            return Decimal(str(params))  # Convert float to Decimal
        return params

    serialized_input_parameters = serialize_input_parameters(input_parameters)

    table.put_item(Item={
        "job_id": job_id,
        "machine": machine,
        "status": "Pending",
        "input_parameters": serialized_input_parameters,
        "output_parameters": {},
        "timestamp": timestamp,
        "priority": priority
    })

    return {"statusCode": 200, "body": json.dumps({"message": "Job added", "job_id": job_id})}

# **Function to Get the Next Pending Job for a Specific Machine
# and Mark It "In Progress", Then Return Updated Data**
def get_next_job(event):
    """
    Get the next pending job for a specific machine and mark it as "In Progress".
    """
    machine = event.get("queryStringParameters", {}).get("machine")
    if not machine:
        return {"statusCode": 400, "body": json.dumps({"message": "Missing machine parameter"})}

    logger.info("Fetching next job for machine: %s", machine)
    response = table.scan(
        FilterExpression="#s = :s AND #m = :m",
        ExpressionAttributeNames={"#s": "status", "#m": "machine"},
        ExpressionAttributeValues={":s": "Pending", ":m": machine}
    )

    jobs = response.get("Items", [])
    if not jobs:
        logger.warning("No pending jobs found for machine: %s", machine)
        return {"statusCode": 404, "body": json.dumps(
            {"message": "No pending jobs found for the specified machine"})}

    # Sort jobs by timestamp (oldest job first)
    jobs.sort(key=lambda x: x.get("timestamp", float('inf')))
    next_job = jobs[0]
    logger.info("Next job selected for machine %s: %s", machine, next_job["job_id"])

    table.update_item(
        Key={"job_id": next_job["job_id"]},
        UpdateExpression="SET #s = :s, #t = :t",
        ExpressionAttributeNames={"#s": "status", "#t": "timestamp"},
        ExpressionAttributeValues={":s": "In Progress", ":t": int(time.time())}
    )

    updated_job = table.get_item(Key={"job_id": next_job["job_id"]}).get("Item", {})
    logger.info("Updated job details: %s", updated_job)

    return {"statusCode": 200, "body": json.dumps(updated_job, default=decimal_serializer)}

# **Function to Fetch a Job by Its ID**
def get_jobs_by_id(event):
    """
    Fetch a job by its ID.
    """
    job_id = event.get("queryStringParameters", {}).get("job_id")

    if not job_id:
        return {"statusCode": 400, "body": json.dumps({"message": "Missing job_id parameter"})}

    response = table.get_item(Key={"job_id": job_id})

    if "Item" not in response:
        return {"statusCode": 404, "body": json.dumps({"message": "Job not found"})}

    return {"statusCode": 200, "body": json.dumps(response["Item"], default=decimal_serializer)}

# **Function to Fetch Jobs by Machine name. This is needed for interface w/web application.**
def get_jobs_by_machine(event):
    """
    Fetch jobs by machine.
    """
    machine = event.get("queryStringParameters", {}).get("machine")
    if not machine:
        return {"statusCode": 400, "body": json.dumps({"message": "Missing machine parameter"})}

    response = table.scan(
        FilterExpression="#m = :m",
        ExpressionAttributeNames={"#m": "machine"},
        ExpressionAttributeValues={":m": machine}
    )

    jobs = response.get("Items", [])
    if not jobs:
        return {"statusCode": 404, "body":
                json.dumps({"message": "No jobs found for the specified machine"})}

    return {"statusCode": 200, "body": json.dumps(jobs, default=decimal_serializer)}

def generate_presigned_upload_url(body):
    """
    Generate a presigned URL for uploading a file to S3.
    """
    s_3 = boto3.client("s3")
    bucket = "job-queue-files"

    # Use the provided filename or generate a unique one
    filename = body.get("filename", f"{uuid.uuid4()}")
    key = f"uploads/{filename}"

    try:
        # Generate a presigned URL without restricting the ContentType
        presigned_url = s_3.generate_presigned_url(
            "put_object",
            Params={"Bucket": bucket, "Key": key},
            ExpiresIn=600  # 10 minutes
        )
        return {
            "statusCode": 200,
            "body": json.dumps({
                "upload_url": presigned_url,
                "s3_key": key
            })
        }
    ## We want to catch all exception, even though this introduces a pylint error. 
    except Exception as exception:
        logger.error("Failed to generate pre-signed URL: %s", str(exception))
        return {
            "statusCode": 500,
            "body": json.dumps({"message": "Failed to generate upload URL"})
        }

def generate_presigned_download_url(body):
    """
    Generate a presigned URL for downloading a file from S3.
    """
    s_3 = boto3.client("s3")
    bucket = "job-queue-files"
    key = body.get("s3_key")

    if not key:
        return {"statusCode": 400, "body": json.dumps({"message": "Missing s3_key"})}

    try:
        url = s_3.generate_presigned_url(
            "get_object",
            Params={"Bucket": bucket, "Key": key},
            ExpiresIn=600  # 10 minutes
        )
        return {"statusCode": 200, "body": json.dumps({"download_url": url})}
    except:
        return {
            "statusCode": 500,
            "body": json.dumps({"message": "Failed to generate download URL"})
        }
"""
This module contains automated tests for the job queue API endpoints.
"""
import requests

# Constants
BASE_URL = "https://fbc4oam2we.execute-api.us-east-2.amazonaws.com/prod"

def test_jobqueue_api():
    """
    Test the job queue API endpoints.
    """
    # Step 1: POST /jobs - Enqueue a new job
    job_data = {
        "machine": "test_machine",
        "input_parameters": {"param1": "value1"},
        "priority": 2
    }
    response = requests.post(f"{BASE_URL}/jobs", json=job_data)
    assert response.status_code == 200, "Failed to enqueue job"
    job_id = response.json().get("job_id")
    print(f"Job enqueued: {job_id}")

    # Step 2: GET /jobs_by_id - Verify job exists
    response = requests.get(f"{BASE_URL}/jobs_by_id", params={"job_id": job_id})
    assert response.status_code == 200, "Job not found"
    print("Job verification successful")

    # Step 3: GET /jobs_by_machine - Verify job is present for machine
    response = requests.get(f"{BASE_URL}/jobs_by_machine", params={"machine": "test_machine"})
    assert response.status_code == 200, "Job not found for machine"
    print("Job found under machine")

    # Step 4: GET /jobs/next - Fetch job from queue
    response = requests.get(f"{BASE_URL}/jobs/next")
    assert response.status_code == 200, "Failed to fetch next job"
    assert response.json().get("job_id") == job_id, "Fetched wrong job"
    print("Job fetched successfully")

    # Step 5: GET /jobs_by_id - Ensure job is now in progress
    response = requests.get(f"{BASE_URL}/jobs_by_id", params={"job_id": job_id})
    assert response.status_code == 200, "Job ID not found"
    assert response.json().get("status") == "In Progress", "Job status not updated"
    print("Job status updated to In Progress")

    # Step 6: POST /jobs_completion - Complete the job
    completion_data = {
        "job_id": job_id,
        "status": "Completed",
        "output_parameters": {"result": "success"}
    }
    response = requests.post(f"{BASE_URL}/job_completion", json=completion_data)
    assert response.status_code == 200, "Failed to update job completion"
    print("Job completion updated")

    # Step 7: GET /jobs_by_id - Verify job is completed
    response = requests.get(f"{BASE_URL}/jobs_by_id", params={"job_id": job_id})
    assert response.status_code == 200, "Job not found"
    assert response.json().get("status") == "Completed", "Job status not updated to Completed"
    print("Job verified as Completed")

if __name__ == "__main__":
    test_jobqueue_api()

scored 10/10 on google pylint

"""
This module contains examples of a few endpoint calls
"""
import requests

# Constants
BASE_URL = "https://fbc4oam2we.execute-api.us-east-2.amazonaws.com/prod"

TEST_FILE_NAME = "PNG_test.png"  # Replace with the path to your test file


def get_file_upload_url_and_key(job_id):
    """
    Generate a presigned URL for uploading an image.
    """
    response = requests.post(f"{BASE_URL}/generate_upload_url", json={"job_id": job_id})
    assert response.status_code == 200, "Failed to generate upload URL"
    upload_url = response.json().get("upload_url")
    s3_key = response.json().get("s3_key")

    print(f"Upload URL: {upload_url}")
    return upload_url, s3_key


def upload_file(file_name, upload_url):
    """
    Upload a file to the presigned URL.
    """
    with open(file_name, "rb") as file:
        response = requests.put(upload_url, data=file)
    if response.status_code != 200:
        print(f"Upload failed. Status code: {response.status_code}, response: {response.text}")
    assert response.status_code == 200, "Upload failed"
    print("File uploaded successfully")



def enqueue_job(machine, input_parameters, priority):
    """
    Enqueue a job with the specified parameters.
    """
    job_data = {
        "machine": machine,
        "input_parameters": input_parameters,
        "priority": priority
    }
    response = requests.post(f"{BASE_URL}/jobs", json=job_data)
    assert response.status_code == 200, "Failed to enqueue job"
    job_id = response.json().get("job_id")
    print(f"Job enqueued: {job_id}")
    return job_id

def download_file(s3_key):
    """
    Download a file from S3 using the presigned URL.
    """

    # get the presigned URL for download
    response = requests.post(f"{BASE_URL}/generate_download_url", json={"s3_key": s3_key})
    assert response.status_code == 200, "Failed to generate download URL"
    download_url = response.json().get("download_url")
    print(f"Download URL: {download_url}")

    # download the file using the presigned URL
    response = requests.get(download_url)
    if response.status_code != 200:
        print(f"Failed to download file. Status code: \
              {response.status_code}, Response text: {response.text}")
    assert response.status_code == 200, "Failed to download file"
    with open("downloaded-" + TEST_FILE_NAME, "wb") as file:
        file.write(response.content)

def test_upload_and_download_file():
    """
    Test uploading a file, providing the S3 key as a job parameter, fetching the job,
    and then downloading the file using the presigned URLs.
    """
    # Step 1: Generate a presigned upload URL and S3 key
    # Passing None as job_id since it's not required here
    upload_url, s3_key = get_file_upload_url_and_key(None)
    print(f"Generated upload URL: {upload_url}")
    print(f"S3 Key: {s3_key}")

    # Step 2: Upload a file
    upload_file(TEST_FILE_NAME, upload_url)
    print(f"File uploaded successfully to S3 key: {s3_key}")

    # Step 3: Enqueue a job with the S3 key as a parameter
    job_id = enqueue_job(
        machine="lithographer",
        input_parameters={"x": 100.0, "y": 200.0, "image_s3_key": s3_key},
        priority=2
    )
    print(f"Job enqueued: {job_id}")

    # Step 4: Fetch the job from the queue
    response = requests.get(f"{BASE_URL}/jobs/next", params={"machine": "lithographer"})
    assert response.status_code == 200, "Failed to fetch next job"
    fetched_job = response.json()
    assert fetched_job.get("job_id") == job_id, "Fetched wrong job"
    fetched_s3_key = fetched_job["input_parameters"]["image_s3_key"]
    print(f"Fetched job successfully. S3 Key: {fetched_s3_key}")

    # Step 5: Download the file using the fetched S3 key
    download_file(fetched_s3_key)
    print("File downloaded successfully.")

if __name__ == "__main__":
    test_upload_and_download_file()

scored 10/10 on google pylint

conceptual overview

The essential behavior of can also be described in the following state machine:

implementation details:

The code completes the following high level actions.

"""
This module contains the GUI for the job queue system.
"""

import uuid
import time
import threading
import tkinter as tk
from tkinter import ttk
import sys
import requests
import gpiod
import serial

IO_PIN = 17  # Change to your GPIO pin number
chip = gpiod.Chip('gpiochip4')
line = chip.get_line(IO_PIN)

# Request the GPIO line for output
line.request(consumer="gpio_test", type=gpiod.LINE_REQ_DIR_OUT)

BASE_URL = "https://fbc4oam2we.execute-api.us-east-2.amazonaws.com/prod"

########################## EDIT HERE: PERIPHERAL CONFIGURATION ##########################
#### INSTRUCTIONS: ######
### Add whatever code you need here to inintialize your peripherals so that they     ####
###        can begin to accept jobs.                                                  ###

#### UART OVER USB SERIAL TO ARDUINO ####
# This may be different on a different RPI
USB_PORT = "/dev/ttyACM0"  # Adjust this based on your device
BAUD_RATE = 115200  # Must match Arduino

# Open Serial Connection
try:
    ser = serial.Serial(USB_PORT, BAUD_RATE, timeout=1)
    time.sleep(2)  # Allow time for connection to stabilize
    print("Connected to Arduino over USB Serial!")
except serial.SerialException:
    print("ERROR: Could not open serial port. Check USB connection!")
    sys.exit()

#########################################################################################


def get_next_job():
    """Fetch the next job from the queue."""
    endpoint = f"{BASE_URL}/jobs/next"
    params = {"machine": JOB_NAME}
    try:
        response = requests.get(endpoint, params=params)
        response.raise_for_status()
        return response.json()
    except requests.exceptions.RequestException as err:
        print(f"Error fetching next job: {err}")
        return None

def send_job_completion(job_id, output_parameters):
    """Send job completion data to the server."""
    endpoint = f"{BASE_URL}/job_completion"
    data = {
        "job_id": job_id,
        "status": "completed",
        "output_parameters": output_parameters
    }
    try:
        response = requests.post(endpoint, json=data)
        response.raise_for_status()
        print("Job completion posted successfully.")
    except requests.exceptions.RequestException as err:
        print(f"Error posting job completion: {err}")

class JobGUI:
    """Class to manage the GUI for the job queue system."""
    def __init__(self, root, job_function):
        """Initialize the JobGUI class."""

        # Google code guidelines recommend fewer class variables
        # (I have 21+, they recommend 7 or fewer)
        # However, I believe this is the most
        # efficient way to manage the GUI

        self.root = root
        self.job_function = job_function  # Store the function pointer
        self.root.title("Job Monitor")

        self.auto_run = tk.BooleanVar(value=True)

        self.auto_run_switch = ttk.Checkbutton(root, text="Auto-run Jobs",
                                               variable=self.auto_run,
                                               command=self.toggle_approve_deny_buttons)
        self.auto_run_switch.pack()

        self.job_id_label = ttk.Label(root, text="Current Job ID: ", font=("Arial", 14))
        self.job_id_label.pack()
        self.job_id_label.pack_forget()

        self.system_status_label = ttk.Label(root,
                                             text="System Status: Waiting for job...",
                                             font=("Arial", 14))
        self.system_status_label.pack()

        self.input_param_label = ttk.Label(root, text="Input parameters: ",
                                           font=("Arial", 14))
        self.input_param_label.pack()
        self.input_param_label.pack_forget()

        self.job_status = ttk.Label(root, text="Job Status: LED OFF",
                                    font=("Arial", 14))
        self.job_status.pack()
        self.job_status.pack_forget()

        self.approve_button = ttk.Button(root, text="Approve Job",
                                         command=self.run_job)
        self.approve_button.pack()
        self.approve_button.pack_forget()

        self.deny_button = ttk.Button(root, text="Deny Job",
                                      command=self.deny_job)
        self.deny_button.pack()
        self.deny_button.pack_forget()

        self.input_label = ttk.Label(root, text="Enter response:",
                                     font=("Arial", 14))
        self.input_entry = ttk.Entry(root, font=("Arial", 14))
        self.input_entry.bind("<Return>",
                              lambda event: self.submit_textbox_response())
        self.submit_button = ttk.Button(root, text="Submit",
                                        command=self.submit_textbox_response)

        self.input_label.pack_forget()
        self.input_entry.pack_forget()
        self.submit_button.pack_forget()


        # create GUI elements for manually entering job parameters based on JOB_PARAM_TEMPLATE
        self.job_param_entries = {}
        for param_name, param_value in JOB_PARAM_TEMPLATE.items():
            label = ttk.Label(root, text=f"{param_name}:")
            label.pack()
            label.pack_forget()
            entry = ttk.Entry(root)
            entry.insert(0, str(param_value))
            entry.pack()
            entry.pack_forget()
            self.job_param_entries[param_name] = {"label" : label, "entry" : entry}


        self.create_new_job_button = ttk.Button(root, text="Create New Job",
                                        command=self.create_new_job)

        self.create_new_job_button.pack()

        self.create_new_job_submit = ttk.Button(root, text="Submit New Job",
                                        command=self.submit_new_job)

        self.create_new_job_submit.pack()
        self.create_new_job_submit.pack_forget()


        self.job = None
        self.job_running_on_machine = False
        self.running = True
        self.output_text = None
        self.output_text_avail_semaphore = threading.Semaphore(0)
        self.check_for_jobs()

    def check_for_jobs(self):
        """Check for new jobs in the queue."""
        if self.running:
            job = get_next_job()
            if job:
                self.job = job
                self.job_id_label.config(
                    text=f"Current Job ID: {self.job.get('job_id', 'unknown')}")
                self.job_id_label.pack()
                self.input_param_label.config(
                    text=f"Input Params: {self.job.get('input_parameters', {})}")
                self.input_param_label.pack()
                if self.auto_run.get():
                    self.run_job()
                else:
                    self.system_status_label.config(
                        text="System Status: Job available. Approve or Deny?")
                    self.approve_button.pack()
                    self.deny_button.pack()
            else:
                self.root.after(5000, self.check_for_jobs)

    def toggle_approve_deny_buttons(self):
        """Toggle the visibility of approve and deny buttons."""
        if self.auto_run.get():
            self.approve_button.pack_forget()
            self.deny_button.pack_forget()

            # we also want the job to run automatically if we just
            # turned on auto-run and the job was already loaded into memory.
            self.run_job()
        elif self.job and not self.job_running_on_machine:
            self.approve_button.pack()
            self.deny_button.pack()

    def run_job(self):
        """Run the current job."""
        if not self.job:
            return

        self.approve_button.pack_forget()
        self.deny_button.pack_forget()

        job_input_parameters = self.job.get("input_parameters", {})
        self.system_status_label.config(text="System Status: Running job...")
        self.job_running_on_machine = True

        # Use the function pointer to run the job
        threading.Thread(target=self.job_function,
                         args=(self, job_input_parameters,), daemon=True).start()

    def deny_job(self):
        """Deny the current job."""
        if self.job:
            send_job_completion(self.job["job_id"], {"info": "job_skipped"})
            self.system_status_label.config(
                text="System Status: Job Denied. Waiting for next job...")
            self.approve_button.pack_forget()
            self.deny_button.pack_forget()
            self.job_id_label.pack_forget()
            self.input_param_label.pack_forget()
            self.root.after(5000, self.check_for_jobs)

    def submit_textbox_response(self):
        """Submit the response from the textbox."""
        user_input = self.input_entry.get()
        self.input_entry.delete(0, tk.END)
        self.input_label.pack_forget()
        self.input_entry.pack_forget()
        self.submit_button.pack_forget()
        self.system_status_label.config(text="System Status: Text submitted...")
        self.output_text = user_input
        self.output_text_avail_semaphore.release()

    def create_new_job(self):
        """Handles the button click to bring up the option to create a new job."""
        self.system_status_label.config(text="System Status: Enter new job parameters...")

        # Show the job parameter entries
        for entry in self.job_param_entries.values():
            entry["label"].pack()
            entry["entry"].pack()

        self.create_new_job_button.pack_forget()
        self.create_new_job_submit.pack()

    def submit_new_job(self):
        """Submit the new job after the user has entered the parameters."""
        self.system_status_label.config(text="System Status: Submitting new job...")

        # Hide the job parameter entries
        for entry in self.job_param_entries.values():
            entry["label"].pack_forget()
            entry["entry"].pack_forget()

        self.create_new_job_button.pack()
        self.create_new_job_submit.pack_forget()

        # Get the job parameters from the entries
        job_input_parameters = {}
        for param_name, entry in self.job_param_entries.items():
            job_input_parameters[param_name] = entry["entry"].get()

        # Submit the job to the server
        endpoint = f"{BASE_URL}/jobs"
        data = {
            "machine": JOB_NAME,
            "input_parameters": job_input_parameters
        }

        print("Submitting job:", data)

        try:
            response = requests.post(endpoint, json=data)
            response.raise_for_status()
            print("Job posted successfully.")
            self.system_status_label.config(text="System Status: Job submitted.")
        except requests.exceptions.RequestException as err:
            print(f"Error posting job: {err}")
            self.system_status_label.config(
                text="System Status: Error submitting. Now running job locally.")

            self.job = {"input_parameters": job_input_parameters, "machine": JOB_NAME,
                        "status": "In Progress", "timestamp": 0, "output_parameters": {},
                        "priority": "1", "job_id": str(uuid.uuid4()) + "-local"}
            self.job_id_label.config(
                text=f"Current Job ID: {self.job.get('job_id', 'unknown')}")
            self.job_id_label.pack()
            self.input_param_label.config(
                text=f"Input Params: {self.job.get('input_parameters', {})}")
            self.input_param_label.pack()
            if self.auto_run.get():
                self.run_job()
            else:
                self.system_status_label.config(
                    text="System Status: Job available. Approve or Deny?")
                self.approve_button.pack()
                self.deny_button.pack()



    def submit_completed_response_to_server(self, output_parameters):
        """Submit the completed job response to the server."""
        if self.job:
            send_job_completion(self.job["job_id"], output_parameters)
            self.job = None
            self.job_id_label.pack_forget()
            self.job_id_label.config(text="Current Job ID: ")
            self.system_status_label.config(text="System Status: Waiting for job...")
            self.input_param_label.pack_forget()
            self.input_param_label.config(text="Input Parameters: ")
            self.job_status.pack_forget()
            self.job_status.config(text="Job Status:")
            self.job_running_on_machine = False
            self.toggle_approve_deny_buttons()
            self.root.after(5000, self.check_for_jobs)

    def stop(self):
        """Stop the GUI and release resources."""
        self.running = False
        line.release()

    def set_job_status_label(self, text):
        """Set the job status label text."""
        self.job_status.config(text=text)
        self.job_status.pack()

    def get_user_output_response(self):
        """Get the user output response."""
        self.input_label.pack()
        self.input_entry.pack()
        self.submit_button.pack()

        # we need to wait until the user has submitted a response...

        # this introduces a pylint warning, but it is necessary to
        # format the program in this way for better readability
        self.output_text_avail_semaphore.acquire()


    ########################## EDIT HERE: PERIPHERAL CONFIGURATION ##########################
    ##### INSTRUCTIONS #######

    ### Write a function in this locaiton that will run the job. ###
    ### This function will be called when the job is approved. ###
    ### The function will be passed the job input parameters. ###

    ### to get started, copy the run_led function and edit it to run your job. ###
    ### only edit the code in between FIRMWARE START and FIRMWARE END ###
    ### This is where you will write the code to run your job. ###

    ### If you want the user to type in a response, leave the following two lines. ###
    ### If you don't want the user to type in a response, remove the two lines. ###

    #### This is the function that will be edited to integrate new tools #####
    def run_led(self, job_input_parameters):
        """Run the LED job."""

        ### FIRMWARE START: This is where you write the firmware code to run the job. ##
        line.set_value(1)  # Turn on GPIO
        self.set_job_status_label("Job Status: GPIO: ON")

        duration = job_input_parameters.get("time", 5)
        for i in range(duration, 0, -1):
            self.set_job_status_label(f"Job Status: GPIO: ON, Time remaining: {i} seconds")
            time.sleep(1)

        line.set_value(0)  # Turn off GPIO

        ### FIRMWARE END ###

        ## Gather the user response [Optional, you can remove]##
        self.set_job_status_label("Job Status: GPIO: OFF. Please type in response.")
        self.get_user_output_response()

        ## Submit the data back to the server ##
        final_output_parameters = {"response": self.output_text}
        self.submit_completed_response_to_server(final_output_parameters)

    def run_spincoater(self, job_input_parameters):
        """Run the spincoater job."""

        print("Job input parameters:", job_input_parameters)

        ### This is where you write the firmware code to run the job. ##
        rpm = job_input_parameters.get("rpm", 1000)
        duration = job_input_parameters.get("time", 5)

        # Send RPM command
        rpm_command = f"RPM:{rpm}\n"
        print(f"Sending: {rpm_command.strip()}")
        ser.write(rpm_command.encode())
        time.sleep(0.5)  # Small delay to ensure command is processed

        # Send Time command
        time_command = f"TIME:{duration}\n"
        print(f"Sending: {time_command.strip()}")
        ser.write(time_command.encode())
        time.sleep(0.5)  # Small delay to ensure command is processed

        # Turn on the compressor and give it time to stabilize
        line.set_value(1)  # Turn on GPIO
        print("Compressor turned on.")
        time.sleep(10)  # Allow time for the compressor to stabilize

        # Send Start command
        start_command = "START\n"
        print(f"Sending: {start_command.strip()}")
        ser.write(start_command.encode())

        run_result = "JOB FAILED"

        # Read response from Arduino
        while True:
            response = ser.readline().decode('utf-8').strip()
            if response:
                print(f"Arduino: {response}")
                if "**SPIN JOB COMPLETED SUCCESSFULLY**" in response:
                    run_result = "JOB COMPLETED"
                    break
            # else:
            #     break  # Stop reading when no more data

        # Turn off the compressor
        time.sleep(5)  # Wait a couple seconds before turning off the compressor
        line.set_value(0)  # Turn off GPIO
        print("Compressor turned off.")

        ### End of firmware code. ###

        ## Submit the data back to the server ##
        final_output_parameters = {"response": run_result}

        self.submit_completed_response_to_server(final_output_parameters)


    ##########################################################################################


########################## EDIT HERE: JOB OBJECT FORMAT ######################################
#### INSTRUCTIONS: ####
### In this section, to integrate a new tool, you must create three new variables ###
### These will be used to know which function to call when the job is run. ###
### The variables are: ###
### 1. JOB_PARAM_TEMPLATE: This is the template for the job parameters. ###
###    It should be a dictionary with the same keys as the job parameters. ###
###    The values should be the default values for the job parameters. ###
### 2. JOB_NAME: This is the name of the job. ###
###    It should be the same as the name of the job in the server. ###
###    It will be used to identify which jobs to fetch from the server###
### 3. JOB_FUNCTION: This is the function that will be called to run the job. ###
###    It should be the function that you wrote to run the job. ###

#### It is imperative that the job object format matches the server's object format ####

#### SPINCOATER JOB ####
SPINCOATER_JOB_PARAM_TEMPLATE = { "time": 12, "rpm": 1100 }
SPINCOATER_JOB_NAME = "spincoater"
SPINCOATER_FUNCTION = JobGUI.run_spincoater


#### LED JOB ####
LED_JOB_PARAM_TEMPLATE = { "time": 5 }
LED_JOB_NAME = "led"
LED_FUNCTION = JobGUI.run_led


### Edit the following variables to match the job type you are integrating ###
JOB_PARAM_TEMPLATE = SPINCOATER_JOB_PARAM_TEMPLATE
JOB_NAME = SPINCOATER_JOB_NAME
JOB_FUNCTION = SPINCOATER_FUNCTION

###########################################################################################


if __name__ == "__main__":
    root = tk.Tk()
    gui = JobGUI(root, JOB_FUNCTION)  # Pass JOB_FUNCTION to the GUI
    try:
        root.mainloop()
    except KeyboardInterrupt:
        gui.stop()
        ser.close()
        line.release()
        print("Exiting program")

scores 9.44/10 on pylint (used by google code guidelines). The failures are purposeful design decisions and are described in the comments.

#include <LiquidCrystal.h>
#include <Servo.h>


#define PIN_RS 10
#define PIN_RW 11
#define PIN_E 12
#define PIN_D4 2
#define PIN_D5 3
#define PIN_D6 4
#define PIN_D7 5

#define PIN_RPM_UP    15
#define PIN_RPM_DOWN  14
#define PIN_TIME_UP   21
#define PIN_TIME_DOWN 20

#define PIN_START 17

#define PIN_MOTOR 9


void setup() {
  Serial.begin(115200);
  pinMode(PIN_RPM_UP, INPUT_PULLUP);
  pinMode(PIN_RPM_DOWN, INPUT_PULLUP);
  pinMode(PIN_TIME_UP, INPUT_PULLUP);
  pinMode(PIN_TIME_DOWN, INPUT_PULLUP);
  pinMode(PIN_START, INPUT_PULLUP);
}

void loop() {
  
  auto lcd = LiquidCrystal(PIN_RS, PIN_RW, PIN_E, PIN_D4, PIN_D5, PIN_D6, PIN_D7);

  Servo servo;

  servo.attach(PIN_MOTOR);
  servo.writeMicroseconds(1000);

  lcd.begin(16, 2);
  lcd.clear();

  bool prev_spinning = false;
  long long prev_rpm = 3000;
  long long prev_duration = 30;
  long long prev_progress = 0;

  long long rpm = 3000;
  long long duration = 30;
  long long progress = 0;
  long long period = 1000;

  lcd.setCursor(0, 0); lcd.print("RPM: "); lcd.print(rpm);
  lcd.setCursor(0, 1); lcd.print("Duration: "); lcd.print(duration);

  bool prev_button_states[5] = { false, false, false, false };
  bool button_states[5] = { false, false, false, false };

  long long start_time = 0;

  bool spinning = false;

  while (true) {
    button_states[0] = digitalRead(PIN_RPM_UP);
    button_states[1] = digitalRead(PIN_RPM_DOWN);
    button_states[2] = digitalRead(PIN_TIME_UP);
    button_states[3] = digitalRead(PIN_TIME_DOWN);
    button_states[4] = digitalRead(PIN_START);

    bool changed = false;

    bool pushed[5] = { false, false, false, false };
    for (int i = 0; i < 5; ++i) {
      pushed[i] = !button_states[i] && prev_button_states[i];
      if (pushed[i]) {
        changed = true;
        delay(100);
      }
    }

    if (spinning) {
      progress = (millis() - start_time) / 1000;
      if ((millis() - start_time) > duration * 1000) {
        spinning = false;
      }
      if (pushed[4]) {
        spinning = false;
        delay(100);
      }
    } 
    else {
      if (pushed[0]) {
        rpm += 100;
        delay(100);
      } 
      else if (pushed[1]) {
        rpm -= 100;
        delay(100);
      }

      if (pushed[2]) {
        duration += 1;
        delay(100);
      }
      else if (pushed[3]) {
        duration -= 1;
        delay(100);
      }

      if (pushed[4]) {
        start_time = millis();
        spinning = true;
        delay(100);
      }


      // Now, read the USB UART serial input and parse the command
      if (Serial.available()) {
        String command = Serial.readStringUntil('\n');  // Read full command

        // Print received command to Serial Monitor (Debugging)
        Serial.print("[DEBUG] Received: ");
        Serial.println(command);

        if (command.startsWith("RPM:")) {
          rpm = command.substring(4).toInt();  // Extract the integer

          Serial.print("[DEBUG] Parsed RPM: ");
          Serial.print(rpm);
          Serial.println(" RPM.");
        } 
        else if (command.startsWith("TIME:")) {
          duration = command.substring(5).toInt();  // Extract the integer

          Serial.print("[DEBUG] Parsed Duration: ");
          Serial.print(duration);
          Serial.println(" seconds.");
        } 
        else if (command.startsWith("START")) {
          start_time = millis();
          spinning = true;

          Serial.println("[DEBUG] Starting the spin...");
        } 
        else {
          Serial.println("[DEBUG] Invalid command received.");
        }
      }

    }

    memcpy(prev_button_states, button_states, sizeof(button_states));

    if (prev_spinning != spinning || prev_progress != progress || prev_rpm != rpm || prev_duration != duration) {
      prev_spinning = spinning;
      prev_rpm = rpm;
      prev_duration = duration;
      prev_progress = progress;

      if (spinning) {
        lcd.clear();
        lcd.setCursor(0, 0); lcd.print("Spinning...");
        lcd.setCursor(0, 1); lcd.print(progress); lcd.print(" / "); lcd.print(duration); lcd.print(" s");
        period = map(rpm, 0, 12000, 1000, 2000);
        servo.writeMicroseconds(period);
      } 
      else {
        lcd.clear();
        lcd.setCursor(0, 0); lcd.print("RPM: "); lcd.print(rpm);
        lcd.setCursor(0, 1); lcd.print("Duration: "); lcd.print(duration);
        servo.writeMicroseconds(1000);
      }
    }
  }
}

In this section I will give additional comments on how the spincoater was integrated to the lab_com system. Many of the specific implementation details were highlighted in prior sections (see run_spincoater method of in earlier section), but this section will fill in a few gaps. This will hopefully guide the design process for integrating additional tools.

The existing control PC does not need to run the entire lab_com_gui software. Carson, the current project lead, was simply able to incorperate a series of API calls to the database into his existing python code for the stepper GUI. The details of the stepper GUI are out of scope of this project (see that section of the doucmentation on gitbook). He directly copied the code from . This file is linked

See get_file_upload_url_and_key and upload_file functions in for the details on this process. After the upload is complete, the web application gets back a s3_key. This is a string that uniquely identifies the image that was just uploaded. The web application then POSTs to the jobs endpoint. The request will have the machine name field set to stepper and the input_parameters will include the image_s3_key.

The control PC for the stepper will poll the jobs queue by repeatedly calling the jobs/next endpoint. Eventually, the json object shown above will be received. The control PC for the stepper will then download the image from AWS S3 storage using the image_s3_key in the input parameters. See the download_file() method of for details on how this work. This method can be reused when automating other machines.

On the micro-level, the code has been written in a way to catch as many error states as possible. For example, in the, the method for returning data to the server after a job has completed has a try-catch block in case the API request fails. This will prevent the application from failing catastrophically and will provide a clear error message for the user. These try-catch blocks are used for many of the HTTP api calls, as this is the most likely point of failure (e.g. the RPI isn't connected to the internet).

Long Term Storage

The SOG from Filmtronics found , has a shelf life of around 3 months when stored at room temperature. For this reason, the bulk SOG bottle must be kept in the fridge at around 32-40 F in order to extend its shelf life. Exposure to air and/or heat can cause some of the SOG vapors to harden. If this happens, flakes of SiO2 may form and contaminate the liquid solution.

  • Store bulk SOG in fridge (32-40F)

  • Shelf life of bulk is 3 months at room temperature

Inspecting SOG bottle prior to use
  • Ensure the SOG has come to room temperature

  • Check the bottle’s date. If the SOG was transferred from the bulk supply more than a week prior, it is likely necessary to prepare a new bottle of SOG

  • Regardless of the date on the bottle, open the bottle to check if any crust has formed near the top of the bottle. If there is any visible crust from hardened SOG, it is necessary to prepare a new bottle of SOG

    1. The crust formed can get into the liquid SOG applied before spin coating and ruin the SOG coating

    2. Example of crusted SOG from a bottle that has been used for too long

    Residue in SOG Bottle - Not Suitable for Use
Tube Furnace

Tube Furnace () with Quartz tube

If the furnace stops and holds at a lower temperature than your setpoint, the high temperature alarm may be too low. Read the instructions on to fix this.

A chip permanently fused to the tube furnace walls when improper slide was used

(should end with .sgd, can only be opened in the Spectrogryph app)

New Acquistion View

Drag the (should end with .sgd) into the New Acquisition View

Calibration Graphs

Spectrogryph Manual Website:

A is used instead of pure HF to control the etch rate.

Spill kit and

Put on the neoprene gloves. Avoid touching the outside of the gloves.

Refer to for proper nitrogen gun usage if needed

This is by far the most dangerous process step. This document is NOT qualified to teach you all the required safety protocols and correct operating procedures - please refer to an and more disposal and safety documents. Every student at CMU must go through a 1 hour safety training specifically for the handling of HF before they are even allowed to be in the same room as somebody handling it.

Tube Furnace () with fused silica tube

Tube Furnace () with fused silica tube

If the furnace stops and holds at a lower temperature than your setpoint, the high temperature alarm may be too low. Read the instructions on to fix this.

A chip permanently fused to the tube furnace walls when improper slide was used

Before reading further, please see the section for more information.

SDS:

Spill kit and

Computer running

Parameter
Value
Parameter
Value

See for reference

Open this sheet, claim the next available chip number, open the blank chip view sheet for that specific chip number and record all subsequent process data into it.

Use a

Use to move once a cut is made

Thermal evaporation is a layer deposition technique wherein the vapor pressure of a material is increased via resistive heating while the surrounding air is evacuated below that vapor pressure. The of gas in the chamber, which is determined by the pressure, must also be larger than the source to substrate distance. Under these conditions, the material evaporates into the vacuum and then coats any exposed surfaces. This is how we create deposit layers of metal, which are later etched into wires, and contact pads.

The Hacker Fab currently uses aluminum for wiring because it’s relatively conductive, fast to evaporate, and cheap. However, it can be tricky to evaporate because it alloys readily with many refractory metals. This is described in depth . We currently use an alumina crucible which seems to work for a handful of evaporations, though other setups may be more effective and should be tested.

Open the sheet and plan your experiment.

(Recommended) Use piranha solution or to clean the chip.

Use double sided kapton tape to attach the chip(s) to the center of the substrate holder.

Program the bakeout sequence to ramp to 700°C over 2000 s, then hold for 3600 s, then ramp down over 2000 s. Refer to page 15 of the for detailed programming instructions.

Take inspection pictures and upload them in a new folder, then link that folder in the spreadsheet.

🔥
database
Github repository
models.py
Models
forms.py
Forms based on models
views.py
urls.py
database querying library
filter_form()
views.py
views.py
QuerySet
forms.models
Vacuum Spin Coater
Hot Plate
Storage and Preparation
Hot Plate
vacuum spin coater
Hot Plate
Tube Furnace SOP
Inspecting SOG wafers
Plasma Etch Process Sheet
Plasma Clean Process Sheet
central chip count
Patterning Process Sheet
Spin Coater
Hot Plate
Hexamethyldisilazane (HMDS) adhesion promoter
specsheet
central chip count
Cleave
Vacuum Spin Coater SOP
patterning data sheet
patterning data sheet
Lithography Stepper V2 Build
this video
this resolution test pattern
drive
https://www.ossila.com/en-us/pages/spin-coating
AZ-P4210 techsheet
AZ 400K developer
spreadsheet
this
aws_labmda.py
auto_test_endpoints.py
auto_test_endpoints.py
auto_test_file_endpoints.py
auto_test_file_endpoints.py
https://roboticsbackend.com/raspberry-pi-arduino-serial-communication/
lab_com_gui.py
lab_com_gui.py
lab_com_gui.py
lab_com_gui
lab_com_gui.py
lab_com_gui.py
spincoater.ino
lab_com_gui.py
auto_test_file_endpoints.py
here
auto_test_file_endpoints.py
auto_test_file_endpoints.py
lab_com_gui.py
ThermoFisher Manual
page 6-7
Calibration Graphs
Calibration graphs file
https://www.effemm2.de/spectragryph/about_help_manual.html
Troubleshooting

Time (if glass annealed at 200-400C)

~10 Seconds with 6:1 BOE

Time (if glass annealed at 1100C)

5-10 Minutes with 6:1 BOE

Temperature

Room Temp.

Temperature

1100°C

Total Time

30 min (subject to change)

Etch Rate

~ .1 um/min

Etch Temp

40C

Stir RPM

350

Vds range

0-10V

Vds step size

.1V

Vgs range

0-5V

Vgs step size

1V

Vb range

0

Vb step size

n/a

V range

+-5V

V step size

<=1V

Vgs range

0-5V

Bakeout Time

Pressure Before Beggining Evaporation (hPa)

Temp Time Sequence [c1, t1, c2, t2, c3, t3, ...]

NAND + Inverter Characterization

Fabrication and Testing of Enhancement Load NMOS Inverter Based on HackFab’s Standard Process Flow

  1. Introduction

NOT gate or inverter outputs the opposite of its input as shown in Table 1 is a basic but crucial part of the digital logic circuit. An NMOS logic inverter normally consists of two parts, a resistive load connected between the supply voltage (VDD) and the output as the “pull up” part and a switching transistor as the “pull down” part. To save device area and fabrication cost, instead of using resistors for the load, an active load such as an enhancement load transistor is used in the design as shown in Figure 1 (left). Enhancement load means a transistor’s gate and the drain are both connected to the supply voltage and make the transistor always in the saturation region. However, this causes there will be a constant current going through the transistors even if it is not performing which makes NMOS logic technology have higher power consumption and eventually be replaced by CMOS technology.

Input

Output

0

1

1

0

Table 1. Inverter Truthtable

https://github.com/offbyfour/OPU_Driver/tree/main/Hardware/Kicad_PCB
https://github.com/gnea/grbl/wiki/Compiling-Grbl
https://github.com/hacker-fab/stepper
zero.offbyfour
zero.offbyfour
https://github.com/hacker-fab/piezo-nanopositioner
🔥
buffered oxide etch
all other required safety equipment, disposal equipment, and building utilities
Photoresist Strip SOP
SOP
ThermoFisher Manual
ThermoFisher Manual
page 6-7
https://www.sigmaaldrich.com/US/en/sds/aldrich/901539?userType=anonymous
all other required safety equipment, disposal equipment, and building utilities
AmScope viewer software
this video
central chip count
diamond tipped scribe
tweezers
mean free path
here
Evaporation Data
O2 plasma
evaporator manual
Evaporation Photos
Evaporation Data
Safety

Exaggerated View of Large Particulate and Improper Dehydration Bake

Radial Variation

Example 1

Example 2

Example 3

Probe Station SOP - V2

Version 2 of the probe station using analog discovery 3s

Purpose

After fabrication, the chip must be tested to demonstrate the functionality of the design. Additionally, variations and errors in fabrication may result in differences in device characteristics which are useful to document when these variations cause the device to fail.

To enable precisely controlled experiments on microscopic chips, we currently use a probe station to contact the device using sharp probes which supply and measure voltages for calculation of various device characteristics such as I-V curves, which are explained in this SOP.

Tools

  • Probe station setup

    • Probe station - Karl Suss PM5

    • At least 4 probes, manipulators, and coaxial to split jumper wires with hooks at the end

  • Microscope setup

    • Camera - AmScope MU1000-HS and AmScope viewing software

    • Light – MI-150 Fiber Optic Illuminator

  • Semiconductor analyzer system

    • 2 Analog Discovery 3s

    • Laptop with ability to connect to camera and analog discovery 3s as well as run a python program

Materials

  • Devices under test – typically a finished chip with pads for probing

Procedure

Setup

  1. Place the chip in the center of the stage and turn on the vacuum.

  2. Turn on the microscope light, which appears as a spot of light on the stage.

  3. Connect the microscope camera to your computer and select the camera MU-1000HS on the AmScope viewer software, which should summon the camera view.

  4. Open the analyzing software on a laptop

  5. Raise the stage using the lever. Focus the stage and center the pattern of interest under the light source using the knobs below the stage.

  6. If the probe tips are not illuminated by the microscope light, carefully move the magnetically-attached manipulators such that the range of motion of the probe tips is within the spot of light.

  7. Using the knobs on each probe’s manipulator, lower the probes so that the tips are focused yet not touching the chip, then position the probe tips above their corresponding probing pads.

  8. Carefully lower the probe tips to touch the pads, which is generally indicated by resistance to movement when attempting to lower the tip further. The manual nature of this process means that the sharp probes can scratch the chip and damage the device beyond future usage, such as scratching the pads off.

  9. Using coaxial cables connected to the jumper wires with hooks, connect each probe to the ground, source, and drain on the Keithley and connect the corresponding red hooks to the equivalent ground, source, and drain pins on the circuit board as well as all the black hooks to the drain pin on the circuit board like in the below picture

Run Program

  1. Run the command python3 smu.py in terminal to run the program

  2. This will open up a new window with a plot of the IV Curve that looks something the below picture under MOSFET I-V Curve

  3. In order to close this window and continue with the program, either hit the red exit button on the image window or go to terminal and type Ctrl-C

  4. If the graph had errors, repeat the experiment as necessary

  5. If the data looks good, enter the title for the current and image csv files

Cleanup

  1. Remove the probes from the chip and continue to the next device, either by lifting the probes or lowering the stage.

  2. Raise the probes using the manipulator knobs.

  3. Lower the stage by turning the lever.

  4. Disconnect the microscope from your computer and turn off the microscope light.

  5. Turn off the vacuum and remove the chip.

MOSFET I-V Curve

The outputs currently look something like this:

The I-V relationship between the two probes and resistance estimated from Ohm’s law should be plotted. An ideal resistor should have a linear relationship and constant resistance.

CMU Updates

As part of CMU's Hacker Fab Course 18469/18669, students will give updates on their project work every Sunday night.

Profilometer SOP

SOP for using the profilometer

Purpose

The purpose of the profilometer is to measure the roughness of a surface. Specifically, it is able to measure height differences across a region of interest (in one dimension) in the nano scale. This is useful especially after etching processes, where we can measure how much etching was performed on the chip.

The precision of this instrument is ~20-30 nm.

Materials

  • Profilometer

  • Your chip

    • If you are learning how to use the profilometer and do not have any patterns yet, you can use Chip 365 (there is a pattern on it, and it is also used in this tutorial)

The profilometer (right) is connected to a very old computer (left). The profilometer contains a metal needle tip that is used to measure the roughness of a surface.

Procedure

  1. Place chip on stage

    • Ensure that you don't place the chip in the ridges, and this can lead to a runtime warning

  2. Switch on the light on the stage, ensure that chip is under the light

  1. On computer, go to Display > Video to visibly see the chip. Also, select Sample Positioning in order to see where the stylus will start measuring.

  1. Move chip until you are able to see the cross hair being in line with the edge of your patterns.

    • Chip can be moved using the knobs as seen in Figure 2.

    • Ensure that you don't touch/bump into the metal tip as it is very sensitive and delicate

  2. Go to Stylus > Stylus Down. This will move the stylus down to the chip and it should be aligned with the cross hair.

    • If the stylus is not aligned with the cross hair, double click on the new location where you want the cross hair to be. You will be prompted to update the cross hair location.

  1. Go to Run > Run Single Scan to start an experiment. The stylus will start moving.

    • If it runs into the AD conversion error, keep retrying (the error tends to go away after 5-6 times, see bottom of this document for photo)

Results and Data Analysis

  1. After the run is completed, this should be seen:

As seen in the Figure above, we can see two "bumps", which are where we want to collect our data. However, we can also see that the graph is slanted, which means we first need to level our data.

  1. Levelling plot: Move the red and green vertical lines such that in between those lines, we have a relatively flat region (as seen in Figure 6). Go to Plot> Level. We should now see this:

  1. In order to measure the step height, drag the red and green vertical lines such that in between these lines we have the region of height difference (shown in Figure 7). The height difference is captured as Vert_D. In this case, we an see that it is 2425 Angstroms, which translates to around 243 nm.

Other Features

As seen in Figure 7 above, some regions are "bumpy". In order to get the average of these "bumps", one can go the Bands > Create Band and set a specific distance. For instance, in Figure 8 below, we have taken the average of 50 nm to the left and 50 nm to the right of the region of interest.

Errors that might occur

1) Timeout Waiting for AD Conversion

This error happens very often. In order to fix this, perform multiple runs (usually around 5-6 times) until the timeout notice is no longer shown.

CMOS Doping Process Development

Dope the channel, and source/drain regions for CMOS chips, via solid source surface diffusion, starting with 5-10 ohm p-type substrate.

Metrics

CMOS Region
Doping level
Doping Profile Details

NMOS Source/Drain

1E19 - 1E20 /cm^3 (Boron)

Uniform over 2 nm Junction depth shallower than channel

NMOS Channel

1E14 - 1E15 /cm^3 (Boron)

Will be uniform by default (p type wafers)

PMOS Source/Drain

1E20 - 1E21 /cm^3 (Boron) with 1E15 - 1E16 /cm^3 (Phosphorous) background

Uniform over 2 nm Junction depth shallower than channel

PMOS Channel

1E15 - 1E16 /cm^3 (Phosphorous) with 1E14 - 1E15 /cm^3 (Boron) background

Uniform over 10 nm Junction depth deeper than source/drain

Sputtering Gate Oxides + Metal Gate Contacts

Motivation:

A metal oxide semiconductor field effect transistor (MOSFET) is essentially made up of two opposing PN junctions and a metal oxide semiconductor capacitor (MOSCap). The current Hacker Fab NMOS process begins with a wafer which already has 20 nm of SiO2 on the surface of the Si, and 500 nm of polysilicon deposited on top of the SiO2. In the final MOSFet device, the SiO2 acts as the oxide and the polySi acts as the “metal” in the MOSCap present within the NMOSFET. This process flow prevents the simultaneous fabrication of PMOSFETs, which is necessary to make CMOS devices. To make CMOS devices, we need to begin with a bare Si wafer, and make the MOSFets “oxide”/dielectric layer ourselves Due to this, and other concerns with the NMOS process flow, Hacker Fab needs to develop the capability to grow or deposit dielectric thin films to act as the oxide. However, the oxide is the thinnest film in the device, and the film most sensitive to impurities. For this reason, the process to deposit gate oxides is the most likely to have quality issues.

Based on this need, and surveying our options for making our own gate oxide, we began building an RF sputtering chamber in the F24 semester (@ CMU). RF sputtering has the capability to deposit thin films of dielectric and conducting materials.

Goals

  • Deposit 40-50nm thick Al2O3 layers to use a gate dielectric in CMOS process

  • Deposit 100 nm thick Al2O3 layers to make electrical contact to the gate dielectric, and protect the sensitive gate dielectric. This is to be done in the same process step as the Al2O3 deposition.

Metrics

Al2O3 Property

Dielectric constant

>8

Resistivity

10^-12 ohm-cm

Surface Roughness

5 nm

The metrics defined above are dependent on other metrics, such as stoichiometry, which is effected by processing parameters like sputtering power and O2 flow rate etc.

Al Metrics

Resistivity

3E-6 ohm-cm

Surface Roughness

15 nm

CMOS Source/Drain Metal Contact Optimization

Goals

Develop metal contact formation process (pre, during, and post deposition development) to reduce the contact resistance and Schottky behavior of of metal contacts on Source/Drain regions of PMOS and NMOS devices. Metal type in metal - Si contact is part of optimization.

Metrics

Metric
Measured Value

Specific contact resistance

1E-5 ohm/cm^2

Schottky barrier height

.7 eV

here
image
image
image
image

Computer running and Python program

Details on the assignment can be found here:

Working Folder in Google Drive:

Working Folder in Google Drive:

Working folder in google drive:

AmScope viewer software
https://docs.google.com/document/d/1VIL6_VEkJ3WJWSxd1Ij3GuT30xgoiurXHgvJoFRKE7c/edit?tab=t.0
https://drive.google.com/drive/folders/1bnJyeBcbssFuE7fQBo4J-6Roz3mHzRwJ
https://drive.google.com/drive/folders/1_SNzkVnHybTjfvlqHM6ZcEksfZroROLm
https://drive.google.com/drive/folders/1qafBxH8luKwNSnPRmJxCRI_14apNio72
154B
v2.1-thorlabs.csv
1MB
CH569DS1-2.PDF
pdf
1MB
EPC21603_datasheet.pdf
pdf
2MB
hd3ss3220.pdf
pdf
2MB
lmk3h0102.pdf
pdf
3MB
max1304-max1314.pdf
pdf
611KB
max40025a-max40026.pdf
pdf
2MB
tpic2010.pdf
pdf
25KB
ECP5UMcsfBGA285Migration.csv
3MB
FPGA-DS-02012-3-3-ECP5-ECP5G-Family-Data-Sheet.pdf
pdf
6MB
FPGA-TN-02024-5-6-PCB-Layout-Rec-for-BGA Packages.pdf
pdf
560KB
FPGA-TN-02028-2-6-Sub-LVDS-Signaling-Using-Lattice-Devices.pdf
pdf
1MB
FPGA-TN-02032-1-4-ECP5-ECP5G-sysIO-Usage-Guide.pdf
pdf
3MB
FPGA-TN-02035-1-3-ECP5-ECP5-5G-HighSpeed-IO-Interface.pdf
pdf
584KB
FPGA-TN-02038-2-0-ECP5-and-ECP5-5G-Hardware-Checklist.pdf
pdf
2MB
FPGA-TN-02050-1-0-Programming-Ext-SPI-Flash-JTAG-ECP5-5G.pdf
pdf
1MB
FPGA-TN-02200-1-3-ECP5-and-ECP5-5G-sysCLOCK-PLL-DLL-Design-and-User-Guide.pdf
pdf
2MB
lm3880.pdf
pdf
2MB
NCP115-D.PDF
pdf
1MB
tlv62569.pdf
pdf
803KB
tpd1s414.pdf
pdf
2MB
OPU_Driver_rev0p1.pdf
pdf
149B
StepperV2_Thorlabs_BOM.csv
Cover

Automated Spin Coater

In Progress
Cover

Gantry

Dimensions: 2 ft x 1.5 ft x 2 ft.

V0
Cover

Gripper

Reliability:

V0
Cover

Liquid Handling

In Progress
Cover

Tube Furnace

Max Temperature: 300 deg Celsius

Time to Max:

On Hold
Cover

Wafer Cleaver

On Hold
*NEED TO UPDATE* Microscope Image of Single NMOS Exposure - November 2023
IV Curves of Good NMOS Transistor November 2023. Red is Gate Leakage
NAND Gate
Enhancement Mode NMOS Inverter
Microscope Image of Single NMOS Exposure - November 2023
IV Curves of Good NMOS Transistor November 2023. Red is Gate Leakage
Accurate Graph of Cost to Build Hacker Fab vs. Semester (More DIY Designs)
Stepper V2.1
it works!
LED current settings in the software
Camera and beamsplitter cube should be parallel.
(Photo has 1 tube piece that shouldn't be there)
You should have the optics attached to the top of this by this point
Wiring diagram for the sensors
GIF of playing in real time
Base Plate
Adapter Plate
it works!
LED current settings in the software
All the tubes!
Camera and beamsplitter cube should be parallel.
Aluminum Frame
Plate with O-Ring
Plate with 8 bolts
Screw in bolts to attach plate to frame
KF-16 viton ring and blank flange
Attaching a blank flange to a KF-16 port
Hinge to allow top face to open
Plate with hinge and knobs
Attaching rubber feet to chamber
Fully assembled vacuum chamber
Crucible heated to evaporate aluminum and deposit over chip.
Figure 30: Soldered motherboard
Piezo mounted externally (to chassis) or on the stage itself
Screenshot of Googling "piezo stick slip" showing pure sawtooths everywhere
A is moving in the same direction as the piezo
A is moving in the opposite direction as the piezo (reversed direction)
Before Spin on Glass (SOG)
After Spin on Glass (SOG)
Acetone rinse
Drying with nitrogen gun
100C hotplate with chip in the center
Pipette with SOG and air pocket
Pipette with filter
Example of Photoresist on Surface of Chip
Photoresist Removed post-strip
Before Reactive Ion Etch (RIE)
After Reactive Ion Etch (RIE)
Generic Patterning Sequence
A well aligned exposure. Note that the previous layer is slightly smaller than the proected pattern.
Well-focused UV, ready to expose.
Developer (Deionized water to AZ-400K 3:1) and DI water rinse.
Measuring Microns with a 10x Objective
Inspection image showing blurring effect from defocused stepper
Insprction image showing incsufficient develop or exposure
Example Flir Blackfly S Camera Settings
Doped Silicon (grey) and Doped Gate Poly (dark blue) Resulting from Thermal Diffusion
Differentiating Quartz from Borosilicate
Before Evaporation
Post Evaporation (Aluminum in Blue)
Laptop with STM2 software and STM2 monitor plugged in
Double sided polyimide tape, tunsten filament, and high purity Al wire (99.999%)
DIY Evaporator (CMU Version)
Inside of thermal evaporator. A (red circle) indicates the Tungsten coil, B (blue circles) screw the coil in place, and C (yellow circle) is the metal sheet blocking the vacuum.
Figure 4: Thermal evaporator with lid open. A (red circle) indicates where the tape and chip should be placed.
Program on computer next to thermal evaporator. Note green start button to begin, rate (A/s) in the table, and thickness (Angstroms) in the table on the computer program. A (yellow circle) indicates the power supply on bottom and B (red circle) indicates the knob for adjusting current.
Spin on Glass (SOG) on Surface masked by photoresist (in red)
Post-Etch SOG Removed
Doped Spin on Glass (SOG) on Surface masked by photoresist (in red)
Post-Etch Doped SOG Removed
Silicon before and after oxidation
Before Etch (Aluminum Metal in Blue)
After Etch
Before Evaporation
Post Evaporation (Aluminum in Blue)
Program from Vscode view + terminal
New window with plot of IV curves for ideal mosfet
IV Curves for Chip 234 with Gate Voltages of 1, 2, 3, 4, and 5 Volts
Figure 1: Profilometer Set Up
Figure 2: Profilometer Setup Movement
Figure 3: Display > Video and Display > Sample Positioning
Figure 4: Display > Sample Positioning shows where the cross hair will appear
Figure 5: What you should see after Stylus Down command
Figure 6: Results from Profilometer Run
Figure 7: Levelled Results from Profilometer
Figure 8: Using Bands when analyzing data
Figure 9: AD Conversion Error
Cover

Hot Plate

Cover

Lithography Stepper V2

Carnegie Mellon

Cover

Vacuum Spin Coater V1

Carnegie Mellon

Cover

Thermal Evaporator V1 (work in progress)

Carnegie Mellon

Cover

Tube Furnace V1 (work in progress)

Projects in Flight

Cover

Plasma Etcher

Plasma Etch PE-25

Cover

DIY SMU

Buy for $800

Cover

Probe Station V1

Source:
Source:

for $125

for $3,015

for $200

for $15,000

for $200

for $17,400

for $15,800

Xeryon
Thorlabs
Buy
Buy
Buy
SOP
Build
SOP
Build
SOP
Build
SOP
Build
SOP
SOP
SOP
Logo
https://github.com/hacker-fab/ald