Equipment Build: Substrate Size Measurement Camera

It has been a while since I’ve put out a site update. I am trying to finish my PhD in a timely manner after all. In the past interval, I’ve spent a fair bit of time building assorted equipment to help with my research, including growth chambers and test/measurement assemblies. I will post articles on the chambers shortly, but just to put something up in the meantime I’ll start with something light that may actually be useful as well (or provide a base for something useful).

1 Overview

Here I present a camera device that uses python/OpenCV to measure the size of pieces of substrate. This has been immensely helpful in the lab as we often scribe larger wafers of Si, MgO, etc, into smaller chunks for test growths in an effort to save money (and the environment? (probably)). If you are careful/lucky, you can break things along cleavage planes and have almost exactly square pieces, but this is not always the outcome. There are certain characterization measurements, e.g. vibrating sample magnetometry (VSM, more on that below), that require knowledge of the film thickness or area. In the example of VSM, the sample total moment is measured, and so the thickness can be calibrated if you know the saturation magnetization and area. This is especially useful when you are growing very thin magnetic films, e.g. < 5 nm, and other methods such as XRR become infeasible. If you are using polished, pre-cut substrates, then this is easy enough, but the area of a randomly cracked shard of substrate is more difficult to determine accurately (before now).

What I’ve created here is a simple and cheap webcam platform to take a snapshot of a substrate on a light or dark background and then integrate the pixels to tell you the area of your piece. After centering your piece in the field of view, you take a snapshot. This snapshot is converted to grayscale and you are presented with two sliders for high and low cutoffs. Moving the sliders back and forth should isolate the area of the substrate piece, and the enclosed pixels are counted. Calibration is done by performing the measurement on a known size of substrate (e.g. 10 mm x 10 mm) and then changing the calibration constant in units of cm^2/pixel.

2 Materials

In regards to hardware, you will need:

Most webcams that are advertised as “driverless” (or are linux compatible) should work with the OpenCV API. In this case, I bought a $20 Logitech C170, and removed its housing so I could screw it directly into the stand for rigidity. For the stand, I simply cut 1/16” Al stock by hand and folded it into a trapezoidal stand shape. I removed the camera PCB from its packaging and screwed it directly into this stand, as shown here:

Camera Assembly
FIGURE 1 Just a simple thing made from scaps in the machine shop and a $20 webcam.

In general, you could probably just make a more simple stand from wood (maybe even actual popsicle sticks, if you think you’re cool enough) and then epoxy the entire camera to it, but I am “particular” so I did what I did. As long as it is relatively stable and the surface is in focus, it should operate just fine with my code.

3 Installation and Operation

Everything here is done with base Python 3.0, with the associated numpy and opencv-python packages. I’ve provided my python script for download here:

Python Script

Other than installing the dependencies and downloading the script, there are a few user configurable parameters:

FRAME_WIDTH = 1024 #640
FRAME_HEIGHT = 768 #480
AREA_PER_PIXEL = 1.0 # cm^2 / PIXEL NEEDS TO BE CALIBRATED
BURN_FRAMES_COUNT = 1
BOUNDARY_RATIO = 0.6
CAMERA_PORT = 0

These should be changed as follows:

To get started, set the camera parameters as desired while leaving AREA_PER_PIXEL = 1.0. Then, load a cut sample of known dimensions into the field of view. Here I have loaded a 10x10 mm sample of MgO:

MgO Calibrate
FIGURE 2 A 10x10 mm sample of MgO used to calibrate the AREA_PER_PIXEL parameter.

Let’s check that we did a good job by jostling the system around a bit and re-measuring the piece:

MgO Measure
FIGURE 3 Checking our work. The basis of good science.

Not bad, a 2% error. I was going very quickly here, and the error can be reduced by setting up a more high contrast background, being more careful with the sliders, etc. The system can also be used in reverse for darker substrates. For a piece of Si, for example, you would put a piece of white paper underneath and do the inverse measurement. The difference between this area and the full area is then the Si shard area.

Si Measure
FIGURE 4 Use of the right background material makes it easier.

So in this case, the pixel count of the Si shard is  460^2 - 200135 = 11465 , giving a Si shard area of approximately  0.37 cm^2, which looks right just from visual inspection. Now that the system is calibrated it can be used for practical application.

4 Example Case

This is an example application, whereby a very thin film of Co is deposited on a tiny shard of Mgo via RF magnetron sputtering (more on that from me later, but here is a link to a decent process description if you’re curious. Because we are \rlap{\textbf{-------}}{\mbox{cheap}} concerned about the environment, we have cut a 5x5 mm MgO substrate into smaller shards for process testing. Here is the shard being used in this growth:

MgO Shard
FIGURE 5 Slice and dice.

After the Co is deposited, that sample is loaded into the VSM system:

VSM System
FIGURE 6 Basically it shakes the magnet and, in this way, it reads how good of a magnet it is (via the shaking).

This is a system with large field coils (here up to ~ 2 T) and smaller sensitive pickup coils. The piezoelectric top stage shakes the sample rod up and down at a known frequency (100 kHz typical). The tiny EMF from the magnetic sample induces a current in the pickup coils, which is then amplified and measured. In this case, the Co was grown to a thickness of several nanometers, so we would expect full in-plane anisotropy (a nice square loop in-plane). Indeed this is what was captured:

Co VSM
FIGURE 7 This has strong in-plane anisotropy. This means that the remnant magnetization at zero field will be large in-plane and small (essentially zero) out of plane.

From the loop amplitude, and assuming a bulk saturation magnetization M_S \approx 1400 emu/cm^2:

1 \displaystyle{\begin{align}t = \frac{m}{M_S \cdot A} = \frac{11.07\cdot10^{-6} (emu)}{1400 (emu/cm^3) \cdot  0.13 (cm^2)}  \approx 0.6 nm\end{align}}

We were aiming for a 1 nm film here, and this is in the expected range. This information would then be used to infer conditions about growing thinner or thicker films. If we wanted to try for something closer to exactly 1 nm, for example, we would increase the deposition time by about 60%.

The analysis here is slightly simplified. In the ultra thin film limit, which this is, strain transfer from the substrates changes the intrinsic properties significantly. From assorted literature, M_S is probably in the range [1000,1300] (emu/cm^3) for a film of this thickness, which would give a more likely range of [0.65, 0.85] (nm) for the thickness. Astute readers might ask whether the film is continuous. In this case, AFM data, as well as the cleanliness of the in-plane loop suggest that it probably is.

5 Conclusion

There it is, a little camera unit to tell you the size of your substrate shards and help with accurate characterization of your film. Now you can cut everything haphazardly and have the computers measure the thing for you #thefutureisnow. If I was more cool than I am right now, I would train some sort of edge detection scheme to find the substrate automatically, but this is fast enough by hand and so that’s not really necessary, in my opinion.