Dog Food Feeder

by tiacharlie in Workshop > 3D Printing

3653 Views, 31 Favorites, 0 Comments

Dog Food Feeder

dog food feeder.jpg
12992384_987738551281852_2104129581_n.jpg
13020140_987738591281848_903630583_n (1).jpg
13020140_987738591281848_903630583_n.jpg
13020448_987738564615184_1197794822_n (1).jpg
13020448_987738564615184_1197794822_n.jpg
13022185_987738611281846_298838332_n.jpg

Here is our dog food feeder. and hopefully your able to follow the instructions. I have attached all the files we have use.

Parts Needed

dog food feeder 2.jpg

Electronics

- 1 Arduino board

- 1 standard servo

- 1 potentiometer

- 1 9v battery

Hardware

- 5 x 3mm Acrylic sheets

- 1 x 5mm Acrylic sheet

- 1 Hinge/ Tape

- 3d Makerbot printer

- Filament

Tools

- Wire cutter

- Saw

- Soldering iron

- Drill

- Glue gun

- Liquid solvent cement

- Masking tape

Build the Base Box

IMG_20160412_135657856.jpg
Corel draw.png

I created a 490mm x 270 mm box with 3mm ridges. For our design we decided to make it into an L shape so using corel draw we redesigned the box so the different parts fitted together.

Then using the laser cutter we cut out the design out using black acrylic.

Cad the 4 Main Parts

5710a53e45bcebb252000f00.jpeg

Using Cad software we 3d printed out the 4 main parts of

the servo mechanism. There are three different size mechanisms to choose from. this depends on the size of the dog and how much food intake they have.

This took 3 days in total to print. You could also CNC the parts which will take less time and cost less to make.

Arduino

fritizing.jpg
wireing.jpg

We started off by building a prototype using an arduino and breadboard. This can be very fiddle and takes time. We uploaded the design and have include the fritizing file so you can see in detail how to set the device up.

We built a breadboard with the LCD on first, having previously learnt the basics on a different project. Then we added a rotary encoder and combined the two. There is a real time clock on the device and you can download the software to enable it to work on the Arduino site. However we decided to invest in a real time clock as well as the servo and started to programme the final code.

I built a breadboard with the LCD on first, then learnt the basics of how to control it. Then I added a rotary encoder and learnt how to use that, then I combined the two in code. Finally I added the real time clock, the servos, and started programming the final code.

Arduino Code

Below is the arduino code we have used.

Automatic Auger Audiono pet

feeder Copyright Roger Donoghue 28/03/2015 all rights reserved. For personal use only. Not for commercial use or resale. Allows you to set 2 feeding times and the quantity as a multiple of the default feed quantity. Uses a DS1307 real time clock to keep the time, with a rechargable battery built in. (You can use the arduino RTC example code in the IDE to set the clock , or use the rotary encoder as intended)

*/ // include the library code: #include

#include // needed for the RTC libraty #include #include // Real Time Clock Library #include #include #include #include

// initialize the library with the numbers of the interface pins dor the LCD LiquidCrystal lcd(12, 11, 5, 8, 7, 6);

#define PIN_SERVO 9

Servo feedServo; Servo stirServo; int pos = 0; volatile boolean TurnDetected; volatile boolean up; const int PinCLK=2; // Used for generating interrupts using CLK signal const int PinDT=3; // Used for reading DT signal const int PinSW=4; // Used for the push button switch of the Rotary Encoder const int buttonPin = A3; // the number of the pushbutton pin for manual feed 13 int buttonState = 0; // variable for reading the manual feed pushbutton status int feed1hour = 07; // variables for feeding times and quantity int feed1minute = 00; int feed2hour = 17; int feed2minute = 30; int feedQty = 4; int feedRate = 800; //a pwm rate the triggers forward on the servo 75 int feedReversal = 80; //a pwm rate that triggers reverse on the servo // play with these numbers for your servo. Mine is a Futaba digital servo // that I removed the pot from and the plastic lug, to make it continuous.

void isr () { // Interrupt service routine is executed when a HIGH to LOW transition is detected on CLK if (digitalRead(PinCLK)) // this keeps an eye out for the rotary encoder being turned regardless of where the program is up = digitalRead(PinDT); // currently exectuting - in other words, during the main loop this ISR will always be active else up = !digitalRead(PinDT); TurnDetected = true; }

void setup () { // set up the LCD's number of columns and rows: lcd.begin(16, 2); // setup the Rotary encoder pinMode(PinCLK,INPUT); pinMode(PinDT,INPUT);

pinMode(PinSW,INPUT); pinMode(buttonPin, INPUT); attachInterrupt (0,isr,FALLING); // interrupt 0 is always connected to pin 2 on Arduino UNO lcd.setCursor(17,0);

lcd.print("Tia & Jordans"); // A bit of fun smile emoticon

lcd.setCursor(17,1); lcd.print("Food Dispencer"); for (int positionCounter = 0; positionCounter < 17; positionCounter++) { // scroll one position left: lcd.scrollDisplayLeft();

// wait a bit: delay(150); } delay(3000); for (int positionCounter = 0; positionCounter < 17; positionCounter++) { // scroll one position left: lcd.scrollDisplayRight();

// wait a bit: delay(150);

} // end of fun lcd.setCursor(17,0); lcd.print(" "); lcd.setCursor(17,1); lcd.print(" "); }

void loop () { //Main program loop - most things in here! static long virtualPosition=0; // without STATIC it does not count correctly!!! tmElements_t tm; // This sectionm reads the time from the RTC, sets it in tmElements tm (nice to work with), then displays it. RTC.read(tm); lcd.setCursor(0, 0); printDigits(tm.Hour); //call to print digit function that adds leading zeros that may be missing lcd.print(":"); printDigits(tm.Minute); lcd.print(":"); printDigits(tm.Second); lcd.print(" "); lcd.print("Qty "); lcd.print(feedQty); lcd.print(" "); lcd.setCursor(0,1); lcd.print("1)"); printDigits(feed1hour); lcd.print(":"); printDigits(feed1minute); lcd.print(" 2)"); printDigits(feed2hour); lcd.print(":"); printDigits(feed2minute);

// MAIN BREAKOUT "IF" SECION BELOW THAT MONITORS THE PUSH BUTTON AND ENTERS PROGRAMMING IF IT'S PUSHED

if (!(digitalRead(PinSW))) { // check if pushbutton is pressed // if YES then enter the programming subroutine lcd.blink(); // Turn on the blinking cursor: lcd.setCursor(5,0); lcd.print(" SET"); virtualPosition = tm.Hour; //needed or the hour will be zero each time you change the clock. do { lcd.setCursor(0,0); // put cursor at Time Hour delay(500); // Delay needed or same button press will exit do-while as while is checking for another button push! if (TurnDetected) { // do this only if rotation was detected if (up) virtualPosition--; else virtualPosition++; TurnDetected = false; // do NOT repeat IF loop until new rotation detected } // Here I change the hour of time - tm.Hour = virtualPosition; RTC.write(tm); lcd.setCursor(0, 0); printDigits(tm.Hour); // then re-print the hour on the LCD } while ((digitalRead(PinSW))); // do this "do" loop while the PinSW button is NOT pressed lcd.noBlink(); delay(1000);

// SET THE MINS

lcd.blink(); // Turn on the blinking cursor: virtualPosition = tm.Minute; //needed or the minute will be zero each time you change the clock. do { lcd.setCursor(3,0); // put cursor at Time Mins delay(500); // Delay needed or same button press will exit do-while as while is checking for another button push! if (TurnDetected) { // do this only if rotation was detected if (up) virtualPosition--; else virtualPosition++; TurnDetected = false; // do NOT repeat IF loop until new rotation detected } // Here I change the min of time - tm.Minute = virtualPosition; RTC.write(tm); lcd.setCursor(3, 0); printDigits(tm.Minute); // then re-print the min on the LCD } while ((digitalRead(PinSW))); lcd.noBlink(); delay(1000);

// SET THE QTY - Feed quantity

lcd.blink(); // Turn on the blinking cursor: virtualPosition = feedQty; //needed or the qty will be zero. do { lcd.setCursor(14,0); // put cursor at QTY delay(500); // Delay needed or same button press will exit do-while as while is checking for another button push! if (TurnDetected) { // do this only if rotation was detected if (up) virtualPosition--; else virtualPosition++; TurnDetected = false; // do NOT repeat IF loop until new rotation detected } // Here I change the feed qty feedQty = virtualPosition; lcd.setCursor(14, 0); lcd.print(feedQty); } while ((digitalRead(PinSW))); lcd.noBlink(); delay(1000);

// SET THE Feed1 Hour

lcd.blink(); // Turn on the blinking cursor: virtualPosition = feed1hour; //needed or will be zero to start with. do { lcd.setCursor(2,1); // put cursor at feed1hour delay(500); // Delay needed or same button press will exit do-while as while is checking for another button push! if (TurnDetected) { // do this only if rotation was detected if (up) virtualPosition--; else virtualPosition++; TurnDetected = false; // do NOT repeat IF loop until new rotation detected } // Here I change the feed1 hour feed1hour = virtualPosition; lcd.setCursor(2,1); printDigits(feed1hour); } while ((digitalRead(PinSW))); lcd.noBlink(); delay(1000);

// SET THE Feed1 Mins

lcd.blink(); // Turn on the blinking cursor: virtualPosition = feed1minute; //needed or will be zero to start with. do { lcd.setCursor(5,1); // put cursor at feed1minute delay(500); // Delay needed or same button press will exit do-while as while is checking for another button push! if (TurnDetected) { // do this only if rotation was detected if (up) virtualPosition--; else virtualPosition++; TurnDetected = false; // do NOT repeat IF loop until new rotation detected } // Here I change the feed1 minute feed1minute = virtualPosition; lcd.setCursor(5,1); printDigits(feed1minute); } while ((digitalRead(PinSW))); lcd.noBlink(); delay(1000);

// SET THE Feed2 Hour

lcd.blink(); // Turn on the blinking cursor: virtualPosition = feed2hour; //needed or will be zero to start with. do { lcd.setCursor(10,1); // put cursor at feed1hour delay(500); // Delay needed or same button press will exit do-while as while is checking for another button push! if (TurnDetected) { // do this only if rotation was detected if (up) virtualPosition--; else virtualPosition++; TurnDetected = false; // do NOT repeat IF loop until new rotation detected } // Here I change the feed1 hour feed2hour = virtualPosition; lcd.setCursor(10,1); printDigits(feed2hour); } while ((digitalRead(PinSW))); lcd.noBlink(); delay(1000);

// SET THE Feed2 Mins

lcd.blink(); // Turn on the blinking cursor: virtualPosition = feed2minute; //needed or will be zero to start with. do { lcd.setCursor(13,1); // put cursor at feed1minute delay(500); // Delay needed or same button press will exit do-while as while is checking for another button push! if (TurnDetected) { // do this only if rotation was detected if (up) virtualPosition--; else virtualPosition++; TurnDetected = false; // do NOT repeat IF loop until new rotation detected } // Here I change the feed1 minute feed2minute = virtualPosition; lcd.setCursor(13,1); printDigits(feed2minute); } while ((digitalRead(PinSW))); lcd.noBlink(); delay(1000);

} // end of main IF rotary encoder push button checker

// CHECK FOR MANUAL FEED BUTTON buttonState = digitalRead(buttonPin); if (buttonState == HIGH) { feed(); } // CHECK FEEDING TIME AND FEED IF MATCHED

if (tm.Hour == feed1hour && tm.Minute == feed1minute && tm.Second == 0) { // if I dont' check seconds are zero feed(); // then it'll feed continuously for 1 minute! } if (tm.Hour == feed2hour && tm.Minute == feed2minute && tm.Second == 0) { feed(); }

} // End of main Loop

void printDigits(int digits){ // utility function for digital clock display: prints leading 0 if(digits < 10) lcd.print('0'); lcd.print(digits); }

void feed() {

lcd.setCursor(17,0); lcd.print(" Woooorf!"); for (int positionCounter = 0; positionCounter < 16; positionCounter++) { // scroll one position left: lcd.scrollDisplayLeft();

// wait a bit: delay(150); }

// Stir servo section If you don't need a stir servo simply comment out all fo this until the Auger rotate section stirServo.attach(10); // I don't know if I need one either but I'm adding it now as it's easiest before I build it! for(pos = 0; pos <= 180; pos += 1) { stirServo.write(pos);

delay(10); } for(pos = 180; pos>=0; pos-=1) { stirServo.write(pos);

delay(10); }

stirServo.detach();

// rotate the Auger feedServo.attach(PIN_SERVO); for (int cnt = 0; cnt < feedQty; cnt++) { feedServo.write(feedRate); //the feedrate is really the feed direction and rate. delay(600); //this delay sets how long the servo stays running from the previous command feedServo.write(feedReversal); //...until this command sets the servo a new task! delay(200); feedServo.write(feedRate);

delay(600); feedServo.write(feedReversal); // if you want to increase the overall feedrate increase the forward delays (1000 at the moment) delay(200); // or better still just copy and past the forward & backwards code underneath to repeat } // that way the little reverse wiggle is always there to prevent jams feedServo.detach(); for (int positionCounter = 0; positionCounter < 16; positionCounter++) { // scroll one position left: lcd.scrollDisplayRight();

// wait a bit: delay(150);

Inserting the Ramp and Designing the Tube

5710a81515be4d6185001c18.jpeg

Using Corel draw, illustrator or similar software we designed the ramp to place inside the box so the food will go down the spout easier. We also designed the tube so food will go straight into the dog bowl.

Downloads

The Inner Mechanism of Our Device

circles.jpg

We tried to 3d printed inner mechanism but it didn’t quite fit so instead we laser cutted using Corel draw. We made 4 circles 96mm each. On two of the circles we put in the centre a 30mm by 30mm square. Then used an acrylic tube and cut a quarter of the piece out using a saw.

Downloads

Putting the Pieces Together

acrylic cement.jpg

Using acrylic cement/ glue we put the box with ramp inside together. We then glued together the tube and attached it to the Cad parts we made earlier with the mechanism inside. There is a hole on one side of the box to put the led screen in so all the wiring and motor components fits underneath the ramp.