49-713 Designing for the Internet of Things
· 26 members
A hands-on introductory course exploring the Internet of Things and connected product experiences.
Unlike dogs, it’s impossible to find a fish sitter for my world traveling Mother. That’s why I made her an automatic fish feeder. #Homehack
Fat Fish Feeder:
My mother is a world traveler and it’s a problem for her pet Betta fish. Unlike dogs, it’s impossible to find a fish sitter. That’s why I find an automatic fish feeder to be a great #Homehack for her. This automatic fish feeder will only be used when my mother is not home so it’s essential to have an on/off switch with an LED to indicate that the feeder is on before she leaves. The fish feeder will have a servo that will roll the fish food canister once every 24 hours and drop the food into the fish tank. The feeder will text my mother once the fishes are fed.
//FINISHED CODE
int ledPin = D1;
Servo fatFishFeeder;
int buttonPin = D0;
int servoPin = A5;
int servoPos = 5;
long timeBeforeSomethingHappens = 24 * 60 * 60 * 1000;
bool counterRunning = false;
long counterStartedAt = 0;
//bool isTriggered = false;
void setup()
{
pinMode( buttonPin , INPUT_PULLUP);
pinMode( ledPin , OUTPUT );
fatFishFeeder.attach( A5 );
Particle.function("servo", servoControl);
Particle.variable ("servoPos", &servoPos, INT);
bool count = checkIfCOunterIsFInished();
Particle.variable("counter",&count);
}
void loop()
{
int buttonState = digitalRead( buttonPin );
if( buttonState == LOW )
{
if(!counterRunning)
startCounter();
digitalWrite( ledPin, HIGH);
}
else
{
digitalWrite( ledPin, LOW);
fatFishFeeder.write(5);
}
if (checkIfCOunterIsFInished())
{
digitalWrite( ledPin, HIGH);
fatFishFeeder.write(180);
Particle.publish("Fat_Fish_Fed", "Fed");
delay(2000);
fatFishFeeder.write(5);
counterRunning = false;
}
if( buttonState == HIGH )
{
counterRunning = false;
digitalWrite( ledPin, LOW);
fatFishFeeder.write(5);
}
}
int servoControl(String command)
{
int newPos = command.toInt();
servoPos = constrain( newPos, 5 , 180);
fatFishFeeder.write( servoPos );
return 1;
}
void startCounter()
{
counterRunning = true;
counterStartedAt = millis();
}
bool checkIfCOunterIsFInished()
{
if (counterRunning == false){
return false;
}
if (counterStartedAt + timeBeforeSomethingHappens < millis() )
{
return true;
}
return false;
}
Click to Expand
Challenges:
Merging two outputs into one circuit was not very hard, but making the code work the way I wanted to was quite tricky.
The plan was to have the servo turn once every 24 hours after the switch is switched on. Using a delay function blocks the rest of the code, therefore using a counter makes more sense. However, this code is very unfamiliar to me so it took a while to apply it to the complete code. With some help from my colleagues, I manged to figure out to work the feeder the way I wanted to.
//CODE WITH DELAY
int ledPin = D1;
Servo fatFishFeeder;
int buttonPin = D0;
int servoPin = A5;
int servoPos = 5;
void setup()
{
pinMode( buttonPin , INPUT_PULLUP); // sets pin as input
pinMode( ledPin , OUTPUT ); // sets pin as output
fatFishFeeder.attach( A5 );
Particle.function("servo", servoControl);
Particle.variable ("servoPos", &servoPos, INT);
}
void loop()
{
int buttonState = digitalRead( buttonPin );
if( buttonState == LOW )
{
// turn the LED On
digitalWrite( ledPin, HIGH);
fatFishFeeder.write(180);
Particle.publish("Fat_Fish_Fed", "Fed");
delay(2000);
fatFishFeeder.write(5);
delay(60000);
}else{
digitalWrite( ledPin, LOW);
fatFishFeeder.write(5);
}
//delay(1000);
}
int servoControl(String command)
{
// Convert
int newPos = command.toInt();
// Make sure it is in the right range
// And set the position
servoPos = constrain( newPos, 5 , 180);
// Set the servo
fatFishFeeder.write( servoPos );
// done
return 1;
}
Click to Expand
//FIRST ATTEMPT WITH COUNTER
int ledPin = D1;
Servo fatFishFeeder;
int buttonPin = D0;
int servoPin = A5;
int servoPos = 5;
long timeBeforeSomethingHappens = 10 * 1000;
bool counterRunning = false;
long counterStartedAt = 0;
void setup()
{
pinMode( buttonPin , INPUT_PULLUP);
pinMode( ledPin , OUTPUT );
fatFishFeeder.attach( A5 );
Particle.function("servo", servoControl);
Particle.variable ("servoPos", &servoPos, INT);
}
void loop()
{
int buttonState = digitalRead( buttonPin );
if( buttonState == LOW )
{
startCounter();
digitalWrite( ledPin, HIGH);
fatFishFeeder.write(180);
// Particle.publish("Fat_Fish_Fed", "Fed");
delay(2000);
fatFishFeeder.write(5);
// delay(2000);
if(checkIfCOunterIsFInished() )
{counterRunning = false;
}
delay (10000);
}else{
digitalWrite( ledPin, LOW);
fatFishFeeder.write(5);
}
}
int servoControl(String command)
{
int newPos = command.toInt();
servoPos = constrain( newPos, 5 , 180);
fatFishFeeder.write( servoPos );
return 1;
}
void startCounter()
{
counterRunning = true;
counterStartedAt = millis();
}
bool checkIfCOunterIsFInished()
{
if (counterRunning == false){
return false;
}
if (counterStartedAt + timeBeforeSomethingHappens < millis() )
{
return true;
}
return false;
}
Click to Expand
//SECOND ATTEMPT WITH COUNTER
int ledPin = D1;
Servo fatFishFeeder;
int buttonPin = D0;
int servoPin = A5;
int servoPos = 5;
long timeBeforeSomethingHappens = 2 * 1000;
bool counterRunning = false;
long counterStartedAt = 0;
bool isTriggered = false;
void setup()
{
pinMode( buttonPin , INPUT_PULLUP);
pinMode( ledPin , OUTPUT );
fatFishFeeder.attach( A5 );
Particle.function("servo", servoControl);
Particle.variable ("servoPos", &servoPos, INT);
/*bool count = checkIfCOunterIsFInished();
Particle.variable("counter",&count);*/
}
void loop()
{
int buttonState = digitalRead( buttonPin );
if( buttonState == LOW )
{
startCounter();
digitalWrite( ledPin, HIGH);
// fatFishFeeder.write(180);
// Particle.publish("Fat_Fish_Fed", "Fed");
// delay(2000);
// fatFishFeeder.write(5);
}
else
{
digitalWrite( ledPin, LOW);
//fatFishFeeder.write(5);
}
if (checkIfCOunterIsFInished() )
{
digitalWrite( ledPin, LOW);
fatFishFeeder.write(180);
//Particle.publish("Fat_Fish_Fed", "Fed");
delay(2000);
fatFishFeeder.write(5);
counterRunning = false;
// I have to add another code where it stops here and not go back up to the loop
// because right now it kept on going back up to line 31 and turning down
// delay(2000);
}
}
int servoControl(String command)
{
int newPos = command.toInt();
servoPos = constrain( newPos, 5 , 180);
fatFishFeeder.write( servoPos );
return 1;
}
void startCounter()
{
counterRunning = true;
counterStartedAt = millis();
}
bool checkIfCOunterIsFInished()
{
if (counterRunning == false){
return false;
}
if (counterStartedAt + timeBeforeSomethingHappens < millis() )
{
return true;
}
return false;
}
Click to Expand
Reflection:
As it was mentioned previously, setting up the circuit wasn't really hard. The hard part is trying to create the right code to make the circuit work the way I wanted to.
With this project, I learned how to read code better and how to connect several inputs and outputs together. After several days of debugging the code, I finally get to where I wanted to.
A hands-on introductory course exploring the Internet of Things and connected product experiences.
Unlike dogs, it’s impossible to find a fish sitter for my world traveling Mother. That’s why I made her an automatic fish feeder. #Homehack
January 25th, 2017