This project was driven by a need for N12 to scale up quality control throughput to enable large scale production of carbon nanotubes. One of the commonly measured properties of carbon nanotubes is their height; however, traditional measurement methods (SEM) are expensive, require extensive training, have low turnaround times and have a small sample size.
Our engineering team developed the concept of using a rastering laser scanner to measure a sample before and after the nanotubes were removed, where the difference gave the height of the nanotubes. I was tasked with electrical and software integration, while my coworker worked on mechanical design.
Enclosure
One of the design constraints was that the system be as self contained as possible. I decided to house everything in a single enclosure, with switches and indicators mounted on the outside. Included are the sensor controller, stage controller, separate power supplies, terminal blocks and standard/timed/ pneumatic relays. The switches and indicators, used to secure the sample during measurement, are hard wired. All power and communication to the sensor and stage were done through two 24-pin connectors.
Software
Due to prior experience and time constraints, I decided to code the system in Python on a PC. The software aspect of the project entailed two subsystems: data acquisition/processing, and a user interface. I further bucketed the first sub-task into two main scripts: one to collect and store data from a scan, and another two take two scans and create a subtractive height map.
After writing byte message handling functions for the sensor and finding a driver for the stage, I created a first multi-pass script for collecting and storing data. During the raster, measurement and position byte data would be captured and saved in a tuple on each iteration. Then, the byte data would be translated and transcribed to a .csv file. I decided to use .csv files as outputs, instead of passing the data directly from script to script, in order to simplify troubleshooting.
Because the "position" read from the stage during motion was actually a step count from an origin (not an absolute encoder), the measurements from two successive scans weren't taken at exactly the same locations. To enable proper subtraction, the height at specific locations (for instance, every millimeter along the scan) had to be interpolated from the actual scan data (this was implemented with a NumPy interpolation function). Finally, the output of this script was a .csv containing the height profile and other statistics. Later on, I added some low pass filtering to remove spikes caused by dust particles settling on the substrate.
The user interface requirements were very basic: buttons to set naming IDs, start scans, and a list to display indicators (average, standard deviation) to the operator. While the system also produced more detailed profiles as a .csv for later analysis, the operator could use the statistics as a cursory check. I chose to use REMI for the user interface, which translates python code into javascript and runs the site on a local server, as it fit my criteria and eliminated a bunch of work. REMI is event-based, which made it easy to integrate with my data collection and processing scripts.
Assembly, Testing and Validation
Once all the parts had arrived, my coworker and I spent a few weeks assembling, testing and validating the system. The biggest software changes were to the user interface, after input from potential users about file naming conventions. Aligning the pneumatic pistons that actuated the sample clamps also gave us some trouble, and ultimately required some shimming.
To ensure that the system provided meaningful data, I also coordinated a validation study using an SEM as ground truth. This was modeled after a previous validation study we had done for a different height sensor, comparing measurements made on the same growth samples. The result of the study was positive, indicating that the system was acceptable for use.