So, one of the biggest hassles in day to day reef tank maintenance is dosing of alkalinity and calcium solutions. In any tank with a relatively high load of stony corals, you need to add these supplements to keep the water chemistry in line. Our current tank requires something on the order of 20ml of each per day. Missing a few days here and there isn't a HUGE problem, but in general, it's a bad thing. Also, adding all 20ml of each at once introduces instability as well, in the form of concentration pulses, which isn't awesome.
A much better solution is to have a very slow, well-metered pump constantly adding each solution. You can't mix the concentrated solutions, because they will form a percepitate. The normal way to do this is with a purpose-built aquarium peristaltic dosing pump. This is fine, but a 2 channel pump can easily cost north of $300!
A couple years ago I decided to try to find a cheaper solution. I ended up buying a gemini pc2tx 2 channel infusion pump off of ebay for about $50. It looks like this:
It's a very nice unit, but it is CRAMMED with safety features (which makes sense, since it's a medical device). The problem is, it's also fairly old, and either it's damaged, or some of the safety sensors are gunked up, or who knows what, but basically I have never been able to get it to work on its own. It powers up, but as soon as I actually try to start it pumping, it just gives me errors, beeps loudly, and stops working. I have tried for HOURS on several occasions to figure out what was wrong, to no avail.
In the end, I popped it open, and realized that the pump trains are driven by 2 pretty standard 6 volt bipolar stepper motors. This is great, because you can control stepper motors with an arduino!
Thus this project was born. First I gutted the machine, removing all of the (now unnecessary) control circuitry, power supply (unfortunately the machine's power supply puts out 6 volts, which is too low for the arduino, and I don't know enough about power supplys to try to change it), and other parts. Most of this went into a pile for later parts scavenging.
Then I went to the electronics store and bought a pair of NTE2013 darlington arrays
to drive the 2 motors (i hoped i would be able to scavenge these from the existing control boards, but i wasn't able to find any. part of that might be because "darlington array" is only one (perhaps the simplest) of a couple of different names for this kind of chip, apparently.) Most tutorials refer to the darlington arrays as ULN2003, but my electronics store stocks NTE parts, and the 2013 has built in protection diodes, which is nice.
With the motor wires sorted, and the driver chips in hand, it was pretty much a snap to get the 2 pump trains running.
One additional item I had to modify was a little unexpected. The pump trains are held together by springs, i suppose to let you use different diameter tubes or something. But my springs aren't strong enough, and don't allow the peristaltic actuators to completely close off the tubing. To solve this, I just wired the spring perches together, so the actuator can't move as much. If you make the wires too tight the motors stall intermittently, so it's a bit of trial and error to get them right.
The red wires in this picture show what I mean:
The remaining steps are to figure out the right motor speeds to get me the pump rates that i need, but that should be pretty easy.
The biggest current stumbling block is that in the arduino code each call to a stepper motor is blocking. Which means until the motor reaches the end of the called-for run, the program is halted. So if you call one motor for 200 steps (one revolution) then the other motor for 200 steps, they each run one revolution, then stop and wait for the other motor to run.
This can be partly solved by only calling for a few steps from each motor at a time, so they effectively are alternating back and forth very fast. The only problem here is that now the speed of one motor is dependent on the speed of the other. If I have both motors going 1 step at a time, and I switch one of them to 3 steps, this speeds up the 3 step motor, but it slows down the 1 step motor, because it now has to wait for the 3 step to finish it's (now longer) call before it steps again.
There is probably a way around this, and it's not a HUGE problem, but for the moment it's not quite a perfect solution.
by operating on a minute-long cycle and with the pumps running at a speed of 30rpm, I can get up to a total of 6ml/minute (between both pumps, divided any way i like) of dosing while keeping the rates completely independent. This is WAY more that I will need (something closer to .1-.2ml/minute will likely be the actual rate), so that problem is more or less taken care of.
A new problem is that I was trying to run the motors (6v) off of the arduino's 5.5v power. Unfortunately, they draw too much current (no big surprise there) and would cause the board to reset. At the moment I have them powered by a 9v battery, but will pick up a wall-wart style power supply shortly. An interesting aside, this device came with a big 6volt sealed lead acid backup battery, so if I wanted to make it keep running in a power outage, and I was a little smarter about leaving the old power system intact, I probably could have done that.
UPDATE: ended up putting the old power supply back together and using it. Should have done that to begin with. Also, after some overnight testing, it seems like the first and ladt couple of steps (say, 5 on each end) of the stepper motor are relatively high-error, in terms of volume delivery. this means that if you call of 14 steps every minute, you get 10 bad steps and 4 good ones, which was killing my overall delivery accuracy. So i changed the software to dose once an hour instead of once a minute. This way you still get 10 "bad" steps, but instead of 4 good steps between them, you get 830 good steps. It seems to be working much better. I also added a 5 minute delay between dosing channel 1 and channel 2 to prevent the solutions from mixing with eachother at high concentrations (before they have time to mix well with the water).