Project tutorial

IoT Pet Feeder © GPL3+

Use circuito.io to build a smart food dispenser for your pet controlled directly from your phone.

  • 6,475 views
  • 1 comment
  • 36 respects

Components and supplies

Apps and online services

8ztngd 9
circuito.io
Use this magic link >>https://www.circuito.io/app?selectedComponentsIds=11021&selectedComponentsIds=9442&selectedComponentsIds=13678&selectedComponentsIds=197253&selectedComponentsIds=931983&selectedComponentsIds=10333

About this project

This IoT pet feeder is our first IoT project with circuito.io! We are happy to share it with our community to demonstrate how simple it can be to make basic IoT projects with circuito.io. We are also excited to share this project with you because it's based on a product that we worked on in the past called Playdog. You can make the feeder for your pets at home - it's both fun JPand useful.

How does it work?

There are many ways to implement a pet feeder: you can set it to fill up the bowl at a certain time, you can command it to fill up whenever it gets empty, or maybe to give your dog food after they follow a set of orders that you taught them.

In this specific project, we set the feeder to start beeping from time to time. Once the dog comes closer to the device, the PIR sensor recognizes it and the servo is triggered.

In addition, we also decided to add the option to control the pet feeder from our mobile phone, using a pre-defined dashboard made with Freeboard. We saw this as a great opportunity to introduce you to the option of connecting your circuito project to the internet with ESP8266-01 - the wifi module currently available on circuito.io.

Setting up the circuit

When clicking on this magic link, you'll be redirected to circuito.io, where you'll find that we've already selected for you the components we used in this project.

The components you need are: PIR sensor, Arduino uno (or other), servo, speaker, esp8266-01, and a power source. This is the basic circuit for this project but you can also add many different sensors and other components to the circuit for example, you can add a weight sensor to monitor the amount of food in the bowl or add LEDs that will change according to different parameters.

Once you've selected the components you waLunant, click on Generate and our engines will start working on your circuit and will generate your circuito reply. The reply has three parts:

1. BoM - A list of all the components you'll need for the project, including auxiliary parts such as resistors and capacitors.

2. Step-by-step wiring guide - shows you how to connect all your components to the Arduino board using a breadboard.

3. Code - a sample code for your circuit. This code is not specific for the pet feeder project, but rather it is a sample code that creates an interaction between the different components in your circuit.

To Upload the code, follow these steps:

  • Download the code from the circuito.io reply
  • Extract it to your computer
  • Open with Arduino IDE
  • Upload to your Arduino

4. Once everything is set up, replace the sample code from the circuito reply with the code in this tutorial. Make sure to leave the //Include Libraries and //Pin Definitions at the top of the code, and also keep all the libraries that are on the original code from circuito.io.

4. Connectivity - this section will guide you how to configure the connection of your project to the internet. Since you're not going to use the sample code from circuito, but rather the code provided in this tutorial, if you click "create dashboard" you'll have to configure the dashboard manually.

If you want to use the pre-set dashboard we used, download the attached pet_feeder_dashboard html file and open it in your browser. Then follow the instructions below.

- Click on “Clone" and create a copy of the dashboard for your project.

- Choose a unique ‘thingName’.

You can find your thingname in the firmware.ino.

- Click on the settings icon at the top of the page.

This should update your dashboard to look like this:

Troubleshooting:

  • If it doesn’t work - try refreshing the page.
  • Check that the dashboard is set up correctly with your firmware. Click on ‘Dweet’ under DATASOURCES. You should see this:

Make sure that the thingname is the same as the one in your firmware.ino.

  • In the OUTPUT section click on settings

A window will open:

  • click on JS EDITOR and look for this line:
  • change the value to the given ‘thingname’ in your firmwae.ino.
  • CLOSE and SAVE.

Assembly

Now that you have the electronics set up, it's time to put the parts together.

We designed a 3d printed casing for the servo, the PIR sensor and the speaker.

The .stl files are attached here. This part isn't mandatory and you can choose to connect it in a different way, it's really up to you, but look how nice and colorful it is :)

Congratulations! You're done!

You're pretty much set to go. You may need to make small adjustments in the code and calibrate the different sensors.

We would love to see

Custom parts and enclosures

speaker mount
servo mount
servo case
PIR case

Schematics

Pet Feeder Dashboard
pet_feeder_dashboard_WOIWcsixUg.html

Code

Code for IoT pet feederArduino
Replace the sample code from the circuito reply with the code below.
Make sure to leave the //Include Libraries and //Pin Definitions at the top of the code, and also keep all the libraries that are on the original code from circuito.io.
const int ServoRestPosition   = 20;  //Starting position
const int ServoTargetPosition = 150; //Position when event is detected
unsigned int HoorayLength          = 6;                                                      // amount of notes in melody
unsigned int HoorayMelody[]        = {NOTE_C4, NOTE_E4, NOTE_G4, NOTE_C5, NOTE_G4, NOTE_C5}; // list of notes. List length must match HoorayLength!
unsigned int HoorayNoteDurations[] = {8      , 8      , 8      , 4      , 8      , 4      }; // note durations; 4 = quarter note, 8 = eighth note, etc. List length must match HoorayLength!

unsigned int comeLength          = 3;
unsigned int comeMelody[]        = {NOTE_C5, NOTE_G5, NOTE_C5};
unsigned int comeNoteDurations[] = {8      , 8      , 8};

ESP8266 wifi(WIFI_PIN_RXD,WIFI_PIN_TXD);
Servo servo;
PIR pir(PIR_PIN_SIG);
PiezoSpeaker piezoSpeaker(PIEZOSPEAKER_PIN_SIG);

int pirCounter = 0;
// ====================================================================
// vvvvvvvvvvvvvvvvvvvv ENTER YOUR WI-FI SETTINGS  vvvvvvvvvvvvvvvvvvvv
//
const char *SSID     = "YOURWIFI"; // Enter your Wi-Fi name 
const char *PASSWORD = "YOURPASSWORD" ; // Enter your Wi-Fi password
//
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// ====================================================================


// These Dweet tokens have been auto generated for you.
char* const inputToken  = "12b2cbb8-3f8e-11e7-a810-0242ac110028_input";
char* const outputToken = "12b2cbb8-3f8e-11e7-a810-0242ac110028_output";

Dweet dweet( &wifi, inputToken, outputToken);

/* This code sets up the essentials for your circuit to work. It runs first every time your circuit is powered with electricity. */
void setup() {
    // Setup Serial which is useful for debugging
    // Use the Serial Monitor to view printed messages
    Serial.begin(9600);
    Serial.println("start");
    
    if (!wifi.init(SSID, PASSWORD))
    {
        Serial.println(F("Wifi Init failed. Check configuration."));
        while (true) ; // loop eternally
    }
    servo.attach(SERVO_PIN);
    servo.write(ServoRestPosition);
    delay(100);
    servo.detach();
}

/* This code is the main logic of your circuit. It defines the interaction between the components you selected. After setup, it runs over and over again, in an eternal loop. */
void loop() {

    bool pirVal = pir.read();
    
    //SET DWEETS
    dweet.setDweet("pir", pirVal );
    dweet.setDweet("pirCounter",  pirCounter);
    
    
    dweet.sendDweetKeys();
    
    
    if (pirVal)
    {
        pirCounter++;
        // The servo will rotate to target position and back to resting position with an interval of 500 milliseconds (0.5 seconds) 
        servo.attach(SERVO_PIN);         // 1. attach the servo to correct pin to control it.
        servo.write(ServoTargetPosition);  // 2. turns servo to target position. Modify target position by modifying the 'ServoTargetPosition' definition above.
        delay(500);                              // 3. waits 500 milliseconds (0.5 sec). change the value in the brackets (500) for a longer or shorter delay in milliseconds.
        servo.write(ServoRestPosition);    // 4. turns servo back to rest position. Modify initial position by modifying the 'ServoRestPosition' definition above.
        delay(500);                              // 5. waits 500 milliseconds (0.5 sec). change the value in the brackets (500) for a longer or shorter delay in milliseconds.
        servo.detach();                    // 6. release the servo to conserve power. When detached the servo will NOT hold it's position under stress.
        
        // The Piezo Speaker light will play a beep for half a second, wait for another 500ms(half a second) and then play a tune
        piezoSpeaker.tone(400);                                                    // 1. plays a 400Hz beep. Change the value in the brackets (400) for a higher or lower beep.
        delay(500);                                                               // 2. keeps playing it for 500ms
        piezoSpeaker.off();                                                        // 3. stops the beep
        delay(500);                                                               // 4. waits 500ms                   
        piezoSpeaker.playMelody(HoorayLength, HoorayMelody, HoorayNoteDurations);  // 5. plays the Hurray melody. to play a different melody, modify HoorayLength, HoorayMelody and HoorayNoteDuration above.                    
        delay(500);                                                               // 4. waits 500ms
    }
    
    
    //GET DWEETS  
    dweet.receiveDweetEvents();
    
    
    if(strcmp(dweet.getValue() , "servo") == 0)
    {
        Serial.println(F("servo was pressed!"));
        // The servo will rotate to target position and back to resting position with an interval of 500 milliseconds (0.5 seconds) 
        servo.attach(SERVO_PIN);         // 1. attach the servo to correct pin to control it.
        servo.write(ServoTargetPosition);  // 2. turns servo to target position. Modify target position by modifying the 'ServoTargetPosition' definition above.
        delay(500);                              // 3. waits 500 milliseconds (0.5 sec). change the value in the brackets (500) for a longer or shorter delay in milliseconds.
        servo.write(ServoRestPosition);    // 4. turns servo back to rest position. Modify initial position by modifying the 'ServoRestPosition' definition above.
        delay(500);                              // 5. waits 500 milliseconds (0.5 sec). change the value in the brackets (500) for a longer or shorter delay in milliseconds.
        servo.detach();                    // 6. release the servo to conserve power. When detached the servo will NOT hold it's position under stress.
    }
    else if(strcmp(dweet.getValue() , "piezoSpeaker") == 0)
    {
        Serial.println(F("piezoSpeaker was pressed!"));
        // The Piezo Speaker light will play a beep for half a second, wait for another 500ms(half a second) and then play a tune
        piezoSpeaker.tone(400);                                                    // 1. plays a 400Hz beep. Change the value in the brackets (400) for a higher or lower beep.
        delay(500);                                                               // 2. keeps playing it for 500ms
        piezoSpeaker.off();                                                        // 3. stops the beep
        delay(500);                                                               // 4. waits 500ms                   
        piezoSpeaker.playMelody(HoorayLength, HoorayMelody, HoorayNoteDurations);  // 5. plays the Hurray melody. to play a different melody, modify HoorayLength, HoorayMelody and HoorayNoteDuration above.                    
        delay(500);                                                               // 4. waits 500ms
    }
    else if(strcmp(dweet.getValue() , "playGame") == 0)
    {
        Serial.println(F("Playing Game!"));
        while (!pir.read())
        {
          piezoSpeaker.playMelody(comeLength, comeMelody, comeNoteDurations);
          delay(500);
        }
        
        servo.attach(SERVO_PIN);
        servo.write(ServoTargetPosition);
        delay(1000);
        servo.write(ServoRestPosition);
        delay(1000);
        servo.detach();
        
        piezoSpeaker.playMelody(HoorayLength, HoorayMelody, HoorayNoteDurations);  // 5. plays the Hurray melody. to play a different melody, modify HoorayLength, HoorayMelody and HoorayNoteDuration above.                    
        
        delay(100);
    }
}

Comments

Similar projects you might like

Starry Night Prom

Project showcase by Maddy

  • 2,373 views
  • 13 comments
  • 18 respects

The Trump Button

Project tutorial by Aurelien Lequertier and Louis Moreau

  • 1,243 views
  • 7 comments
  • 9 respects

Direction Indicators for Bikes

Project tutorial by Rosaliew

  • 330 views
  • 0 comments
  • 6 respects

Third Eye for The Blind

Project tutorial by Muhammed Azhar

  • 1,055 views
  • 4 comments
  • 13 respects

ArduRadio AlarmClock

Project tutorial by Tittiamo

  • 2,279 views
  • 4 comments
  • 2 respects

CO2 Monitoring with K30 Sensor

Project tutorial by alfred333

  • 519 views
  • 0 comments
  • 3 respects
Add projectSign up / Login