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]

Arduino Auto Doser

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)

arduino dosing pump controller IMG_3398

Find a box to mount your project in… This lovely tea box was a whopping $3  and makes a perfect project box.  IMG_3406

Drill some holes yo mount the motors. IMG_3408

Paint your box if desired them mount your components.
IMG_3418 IMG_3433

Update: I finally got a proper tube holder!

tube-holder-aquarium-doser

The Schematic:

arduino controlled dosing pumps

arduino controlled dosing pumps

Arduino Sketch

[code lang=”arduino”]
// 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);

}

[/code]

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

20140204-081636.jpg

85 comments

  • Pingback: Arduino auto dosser - Page 3

  • Where u get ur motor?

  • They were $20 each off ebay

  • Pingback: Osaka Forest Tank log | Fish Tank Projects

  • What is the Arduino Prototype Shield supposed to be for? The link for that is missing.

  • Hey Justin, i fixed the link above for the Prototype shield.

    Its generally used with the mini breadboard but i soldered directly to it to create my final product.You could do this with a breadboard or one of the blank diy boards but the protosheild give you a nice clean pre-pinned board to build onto.

  • Hi there, this is exactly what im looking for, but I want the pumps to turn on at different times, for example I want pump 1 to turn on at 1900 on Monday / Wed / Fri and pump 2 to turn on at 1900 on Tues and Thur and Sat. pump three isnt used at the moment, but will be eventually. Can you please help with the code? Cheers!!

  • To do that you will have to break up the IF statement into a statment into one for day/time you want to run a specific pump.
    exmpale:

    //day 1 at 9:20 am for 8.5 seconds
    if((dayOfWeek=1) && (hour == 09) && (minute == 20) && (second==10)){
    analogWrite(motorPin1, 255);
    delay(8500); // set how long you want the motor to run… 1000 = aprox 1ml
    }
    analogWrite(motorPin1, 0); //turn off motor.

    //Day 3 4:20 pm turn on pump 2 for 10 seconds.
    if((dayOfWeek=3) && (hour == 16) && (minute == 20) && (second==10)){
    analogWrite(motorPin2, 255);
    delay(10000); // set how long you want the motor to run… 1000 = aprox 1ml
    }
    analogWrite(motorPin2, 0); //turn off motor.

    Hope that clears it up a bit 🙂

  • Pingback: Automated aquarium fertilizer doser

  • Pingback: rndm(mod) » Automated aquarium fertilizer doser

  • How have you found the quality of the peristaltic pumps? I have found a number of references that indicate that these low price units from China are not worth the asking price, is that your experience?

    I’m keen to give this a go, have been accumulating parts for a while!

  • So far they have been working awesome for me. there are higher grade (medical) dosing pumps out there but they also come with a higher prices tag. For any hobby project i would defiantly recommend them for the price…

  • What happens if during that delay 1000 at the end (and however many ms to check the time each loop, the rtc skips that exact second you’re looking for? I’d either lower/remove the last delay, or use something like if (seconds > x && seconds < x2) instead of (seconds = x)

    I'll be doing something like this eventually, will be sure to post back with my adventure 🙂

    Awesome project!

    • Mr. Ryan you are entirely correct, this is a race condition waiting to happen. The delay(1000) should be shorter. I’d use 500ms personally, but anything up to 900ms would probably work fine.

  • Great build, I too have been looking at the Chinese peristaltic pumps. Did yours come with the internal silicone tubing or was that a separate buy.

  • Is there any particular reason why you did not use the 12V power for Arduino but the 5V across l7805cv ?
    Arduino can be also supplied with a voltage of 12V.

  • David James Ryan – There really is no point to that.. I think it was there from my initial testing/build and i never bothered removing it.. Be sure to post back with your progress and let me know if you have any questions. I just got a arduino mega and micro in the mail.. so I’m already brainstorming the next project 🙂

    Tom – The Pumps came with a small attached chunk of silicone tube. Conveniently (with a bit of work) fit inside of standard airline tubing which i slid the pump tubes into. It was a bit of a battle to slide them in so its a friction fit but in the past few weeks there has been no issues. you can get dosing pump tubing but i all of the ones i found were overly priced for silicone tube.

    limel – The arduino can accept 12V in but i don’t believe any of the pins output any higher then 5v. I wanted to build it all on to the add on board. In order to accept the 12V i believe i would have had to solder to the power jack pins on the uno.. (i may be wrong.. but i didn’t see a source for 12V on the board itself)

    • I think this can be done from the Vin pin? I just looked it up, and it seems that’s whatever the input voltage is. This would make it possible to use a wall wort direct into the arduino in lieu of the 7805v regulator.

  • I am looking at the Peristaltic Pumps on Ebay and I am wondering which type I need or if it makes a difference. Do I need the 6v, 12v, or 24v pump?
    What is the life expectancy of these Ebay pumps from Hong Kong?
    If the pumps fail, will it overdose my tank and kill my fish, or will they just not dose at all?
    I have 2 large planted tanks sitting next to each other, would it be difficult to turn this into a 6 pump system that can handle both tanks at the same time?(same size tanks) Or would I be better off building two units?
    Also what type of probe/cable/tube holder are you using to keep the dosing lines near your circulation pump?

    Thank you for your time in putting together and posting this awesome project. I can see it making life much simpler, at an affordable price. Once I have this all figured out on the home tanks, I will likely build one for the big tank in my store as well. Thanks again!

    -Sage

  • Hey sage.
    If I were you I would do a single system with 4 pumps. You only really need 2 pumps per tank .. 1 for macros and 1 for micro nutrients.

    This could all be down from a single board. I went with 12v pumps but 6v would work as well(what ever is cheaper!) since the pumps are only on or say 5-10 seconds the the controller is providing power I wouldn’t ever worry about overdosing. The pump heads are a little gear box, the gears being stripped would be the only potential (and highly unlikely) possibility. So unless you tell your code to turn them on to long I wouldn’t worry about it.

  • Deven,

    Great project! Thanks for sharing it with us. I’m looking into a similar application and wonder if you might be able to answer a few of my questions?

    How precise is the measurement of the dosing? I’m wondering what the minimum amount that could be dispensed at a time with this type of setup.

    Do you have to prime the unit initially to get the fluid into the line? When not pumping does it stop the fluid in the line from flowing (on both sides of the pump)?

    Thanks again,

    Nick

  • The pumps are fairly precise for the price. You can get higher precision but it comes with a higher price tag. you control the dosage by how many milliseconds you apply power to the pumps.. so i’m sure you could tweak/test it to fine tune your desired results.

    You would have to run the pumps for a few seconds initially to get the fluid through the lines

  • Hey, could you provide the info of the pumps?
    Model, etc…
    Thanks

  • A half year ago i was searching diy automatic doser too. My priority was inexpensive dosing system and i found this good page https://sites.google.com/site/yourcreativeautomation/diy-auto-dosing-system-for-the-aquarium-ii . Here were used the same or similar cheap peristaltic pumps from ebay, like you did. I recently made this doser, it has many functions. For example i liked that i dont need manually calculate time amount, for which pumps must stay on, it is done automatically.

  • Just ordered my parts, and can’t wait to try this out on my reef tank! Thanks for the How-To, do you happen to have any more pictures of the way the board was wired together?

    Thanks

  • Hello

    Sorry for my poor English and I hope you can understand me 🙂

    Can you please send pictures from top and behind Prototype Shield board? And can i use and how to connect all of that on shield board:
    -20X4 Character LCD Module Display For Arduino
    -Matrix Array 4×4 16 Key Membrane Switch Keypad
    -DS3231 AT24C32 IIC Real Time Clock (i think that those pins are the same as on DS1307)
    Hope you can help me 🙂

    Kind regards
    Robert

  • Deven,

    I am trying to adapt your project to 6V pumps and a 6V power source, so I can power the pumps out of the Arduino 5V pin.
    This would save a voltage regulator and allow me to use the 6V pumps off eBay, which have a cooler looking compared to the 12V ones.

    However, it seems that the IRFZ44N transistor doesn’t get activated with 5V logic. Would you know what transistor would do the job? (I am pretty bad at reading electronic component datasheets)

    thanks and congrats for such a nice project.

  • With the tubes left in the water of the aquarium, wont they continue to leach fertilizer throughout the day? I would think this would cause some real over dosing issues. Or maybe im wrong?

  • hi

    I working on project probably quite similar to this. I want to control EC level of water tank. The EC sensor will feed signal to arduino. If the EC too high, the arduino will operate Pump 1 that add water to the tank. If EC too low, the arduino will operate Pump 2 that add fertilizer solution to the tank.

    Can you explain what i need to create the circuit

    Thank you

  • what 12v power supply are you using? can you provide more concise info on how you wired it to the board?
    thanks!

  • Mathias – I’m not sure of the model. but if you search for 12V dosing pump on ebay they will pop up.

    Robert – Do you still need a pic of the back of the board? I can take one if so 🙂

    Franklin Dattein – i’m not to sure off hand.. but do a search for 6V transistor. I’m sure you will find something.

    Derek- It possible that ferts may be leeching into the water since the tubs are submersed.. in theory I should be adding check valves close to the top.. i havent bother yet beacause if its happening it will be very minimal. – Future add on! 🙂

    adham – The only real addition would eb the EC sensor. You would have arduino constantly check the levels (or every so often) and have an if statement.. IF read EC sensor > 200 do this.. if < 100 do this. ect. SteveS - The 12V power supply goes directly to the voltage regulator. The Voltage Regulator has 3 pins +12V Ground and +5V The 12V goes connets to the power supply positive and the positive on the dosing pumps. the +5V pin on the Voltage reg goes to the +5v on the arduino board to power it.

  • Deven thanks for help but my dosing pump is already finish :D. I will make the new one with ULN2003 for more pumps and Mega 2560 ATmega2560-16AU Board for arduino + 3.2″ TFT LCD with Ph meter and temp. sensor.

  • Nice work Robert! I have is waiting for a future project! (once i decide on what.. ).. i may have to add on to my doser 🙂

    255 is the PWM signal.. It can be anywhere 0-255.. where 0 is off 255 is the fully on. If you were using this to control an LED.. then this is how you would dim/control the brightness. 255 in the dosing situation just means fully on to the pumps. a lower value would slow it down (providing they can handle it)

  • Is there any specific wattage on those resistors? Also, is it possible to get a few pics of your soldering on the bottom of the shield? I want to make absolutely sure I’m doing this correctly, since I’m kind of a newb with schematics. Also, can we use any old diode or does it need to have some specific properties?

  • Pingback: 90g planted tank -- rebuild - Page 6

  • OK so I got this working. Thank you for posting the pic of your shield underside. Is it normal that my timers reset when I unplug the system? I was under the assumption that the RTC would keep time using its battery should the whole system lose power.

  • Just wanted to say thank you for making this tutorial. It helped inspire me to start playing with arduino and do something useful. I made a few small changes I thought you might find interesting. I had some extra parts laying around from some arcade stick mods and used .110 disconnects for the pump contacts. I also had a usb passthrough which I installed on the box so I don’t have to open the box to program should I want to mess around with the code. The last thing I did was install a small power pass through that matches the 12v power supply I chose.

    I was thinking it would be cool to add connectivity so it’ll tweet or something when it runs, or add led’s to the pumps that light up on the front of the case when one is running. I know its just eye candy but I think it’s cool.

    Also, what do you think about the code to run the pump being a function where you pass the motorpin and delay time?

  • when I copied and pasted the sketch to program it had a error that stated wire no declared in this scope and high lighted Wire.beginTransmission(DS1307_I2C_ADDRESS);

  • Dosing pump, atmega32, bascom source

  • Hi again 🙂

    I build a second arduino Leonardo R3 dosing pump. But I have some problem with fourth dosing pump at boot up Leonardo. I used digital pins 9, 10, 11 and 12 and the last one 12 is always ON and runing until Leonardo boot up this is about 5 sec. But when LCD turns ON pump turn off and the program is working normaly.

    Kind regards

  • Thanks for posting this build. Im having trouble verifying the code. I get this error:
    Devons_doser_pump.ino:8:10: error: #include expects “FILENAME” or
    Devons_doser_pump.ino: In function ‘void setDateDs1307(byte, byte, byte, byte, byte, byte, byte)’:
    Devons_doser_pump:45: error: ‘Wire’ was not declared in this scope
    Devons_doser_pump.ino: In function ‘void getDateDs1307(byte*, byte*, byte*, byte*, byte*, byte*, byte*)’:
    Devons_doser_pump:68: error: ‘Wire’ was not declared in this scope
    Devons_doser_pump:75: error: ‘amp’ was not declared in this scope
    Devons_doser_pump:75: error: expected `;’ before ‘)’ token
    Devons_doser_pump:77: error: expected `;’ before ‘)’ token
    Devons_doser_pump.ino: In function ‘void setup()’:
    Devons_doser_pump:96: error: ‘Wire’ was not declared in this scope
    Devons_doser_pump.ino: In function ‘void loop()’:
    Devons_doser_pump:121: error: ‘amp’ was not declared in this scope
    Devons_doser_pump:121: error: expected `;’ before ‘)’ token
    Devons_doser_pump:123: error: ‘quot’ was not declared in this scope
    Devons_doser_pump:123: error: expected primary-expression before ‘:’ token
    Devons_doser_pump:123: error: expected `;’ before ‘:’ token
    Devons_doser_pump:123: error: expected primary-expression before ‘)’ token
    Devons_doser_pump:123: error: expected `;’ before ‘)’ token
    Devons_doser_pump:125: error: expected primary-expression before ‘:’ token
    Devons_doser_pump:125: error: expected `;’ before ‘:’ token
    Devons_doser_pump:125: error: expected primary-expression before ‘)’ token
    Devons_doser_pump:125: error: expected `;’ before ‘)’ token
    Devons_doser_pump:129: error: expected `)’ before ‘;’ token
    Devons_doser_pump:129: error: expected `;’ before ‘)’ token
    Devons_doser_pump:149: error: ‘else’ without a previous ‘if’
    Devons_doser_pump:149: error: expected primary-expression before ‘)’ token
    Devons_doser_pump:149: error: expected `;’ before ‘)’ token

    Anyone know what the problem might be.

    Thanks

  • This tutorial has inspired me to attempt this build myself. I’d like to add a 4th pump and an autofeeder (so I can go on vacation again and not have to rely on someone to perform these tasks for me). Have you considered adding an interface so you can change doses without going into the code manually?

  • This isn’t really a “complete” guide as you mentioned. You skipped the whole putting it together part.

    Looks awesome though…

  • thanks for the code. this is my sketch i made for a 2 pump doser.

    // 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
    #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) );
    }

    // 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 ato = 9;
    int vinegar = 10;
    //int motorPin3 = 11;

    void setup() // run once, when the sketch starts
    {
    byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
    pinMode(ato, OUTPUT);
    pinMode(vinegar, 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.

    /* remove line to set time on RTC
    second = 00;
    minute = 40;
    hour = 12;
    dayOfWeek = 2;
    dayOfMonth = 17;
    month = 3;
    year = 14;
    setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);

    */ //Remove Line to set time and Date

    }
    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);
    Serial.println();

    // Set the time you want the motors to kick in
    if((hour == 10)&(minute == 00)&(second==00)){
    Serial.print(“Dosing”);
    Serial.println(“:”);
    Serial.println(“ATO”);
    analogWrite(ato, 255);
    delay(300000); // =5min set how long you want the motor to run… 2000 = aprox 1ml 25ml/sec
    analogWrite(ato, 0);}

    if((hour == 10)&(minute == 15)&(second==00)){
    Serial.print(“Dosing”);
    Serial.println(“:”);
    Serial.println(“Vinegar”);
    analogWrite(vinegar, 255);
    delay(12000); // =6sec set how long you want the motor to run… 2000 = aprox 1ml 27ml/sec
    analogWrite(vinegar, 0);}

    /*
    if((hour == 10)&(minute == 05)&(second==00)){
    delay(10000); //Time between pump running
    Serial.println(“Vine”);
    analogWrite(motorPin3, 255);
    delay(60000); // set how long you want the motor to run… 1000 = aprox 1ml
    analogWrite(motorPin3, 0);}
    */
    }

  • Pingback: **SHOW-AND-TELL - MAIN SHOWROOM** - BCA members' Aquarium Setup(s) - Page 6

  • Can you modulate the pump speed by using the arduino to change the power supply to the motor? I’m interested in smaller feed rates

  • Hey,

    First of all, thanks for the very clear instructions, was a “breeze” to copy everything.

    I have one question tho, how hard would it be to add either a button or a function which you can call in the serial monitor so you can run the pump (s) to fill your hoses, because if you have installed new ferts the hoses are empy and have to fill up again before the ferts come out of them and into the tank.

    Hope i make sense 😉

  • Thank you very much for the code. You did a great job. This is my sketch modded to activate the internal Arduino led and blink every 1 second so I can have a monitor that code is running. This also makes the time output in monitor to update every second.

    #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 clock, but it has the side effect of setting seconds to 0.
    /*void stopDs1307()
    {
    Wire.beginTransmission(DS1307_I2C_ADDRESS);
    Wire.write(0);
    Wire.writeWire.writeWire.write(0x80);
    Wire.endTransmission();
    }*/

    ////1) Sets date and time on the clock.
    ////2) Starts the clock.
    ////3) Sets hour mode to 24 hours.
    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 hours (am/pm) you need to set
    ////bit 6 (also need to change getDateDs1307)
    Wire.write(decToBcd(dayOfWeek));
    Wire.write(decToBcd(dayOfMonth));
    Wire.write(decToBcd(month));
    Wire.write(decToBcd(year));
    Wire.endTransmission();
    }

    ////Reads date and time from the clock,
    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 for 12 hours (am/pm)
    *dayOfWeek = bcdToDec(Wire.read());
    *dayOfMonth = bcdToDec(Wire.read());
    *month = bcdToDec(Wire.read());
    *year = bcdToDec(Wire.read());
    }

    ////Define pump pin outs.
    int motorPin1 = 10; //Pump 1 – Flourish Excel
    int motorPin2 = 11; //Pump 2 – Flourish Iron
    int motorPin3 = 9; //Pump 3 – Flourish
    int actled = 13; //Status Led

    void setup() ////One time run at each execution.
    {
    byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
    pinMode(motorPin1, OUTPUT);
    pinMode(motorPin2, OUTPUT);
    pinMode(motorPin3, OUTPUT);
    pinMode(actled, OUTPUT);
    Wire.begin();
    Serial.begin(9600);

    ////Set date and time on the clock.
    ////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 = 01;
    minute = 32;
    hour = 21;
    dayOfWeek = 3;
    dayOfMonth = 19;
    month = 3;
    year = 14;
    setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
    */

    }

    ////Main programm loop.
    void loop()
    {
    byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;

    ////Serial Monitor Output.
    getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
    Serial.print(“Date: “);
    Serial.print(dayOfMonth, DEC);
    Serial.print(“/”);
    Serial.print(month, DEC);
    Serial.print(“/”);
    Serial.print(year, DEC);
    Serial.println(” “);
    Serial.print(“Day of week: “);
    Serial.print(dayOfWeek, DEC);
    Serial.println(” “);
    Serial.print(“Time: “);
    Serial.print(hour, DEC);
    Serial.print(“:”);
    Serial.print(minute, DEC);
    Serial.print(“:”);
    Serial.print(second, DEC);
    Serial.println(” “);

    delay(500);
    analogWrite(actled, 255);
    delay(500);

    ////Pump Operation
    ////Everyday: Flourish Excel
    if((dayOfWeek != 7)&&(hour == 10)&&(minute == 00)&&(second == 10)){

    ////Start Flourish Iron pump 1,5ml
    Serial.print(” Flourish Iron Pump 1,5ml”);
    Serial.println(” “);
    Serial.println(” On”);
    analogWrite(motorPin2, 255);
    delay(1500); // 1000 = aprox 1 ml
    analogWrite(motorPin2, 0);
    Serial.println(” “);
    Serial.println(” Off”);

    ////Monday: Flourish Excel Pump 7,5ml + Flourish 1,5ml
    if(dayOfWeek == 1){

    ////Start Flourish Excel pump 7,5ml
    Serial.print(” Flourish Excel Pump 7,5ml”);
    Serial.println(” “);
    Serial.println(” On”);
    analogWrite(motorPin1, 255);
    delay(7500); // 1000 = aprox 1 ml
    analogWrite(motorPin1, 0);
    Serial.println(” “);
    Serial.println(” Off”);

    ////Start Flourish pump 1,5ml
    Serial.print(” Flourish Pump 1,5ml”);
    Serial.println(” “);
    Serial.println(” On”);
    analogWrite(motorPin3, 255);
    delay(1500); // 1000 = aprox 1 ml
    analogWrite(motorPin3, 0);
    Serial.println(” “);
    Serial.println(” Off”);

    }

    else{

    ////Start Flourish Excel pump 1,5ml
    Serial.print(” Flourish Excel Pump 1,5ml”);
    Serial.println(” “);
    Serial.println(” On”);
    analogWrite(motorPin1, 255);
    delay(1500); // 1000 = aprox 1 ml
    analogWrite(motorPin1, 0);
    Serial.println(” “);
    Serial.println(” Off”);

    }

    ////Saturday: Flourish 1,5ml
    if(dayOfWeek == 6){

    ////Start Flourish pump
    Serial.print(” Flourish Pump 1,5ml”);
    Serial.println(” “);
    Serial.println(” On”);
    analogWrite(motorPin3, 255);
    delay(1500); // 1000 = aprox 1 ml
    analogWrite(motorPin3, 0);
    Serial.println(” “);
    Serial.println(” Off”);

    }
    }

    else{
    Serial.println(“Pump Status: Off”);

    ////Backup Close Pump
    analogWrite(motorPin1, 0);
    analogWrite(motorPin2, 0);
    analogWrite(motorPin3, 0);
    analogWrite(actled, 0);

    }

    // delay(1000);

    }

    • May I ask the IDE you are using as I have “stray \ error in program” compile erroe

      • I had the exact same compilation error. If you search the Web, it appears to be an issue with copying code from the browser to Arduino, some characters don’t carry over correctly. PaulS post at http://forum.arduino.cc/index.php?topic=226109.0 gave me this idea. So I visually looked through the code to see what has not been properly colored in the code. Appeared to be the ” (quotation marks), so I copied the ” from the code and auto replaced all with those keyed in from my keyboard. HINT:There are more than one kind of wrong ” in the copied code in my case so check all.

  • very nice post, i certainly love this web site, keep on it edecdcdbbdkb

  • Hi mate, what liblary have you use.
    I have some error’s

  • I have Arduino nano, does this code works with this nano?
    I have some error also.

    wire was not declare in this scope
    etc.

  • hello sir. this is very great info i just came across and about to order all the stuff..

    can you please explain me i just want tot make 1 doser. a very slow automatic doser..

    please help.

    thank you

  • Hello,

    nice project. I did the same with a less powered pump. SO I was able to run my project with a 5V power supply. But my new project will use the same pump as you did.

    But I was asking myself if the 5V-regulator (l7805cv) wont get to warm? I see you are not protecting your regulator against getting too hot.

  • Mine never got hot enough to worry about. there is alot of current flowing through it except when the pumps are one.. which is a fairly short time span. you could always attach a small heatsink if you are worried about it or plan on doing a longer cycle.

  • HI,

    Im very great full for this website and write up. You opened my eyes on what could be done. I always wanted a liquid dosing pump for exactly this reason too.

    Iv now made my own dosing pump but mine doses on alternate days. So one pump one day and one pump another day. (macro and Micro). I done this by using the day of the week information. I wrote out a little bit of code to work out odd and even numbers and in the IF statements now it doses one pump if the day of the week is even and the other if the day of the week is odd. My code is completely different to yours just so i could prove to my self i could write it out and understand whas going on, rather then just pinching your code which im sure youve put plenty of research into.

    Ill be looking to upgrade my project now to have an LCD screen so that i can see everything its doing e.g. Time, what its dosing when it does it, Im going to try make it standalone too so that it can be programmed using buttons on the arduino.

    Thanks again for you little idea. Its perfect for what i need it for.

    Craig

  • Craig – Thanks for the great feedback! Its nice to hear my site has helped so many people. Another though on the doser (currently using this method on my auto water change project) .. If you want to dose 10ml per day, you could dose 1ml/hour for 10 hours to distribute it throughout the day. May be easier on the tank and provide a constantish flow.

    I ordered a touchscreen or two of the net.. so it will be neat to incorporate into the next project 🙂

  • I think i will be keeping it at 10ml in one go as i think the plants will benefit from the large dosage and i wont have to worry about them up taking more then 1ml per hour but its worth a thought :).

    I now love this thing and i have so many ideas on what i can do to make it better for my own personal use. Im going to make another also due to having more then one tank. Its perfect for the money.

    I forgot to mention I also took into account one of the comments above, which was using the Vin pin to provide the 12v power for the motors.

    The Vin pin will allow you to use the power sauce thats connected to the board direct before it enters the voltage regulator. So im using a 12v plug connected to the Arduino, which then converts it to 5v so that board can use it but then the Vin pin is supplying 12v for my motors. Its able to provide up to 1amp of power from that pin i think it was due to a diode on the board.

    It may be worth looking into if your looking to maybe change your board or upgrade it or even replicate it. 🙂

  • Hello admin. I have bought all the parts u listed n joined those. the code which you provided, should i just copy n paste it directly and the pumps will start working?? or there are any changes that i have to do ??

  • Pingback: University Peristaltic Pump Has Hacker Heritage | Hackaday

  • Pingback: University Peristaltic Pump Has Hacker Heritage | Hack The Planet

  • You can explain to me how I can add to this system one module shield LCD with buttons equal to this link:http://produto.mercadolivre.com.br/MLB-705097658-lcd-16×2-keypad-arduino-shield-modulo-botoes-teclado-tela-_JM

  • Hi there, I found your video in youtube as you have made the same (almost) setup as I am going to do. Are you still happy with the setup? Have the pumps survived all these years? 🙂

    • They sure have, well… i did replace the pump on one of the heads since it was noisy but aside from that they have been working well.

  • Thanks you for the instructions, I was looking to install a DIY pumps too.
    I’m just wondering what’s the Diodes for and where do they go on the board?

    • I can’t recall off hand but any decent size diode should work. I did sell that dosser but may make new one in the near future 🙂

  • deven
    i would like to build this project but would like to know how to add 1 or 2 more pumps to the code and how to make them dose once to twice a week not to good at writing code i’m ok a builging the curcets but the code is the problem for me!
    thanks a lot .

    • would i be able to use a mos module in place of building the expansion board that you did and it would cut out the extra circuit for the 12v to 5v step down and should allow me to keep the the micro computer away from the pumps

  • please help no matter what i do the code will not compile all i get is nothing but stray \342′ in program

    • I’m guessing something didnt copy and paste right form the web site.. likely a quote.. try deleting and re-typing all the quotes

      • I have done that and still will not work . is there anyway you can dropbox me the code ? or something?

      • i have figured out that "in your code is really ”
        but i cannot figure out what & is supposed to be !?

        this is all the errors that are still coming up
        G:\MY Documents\Arduino\doseing_test\doseing_test.ino: In function ‘void getDateDs1307(byte*, byte*, byte*, byte*, byte*, byte*, byte*)’:

        doseing_test:75: error: ‘amp’ was not declared in this scope

        *second = bcdToDec(Wire.read() & 0x7f);

        ^

        doseing_test:75: error: expected ‘;’ before ‘)’ token

        *second = bcdToDec(Wire.read() & 0x7f);

        ^

        doseing_test:77: error: expected ‘;’ before ‘)’ token

        *hour = bcdToDec(Wire.read() & 0x3f); // Need to change this if 12 hour am/pm

        ^

        G:\MY Documents\Arduino\doseing_test\doseing_test.ino: In function ‘void loop()’:

        doseing_test:121: error: ‘amp’ was not declared in this scope

        getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);

        ^

        doseing_test:121: error: expected ‘;’ before ‘)’ token

        getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);

        ^

        doseing_test:129: error: expected ‘)’ before ‘;’ token

        if((hour == 21)&&(minute == 23)&&(second==10)){

        ^

        doseing_test:129: error: expected ‘;’ before ‘)’ token

        if((hour == 21)&&(minute == 23)&&(second==10)){

        ^

        doseing_test:149: error: ‘else’ without a previous ‘if’

        else{Serial.println(” false”);

        ^

        exit status 1
        ‘amp’ was not declared in this scope

      • never mind about that last comment i figured that out ! LoL but do i need to put in an address for (DS1307_I2C_ADDRESS)

        i also plane on replacing the Serial.print with a LCD.print and i’ll be using another IC2 device so would i have to declare each address

      • as of right now i have used you coad as a starting point. i have changed it so i have 2 pumps dosing every day and 2 other pumps dosing on alt days . i have also set it up to display on a 20×4 ic2 LCD it displays the current time and date and temp and then shows what pump is dosing . i’m trying to figure out hoe to add buttons to the code for priming of the pumps. it’s kinds of looking like an arduino will be limited for what i would like to do and my have to switch to a PI but have never worked with one 1 any thoughts

  • Hi all! So. I tried adapting this to use an LCD and found an interesting… issue. When the pumps kick on, it basically scrambles the code I’m running in memory (buttons unresponsive, LCD prints gibberish, and the pump will run forever). The program runs fine without actually hooking the pumps up.

    So, I also built the same as the diagram you have here… it appears to work fine, but it in fact does not (for me). The pumps scramble the memory, but since the program does not use any libraries, it is significantly smaller and will on average take a lot longer to corrupt the program. Presumably, the corruption is random, so it takes longer to hit the unfortunate spot. After about 30 seconds of a pump running, the program will become corrupted and continue to run the pump, forever.

    My guess is that a 5V regulator is not enough due to fluctuations caused by the DC motor, which the arduino is sensitive to. Unfortunately, I’m not too experienced with electronics and can’t say for sure if that is the case. I’ve also tried putting a diode across the pump and it did not help. My 12 V DC wall wart is unregulated… dunno if that would cause issues.

    It would be helpful if someone else could run water through their own to try and see if they can “break” it like mine. Kind of concerned that one day someone’s going to get their dosing containers emptied into their tank 🙁

    • It would not be quite as precise.. but you could run the pumps on full and power them through a relay to isolate the pumps from the arduino.

  • Would you take a 12v cable connection picture?

    • Sorry, i sold the doser to a buddy so it may be a bit difficult but ill try to snap one next time i see him.

  • really nice guide, making it myself now. However i have 2 questions. first is i cannot see where you connected your diodes on your shield (i’m using a breadboard myself) and i can’t really figure out where i should put them. secondly is there a way i could control the speed of the pumps? i’m using mosfet modules (http://hobbycomponents.com/motor-drivers/661-irf520-mosfet-driver-module) instead of regular mosfets because i couldn’t find them. So i tought speed control should be doable. I’m kind of a noob sorry, still learning this stuff on the go.

Leave a Reply

Your email address will not be published. Required fields are marked *