Casey JacobsonGreg Kerchmar
Published

Automatic Dog Feeder

This is not only a device that will feed your dog for you, but it will also let you know when it is time to buy more food for your pup.

IntermediateFull instructions provided5 hours2,123
Automatic Dog Feeder

Things used in this project

Story

Read more

Schematics

Button Board

This board contains the button circuit and photon, which is the primary "brain" of the system. This configuration has two primary purposes: to find the time of day and compare that to the required feed times, and to read the output of the button to determine if the food weight is above or below the threshold required to refill. This information is then sent through a wireless connection to the servo photon to administer the feeding, as well as determine which color LEDs must be displayed.

Servo and LED Board

This board is considered the secondary and weights for input from the button board to proceed. After this board receives the notice to feed and display an LED color, it informs the primary button board of the successful feeding, and waits for a second weight reading to display a final LED color.

Code

DogFeederButton

C/C++
The code displayed here is the brain of the dual photon system, and is downloaded to the photon which is connected to the button circuit. The purpose of this circuit is to activate at the specified time, determine the status of the food inside the container, and send the appropriate response to the second photon. In addition, if the second photon activates a feed, this photon rechecks the status of the food container and updates the second photon with the LEDs.
//Ports
int SensRead = D1;
int SensWrite = D0;
int delayShort = 1000;
int delayLong = 5000;
int delayLong2 = 60000;

void setup() {
    Particle.subscribe("Servo", myHandler);
    pinMode(SensWrite, OUTPUT);
    pinMode(SensRead, INPUT);
    Time.zone(-4);
}

void loop() {
    if (Time.hour() == 8 && Time.minute() == 0 && Time.second() >= 0) {
        digitalWrite(SensWrite, HIGH);
        delay(delayShort);
        if(digitalRead(SensRead)==1){
            Particle.publish("Message","servo");
            String Weight = String(digitalRead(SensRead));
            Particle.publish("Food Quantity Threshold", Weight, PUBLIC);
            delay(delayLong);
        }
        else {
            Particle.publish("Message","red");
            String Weight = String(digitalRead(SensRead));
            Particle.publish("Food Quantity Threshold", Weight, PUBLIC);
            delay(delayLong);
        }
    }
    else if (Time.hour() == 13 && Time.minute() == 0 && Time.second() >= 0) {
        digitalWrite(SensWrite, HIGH);
        delay(delayShort);
        if(digitalRead(SensRead)==1){
            Particle.publish("Message","servo");
            String Weight = String(digitalRead(SensRead));
            Particle.publish("Food Quantity Threshold", Weight, PUBLIC);
            delay(delayLong);
        }
        else {
            Particle.publish("Message","red");
            String Weight = String(digitalRead(SensRead));
            Particle.publish("Food Quantity Threshold", Weight, PUBLIC);
            delay(delayLong);
        }
    }
    else if (Time.hour() == 19 && Time.minute() == 0 && Time.second() >= 0) {
        digitalWrite(SensWrite, HIGH);
        delay(delayShort);
        if(digitalRead(SensRead)==1){
            Particle.publish("Message","servo");
            String Weight = String(digitalRead(SensRead));
            Particle.publish("Food Quantity Threshold", Weight, PUBLIC);
            delay(delayLong);
        }
        else {
            Particle.publish("Message","red");
            String Weight = String(digitalRead(SensRead));
            Particle.publish("Food Quantity Threshold", Weight, PUBLIC);
            delay(delayLong);
        }
    }
}

void myHandler(const char *event, const char *data) {
    if(strcmp(data, "fed")==0) {
        if(digitalRead(SensRead)==1){
            Particle.publish("Message","green");
            String Weight = String(digitalRead(SensRead));
            Particle.publish("Food Quantity Threshold", Weight, PUBLIC);
            delay(delayLong2);
        }
        else {
            Particle.publish("Message","red");
            String Weight = String(digitalRead(SensRead));
            Particle.publish("Food Quantity Threshold", Weight, PUBLIC);
            delay(delayLong2);
        }
    }
    else {
        
    }
}

DogFeederServo

C/C++
This photon is secondary to the DogFeederButton photon, and waits until the button photons tells it to do anything. When activated by the code telling it to display green, display red, or both display green and run the servo motor, it responds by completing the corresponding action. If the servo photon successfully completes the feed, it informs the primary photon, waits for further command, and then is told to display another light for the post-feed food status.
//Ports
int servoPin = D0;
int LEDred = D3;
int LEDgreen = D4;

//Constants
int InitPos = 20;
int FeedPos = 110;
int FeedDelay = 2000;
int longDelay = 15000;

//Servo Setup
Servo FeederServo; 

void setup() {
    FeederServo.attach(servoPin);
    Particle.subscribe("Message", myHandler);
    pinMode(LEDred, OUTPUT);
    pinMode(LEDgreen, OUTPUT);
}



void myHandler(const char *event, const char *data) {
    if(strcmp(data,"servo")==0) {
        digitalWrite(LEDgreen, HIGH);
        digitalWrite(LEDred, LOW);
        FeederServo.write(FeedPos);
        delay(FeedDelay);
        FeederServo.write(InitPos);
        Particle.publish("Servo", "fed");
    }
    else if(strcmp(data,"red")==0) {
        digitalWrite(LEDgreen, LOW);
        digitalWrite(LEDred, HIGH);
        Particle.publish("Servo", "not_fed");
    }
    else if(strcmp(data,"green")==0) {
        digitalWrite(LEDgreen, HIGH);
        digitalWrite(LEDred, LOW);
        Particle.publish("Servo", "not_fed");
    }
}

Credits

Casey Jacobson

Casey Jacobson

1 project • 2 followers
Greg Kerchmar

Greg Kerchmar

0 projects • 2 followers

Comments