TITLE:  Low-cost syringe pump

CATEGORY:   Mechanical Design, Automation

DATE:   July, 2015

TOOLKITS:   Arduino, Solidworks, EagleCAD

COLLABORATORS:   Built for Arable Labs, inc.

During the summer of 2015 I was extremely fortunate in that I got to work with some fantastic people over at a startup called Arable Labs, inc.  During my time there, I designed and built a low-cost syringe pump for the purposes of testing some equipment.  The pump is controlled by an Arduino Uno, for which I custom-built a shield for the Schmalz Haus stepper driver, and uses the Arduino IDE's serial monitor to input values.  The pump itself is driven by a 12V NEMA-17 stepper motor, which turns the lead screw and drives the gantry forward or backward - this is in turn attached to the plunger of a laboratory-grade microliter syringe that contains the fluid.  The pump was designed using Solidworks and was cut from ABS plastic using a laser cutter.

CODE:   The firmware code can be found on GitHub ( HERE ).

Given that the volume of water displaced by the plunger is essentially cylindrical in shape, the pseudocode presented below outlines the logic for determining how many steps, and microsteps, are required for the stepper motor to execute:

The volume (Vs) of a sphere (in mm^3) is: Vs = (4/3)*PI*r^3;
drop_radius = drop_diameter / 2;
therefore, Vs = (4/3) * PI * drop_radius^3;
Given that the volume of water displaced by the syringe plunger
is cylindrical in shape, and that this volume will be equal to
the volume of the droplet required, cylnder_volume (Vc) = sphere_volume (Vs);
If Vc = PI * r^2 * h, where r is half of the internal diameter of
the syringe, and h is the height of the cylinder (or distance
travelled by the plunger) in mm. At this stage, both Vs and
internal_diameter are known variables, so:
Vs = Vc;
Vs = PI * (internal_diameter / 2)^2 * h;
h = Vs / ( PI * (internal_diameter / 2)^2 );
Thus, h is the distance in mm that the plunger must travel in order to dispense a drop of size of size drop_diameter;
plunger_travel_distance = h;
The stepper motor has a resolution of 200 steps / revolution ( or 1.8’ per step);
The lead screw has a travel distance of 1/16” (or 1.5875mm) per
revolution (McMaster Carr Part No. 93410A904), therefore the 
plunger travels 1.5875mm in the axial direction per revolution
(200 steps);
travel_per_revolution = 1.5875;
The total number of revolutions required: rev_count =
plunger_travel_distance / travel_per_revolution;

We can then determine the number of steps required:
number_of_steps = rev_count * 200;
number_of_steps returns a floating point number. We separate
this value into two components: the number of full steps
required, and the number of 1/8th microsteps required.
rounded_steps (full steps) = floor(number_of_steps);
we get the remainder by subtracting rounded_steps from
number_of_steps: remainder = number_of_steps - rounded_steps;
In order to get the number of microsteps required, we divide the
remainder by 0.125 (1/8);
num_microsteps = remainder / 0.125;
total steps to execute = rounded_steps + num_microsteps;