Annealing For ABS Plastic Parts


The use of annealing ovens for 3D printed plastic is a useful technique that helps strengthen the plastic part and improves the overall look of the plastic. In this experiment, four 3D printed bag sealing caps were annealed with different techniques to compare the results. The annealing of ABS plastic is performed at a temperature range of 105C-107C which the glass transition phase of the plastic is. When ABS is printed, it is cooled below its glass transition phase which keeps the plastic harder and brittle. By slowly heating up the plastic to its glass transition phase the plastic begins to deform. This deformation is the breaking of the semi crystalline structure within the plastic to relieve stress that is created when the plastic is printed. When plastic is slowly heated, and this stress is relieved, the material is then cool very slowly so that the internal structure remains somewhat viscous- increasing overall strength of the material.


The oven used to perform this experiment was a mechanical convection oven [Source]. The mechanically circulated air heats the plastic, and then melts it. The plastic parts are in the oven for the entire heating, baking, and cooling process. The error of the oven is estimated to be +-2C. [Source] Literature states that annealing can vary in process but most sources suggest the heating of the oven to the glass transition phase at a rate of 50F to 200F over the course of 2 hours. Holding in the oven 30 minutes for every ¼” of plastic (width) and then cooled 50F every hour. The purpose of the slow process is that the plastic is amorphous. Different parts of the plastic can be in different states at different times based on thickness and air exposure. In other words, there is uneven melting and cooling of plastics. The mechanical circulation of air and the slow process is supposed to account for much of these errors. If plastics are cooled or heated at different rates then different parts of the plastics can be in different states which could potentially weaken the part overall by creating stress concentrations; having a brittle location, a half-melted location, or a partially cooled location will disrupt the uniformity of the printed part.


Experiment one was conducted with a high range of temperature, revealing the importance of the glass transition phase temperature. The first cap was placed in the oven at a temperature of 50C and then slowly brought to a temperature of 108C over the course of 30 min. The 3D printed cap is ¼” in thick. After 30 min at this temperature, the cap was removed without cooling slowly. There was no difference in appearance or feel of the cap.

This cap was cooled for over 24 hours before being put back in the oven. The purpose of a second heating was to try and see a noticeable difference in the plastic. The second heating was conducted at a stable temperature of 121C. The total time in the oven was 1 hour 42 minutes. This much longer than the recommended time. When pulled from the oven, the caps were noticeably deformed with visible melting near the center. This warping was the plastic melting outwardly.  This is not desired. The purpose of the glass transition phase is to melt the crystalline internal structure of the plastic without deforming the overall shape. It was concluded that the temperature was much too high and that the glass transition phase does hold precedence.

The next experiment tested an extended time in the oven. A cap was placed in the oven and the temperature was increased by 12-15C every 15 minutes until the oven reached 105-107C. The cap was then held in the oven for 57 minutes. After this, the cooling process began. The oven was decreased by 15-20 degrees every 15 minutes until the oven reach 50C. It was then turned off and allowed to cool to a temperature slightly above room temperature. This cap shrank slightly (3mm) which was noticed when the cap was not able to screw onto its respective bottle.

The above experiment was repeated, and it was found that this shrank as well.

A final experiment was conducted with a newly printed cap. The oven was heated by increasing the temperature 12-15 degrees Celsius every 15 until it was brought to 105-107C (oven fluctuates slightly). The part was kept in the oven for almost 2 hours before the cooling process began. The oven was brought down to 50C in the same manner as above. The part was cooled to room temperature. This part also shrank by approximately 3 mm. The part, however, was also shinier than its un-annealed state, and was smoother after it was cooled.


The pictures above highlight the difference between the annealed and the unannealed caps. The Annealed caps show the visual signs of warping and slight melting.



The photo above shows the shrinking that occurs when the 3D caps are annealed. There was little warping on this cap-temperature was correct- but shrinking still occurred which can be seen above with the unannealed cap is larger underneath the other cap.


Based on the above experiments, it could be concluded that annealing for smaller printed parts that need to fit counter parts (ie. Caps) may not be the most efficient method of finishing a part. The shrinkage of 3 mm could be accounted for in the 3D design process by adjusting dimensions of the design. There are, however, better methods that do not have such a large amount of shrinking involved. Also, if the goal of the annealing is for aesthetic purposes then vapor finishing is the suggested method. The unfinished cap has a diameter of 19 mm, a vapor finished one of 18 mm, and an annealed one of 16.5 mm. Future annealing experiments could be conducted on flatter parts whose max load tolerance could be measured- to test strength improvement-, or parts in which shrinking is easily accounted for. Based on the annealing of caps, however, the process was more cumbersome than necessary and vapor finishing with acetone is the recommended method for both these parts and parts similar in design. Vapor finishing accomplishes the same aesthetic results without the wait time and the shrinking.



 Vapor Finishing for Small Printed Parts

Vapor Finishing for Small Printed Parts

The above picture shows a cap treated with 10mL (L) and a 19 mL (R). The 10mL treated cap is less smooth than the 19mL treated cap. The edges are less rounded. The necessity of more acetone was also supported when the 19mL treated cap allowed less water to both escape the bag and cap connection and infiltrate the cap.

A Review of SLA Printed Bag Caps To Improve Sealing Over FDM Bag Caps

A Review of SLA Printed Bag Caps To Improve Sealing Over FDM Bag Caps

An important feature of the OPEnSampler is the ability to seal the collected water post-sample such that evaporation and contact with the air have a negligible impact on concentrations of minerals and isotopes in the samples. We’ve tried many different options but solid resin-based 3D printed caps proved to be the best option.

Redesigning the Bottle Trays

Redesigning the Bottle Trays

A tray to hold 12 ISCO bottles was previously designed without considering the weight of water when they are filled. The plastic tray was redesigned using Fusion360's sheet material modeling and static stress simulation tools.

Capstone: Project Features

This post provides a very general description of the functionality that will be delivered by the OPEnSampler capstone project, and includes a link to our requirements specification on GitHub. It discusses the two primary pieces of the project: the OPEnSampler Companion App and status update functionality.

Shipping the OPEnSampler

Shipping the OPEnSampler

The late-summer OPEnSampler has entered the shipping process! I'm excited to work closely with the researchers in Zürich and get feedback on our design. Additionally, there will be a round of documentation updates very soon for the new batch of samplers.

Capstone Team Intro: Travis Whitehead

I'm Travis Whitehead, one of three CS students contributing to the OPEnSampler for my capstone project. This post elaborates on the capstone process and serves as a personal introduction sharing a little bit about me and my future involvement with the OPEnSampler project.

Capstone Team Intro: Chase Coltman

Hello OPEns Lab Community, my name is Chase Coltman and I am one of the three members of Capstone team assigned to the development of the OpenSampler Companion Application.

OPEnSampler October 17 Update

OPEnSampler October 17 Update

Much has happened with the samplers in the past two weeks! There are two categories of updates: those relevant to the Zurich Sampler and those relevant to the new versions of samplers. In short, the frames have been assembled for the new samplers and the PCBs are being soldered up; the new pumps arrived; the final pieces of the Zurich Sampler are coming together and it will be ready to ship very soon.

Choosing a Different Peristaltic Pump

Due to concerns about the vendor, we are not able to use the Honlite pump featured in the post "Choosing a Peristaltic Pump" a few weeks ago. Luckily, I found a $99 pump that should do the trick on Amazon. This post discusses the considerations necessary to use it.

Assembly Day 1

Azad and I spent part of the morning assembling the frame of the bottle-based OPEnSampler. I found quite a few changes I will make when assembling the next sampler. In the end we found the device didn't quite fit in the duffle bag and so some machining will need to be done to reduce a couple dimensions.

Investigating a Solenoid Valve's Strong and Weak Orientations

Investigating a Solenoid Valve's Strong and Weak Orientations

We observed our $1 solenoid valves were failing under low pressure conditions. After some investigation and testing, we found we could safely orient the valves in  to ensure the flush valve will fail first while the sample valves will form quite strong seals when closed. This solution allows us to continue to use the cheaper valves and keep our cost of materials down.

Choosing a Peristaltic Pump

Choosing a Peristaltic Pump

There are currently two pumps to choose from for the OPEnSampler: a low flow rate, unknown-precision peristaltic pump and a high flow rate, "low precision" pump. They have their pros and cons and this writeup will discuss the angles of attack for deciding which one is more appropriate for our system.

Reviewing the Diameter and Material of OPEnSampler Tubing

Reviewing the Diameter and Material of OPEnSampler Tubing

The EPA recommends a flow rate of 2 ft./s or greater to minimize the relative difference in velocities of suspended sediments. They also recommend a tubing diameter of 1/4 in. as well, but not for a particularly well documented reason. One unanswered question brought up in the design review meeting was the impact of tubing diameter on the quality of water samples. This short writeup discusses some of the considerations involved in the decision to use 1/4'' OD Teflon tubing for future sampler designs.

OPEnSampler Update August 9, 2017

Much progress has been made with the OPEnSampler! The frame is lightweight, the entire system fits into the Pelican rolling cooler, and the sample control works as expected. 24 bags fit with room inside the frame, and the system can be set on any face without issues, easing maintenance, testing, transport, and drawing out samples. Some issues persist in this iteration, namely light leaking from the bags and a low flow rate due to the cheap pumps.

OPEnSampler Update, Bertha


Our efforts over the past moths have culminated in a robust lab-tested prototype of the OPEnSampler we endearingly call "Bertha." We've determined this will be our in-house lab prototype that we will use as a testing bed for integrating new features and hardware. Lessons learned experimenting with Bertha will directly translate into field-deployable OPEnSampler versions to be distributed for use. This post details the technical specifications of Bertha, features, Serial Commands, and use cases.

Technical Specs

  • Frame dimensions are 24in x 12in x 12in and made out of 40mmx40mm extrusion.
  • 2 12VDC Peristaltic pumps (250ml water pumped in 2min)
  • 24 250ml aluminum-lined Mylar bags (spout packs)
  • 25 12VDC valves (24 valves attached to bags, 25th valve is used as a system flush outlet valve)
  • Arduino Uno, Microprocessor
  • Custom PCB with TPIC power-shits registers for handling valve actuation
  • Motor driver board
  • High Precision, Temp-compensated Real-Time Clock, for microprocessor sleep/wake(sample) scheduling.
  • Mode switch toggles between Sampler operation modes: standard operation mode, serial command mode.
  • EEPROM saves configuration of sampler parameters (sample duration, flush duration, next valve to sample, etc).
  • Serial command set for configuring the sampler's behavior out in the field and for sending discrete commands (puppet-string) to turn on/off discrete components of the sampler. e.g. turn pups on/off/reverse and open/close specified valves.
  • Power-save Sleep mode, for ling battery life in the field. At the moment, drawing 24 250ml samples should require just 1 Amp Hour of a 12VDC battery. In standard operation mode, sampler stands by in low-power sleep in between taking samples. In serial command mode, electronics remain awake and stand by for configuration commands from computer.


In consultations with many different researchers hoping to use this OPENSampler, we identified that the technical specifications of the sampler will vary depending on the context of use. This includes: What kind of water source is being sampled, what is being tested or analyzed, and environmental conditions and considerations in the field. To this end, we decided to make a "core" system that would be extensible using attachments for particular deployment contexts. This architecture is not dissimilar with many vacuum cleaner systems, where the core remains immutable but changes utility based on the attachments used.

Packaging: The frame is designed to be dropped into a variety of different "packages" depending on the field requirements. In many instances, a waterproof duffle bag may suffice for carrying the device into back-country environments. Rigid stack-able boxes made from corrugated plastic may be desirable for other deployments. For field deployments requiring samples be temperature protected (from wither extreme heat or cold), dropping this into a rolling lockable travel cooler such as the Pelican 80qt Elite.


Switch the sampler into "serial command mode." Not required, but should be done for best practice. After programming the Uno over USB, you may either switch the sampler directly into standard operation mode or send serial commands to configure your sampler's parameters. Switching modes back and fourth may be done at anytime. In operation mode, a sample cycle is initiated whenever the specified time has elapsed.

Each sample cycle consists of the following states:

  1. System Flush
  2. Sample Draw (in next bag in sequence)
  3. System Sleep/standby

Samples may be removed from the device without manually removing bags. This is achieved by switching the sampler into serial command mode and typing commands into the Arduino Serial Monitor window to draw samples out one by one in any desired order. See commands below. This process may be automated (and should be) using a program to send a sequence of timed commands. A sample python script can be found on the project GitHub site.

Sampler Configurable Parameters and Factory Defaults Are:

  • IsDaily = True (Take a sample either daily or at a set periodic rate throughout the day)
  • 8:00 (default daily time to take sample)
  • Sampler Duration = 100 seconds (takes 120 seconds to fill 250ml)
  • Flush Duration = 30 seconds (this will need to be set based on the length of tubing away from main sampler - longer tubing requires longer flush duration for full system purge)
  • Sample volume = 250 (in ml, this isn't being used right now, but there in case features need in the future)
  • Sample Valve Number = 1 (next bag to draw sample into)
  • Sample Period = 3 (if the IsDaily flag is FALSE,

The above parameters may be changed at anytime by switching into Serial Command Mode. Parameters are saved in EEPROM and are preserved even if the sampler looses power. Sampler operation will proceed with the new configuration behavior when switched back into operation mode.

Serial Command Set

  • CLK, Checks the current RTC time, Hr:Min:Sec - useful for checking before using SA to set sample alarm
  • SAD (int)X (int)X, sets "Daily Sample Alarm" Hr:Mn to take samples daily at time. Uses 24hr format.
        ex: SAD 9 30 sets sample alarm to 9:30AM daily.
        ex: SAD 16 22 sets sample alarm to 4:22PM daily.
        Also sets Is_Daily flag for initialization if power-down restart, clears Is_Hourly flag
  • SAP (int)X, sets "Periodic Sample Alarm" to take samples at specified period duration in Min.
        ex: SAH 30 sets sample alarm to go off every 30min.
        ex: SAH 47 sets sample alarm to go off 47min.
  • FD (int)X, sets "Flush duration" period in ms, should be about 20sec, but will change with the length of tubing you use to get from sampler to water source
  • SD (int)X, sets "Sample Duration" time that pumps run water into each bag in milliseconds
      ** removed for this version : SV (int)X, sets "Sample Volume" in ml, a transform of Sample Duration, may not be 100% accurate, 2min per 250ml,
  • VN (int)X, Sets the next valve/bag to place sample. Sampler saves curent valve number during operation in EEPROM in case of power failure, it picks up where it left off. This ensures you can reset the valve count before each new deployment, or manually skip to next available bag should the sampler malfunction
  • RST, Full system "factory" reset - set default sample period, sample duration, reset vlve counter, writes defaults to EEPROM (over-wirghting previous settings)

Pupet-String Commands:

  • Vx (int)#, Turn valve on/off where x is valve number (starting at 1, V0 is flush valve). # is 1 for on (open) and 0 for off (close) example: V1 1 opens valve 1. V1 0 closes it.
  • M #, turn motor on/off and direction. #=0 for off, #=1 for draw water into sampler, #=-1 for draw water out of sampler    example: M 1 will begin drawing water into sampler.

From here, you may use Arduino IDE, Python, or other software to send timed sequences to sampler. For example: V0 1 followed by M 1will begin flush.  The sequence (press return where you see / ) V0 0 / V1 1 / M 1will disable flush and draw water into bag1
    You could also make a "macro" or timed program in something like Python for drawing water out of the sampler sequentially into your analysis machine without removing bags! Example of this is on the project GitHub site.

Features to be integrated for Zurich Version

The Zurich version is underway, with frame being constructed out of much lighter 15mmx15mm extrusion. This will make the total sampler weight (without filled with water) about 10lbs!

Packaging: The frame is designed to be dropped into a variety of different "packages" depending on the field requirements. The package for Zurich is intended to be a waterproof duffle bag. However, for field deployments requiring samples be temperature protected (from wither extreme heat or cold),

Currently, all sampler status messages are reflected on the Arduino IDE Serial Monitor window when sampler is attached to host computer. We're evaluating an OLED display that will show all status information during sampler operation.  There will also be a wake button for the display that will show the status of the sampler at anytime during its sleep cycle.

Features for future versions

One major issue is not knowing the operational status of your sampler when left out in the field. Instead of being forced to check in on the sampler in person, we plan to integrate a GSM extension for the core, which will send updates over texts or emails using any 2G SIM card.

A Simpler Pump Test: No SD


This is a follow-up to the previous post, "A Simple Pump Test". There were several complications with storing the pump data on an SD so this post will describe a new method that stores data on the Arduino's own memory.


In the field, the pumps will be run for 2.5 minutes per sample for 24 samples, resulting in one hour of total runtime. As described in the previous post, the pumps used in the sampler are poorly documented and information on their lifespan and behavior under long periods of use is needed. 

The SD breakout board used in the previous test was a 3.3v board and was not compatible with 5v arduino logic without some voltage conversion in between. While it worked some of the time, it resulted in corrupt data after a few points. Rather than using a 5v board or something to step down the signal voltage, the Arduino's own memory can be used to store a small amount of data.

Arduinos have a small amount of available memory that doesn't get reset between power cycles, known as EEPROM. A single byte can be stored per register, and an Arduino Uno has 512 available registers.

Setup and Method

A 12v peristaltic dosing pump is wired such that the positive end is connected to a 12v source and the negative end is split between a .85 Ohm resistor and the Arduino's A0 analog input pin. The Arduino's GND is connected to GND on the power source and VIN is connected to 12v. The other end of the .85 Ohm resistor is connected to GND.

A jumper wire connects GND to the Arduino's digital pin 3, which is initialized to INPUT_PULLUP.

When powered on, the Arduino continuously checks that pin 3 is LOW. If it is, the voltage across the .85 ohm resistor is effectively measured via an analog read of pin A0 and the value is stored in a register of EEPROM. The register address is incremented and the loop resets.

If pin 3 is HIGH, data collection is turned off and the Arduino checks for a serial input of "p". If the user inputs in the serial monitor "p" then it prints all the data from the registers separated by spaces. This data should be copied and pasted into a text file, but can be reprinted as long as pin 3 is HIGH.


// A simple voltage logger that is 

#include <EEPROM.h>

const int sensorPin = A0;
const int startPin = 3;

long sTime = 0; // last sample time
int maxPoints = 240; // maximum number of points to store
int sDelay = 30000; // delay between samples
int addr = 0;

void storeData();

void setup() {
  pinMode(startPin,INPUT_PULLUP); // if grounded, enable recording


void loop() {
  //If datalogging is enabled, store data in a new address
    if(millis() - sTime > sDelay){
      Serial.println("reading data point " + String(addr));
    Serial.println("Enter 'p' to print out data");
      int input = 0;
      if(Serial.available() > 0){
        input =;
      if (input == 112){
        for(int i = 0; i < maxPoints && i < EEPROM.length(); i++){
          Serial.print(" ");

 * store the sensorPin voltage and increment the address. If the address has
 * reached the limit of number of the points or hit the last address of
 * the EEPROM, don't store data and return from the function.
void storeData(){
  if(addr == EEPROM.length() || addr == maxPoints){
    Serial.println("Max addr reached");
    sTime = millis();
  EEPROM.write(addr, analogRead(sensorPin)/4);
  sTime = millis();

Python Code

# This code will take in data via a text file that was collected using
# the pumptest arduino code. Data points should be separated by spaces.

import matplotlib.pyplot as plt

data = []
splitter = []
voltage = []
current = []
average = []
avg = 0

with open('pumplog_2_p1t2.txt') as f: #file name for test data to be graphed
    reader = f.readlines() #read in the data

for line in reader: #split up the data. Could be conbined with converting to int but is more readable this way.

for point in splitter[0]:
    data.append(int(point) * 4) # turn each point of data into an int. Data values were divided by 4
                                # to fit into EEPROM.

for point in data: # calculate the voltage at each point.
    voltage.append(point * 5 / 1024)

for point in voltage: # calculate the current at each point.
    current.append(point / .85)

for point in current: # calculate the average current.
    avg += point
avg = avg / len(data)

for point in data: # turn average into a plottable list

plt.title("Pump 1 Test 2") #rename based on test
plt.xlabel("time (minutes)")
plt.ylabel("current (A)")


Initial Results


Three tests have been run so far. They were graphed using Python 3 and matplotlib.pyplot. Another test is currently being run on the second pump. The data between the two pumps will be compared using a two-sample T test to check if the two pumps perform the same. The same method will be used for the pumps under condition of pumping water.

The initial three tests might suggest that there is a long term decrease in the pumps' current draw. Future tests should be conducted for a full day and a linear regression analysis should be performed. More importantly, such inconsistency in the current draw suggests the flow rate though these pumps is not constant. A test should be conducted to observe the trend and variance in the mass flow rate of water through the pump via a logging scale. A better conclusion can be made once the first round of testing is finished and statistically analyzed.