// SYRINGE DOSING PUMP
// Rob Conway, 25-05-2014 Rev1
//
// DESCRIPTION
// The Syringe pump uses 2 x 30ml syringes energised by a geared stepper motor 28BYJ-48
// Designed with Tinkercad 3D Modelling software
// Body of unit (without syringes) measures 110mm Wide x 75mm Long x 42mm High
// 3DPrinted in ABS with Makerstoolworks MendelMax 2
// USAGE
// Used to Dose any liquid in an aquarium however will be used for Carbon Dosing.
// OPERATION
// Normal operation is applying power to the unit it will dispense xx ml
// then will not dose again until power is re-applied.
// On powerup if the toggle switch is held ON (prime or retract) it will not dose,
// however run the motor forward (Prime) or reverse (retract).
// If retract is toggled the motor will back off the plunger plate 5mm to enable the
// syringe to be withdrawn from the unit.
// MOTOR DETAILS
// This Arduino example demonstrates bidirectional operation of a
// 28BYJ-48, using a ULN2003 interface board to drive the stepper.
// The 28BYJ-48 motor is a 4-phase, 8-beat motor, geared down by
// a factor of 68. One bipolar winding is on motor pins 1 & 3 and
// the other on motor pins 2 & 4. The step angle is 5.625/64 and the
// operating Frequency is 100pps. Current draw is 92mA.
//declare variables
int motorPin1 = 6; // Blue - 28BYJ48 pin 1
int motorPin2 = 7; // Pink - 28BYJ48 pin 2
int motorPin3 = 8; // Yellow - 28BYJ48 pin 3
int motorPin4 = 9; // Orange - 28BYJ48 pin 4
int sw_prime = 2; // Manual Toggle Switch arduino pin 2
int sw_retract = 3; // Manual Toggle Switch arduino pin 3
int count_d = 0; // internal counter -steps DOSE
int count_r = 0; // internal counter -steps RETRACT
int lookup[8] = {B01000, B01100, B00100, B00110, B00010, B00011, B00001, B01001};
// Tuning Parameters
int motorSpeed = 1100; // variable to set stepper speed
int countsdose = 1050; // number of steps per DOSE amount (1050 steps = 1.5 ml)
int countsretract = 20000; // number of steps to retract to enable removal of syringe
// Setup I/O Channels
void setup() {
pinMode(motorPin1, OUTPUT); //declare the motor pins as outputs
pinMode(motorPin2, OUTPUT);
pinMode(motorPin3, OUTPUT);
pinMode(motorPin4, OUTPUT);
pinMode(sw_prime, INPUT); //declare toggle switch as inputs
pinMode(sw_retract, INPUT);
digitalWrite(sw_prime, HIGH); // turn on pullup resistors
digitalWrite(sw_retract, HIGH);
Serial.begin(9600);
delay (2000); // Startup delay 2 seconds
}
// Main Continuous Loop //
void loop(){
{if (digitalRead(sw_prime) == LOW) // Check switch to PRIME
prime();
}
{if (digitalRead(sw_retract) == LOW) // Check Switch to RETRACT
retract();
}
{if(count_d < countsdose) // Will DOSE once on powerup.
dose();
}
}
// Subroutines //
void dose(){
count_d++;
for(int i = 0; i < 8; i++)
{ setOutput(i);
delayMicroseconds(motorSpeed);
}}
void prime(){
for(int i = 0; i < 8; i++)
{ setOutput(i);
delayMicroseconds(motorSpeed);
count_d =countsdose + 1; // Disables DOSE in main loop
}}
void retract() {
{while (count_r < countsretract)
for(int i = 7; i >= 0; i--)
{setOutput(i);
delayMicroseconds(motorSpeed);
count_r++;;
}
count_r =0; // Reset RETRACT counter
count_d =countsdose + 1; // Disables DOSE in main loop
}}
void setOutput(int out) {
digitalWrite(motorPin1, bitRead(lookup[out], 0));
digitalWrite(motorPin2, bitRead(lookup[out], 1));
digitalWrite(motorPin3, bitRead(lookup[out], 2));
digitalWrite(motorPin4, bitRead(lookup[out], 3));
}