Arduino fish tank

Hello!
I've been trying to get some code together for an auto fish tank feeder.
Here is the code I have so far:

/* 
Made by Elijah Wood
Based off of Rob Glinka's version
Auto fish feeder
It will feed fish everyday and change the water every week. It will send email notifiers to conferm feeding when away from your home.
Made to be used with the Arduino ethernet sheild.
* are used to protect my personal information. You must replace them with your info.
*/

#include <Ethernet.h>
#include <Servo.h> 

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xAF, 0xCE, 0xDD }; // whatever mac you want
byte ip[] = {LOCAL IP};
byte server[] = { 98, 136, 86, 109 }; // Mail server address  (this is for yahoo's mobile smtp)

Client client(server, 587);  // yahoo's mobile smtp server ip/port

Servo myservo; //declares servo

int switch1 = 1;
int switch2 = 2;
int motor1 = 3;
int relay1 = 4;
int relay2 = 5;


void setup()
{
 
 myservo.attach(9); //attaches servo on pin 9 
 pinMode(switch1, INPUT);
 pinMode(switch2, INPUT);
 pinMode(motor1, OUTPUT);
 pinMode(relay1, OUTPUT);
 pinMode(relay2, OUTPUT);
 
 Ethernet.begin(mac, ip);
 
}

void loop() {
  
while(true) { //manual water change/feeding
  
     if (digitalRead(switch1) == HIGH) { 
     digitalWrite(motor1, HIGH);
     delay(4100);
     digitalWrite(motor1, LOW);
     
      if (client.connect()) {
   client.println("EHLO MYSERVER");
   client.println("AUTH PLAIN ************************************");  // replace the **'s with your auth info from the perl script.
   client.println("MAIL FROM:<drummerboyx@yahoo.com>");
   client.println("RCPT TO:<drummerboyx@verizon.net>");
   client.println("DATA");
   client.println("From: <drummerboyx@yahoo.com>");
   client.println("TO: <drummerboyx@verizon.net>");
   client.println("SUBJECT: FishBot feeding");
   client.println();
   client.println("Fish have been feed today");
   client.println("FishBot has sucsessfully emailed Elijah Wood! YAY!");
   client.println(".");
   client.println(".");
 }
     }
     
   if (digitalRead(switch2) == HIGH) {
     digitalWrite(relay1, HIGH);
     delay(3000); //wait untill tank fills 
     digitalWrite(relay1, LOW);
     delay(500); //stop and wait
     digitalWrite(relay2, HIGH);
     delay(3000); //wait untill tank empties
     digitalWrite(relay2, LOW);
     delay(500); //stop and wait
     
     myservo.write(180); //turns servo w/ water conditioner
     delay(1000);
     myservo.write(0); // puts servo back in nuetral position
     
      if (client.connect()) {
   client.println("EHLO MYSERVER");
   client.println("AUTH PLAIN ************************************");  // replace the **'s with your auth info from the perl script.
   client.println("MAIL FROM:<drummerboyx@yahoo.com>");
   client.println("RCPT TO:<drummerboyx@verizon.net>");
   client.println("DATA");
   client.println("From: <drummerboyx@yahoo.com>");
   client.println("TO: <drummerboyx@verizon.net>");
   client.println("SUBJECT: FishBot water change");
   client.println();
   client.println("Water change has been accomplished today");
   client.println("FishBot has sucsessfully emailed Elijah Wood! YAY!");
   client.println(".");
   client.println(".");
    }
   }
  }
  
while(true) { //auto water change
     delay(604800000); //wait 1 week from start-up (604,800,000 MS)
     digitalWrite(relay1, HIGH);
     delay(3000); //wait untill tank fills 
     digitalWrite(relay1, LOW);
     delay(500); //stop and wait
     digitalWrite(relay2, HIGH);
     delay(3000); //wait untill tank empties
     digitalWrite(relay2, LOW);
     delay(500); //stop and wait
     
     myservo.write(180); //turns servo w/ water conditioner
     delay(1000);
     myservo.write(0); // puts servo back in nuetral position
     
           if (client.connect()) {
   client.println("EHLO MYSERVER");
   client.println("AUTH PLAIN ************************************");  // replace the **'s with your auth info from the perl script.
   client.println("MAIL FROM:<drummerboyx@yahoo.com>");
   client.println("RCPT TO:<drummerboyx@verizon.net>");
   client.println("DATA");
   client.println("From: <drummerboyx@yahoo.com>");
   client.println("TO: <drummerboyx@verizon.net>");
   client.println("SUBJECT: FishBot water change");
   client.println();
   client.println("Water change has been accomplished today");
   client.println("FishBot has sucsessfully emailed Elijah Wood! YAY!");
   client.println(".");
   client.println(".");
    }
  }

while(true) { //auto feeding
     delay(86400000); //wait 24 hours from start-up (86,400,000 MS)
     digitalWrite(motor1, HIGH);
     delay(4100);
     digitalWrite(motor1, LOW);
     
     if (client.connect()) {
   client.println("EHLO MYSERVER");
   client.println("AUTH PLAIN ************************************");  // replace the **'s with your auth info from the perl script.
   client.println("MAIL FROM:<drummerboyx@yahoo.com>");
   client.println("RCPT TO:<drummerboyx@verizon.net>");
   client.println("DATA");
   client.println("From: <drummerboyx@yahoo.com>");
   client.println("TO: <drummerboyx@verizon.net>");
   client.println("SUBJECT: FishBot feeding");
   client.println();
   client.println("Fish have been feed today");
   client.println("FishBot has sucsessfully emailed Elijah Wood! YAY!");
   client.println(".");
   client.println(".");
     }
   }
   
 if (client.available()) {
   char c = client.read();
   Serial.print(c);
  }
 }
}

What I'm trying to accomplish is this; every day my tank will be fed and every week my tank will go through a water change. I want it to send me an email after it does these two actions. For example, it just fed the fish at 7:00 AM and then it will send me a conformation email telling me that they have been fed.

My question: based some of my code off of Rob Glinka's email sender. But I'm not sure how to get auth info for my yahoo account. His version says that it's created via some perl script. Being a beginer in programming; I'm not sure what that is. Can someone help?

Also, if anyone spots any problems with the code, please tell me.

Thanks,
Elijah

Also, has someone tried to control an Arduino with an ethernet sheild with an iphone web app? What I'm thinking is that when I'm gone or on vacation I can take out my iphone and manually feed them/check tank temperature/check tank PH/ect. Maybe even have a live video feed. If so, do they have the code so I can try to figure out how to incorperate it with my set up.

Thanks in advance!

Elijah

how are you changing out the water with a servo? this is pretty cool and i might use it for my tank at home.

I'm accually using it to put in the water conditioner once the water has been changed.

I've been working on the code some more and here is the newest:

/* 
Made by Elijah Wood
Based off of Rob Glinka's version
Auto fish feeder
From start up, it will feed fish every 24 hours and change the water every week. 
It will send email notifiers to conferm feeding when away from your home.
Made to be used with the Arduino ethernet sheild.
*/

#include <Ethernet.h>
#include <Servo.h> 

byte mac[] = { 0x2, 0x5, 0x1, 0x9, 0x6, 0x4 }; // Arduino's artificial mac address
byte ip[] = { 192, 168, 1, 121 }; // my ip
byte server[] = { 98, 136, 86, 109 }; // my smtp server ip
Client client(server, 587);  // yahoo's mobile smtp server ip/port
int time = 5000;
int wait = 2000;

Servo myservo; //declares servo

int switch1 = 1;
int switch2 = 2;
int motor1 = 3;
int relay1 = 4;
int relay2 = 5;


void setup()
{
 
 myservo.attach(9); //attaches servo on pin 9 
 
 pinMode(switch1, INPUT);
 pinMode(switch2, INPUT);
 pinMode(motor1, OUTPUT);
 pinMode(relay1, OUTPUT);
 pinMode(relay2, OUTPUT);
 
 Ethernet.begin(mac, ip);
 
 if (client.connect()) {
                        client.println("HELO itismeletschat"); /* say hello (statement after helo is needed but irrelevant)*/
                          delay(wait); /* wait for a response */

                        client.println("MAIL From: myreprapinfo@yahoo.com"); /* identify sender, this should be the same as the smtp server you are using */
                          delay(wait); /* wait for a response */

                        client.println("RCPT To: drummerboyx@verizon.net"); /* identify recipient */
                        delay(wait); /* wait for a response */

                        client.println("DATA"); 
                          delay(wait); /* wait for a response */
 
                        client.println("To: drummerboyx@verizon.net"); /* identify recipient */
                        client.println("Subject: FishBot online"); /* insert subject */

                        client.println("FishBot has sucsessfully been activated"); /* insert body */
                        client.println("."); /* end email */
 } 
 
 delay(5000); //wait 5 seconds before starting program
 
}

void loop() {
  
while(true) { //manual water change/feeding
  
     if (digitalRead(switch1) == HIGH) { 
     digitalWrite(motor1, HIGH);
     delay(4100);
     digitalWrite(motor1, LOW);
     
                        client.println("HELO itismeletschat"); /* say hello (statement after helo is needed but irrelevant)*/
                          delay(wait); /* wait for a response */

                        client.println("MAIL From: myreprapinfo@yahoo.com"); /* identify sender, this should be the same as the smtp server you are using */
                          delay(wait); /* wait for a response */

                        client.println("RCPT To: drummerboyx@verizon.net"); /* identify recipient */
                        delay(wait); /* wait for a response */

                        client.println("DATA"); 
                          delay(wait); /* wait for a response */
 
                        client.println("To: drummerboyx@verizon.net"); /* identify recipient */
                        client.println("Subject: FishBot feeding"); /* insert subject */

                        client.println("FishBot has feed fish today"); /* insert body */
                        client.println("."); /* end email */
      }
     
   if (digitalRead(switch2) == HIGH) {
     digitalWrite(relay1, HIGH);
     delay(3000); //wait untill tank fills 
     digitalWrite(relay1, LOW);
     delay(500); //stop and wait
     digitalWrite(relay2, HIGH);
     delay(3000); //wait untill tank empties
     digitalWrite(relay2, LOW);
     delay(500); //stop and wait
     
     myservo.write(180); //turns servo w/ water conditioner
     delay(1000);
     myservo.write(0); // puts servo back in nuetral position
     
                           client.println("HELO itismeletschat"); /* say hello (statement after helo is needed but irrelevant)*/
                          delay(wait); /* wait for a response */

                        client.println("MAIL From: myreprapinfo@yahoo.com"); /* identify sender, this should be the same as the smtp server you are using */
                          delay(wait); /* wait for a response */

                        client.println("RCPT To: drummerboyx@verizon.net"); /* identify recipient */
                        delay(wait); /* wait for a response */

                        client.println("DATA"); 
                          delay(wait); /* wait for a response */
 
                        client.println("To: drummerboyx@verizon.net"); /* identify recipient */
                        client.println("Subject: FishBot water change"); /* insert subject */

                        client.println("FishBot has just changed the water in the tank"); /* insert body */
                        client.println("."); /* end email */
   }
}
  

  
while(true) { //auto water change
     delay(604800000); //wait 1 week from start-up (604,800,000 MS)
     digitalWrite(relay1, HIGH);
     delay(3000); //wait untill tank fills 
     digitalWrite(relay1, LOW);
     delay(500); //stop and wait
     digitalWrite(relay2, HIGH);
     delay(3000); //wait untill tank empties
     digitalWrite(relay2, LOW);
     delay(500); //stop and wait
     
     myservo.write(180); //turns servo w/ water conditioner
     delay(1000);
     myservo.write(0); // puts servo back in nuetral position
    
                        client.println("HELO itismeletschat"); /* say hello (statement after helo is needed but irrelevant)*/
                          delay(wait); /* wait for a response */

                        client.println("MAIL From: myreprapinfo@yahoo.com"); /* identify sender, this should be the same as the smtp server you are using */
                          delay(wait); /* wait for a response */

                        client.println("RCPT To: drummerboyx@verizon.net"); /* identify recipient */
                        delay(wait); /* wait for a response */

                        client.println("DATA"); 
                          delay(wait); /* wait for a response */
 
                        client.println("To: drummerboyx@verizon.net"); /* identify recipient */
                        client.println("Subject: FishBot water change"); /* insert subject */

                        client.println("FishBot has just changed the water in the tank"); /* insert body */
                        client.println("."); /* end email */
  }
 

while(true) { //auto feeding
     delay(86400000); //wait 24 hours from start-up (86,400,000 MS)
     digitalWrite(motor1, HIGH);
     delay(4100);
     digitalWrite(motor1, LOW);
     
                           client.println("HELO itismeletschat"); /* say hello (statement after helo is needed but irrelevant)*/
                          delay(wait); /* wait for a response */

                        client.println("MAIL From: myreprapinfo@yahoo.com"); /* identify sender, this should be the same as the smtp server you are using */
                          delay(wait); /* wait for a response */

                        client.println("RCPT To: drummerboyx@verizon.net"); /* identify recipient */
                        delay(wait); /* wait for a response */

                        client.println("DATA"); 
                          delay(wait); /* wait for a response */
 
                        client.println("To: drummerboyx@verizon.net"); /* identify recipient */
                        client.println("Subject: FishBot feeding"); /* insert subject */

                        client.println("FishBot has feed fish today."); /* insert body */
                        client.println("."); /* end email */
   }
 }

I'm still trying to figure out the email send feature. I've seen some people do it without autherization info. So, when I get my ethernet shield in the mail (should be tomorrow) I'll test it out.

Did you notice any problems with the code?

Thanks,
Elijah

Now all you need to do is put a waterproof momentary button in the tank and teach the fish to push it when they get hungry. ;D

Ha! That would be perfect!

teach the fish to push it when they get hungry

But you have to automate the teaching process, because it needs to be re-done every 3 seconds :slight_smile:

But, seriously, it might be interesting to borrow from the design of the Mythbusters maze, and create a separate area of the tank for feeding, with photocells to detect when the fish pass through the partition. For ultimate geekiness, you could use lasers as the light source for the fish detectors, and get double-duty since the visibility of the beam would give you an indication of the level of particulates in the water.

I haven't tried an iPhone app. I am using a Linux machine with Apache web server, Perl, and MySQL to log temps & rainfall, (soon to add humidity & pressure) and to control the furnace. There are multiple perl scripts running. One runs via cron to read sensors and log values into MySQL. Another perl script is the "thermostat" for the house and gets the current temp and current setpoint from MySQL and sends commands to a microcontroller to set fan & heating stage. Other perl scripts are CGI webpages to build graphs from the logged readings in the database, or to change setting for the thermostat via webpage. It's not tied to an iPhone. Any web browser will work.

I haven't fiddled with a webcam in quite a while, but it's not difficult to make it available via a webpage.

BTW: Perl, MySQL, and Apache are all free and available on Windows as well.

So I'm looking at your code, and it looks like you open the connection to the email server when you power on, but you never close or re-open your connection.

I think Yahoo is eventually going to timeout your connection and you'll be sitting there with no server connection.

Before each email (because you're not going to be sending emails very often) you should start your email connection, and at the end of each email block, you should close it again.

Client client(server, port)
 if (client.connect()) {
  client.println("email stuff here")
 }
client.stop();

That way you know you always have a good connection.

Also, you can test out the same stuff you're sending over this client connection by just doing a

telnet ip port
and typing in each line manually.

So you can do this on your local computer:

robglinka@Azrael:~$ telnet 98.136.86.109 587
Trying 98.136.86.109...
Connected to 98.136.86.109.
Escape character is '^]'.
220 smtp109-mob.biz.mail.ac4.yahoo.com ESMTP
ehlo itsme
250-smtp109-mob.biz.mail.ac4.yahoo.com
250-AUTH LOGIN PLAIN XYMCOOKIE
250-PIPELINING
250 8BITMIME
MAIL From: myreprapinfo@yahoo.com
530 authentication required - for help go to http://help.yahoo.com/help/us/mail/pop/pop-11.html

As you can see, as soon as you send your first command, you're going to get an error. That's why you need to send the AUTH command.

Thanks for the info! I'll definatly change that in the code.

Like I said earlier, I'm not sure how to create an autherization with my email and password. I've looked everywhere; but I can't figure it out. Do you know? If so, can you possibly create it for me?

Thanks,
Elijah

Hey, looking at your code a little more... you have a bunch of

while(true) {
   ... this runs over and over
}
while(true) {
   ... this will never run
}

snippits. Those each will loop forever, so as soon as you hit the first one, you're done. You'll never get past that block.

Also, sometimes you wait for a week, sometimes a day... not sure how that's going to do what you expect.

You can use the millis() timer to do your timing without using delays, but there are other pitfalls with that because it has a 45 day overflow.

I wrote a function here that lets you query how many minutes have passed since you're started the Arduino, and it might work better than using your delays, especially if you are waiting a week between actions.

You set two counter variables, and then you can just query getMinutes() this way you can keep track of how many minutes have passed since you started the arduino. Then you can just say:

unsigned long lastWaterChange = 0;
unsigned long lastFeeding = 0;

void loop()
{
 if ( (getMinutes() - lastWaterChange) > 10080 )  // minutes in a week
  {
     < water change code >
     lastWaterChange = getMinutes();
  }
 if ( (getMinutes() - lastFeeding) > 1440 ) // minutes per day
 {
     < feeding code >
    lastFeeding = getMinutes();
 }
}

// useful variables to keep track of millis overflows
unsigned long millisCounter = 0; // needs to be an unsigned long to store millis's.
unsigned int millisOverflows = 0; // int is plenty, cause the minutes will overflow before this hits unsigned maxint.

unsigned long getMinutes()
{
  unsigned long currentMillis = millis(); // grab the current time, cause it's likely to change during execution.
  // max millis = 4,294,967,294. / 1000 for seconds / 60 for minutes = 71582.788. Not sure if rounding down or up is good? 
  // The local timer isn't that accurate, so I guess it doesn't matter. This will gain a minute every 135 days or so.
  unsigned long MAX_MINUTES = 71583;      // how many total minutes are possible before rollover? 

  if (currentMillis < millisCounter) {    // did we overflow? If so, increment the counter.
    millisOverflows += 1; 
  }

  unsigned long currentMinutes = currentMillis / 60000; // calculate the toal minutes on this millis loop.
  unsigned long overflowMinutes = MAX_MINUTES * millisOverflows; // calculate the total minutes of all previous loops.

  millisCounter = currentMillis;  // keep track of what the millis was.
  return (currentMinutes + overflowMinutes); // return the total of the current + previous loops.
}

I CAN, but you'd have to send me your username and password, and if you ever changed your password you'd have to ask for help again.

Google around for getting perl running on your computer, then just type that line into a command line window, it is really probably a lot easier then you expect.

Thanks! I'll try to change my code. I'll post it too as soon as I get it working.

Rob: I just sent you a PM with my UN and PW for my yahoo account.

Thanks again everyone for your help!!

Elijah

Here is the newest code that I've made:

/* 
Made by Elijah Wood
Based off of Rob Glinka's version
Auto fish feeder
From start up, it will feed fish every 24 hours and change the water every week. 
It will send email notifiers to conferm feeding when away from your home.
Made to be used with the Arduino ethernet sheild.
*/

#include <Ethernet.h>
#include <Servo.h> 

byte mac[] = { 0x2, 0x5, 0x1, 0x9, 0x6, 0x4 }; // Arduino's artificial mac address
byte ip[] = { 192, 168, 1, 121 }; // my ip
byte server[] = { 98, 136, 86, 109 }; // my smtp server ip
Client client(server, 587);  // yahoo's mobile smtp server ip/port
int time = 5000;
int wait = 2000;

Servo myservo; //declares servo

int switch1 = 1;
int switch2 = 2;
int motor1 = 3;
int relay1 = 4;
int relay2 = 5;

unsigned long lastWaterChange = 0;
unsigned long lastFeeding = 0;


void setup()
{
 
 myservo.attach(9); //attaches servo on pin 9 
 
 pinMode(switch1, INPUT);
 pinMode(switch2, INPUT);
 pinMode(motor1, OUTPUT);
 pinMode(relay1, OUTPUT);
 pinMode(relay2, OUTPUT);
 
 Ethernet.begin(mac, ip);
 
 if (client.connect()) {
   
   client.println("EHLO MYSERVER");
   delay(wait);
   client.println("AUTH PLAIN ************************************");  // replace the **'s with your auth info from the perl script.
   delay(wait);
   client.println("MAIL FROM:<myreprapinfo@yahoo.com>");
   delay(wait);
   client.println("RCPT TO:<drummerboyx@verizon.net>");
   delay(wait);
   client.println("DATA");
   delay(wait);
   client.println("From: <myreprapinfo@yahoo.com>");
   delay(wait);
   client.println("TO: <drummerboyx@verizon.net>");
   delay(wait);
   client.println("SUBJECT: FishBot has been turned on");
   delay(wait);
   client.println();
   delay(wait);
   client.println("FishBot has been turned on");
   delay(wait);
   client.println("FishBot has sucsessfully emailed Elijah Wood! YAY!");
   delay(wait);
   client.println(".");
   delay(wait);
   client.println(".");
                        
   client.stop();
 } 
 
 delay(5000); //wait 5 seconds before starting program
 
}

void loop() {
 
     if (digitalRead(switch1) == HIGH) { 
     digitalWrite(motor1, HIGH);
     delay(4100);
     digitalWrite(motor1, LOW);

Client client(server, 587);
                        
if (client.connect()) {
                        
      client.println("EHLO MYSERVER");
   delay(wait);
   client.println("AUTH PLAIN ************************************");  // replace the **'s with your auth info from the perl script.
   delay(wait);
   client.println("MAIL FROM:<myreprapinfo@yahoo.com>");
   delay(wait);
   client.println("RCPT TO:<drummerboyx@verizon.net>");
   delay(wait);
   client.println("DATA");
   delay(wait);
   client.println("From: <myreprapinfo@yahoo.com>");
   delay(wait);
   client.println("TO: <drummerboyx@verizon.net>");
   delay(wait);
   client.println("SUBJECT: FishBot has feed the fish today");
   delay(wait);
   client.println();
   delay(wait);
   client.println("FishBot has feed the fish today");
   delay(wait);
   client.println("FishBot has sucsessfully emailed Elijah Wood! YAY!");
   delay(wait);
   client.println(".");
   delay(wait);
   client.println(".");
                        
client.stop();
                        
      }
     }
 
    


   
   if (digitalRead(switch2) == HIGH) {
     digitalWrite(relay1, HIGH);
     delay(3000); //wait untill tank fills 
     digitalWrite(relay1, LOW);
     delay(500); //stop and wait
     digitalWrite(relay2, HIGH);
     delay(3000); //wait untill tank empties
     digitalWrite(relay2, LOW);
     delay(500); //stop and wait
     
     myservo.write(180); //turns servo w/ water conditioner
     delay(1000);
     myservo.write(0); // puts servo back in nuetral position
     
                         Client client(server, 587);
                         
                         
    if (client.connect()) {
      
      client.println("EHLO MYSERVER");
   delay(wait);
   client.println("AUTH PLAIN ************************************");  // replace the **'s with your auth info from the perl script.
   delay(wait);
   client.println("MAIL FROM:<myreprapinfo@yahoo.com>");
   delay(wait);
   client.println("RCPT TO:<drummerboyx@verizon.net>");
   delay(wait);
   client.println("DATA");
   delay(wait);
   client.println("From: <myreprapinfo@yahoo.com>");
   delay(wait);
   client.println("TO: <drummerboyx@verizon.net>");
   delay(wait);
   client.println("SUBJECT: FishBot has just changed the water in the tank");
   delay(wait);
   client.println();
   delay(wait);
   client.println("FishBot has just changed the water in the tank");
   delay(wait);
   client.println("FishBot has sucsessfully emailed Elijah Wood! YAY!");
   delay(wait);
   client.println(".");
   delay(wait);
   client.println(".");
                        
client.stop();
    }
   }
 
  
  
  
  
  
  
  
if ( (getMinutes() - lastWaterChange) > 10080 )  // minutes in a week
  {
     digitalWrite(relay1, HIGH);
     delay(3000); //wait untill tank fills 
     digitalWrite(relay1, LOW);
     delay(500); //stop and wait
     digitalWrite(relay2, HIGH);
     delay(3000); //wait untill tank empties
     digitalWrite(relay2, LOW);
     delay(500); //stop and wait
     
     myservo.write(180); //turns servo w/ water conditioner
     delay(1000);
     myservo.write(0); // puts servo back in nuetral position
     
                        Client client(server, 587);
                        
    if (client.connect()) {
      
      client.println("EHLO MYSERVER");
   delay(wait);
   client.println("AUTH PLAIN ************************************");  // replace the **'s with your auth info from the perl script.
   delay(wait);
   client.println("MAIL FROM:<myreprapinfo@yahoo.com>");
   delay(wait);
   client.println("RCPT TO:<drummerboyx@verizon.net>");
   delay(wait);
   client.println("DATA");
   delay(wait);
   client.println("From: <myreprapinfo@yahoo.com>");
   delay(wait);
   client.println("TO: <drummerboyx@verizon.net>");
   delay(wait);
   client.println("SUBJECT: FishBot has just changed the water in the tank");
   delay(wait);
   client.println();
   delay(wait);
   client.println("FishBot has sucsessfully chagned the water in the tank");
   delay(wait);
   client.println("FishBot has sucsessfully emailed Elijah Wood! YAY!");
   delay(wait);
   client.println(".");
   delay(wait);
   client.println(".");
                        
client.stop();
    }
  
     lastWaterChange = getMinutes();
  }
  
  
 if ( (getMinutes() - lastFeeding) > 1440 ) // minutes per day
 {
     delay(86400000); //wait 24 hours from start-up (86,400,000 MS)
     digitalWrite(motor1, HIGH);
     delay(4100);
     digitalWrite(motor1, LOW);
     
                        Client client(server, 587);
                        
 if (client.connect()) {
     
      client.println("EHLO MYSERVER");
   delay(wait);
   client.println("AUTH PLAIN ************************************");  // replace the **'s with your auth info from the perl script.
   delay(wait);
   client.println("MAIL FROM:<myreprapinfo@yahoo.com>");
   delay(wait);
   client.println("RCPT TO:<drummerboyx@verizon.net>");
   delay(wait);
   client.println("DATA");
   delay(wait);
   client.println("From: <myreprapinfo@yahoo.com>");
   delay(wait);
   client.println("TO: <drummerboyx@verizon.net>");
   delay(wait);
   client.println("SUBJECT: FishBot has feed the fish today");
   delay(wait);
   client.println();
   delay(wait);
   client.println("FishBot has sucsessfully feed the fish");
   delay(wait);
   client.println("FishBot has sucsessfully emailed Elijah Wood! YAY!");
   delay(wait);
   client.println(".");
   delay(wait);
   client.println(".");
                        
client.stop();

    }
    lastFeeding = getMinutes();
 } 
}


// useful variables to keep track of millis overflows
unsigned long millisCounter = 0; // needs to be an unsigned long to store millis's.
unsigned int millisOverflows = 0; // int is plenty, cause the minutes will overflow before this hits unsigned maxint.

unsigned long getMinutes()
{
  unsigned long currentMillis = millis(); // grab the current time, cause it's likely to change during execution.
  // max millis = 4,294,967,294. / 1000 for seconds / 60 for minutes = 71582.788. Not sure if rounding down or up is good?
  // The local timer isn't that accurate, so I guess it doesn't matter. This will gain a minute every 135 days or so.
  unsigned long MAX_MINUTES = 71583;      // how many total minutes are possible before rollover?

  if (currentMillis < millisCounter) {    // did we overflow? If so, increment the counter.
    millisOverflows += 1;
  }

  unsigned long currentMinutes = currentMillis / 60000; // calculate the toal minutes on this millis loop.
  unsigned long overflowMinutes = MAX_MINUTES * millisOverflows; // calculate the total minutes of all previous loops.

  millisCounter = currentMillis;  // keep track of what the millis was.
  return (currentMinutes + overflowMinutes); // return the total of the current + previous loops.
}

Now, I'll replace the auth info **** with the accually info once I get it from rob.

Thanks again so much for all of your help!

Elijah

Completely off topic... Elijah... is this you?

pwillard, yes that is me! I play drums with my Dad's music education program! I'm in high school now (I know, a little young to be doing this kind of stuff) and I'm just starting to get into coding and the Arduino. This is all a learning experiance for me.

That's really funny that you found that! :wink:

Elijah

I know, a little young to be doing this kind of stuff

No, you're not.

Maybe someday I'll post a long rant in Bar Sport about this, but I think it's vitally important to the future, especially of the U.S., but also of the whole planet, that we have high school students, and even grade school students, actively interested in activities like tinkering with Arduinos and learning how to make stuff work. Encouraging people who are trying to learn is one of the best investments of our time we can make.

(Which is also why I occasionally bitch about people whose idea of "education" is getting forum members to design their college projects for them: having people who can pretend to solve problems in the workforce is almost as bad for technological progress as having people who can't even do that >:()

Ran

Finding you... Neat trick, huh? I so admire good drummers.

You are not too young by the way! Go for it.

My father was an Electronics engineer and he realized I had an interest when I was about 13. By the time I was a senior in High School I pretty much already knew more than my Physics textbook could teach me about electronics. I did a senior electronics project for the science fair about about advancements in electronics and semiconductor theory which sort of blew people away. Granted, it was 1977 then. I pursued a different career... but I have always kept this geeky stuff going on around me. It never hurts to understand how to make electronic things...

Great! Thanks everybody for their comments!

I think I just finished the code:

/* 
Made by Elijah Wood
Based off of Rob Glinka's version
Auto fish feeder
From start up, it will feed fish every 24 hours and change the water every week. 
It will send email notifiers to conferm feeding when away from your home.
Made to be used with the Arduino ethernet sheild.
*/

#include <Ethernet.h>
#include <Servo.h> 

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xAF, 0xCE, 0xDD }; // whatever mac you want
byte ip[] = { 192, 168, 1, 100 };
byte server[] = { 98, 136, 86, 109 }; // Mail server address  (this is for yahoo's mobile smtp

int time = 5000;

Servo myservo; //declares servo

int LED = 2;
int motor1 = 9;
int relay1 = 8;
int relay2 = 7;
int switch1 = 3;
int switch2 = 4;

unsigned long lastWaterChange = 0;
unsigned long lastFeeding = 0;


void setup()
{
  
 myservo.attach(1); //attaches servo on pin 9 
 
 pinMode(switch1, INPUT);
 pinMode(switch2, INPUT);
 pinMode(LED, OUTPUT);
 pinMode(motor1, OUTPUT);
 pinMode(relay1, OUTPUT);
 pinMode(relay2, OUTPUT);
 
 Ethernet.begin(mac, ip);
 
 Client client(server, 587);  // yahoo's mobile smtp server ip/port

if (client.connect()) {
   client.println("EHLO MYSERVER");
   client.println("AUTH PLAIN *************************************==");  // replace the **'s with your auth info from the perl script.
   client.println("MAIL FROM:<myreprapinfo@yahoo.com>");
   client.println("RCPT TO:<drummerboyx@verizon.net>");
   client.println("DATA");
   client.println("From: <myreprapinfo@yahoo.com>");
   client.println("TO: <drummerboyx@verizon.net>");
   client.println("SUBJECT: FishBot");
   client.println();
   client.println("FishBot has just been activated");
   client.println("Sincerly, FishBot");
   client.println(".");
   client.println(".");
   client.println("QUIT");
                        
   client.stop();
}
 
 delay(1000); //wait 1 seconds before starting program
 
}

void loop() {
  
  digitalWrite(LED, HIGH); //turns on program light
 
 delay(1000);
 
 if (digitalRead(switch1) == HIGH) {
  digitalWrite(motor1, HIGH);
  delay(4100);
  digitalWrite(motor1, LOW);
  
   Client client(server, 587);
  
if (client.connect()) {
   client.println("EHLO MYSERVER");
   client.println("AUTH PLAIN *******************************************==");  // replace the **'s with your auth info from the perl script.
   client.println("MAIL FROM:<myreprapinfo@yahoo.com>");
   client.println("RCPT TO:<drummerboyx@verizon.net>");
   client.println("DATA");
   client.println("From: <myreprapinfo@yahoo.com>");
   client.println("TO: <drummerboyx@verizon.net>");
   client.println("SUBJECT: FishBot");
   client.println();
   client.println("You have manually fed the fish");
   client.println("Sincerly, FishBot");
   client.println(".");
   client.println(".");
   client.println("QUIT");
   client.stop();

 }
 }
 
 if (digitalRead(switch2) == HIGH) {
     digitalWrite(relay1, HIGH);
     delay(3000); //wait untill tank fills 
     digitalWrite(relay1, LOW);
     delay(500); //stop and wait
     digitalWrite(relay2, HIGH);
     delay(3000); //wait untill tank empties
     digitalWrite(relay2, LOW);
     delay(500); //stop and wait
     
     myservo.write(180); //turns servo w/ water conditioner
     delay(1000);
     myservo.write(0); // puts servo back in nuetral position
     
   Client client(server, 587);
   
if (client.connect()) {
   client.println("EHLO MYSERVER");
   client.println("AUTH PLAIN ****************************************************==");  // replace the **'s with your auth info from the perl script.
   client.println("MAIL FROM:<myreprapinfo@yahoo.com>");
   client.println("RCPT TO:<drummerboyx@verizon.net>");
   client.println("DATA");
   client.println("From: <myreprapinfo@yahoo.com>");
   client.println("TO: <drummerboyx@verizon.net>");
   client.println("SUBJECT: FishBot");
   client.println();
   client.println("You have just manually changed the water in the tank");
   client.println("Sincerly, FishBot");
   client.println(".");
   client.println(".");
   client.println("QUIT");
   client.stop();
}
 }




    
  
   if ( (getMinutes() - lastFeeding) > 1440 ) // minutes per day
 {
     digitalWrite(motor1, HIGH);
     delay(4100);
     digitalWrite(motor1, LOW);
     
   Client client(server, 587);

if (client.connect()) {
   client.println("EHLO MYSERVER");
   client.println("AUTH PLAIN **********************************************==");  // replace the **'s with your auth info from the perl script.
   client.println("MAIL FROM:<myreprapinfo@yahoo.com>");
   client.println("RCPT TO:<drummerboyx@verizon.net>");
   client.println("DATA");
   client.println("From: <myreprapinfo@yahoo.com>");
   client.println("TO: <drummerboyx@verizon.net>");
   client.println("SUBJECT: FishBot");
   client.println();
   client.println("FishBot has just fed the fish today automaticly");
   client.println("Sincerly, FishBot");
   client.println(".");
   client.println(".");
   client.println("QUIT");
   client.stop();
}

    lastFeeding = getMinutes(); 
 }

  
if ( (getMinutes() - lastWaterChange) > 10080 )  // minutes in a week
  {
     digitalWrite(relay1, HIGH);
     delay(3000); //wait untill tank fills 
     digitalWrite(relay1, LOW);
     delay(500); //stop and wait
     digitalWrite(relay2, HIGH);
     delay(3000); //wait untill tank empties
     digitalWrite(relay2, LOW);
     delay(500); //stop and wait
     
     myservo.write(180); //turns servo w/ water conditioner
     delay(1000);
     myservo.write(0); // puts servo back in nuetral position
     
     Client client(server, 587);
     
if (client.connect()) {
   client.println("EHLO MYSERVER");
   client.println("AUTH PLAIN ***********************************************==");  // replace the **'s with your auth info from the perl script.
   client.println("MAIL FROM:<myreprapinfo@yahoo.com>");
   client.println("RCPT TO:<drummerboyx@verizon.net>");
   client.println("DATA");
   client.println("From: <myreprapinfo@yahoo.com>");
   client.println("TO: <drummerboyx@verizon.net>");
   client.println("SUBJECT: FishBot");
   client.println();
   client.println("FishBot has just changed the water in the tank automaticly");
   client.println("Sincerly, FishBot");
   client.println(".");
   client.println(".");
   client.println("QUIT");
   client.stop();
}

     lastWaterChange = getMinutes();
  }
}

// useful variables to keep track of millis overflows
unsigned long millisCounter = 0; // needs to be an unsigned long to store millis's.
unsigned int millisOverflows = 0; // int is plenty, cause the minutes will overflow before this hits unsigned maxint.

unsigned long getMinutes()
{
  unsigned long currentMillis = millis(); // grab the current time, cause it's likely to change during execution.
  // max millis = 4,294,967,294. / 1000 for seconds / 60 for minutes = 71582.788. Not sure if rounding down or up is good?
  // The local timer isn't that accurate, so I guess it doesn't matter. This will gain a minute every 135 days or so.
  unsigned long MAX_MINUTES = 71583;      // how many total minutes are possible before rollover?

  if (currentMillis < millisCounter) {    // did we overflow? If so, increment the counter.
    millisOverflows += 1;
  }

  unsigned long currentMinutes = currentMillis / 60000; // calculate the toal minutes on this millis loop.
  unsigned long overflowMinutes = MAX_MINUTES * millisOverflows; // calculate the total minutes of all previous loops.

  millisCounter = currentMillis;  // keep track of what the millis was.
  return (currentMinutes + overflowMinutes); // return the total of the current + previous loops.
}

It sucsessfully emails me and it runs everything properly.

But...I want to be able to control it manually via my iphone when I'm away. I'm thinking maybe a web app that can tell me the temp/ph/last water change/last feeding and have 2 buttons for manually feeding and water changes.

Has anyone tried to do anything similar to this(sending and receiving data between the iphone and the arduino)?

Thanks,
Elijah

HI,
i'm also making a fish feeder, can you post some pictures or video from your project?

Thanks!