Arduino Controlled Dosing Pumps
Aquarium controllers can make your life easier.. especially when it comes to remembering to dose your aquarium. I recently started a new planted tank and realized how bad my lax dosing schedule was… to fix this i decided to build an arduino based dosing system. Yes it may be overkill.. but I do love automation and building so this seemed like the perfect project! They dosing shield consists of an RTC DS1307. I searched the web for countless hours researching how to build this project… I found lots of bits of information but no complete guides so i decided to do this write up as a step by step guide for the beginner arduino builder.
[youtube_video] 8gr5I7OUo7I [/youtube_video]
Shopping list:
DS1307 RTC $3.50
Arduino Uno ATmega 328 $15
Arduino Prototype Shield $5.50 (optional but recommended)3x 1k Resistor
3x IRFZ44N (or any other N channel transistor)
3x Diodes
1x l7805cv – 5V regulator
3x Dosing pump (ebay)
Find a box to mount your project in… This lovely tea box was a whopping $3 and makes a perfect project box.
Drill some holes yo mount the motors.
Paint your box if desired them mount your components.
Update: I finally got a proper tube holder!
The Schematic:

arduino controlled dosing pumps
Arduino Sketch
// Deven Rich 12-5-2013 // This project was built on the Arduino Uno - ATmega328P // I would also like to give credit to Maurice Ribble for providing chunks of the RTC code // This code sets up the DS1307 Real Time clock on the Arduino board to controll 3 dosing pumps // The RTC keeps track of time, the code checks it and turns on the pumps at a specified time // to dose your aquarium #include "Wire.h" #define DS1307_I2C_ADDRESS 0x68 // Convert normal decimal numbers to binary coded decimal byte decToBcd(byte val) { return ( (val/10*16) + (val%10) ); } // Convert binary coded decimal to normal decimal numbers byte bcdToDec(byte val) { return ( (val/16*10) + (val%16) ); } // Stops the DS1307, but it has the side effect of setting seconds to 0 // Probably only want to use this for testing /*void stopDs1307() { Wire.beginTransmission(DS1307_I2C_ADDRESS); Wire.write(0); Wire.writeWire.writeWire.write(0x80); Wire.endTransmission(); }*/ // 1) Sets the date and time on the ds1307 // 2) Starts the clock // 3) Sets hour mode to 24 hour clock // Assumes you're passing in valid numbers void setDateDs1307(byte second, // 0-59 byte minute, // 0-59 byte hour, // 1-23 byte dayOfWeek, // 1-7 byte dayOfMonth, // 1-28/29/30/31 byte month, // 1-12 byte year) // 0-99 { Wire.beginTransmission(DS1307_I2C_ADDRESS); Wire.write(0); Wire.write(decToBcd(second)); // 0 to bit 7 starts the clock Wire.write(decToBcd(minute)); Wire.write(decToBcd(hour)); // If you want 12 hour am/pm you need to set // bit 6 (also need to change readDateDs1307) Wire.write(decToBcd(dayOfWeek)); Wire.write(decToBcd(dayOfMonth)); Wire.write(decToBcd(month)); Wire.write(decToBcd(year)); Wire.endTransmission(); } // Gets the date and time from the ds1307 void getDateDs1307(byte *second, byte *minute, byte *hour, byte *dayOfWeek, byte *dayOfMonth, byte *month, byte *year) { // Reset the register pointer Wire.beginTransmission(DS1307_I2C_ADDRESS); Wire.write(0); Wire.endTransmission(); Wire.requestFrom(DS1307_I2C_ADDRESS, 7); // A few of these need masks because certain bits are control bits *second = bcdToDec(Wire.read() & 0x7f); *minute = bcdToDec(Wire.read()); *hour = bcdToDec(Wire.read() & 0x3f); // Need to change this if 12 hour am/pm *dayOfWeek = bcdToDec(Wire.read()); *dayOfMonth = bcdToDec(Wire.read()); *month = bcdToDec(Wire.read()); *year = bcdToDec(Wire.read()); } //define pins int motorPin1 = 9; int motorPin2 = 10; int motorPin3 = 11; void setup() // run once, when the sketch starts { byte second, minute, hour, dayOfWeek, dayOfMonth, month, year; pinMode(motorPin1, OUTPUT); pinMode(motorPin2, OUTPUT); pinMode(motorPin3, OUTPUT); Wire.begin(); Serial.begin(9600); // Change these values to what you want to set your clock to. // You only need to run this the first time you setup your RTC. // Set the correct value below and un comment it to run it. /* second = 45; minute = 55; hour = 9; dayOfWeek = 2; dayOfMonth = 30; month = 4; year = 13; setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year); */ } void loop() // run over and over again { byte second, minute, hour, dayOfWeek, dayOfMonth, month, year; // this prints the output to the serial window (tools > serial monitor in arduino) and is great for testing getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year); Serial.print(hour, DEC); Serial.print(":"); Serial.print(minute, DEC); Serial.print(":"); Serial.print(second, DEC); // Set the time you want the motors to kick in if((hour == 21)&&(minute == 23)&&(second==10)){ Serial.print(" TRUE"); Serial.println(" "); Serial.println(" MP1"); analogWrite(motorPin1, 255); delay(8500); // set how long you want the motor to run... 1000 = aprox 1ml analogWrite(motorPin1, 0); Serial.println(" MP2"); analogWrite(motorPin2, 255); delay(9500); // set how long you want the motor to run... 1000 = aprox 1ml analogWrite(motorPin2, 0); Serial.println(" MP3"); analogWrite(motorPin3, 255); delay(5500); // set how long you want the motor to run... 1000 = aprox 1ml analogWrite(motorPin3, 0); } // we dont really need this since we set the pin to low above but just incase :) else{Serial.println(" false"); analogWrite(motorPin1, 0); analogWrite(motorPin2, 0); analogWrite(motorPin3, 0); } delay(1000); }
Let me know if you have any questions and enjoy your new Arduino Dosing pumps!
As request I snapped a pic of the underside of the board