Things used in this project

Hardware components:
Mfr 25frf52 1k sml
Resistor 1k ohm
×4
LM317T Voltage Regulator
Used this to step the voltage down from the 6.5V to 5V to operate the photon
×1
Photon new
Particle Photon
×2
6.6V/2500maH Power supply by DigiPower
I already had one of these in the garage.
×1
MG958 Servo Motor
×1
13285 01
PIR Motion Sensor (generic)
From the maker kit
×1
PlexiGlass .75'' thick (servo mount)
Had a piece of this already. You can actually make this mount out of something cheaper.
×1
EMAX ES08A Micro Servo Motor (photon maker kit)
From the maker kit
×1
12002 04
Breadboard (generic)
×2
Adafruit industries ada830 image 75px
4xAA battery holder
×1
1/4-20 Socket Head Cap Screws
Use one at full length for the upper bolt hole in the servo mount. Shorten the one for the lower mount to 1/2.
×2
11026 02
Jumper wires (generic)
×32
61vhxtmzbyl
AA Batteries
×4
09590 01
LED (generic)
×2
Steel Round Rod: 0.066" Diameter, 36" Length
×1
45 2719133f d90e 4f08 9a52 b5c9ba10eb77 large
Onion OLED Expansion
×1
Shadow Box Frame
×1
Used Food Dispenser
×1
Drinking Straw
×1
Software apps and online services:
Hackster
ThingSpeak API
Fritzing For Building Circuits
Mobicle 1024
ControlEverything.com Mobicle
Hand tools and fabrication machines:
ENCO Knee Mill 100 5200
1/2 End Mill
Use this to shape the servo mount and clearance the dispenser for wiring.
1/4 Drill Bit
Use this to drill the holes in the servo mount for the 1/4-20 fasteners.
8mm End MIll
Use this to counter sink the upper socket head cap screw in the servo mount.
Screwdriver
Box Cutter
Scissor
Super Glue
Foam Board

Custom parts and enclosures

Servo Mount Blueprint
This is a blueprint of the servo mount for the pet feeder.
Servomount moxszcqazv

Schematics

Pet Feeder wiring schematic
This is the wiring schematic used for the circuit in the pet feeder. The servo and open wire going to the LM317 voltage regulator are connected to a 6.6V power supply.
Pet feeder schematic1 2lvs4vmnjz
Shadow Box Frame Wiring Schematic
This is the wiring schematic used for the circuit in the Shadow Box Frame to display how many times the pet eats by using a servo motor that moves certain degrees every time the pet eats which changes from Skinny cat to Fatty cat during the day.
Shadow box frame for iot project hczpokgaly

Code

Pet_Feeder_CodeArduino
This is the code used on the photon that was on the pet feeder. It signals the mg958 servo to actuate the lever on the pet food dispenser and publishes an event to the cloud. It also reads the status of a PIR sensor and publishes a count to thingspeak. It also operates the OLED display.
// This #include statement was automatically added by the Particle IDE.
#include <Adafruit_SSD1306.h>

Servo myservo;  // create servo object to control a servo
                // a maximum of eight servo objects can be created

int pos = 0;    // variable to store the servo position
int displayTime(); //displaytime function
int inputPin = D0; // choose the input pin (for PIR sensor)
int ledPin = D7; //Onboard LED pin
int ledPin2 = D3;// LED Pin for showcase function
int pirState = LOW; // assuming no motion detected
int val = 0; // variable for reading the pin status
int count = 0;//count for the thingspeakwriteall
int calibrateTime = 10000;// wait for the calibration
int Feedings = 0;//initial feedings 

#define OLED_DC     D2 //Pin out for the OLED Display
#define OLED_CS     D4 //   "   "   "   "   "   "
#define OLED_RESET  D5 //  "   "   "   "   "   "
Adafruit_SSD1306 display(OLED_DC, OLED_RESET, OLED_CS); //OLED Display function
 int  x, minX;

const String key = "write-key-here"; //Thing Speak write key
Timer timer3(15000, updateThingspeak); //Calls Thingspeak every 15000 ms

void setup()
{
  Particle.function("feed", feedf);  // create a function called "feedf" 
  Particle.function("Showcase",Showcasef); // create a function called "Showcasef"                                     
    timer3.start(); //initialize timer3 for thingspeakwrite all
    myservo.attach(D1);  // attach the servo on the D1 pin to the servo object
    myservo.write(0);    // Start from position 0 degree
    pinMode(ledPin,OUTPUT); //Sets D7 as an output
    pinMode( ledPin2, OUTPUT); // Sets showcase LED pin as an output
    pinMode(inputPin, INPUT);  // declare PIR sensor as input
    //Particle.subscribe("Feed", myHandler); //Subscribes to operate the OLED display
    Time.zone(-5); //Sets the time zone for eastern time
    Serial.begin(9600); //Begins the serial print

  display.begin(SSD1306_SWITCHCAPVCC);
  display.setTextSize(1);       // text size for OLED display
  display.setTextColor(WHITE); // text color for OLED display
  display.setTextWrap(false); // turn off text wrapping so we can do scrolling
}

int feedf(String command)   // Command function for mg958 servo to actuate the feed lever
{                          // be accompanied by a string.
    if(command == "morning")   // if the string is "feed now", feed once.
    {          
        Particle.publish("Feed","morning"); //publishes "Feed" event to the cloud
        oled();
        myservo.write(180);       // move servo to 180 degrees
        digitalWrite(D7, HIGH); // flash the LED (as an indicator)
        delay(800);             // wait 800 ms
        myservo.write(0);      // move servo to 0
        digitalWrite(D7, LOW);  // turn off LED
        return 1;               // return a status of "1"
    }
    
    else if(command == "lunch")   // if the string is "feed now", feed once.
    {          
        Particle.publish("Feed","lunch"); //publishes "Feed" event to the cloud
        oled();
        myservo.write(180);       // move servo to 180 degrees
        digitalWrite(D7, HIGH); // flash the LED (as an indicator)
        delay(800);             // wait 800 ms
        myservo.write(0);      // move servo to 0
        digitalWrite(D7, LOW);  // turn off LED
        return 1;               // return a status of "1"
    }
    
   else if(command == "dinner")   // if the string is "feed now", feed once.
    {          
        Particle.publish("Feed","dinner"); //publishes "Feed" event to the cloud
        oled();
        myservo.write(180);       // move servo to 180 degrees
        digitalWrite(D7, HIGH); // flash the LED (as an indicator)
        delay(800);             // wait 800 ms
        myservo.write(0);      // move servo to 0
        digitalWrite(D7, LOW);  // turn off LED
        return 1;               // return a status of "1"
    }
    
}

int Showcasef(String command) //Command function for turning the light on/off for viewing the circuit inside once installed in the feeder
{
    if(command == "On")
    {
        digitalWrite(ledPin2, HIGH); //Turns on white led on pin D3
    }
    else if(command == "Off")
    {
        digitalWrite(ledPin2, LOW); //Turns off whit led on pin D3
    }
}

void loop()
{
  
  if ( calibrated() )// if the sensor is calibrated
  {
  
    readTheSensor();// get the data from the sensor

     reportTheData();// report it out, if the state has changed
  
   }
    else {}
  
}

void readTheSensor() { //Function for reading the PIR sensor
  val = digitalRead(inputPin); //Establishes variable for reading the PIR sensor
}

bool calibrated() {
  return millis() - calibrateTime > 0;
}

void reportTheData() { //function for using the PIR sensor input to display on the OLED and publish to the cloud

  if (val == HIGH) {
        //Setup for the OLED. Splits it onto two lines
        display.clearDisplay();
        display.setTextSize(2);
        display.setTextColor(WHITE);
        display.setCursor(0,0); //Starts text in upper left hand corner as the datum
        display.print("Chewie");
        display.setCursor(10,30); //Moves text over 10 and down 30 from datum
        display.print("is eating");
        display.display();
    
    if (pirState == LOW) {
     
        Feedings = Feedings+1; //Iteration adds one 
        Particle.publish("Chewie-is-eating",String(Feedings)); //Publishes the string of Feedings to use on the Picture frame and thingspeak
        pirState = HIGH;
        setLED( pirState );
    }
  } 
  else {
      static int lastSecond = 61;
  if (Time.second() != lastSecond)
  {
    char myTimeString[125] = "";
    const int currentTime = Time.now();
    sprintf(myTimeString, "%02d:%02d:%02d", Time.hour(currentTime), Time.minute(currentTime), Time.second(currentTime)); //displays time when no activity
    
    display.clearDisplay();   // clears the screen and buffer
    display.setTextSize(2); //Text size for OLED
    display.setTextColor(WHITE);
    display.setCursor(12,20); //Moves text over 12 and down 20
    display.println(myTimeString);
    display.display();
    lastSecond = Time.second(currentTime);
  }

    if (pirState == HIGH) {
      pirState = LOW;
      setLED( pirState );
    }
}
}
void oled()
{
//void myHandler(const char *event, const char *data) //Function for displaying on the OLED that the pet feeder was activated
//{
 //if (strcmp(data,"Chewie_was_fed!")==0) {
        display.clearDisplay();
        display.setTextSize(2);
        display.setTextColor(WHITE);
        display.setCursor(0,0);
        display.print("Chewie");
        display.setCursor(10,30);
        display.print("was fed!");
        display.display();
        delay(3000); //Will Display this message for 3000ms before returning to the time
 //}
}

void setLED( int state )
{
  digitalWrite( ledPin, state );//turns the d7 led on/off based on PIR status
}

bool updateThingspeak() //ThingsSpeak code from John McAlpine
{
    count++;
    Serial.print("Updating Thingspeak:");
    Serial.print(count);
    

      bool success = Particle.publish("thingSpeakWrite_All", +
     "{ \"1\": \"" + String(Feedings) + "\"," +
       "\"k\": \"" + key + "\" }", 60, PRIVATE);
    return success; 
    
}
Picture_FrameArduino
This is the code used on the picture frame to move the servo.
Servo myservo;  // create servo object to control a servo
                // a maximum of eight servo objects can be created
int pos = 0;    // variable to store the servo position
int ledpin = D7; //Onboard LED pin


void setup()
{
    myservo.attach(D1);   // attach the servo on the D0 pin to the servo object
    myservo.write(180);    // test the servo by moving it to 20
    Particle.subscribe("Feed", myHandler); //Subacribes to published PIR sensor string and calls muHandler function
    pinMode(ledpin,OUTPUT);
}

void myHandler(const char *event, const char *data) //Uses the variable from the subscribed event from the PIR sensor
{
 if (strcmp(data,"morning")==0) {
    
     myservo.write(135);       // Mutiplies the string iteration by the number of degrees of movement per picture in the frame plus the inital 20 degrees
     digitalWrite(ledpin,HIGH);
     delay(2000);
     digitalWrite(ledpin,LOW);
 }
 
 else if (strcmp(data,"lunch")==0) {
    
     myservo.write(105);       // Mutiplies the string iteration by the number of degrees of movement per picture in the frame plus the inital 20 degrees
     digitalWrite(ledpin,HIGH);
     delay(2000);
     digitalWrite(ledpin,LOW);
 }
 
 else if (strcmp(data,"dinner")==0) {
    
     myservo.write(65);       // Mutiplies the string iteration by the number of degrees of movement per picture in the frame plus the inital 20 degrees
     digitalWrite(ledpin,HIGH);
     delay(2000);
     digitalWrite(ledpin,LOW);
 }
 
 else {
 }
 
}

Credits

Replications

Did you replicate this project? Share it!

I made one

Love this project? Think it could be improved? Tell us what you think!

Give feedback

Comments

Similar projects you might like

Particle Photon Based Security System with Alerting
Intermediate
  • 1,246
  • 20

Full instructions

Be alerted to any door or window opening and closing in your house on your smart phone.

Happy Plant Notifier
Intermediate
  • 224
  • 4

Full instructions

Get a text or call if your plant is getting too dry, along with a nice LCD display giving information regarding your plant's health.

My Guardian for the Workshop
Intermediate
  • 136
  • 3

Full instructions

Device will send emails if the door or window has been opened, and will monitor the temperature and humidity of the place.

Smart and Safe Outdoor Plant Watering System
Intermediate
  • 2,406
  • 18

Monitors soil moisture and weather forecasts to give plants just the water they need. Safe garden hose hookup for season long watering.

Cooler Status Monitor
Intermediate
  • 145
  • 2

Full instructions

Keep your drinks nearby and cool on hot summer days!

Christmas Gift Box
Intermediate
  • 3,679
  • 595

Full instructions

Christmas Gift Box plays music and sends an email when it is opened.

Sign up / LoginProjectsPlatformsTopicsContestsLiveAppsBetaFree StoreBlog