element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • About Us
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Making Time
  • Challenges & Projects
  • Project14
  • Making Time
  • More
  • Cancel
Making Time
Blog Cat Commander iot Clock and Kibble Dispenser
  • Blog
  • Forum
  • Documents
  • Events
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Making Time to participate - click to join for free!
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: fmilburn
  • Date Created: 14 Jan 2021 7:56 PM Date Created
  • Views 4309 views
  • Likes 15 likes
  • Comments 28 comments
  • mkr 1010
  • makingtimech
  • led
  • rgb
  • iot
  • time
  • arduino
  • continuous servo
Related
Recommended

Cat Commander iot Clock and Kibble Dispenser

fmilburn
fmilburn
14 Jan 2021

We present a clock that synchs itself with the Network Time Protocol (NTP), feeds cats, and can be controlled wirelessly.

image

Features

 

This is the kind of fun that can happen when working with 7 to 9 year old children image

 

The Cat Commander iot Clock and Kibble Dispenser has the following features:

  • Timeless style that looks great with any décor
  • Synchs automatically on startup for accurate time keeping using NTP
  • Scrolling time and helpful messages displayed on RGB LED matrix
  • Kibble reservoir stores enough food for two or more cats for several days
  • Up to two feedings per day at user set times
  • Adjustable feed amount
  • Wireless User Interface works with smart phones, tablets, and computers

 

Design

 

The kids and I did an internet search for animal feeders and looked at a number of methods for metering the feed.  We decided on the "Archimedes Screw" because a machine based on ancient Egyptian technology and looking this cool had to be the right answer.  One of the designs we saw used a PVC tee as the body and we adopted that.  I sketched everything out freehand and for no good reason made the storage cylindrical.  It kind of looked like a rocket ship so a nose cone was drawn on top and the Cat Commander Kibble Dispenser was born.  The detailed design and fabrication was done by me, but my grandson helped with assembly.

 

Mechanical Fabrication and Construction

 

The 3D printed parts were designed in Fusion 360 and printed on an Anycubic I3 Mega printer with PLA filament.  The main body of the metering section is a 1 1/2 inch Sch. 40 PVC pipe tee from the local hardware store.  The modeled parts are shown below and described in the sections that follow.

image

All parts can be printed without supports but the screw was split and printed in halves axially which were then glued together.

 

Kibble Storage

 

Parts:  nose cone, body, and tail

 

Kibble (coarsely ground meal or grain typically used as animal feed per Merriam-Webster) is stored in the rocket ship shaped silo atop the metering section.  The nose cone can be lifted off for refilling.  The tail section has an internal funnel that fits snugly over the metering section and can be removed for cleaning.  The tail section and body were glued together.

 

image

 

Metering and Delivery

 

Parts:  PVC tee, metering throat, screw / auger, motor mount, 360 degree servo motor, forward mount, kibble slide, 2 mm nuts and bolts

 

The metering and delivery section is contained inside a 1 1/2 PVC tee and kibble is fed into the top of the tee.  A 3D printed piece that is friction fit into the throat of the tee regulates and directs feed towards the back of the body of the tee.  A screw (auger) in the body of the tee drives the kibble out of the front towards a slide.  The device positively displaces the kibble so metering can be controlled by the number of rotations of the screw.  The screw is driven by a 360 degree servo (MG-360) and a slide at the front of the tee directs the kibble towards a bowl.

 

Every so often the screw can eject kibble roughly as it exits due to catching on the face of the mount.  This does not materially impact performance but could be improved with a change in geometry and tolerances.

 

image

 

Control Panel and Enclosure

 

Parts: control panel enclosure, control panel back, wire entry plug, 3 mm threaded brass insert and screw, cable management sleeve

 

The electronics are contained in a 3D printed enclosure with an integrated panel.  The RGB LED matrix attaches to the panel with four 2 mm bolts, 6 mm long.  The button switch with LED slips into a mount with fingers to hold it to the panel and are hot glued in place.  The back to the enclosure was printed separately and presses into the enclosure with a single 3 mm screw to keep it firmly in place.  A threaded brass insert heat pressed into the enclosure allows easy and repeated removal and reattachment of the back.  Power for the electronics and control to the servo is through a hole in the enclosure back with a wire entry plug to keep things tidy.  The USB cables were encased in a 1/4" cable management  sleeve for tidiness.

 

image

 

Electronics

 

Parts: Arduino MKR 1010 microcontroller, Arduino MKR RGB shield, protoboard, dual USB wall wart and cables, momentary switch with LED, assorted bits and wire

 

Thanks to element14 and Tariq for providing the Arduino parts sometime back as a reward for participation in Project14.  The electronics are straight forward and were prototyped on a breadboard before soldering up on protoboard configured as a breadboard which eased development and construction.

 

image

 

Unfortunately it was soldered "upside down" and as a result the display was upside down.  This was not originally considered an issue as the Adafruit RGB libraries allow the display to be rotated in software.  This turned out to not be the case for the Arduino library and due to time the protoboard was rotated and notched out so that it would fit the enclosure.  To accomplish the fit of the USB connection it was necessary to move the RGB matrix further from the center than originally planned.

 

Because the motor draws a fair amount of current, especially when starting, it requires a separate power source and the motor used requires 5V or greater.  Using what was at hand, a section from a surplus PCB with an SMD USB footprint was cut out and soldered to the protoboard (the green PCB section visible in the photo below) to provide power for the motor.  The final assembly is tight and fiddly but neat.

 

image

 

Firmware

 

The firmware was developed using the Arduino IDE version 1.8.13 and developed on an Arduino MKR 1010.  My contributions are entirely in the public domain.  The major sections of the code rely on the following libraries:

 

  • Display:  Uses the Arduino_MKRRGB and ArduinoGraphics libraries for output
  • Setting Time: Uses the WiFiUdp library to get time from an NTP server
  • Real Time Clock: Uses RTCZero to display the time and trigger feeding
  • Servo: Uses the Servo library to control the 360 degree servo motor
  • User Interface: Sets up a server on the microcontroller using WiFiNINA

 

A line by line walkthrough of the code is not provided as it is rather lengthy but it is built off of examples in the libraries and I am happy to answer questions.  Since the project has just finished and is not field tested there may be future changes.  If so, it may be reposted or a link to a github repository made.

 

/* Cat Commander ntpTime_v8
 * Tested on Arduino MKR 1010 with MKRRGB shield
 *  
 * Gets time from NTP server and uses a servo to control cat food delivery.  The User Interface
 * is over WiFi.  The MKRRGB displays time and a countdown when close to feeding time.
 *  
 * Servo Leads:  Red = Power from separate source
 *               Brown = Ground connected to Arduino
 *               Yellow = Servo control, Arduino pin 5
 * Button: Purple = Power from Arduino Vcc to button switch
 *         Brown = Ground connected to Arduino
 *         Blue = Button swich pulled down connected to Arduino pin 6
 *         White = LED on button switch connected thru 680R to Arduino pin 7
 * 
 * Modified sections of examples from the Arduino libraries were used in the development of this code.
 * The contributions of the authors are fully in the public domain.
 *  
 * fmilburn Jan 2021
 */


#include "arduino_secrets.h"
#include <SPI.h>
#include <WiFiNINA.h>
#include <WiFiUdp.h>
#include <RTCZero.h>
#include <Servo.h>
#include <ArduinoGraphics.h>      // Arduino_MKRRGB needs ArduinoGraphics
#include <Arduino_MKRRGB.h>     


#define DEBUG false


const int SERVOPIN = 5;           // Servo control pin
const int SPEED =   30;           // Servo speed
const int BUTTONLED = 7;          // LED inside button switch
const int BUTTONPIN = 6;          // Button switch pin, 10k pulldown
volatile bool buttonPushed = false;
bool displayStatus = true;


char ssid[] = SECRET_SSID;        // network SSID (name)
char pass[] = SECRET_PASS;        // network password
int keyIndex = 0;                 // network key Index number (needed for WEP)
int status = WL_IDLE_STATUS;


const int GMT_OFFSET = -8;        // local offset from GMT
struct Feeding{
  int h;                          // hr (24 hour) to feed cats
  int m;                          // minute of hour to feed cats
}; 
const int FEEDINGTIMES = 2;
struct Feeding feedingTime[FEEDINGTIMES] = {
                                  {8, 00},     // eg 08:00
                                  {16, 00}     // eg 16:00
                                };


int feedingTimeIndex = 0;
volatile bool timeToFeed = false; // turns true when feed time occurs
float feedRate = 2.0;             // number of seconds the feed motor runs


WiFiServer server(80);            // server socket
WiFiClient client = server.available();


RTCZero rtc;                      // Real Time Clock instance
Servo myservo;                    // A servo instance to feed the cats


// -----------------------------------------------------------------
// setup
// -----------------------------------------------------------------
void setup() {


  if (DEBUG == true){
    Serial.begin(115200);
    while (!Serial){
      // wait for serial
    }
    Serial.println("Started...");
  }


  initLedMatrix();
  initGpio();
  initWifi();
  initRtc();
  setFeedTime();
  initServer();
  
  // Interrupts
  attachInterrupt(digitalPinToInterrupt(BUTTONPIN), buttonPush, HIGH);
  rtc.attachInterrupt(rtcAlarm);


}


// -----------------------------------------------------------------
// loop
// -----------------------------------------------------------------
void loop() {


  if (displayStatus == true){
    displayTime();
  }


  client = server.available();


  if (client) {
    webPage();
  }
  
  if (buttonPushed == true){     // button used to turn display on /off       
    displayStatus = !displayStatus; 
    buttonPushed = false;       
  }


  if (timeToFeed == true){       
    feedCats();                  // feed the cats
  }
}


// -----------------------------------------------------------------
// initialize the server
// -----------------------------------------------------------------
void initServer(){


  server.begin();
  printWifiStatus();
  
}


// -----------------------------------------------------------------
// start the web page
// -----------------------------------------------------------------
void webPage() {


  if (client) {                             // check if there is a cllent
    String currentLine = "";                // string to hold incoming data from the client
    while (client.connected()) {            // loop while the client's connected
      if (client.available()) {             // check for byte to read from the client,
        char c = client.read();             // read a byte, then
        if (c == '\n') {                    // respond only when there is new line


          // if the current line is blank there were two newline characters in a row.
          // that's the end of the client HTTP request, so send a response:
          if (currentLine.length() == 0) {


            // standard response header
            client.println("HTTP/1.1 200 OK");
            client.println("Content-Type: text/html");
            client.println("Connection: close");
            client.println();


            // web page
            client.println("<!DOCTYPE html>");
            client.println("<html>");
            client.println("<head>");
            client.println("<title>Cat Commander Kibble Dispenser</title>");
            client.println("</head>");
            
            client.println("<body>");
            // Title
            client.println("<h1>Cat Commander Kibble Dispenser</h1>");
            // feeding times
            client.println("<h2>");
            client.print("<br><br>------------- Feed Times -------------<br>");
            for (int i = 0; i < FEEDINGTIMES; i++){
              client.print("Feeding Time ");
              client.print(i+1);
              client.print(": ");
              client.print(feedingTime[i].h);
              client.print(":");
              if (feedingTime[i].m < 10){
                client.print("0");
              }
              client.print(feedingTime[i].m);
              client.print("<br>");
            }


            // create the adjust time buttons
            client.print("<br>Click <a href=\"/UP1\">here</a> for later first feeding<br>");
            client.print("Click <a href=\"/DOWN1\">here</a> for earlier first feeding<br>");
            client.print("<br>Click <a href=\"/UP2\">here</a> for later second feeding<br>");
            client.print("Click <a href=\"/DOWN2\">here</a> for earlier second feeding<br>");


            // feed rate
            client.print("<br>-------------- Feed Rate --------------<br>");
            client.print("Run motor for ");
            client.print(feedRate);
            client.print(" seconds<br><br>");


            // create the change feed buttons
            client.print("Click <a href=\"/MORE\">here</a> to increase feed rate<br>");
            client.print("Click <a href=\"/LESS\">here</a> to decrease feed rate<br><br>");


            client.print("Click <a href=\"/FEED\">here</a> to feed now<br><br>");
            client.println("<\h2>");
            client.println();
            client.println("</body>");
            
            client.println("</html>");   
                    
            // break out of the while loop:
            break;
          }
          else {      // if you got a newline, then clear currentLine:
            currentLine = "";
          }
        }
        else if (c != '\r') {    // if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
        }


        if (currentLine.endsWith("GET /MORE")) {
          if (feedRate < 10){
            feedRate = feedRate + 0.5;
          }       
        }
        if (currentLine.endsWith("GET /LESS")) {
          if (feedRate > 0) {
            feedRate = feedRate - 0.5;
          }   
        }
        if (currentLine.endsWith("GET /FEED")) {
          // Check for last feeding?
          feedCats();       
        }
        if (currentLine.endsWith("GET /UP1")) {
          feedingTime[0].h++;
          if (feedingTime[0].h > 24){
            feedingTime[0].h = 0;       
          }
        }
        if (currentLine.endsWith("GET /DOWN1")) {
          feedingTime[0].h--;
          if (feedingTime[0].h < 0){
            feedingTime[0].h = 24;       
          }
        }
        if (currentLine.endsWith("GET /UP2")) {
          feedingTime[1].h++;
          if (feedingTime[1].h > 24){
            feedingTime[1].h = 0;       
          }
        }
      }
      if (currentLine.endsWith("GET /DOWN2")) {
        feedingTime[01].h--;
        if (feedingTime[1].h < 0){
          feedingTime[1].h = 24;       
        }
      }
    }
    // close the connection:
    client.stop();
    // Serial.println("client disconnected");
  }
}


// -----------------------------------------------------------------
// print the WiFi Status
// -----------------------------------------------------------------
void printWifiStatus() {
  
  IPAddress ip = WiFi.localIP(); 
  MATRIX.beginText(0, 0, 127, 127, 127);
  MATRIX.print("  http://");
  MATRIX.print(ip);
  MATRIX.endText(SCROLL_LEFT);
  
  if (DEBUG == true){
    // print the SSID of the network you're attached to:
    Serial.print("SSID: ");
    Serial.println(WiFi.SSID());
  
    // print your board's IP address:
    Serial.print("IP Address: ");
    Serial.println(ip);
  
    // print the received signal strength:
    long rssi = WiFi.RSSI();
    Serial.print("signal strength (RSSI):");
    Serial.print(rssi);
    Serial.println(" dBm");
  
    Serial.print("To see this page in action, open a browser to http://");
    Serial.println(ip); 
  }
  
}


// -----------------------------------------------------------------
// initialize GPIO
// -----------------------------------------------------------------
void initGpio(){


  pinMode(BUTTONPIN, INPUT);
  pinMode(BUTTONLED, OUTPUT);
  digitalWrite(BUTTONLED, HIGH);
}


// -----------------------------------------------------------------
// initialize and start WiFi
// -----------------------------------------------------------------
void initWifi(){
  
  // check for the WiFi module:
  if (WiFi.status() == WL_NO_MODULE) {
    while (true){
      MATRIX.println("No WiFi");
      MATRIX.endText(SCROLL_LEFT);
    }
  }


  // attempt to connect to Wifi network:
  while (status != WL_CONNECTED) {
    // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
    status = WiFi.begin(ssid, pass);
    // wait 10 seconds for connection:
    delay(10000);
  }
}


// -----------------------------------------------------------------
// set feeding time by setting rtc alarm
// -----------------------------------------------------------------
void setFeedTime(){


  // adjust for GMT offset
  int adjTime = feedingTime[feedingTimeIndex].h - GMT_OFFSET;
  if (adjTime < 0){
    adjTime = adjTime + 24;
  }
    if (adjTime > 24){
    adjTime = adjTime - 24;
  }


  // set alarm to feed
  rtc.setAlarmTime(adjTime, feedingTime[feedingTimeIndex].m, 0);
  rtc.enableAlarm(rtc.MATCH_HHMMSS);


  // set index to next feeding time
  feedingTimeIndex++;
  if (feedingTimeIndex >= FEEDINGTIMES){
    feedingTimeIndex = 0;
  }
}


// -----------------------------------------------------------------
// initialize the Real Time Clock
// -----------------------------------------------------------------
void initRtc(){
  
  rtc.begin();
  unsigned long epoch = 0;
  do {
    epoch = WiFi.getTime();
    delay(100);
  } while (epoch == 0);


  rtc.setEpoch(epoch + GMT_OFFSET);  
}


// -----------------------------------------------------------------
// initialize the LED matrix
// -----------------------------------------------------------------
void initLedMatrix(){
  MATRIX.begin();
  MATRIX.brightness(5);
  MATRIX.textScrollSpeed(200);
  MATRIX.beginText(0, 0, 127, 127, 127); // X, Y, then R, G, B
}


// -----------------------------------------------------------------
// display Time
// -----------------------------------------------------------------
void displayTime(){


  MATRIX.beginText(0, 0, 127, 127, 127);
  MATRIX.print("  ");
  int timeH = rtc.getHours() + GMT_OFFSET;
  if (timeH < 0){
    timeH = timeH + 24;
  }
    if (timeH > 24){
    timeH = timeH - 24;
  }
  if (timeH > 12) {
    timeH = timeH - 12;
  }
  MATRIX.print(timeH);
  MATRIX.print(":");
  int timeM = rtc.getMinutes();
  if (timeM < 10){
    MATRIX.print("0");
  }
  MATRIX.println(timeM);
  MATRIX.endText(SCROLL_LEFT);
}


// -----------------------------------------------------------------
// feed the cats!
// -----------------------------------------------------------------
void feedCats(){
  
  if (feedRate > 0){
    // count down
    int i;
    for (i=10; i>0; i--){
      MATRIX.beginText(0, 0, 127, 0, 0);
      if (i < 10){
        MATRIX.print(" ");
      }
      MATRIX.println(i);
      MATRIX.endText();
      delay(1000);
    }
    MATRIX.println("  BLAST OFF! ");
    MATRIX.endText(SCROLL_LEFT);
  
    // servo
    myservo.attach(SERVOPIN);
    myservo.write(SPEED);
    delay((int)(1000 * feedRate));  
    myservo.detach();
  }
  
  // restore button
  pinMode(BUTTONLED, HIGH);
  delay(200);
  buttonPushed = false;


  // mark cats as fed
  timeToFeed = false;


  // set the next feeding time
  setFeedTime();
}  


// -----------------------------------------------------------------
// ISR for button
// -----------------------------------------------------------------
void buttonPush(){
  
  if (buttonPushed == false){
    buttonPushed = true;          // flag button push
  }
}


// -----------------------------------------------------------------
// ISR for rtc alarm
// -----------------------------------------------------------------
void rtcAlarm(){


  // Time to feed the cats!
  timeToFeed = true;
}

 

User Interface

 

The User Interface runs on a server on the Arduino MKR 1010 and is only accessible locally.  It is basic at the moment but we have plans to enhance it with improved HTML and CSS which are not in my core skills at the moment.  Access from a PC, tablet, or smart phone is possible.

image

 

Demonstration

 

The following 90 second demonstration shows the time scrolling and manually activating a feeding cycle.

 

You don't have permission to edit metadata of this video.
Edit media
x
image
Upload Preview
image

 

Conclusion

 

The project was a success in that the design criteria were met and the kids and I  enjoyed the project and learned something.  The positive aspects include:

 

  • Overall design is both fun and functional
  • Scrolling RGB matrix is eye catching
  • Positive displacement screw pump works well
  • Threaded brass inserts worked well and I will be using them again

 

Upgrades that can be considered in future and things that could have gone smoother include:

 

  • The screw geometry and tolerances can be improved
  • Modify the design for easier maintenance, particularly the ability to disassemble and clean
  • Reassess power supply (currently USB power to microcontroller and separate USB to motor)
  • Enhance the User Interface

 

Since the project is fully functional we are going to run it for a while and see if issues crop up.  I would like to reprint some of the parts and include some of the upgrades mentioned above.  Thanks for reading and as always comments, corrections, and suggestions for improvement are always welcome.

 

image

  • Sign in to reply

Top Comments

  • fmilburn
    fmilburn over 4 years ago in reply to ntewinkel +7
    I like your project!! I am happy to send you the STL files although as noted in the writeup there are things I am not entirely happy with and may be changing in the near future. It is one of those projects…
  • genebren
    genebren over 4 years ago +6
    Very nice project! I had always wanted to build a cat feeder, but alas I no longer have need for one. Great selection of 3D printed parts as well as the used of a PVC tee. Everything looked like it worked…
  • fmilburn
    fmilburn over 4 years ago in reply to genebren +6
    Hi Gene, I purchased a set off Amazon that came with a tip that fits my soldering iron: Heat Set Insert Tip for M3 with Qty 30 M3 Inserts Compatible with Hakko FX-888D and Weller SP40NUS Irons: Amazon…
Parents
  • ntewinkel
    ntewinkel over 4 years ago

    This is amazing, Frank!!

     

    I totally want to follow in your footsteps on this one!

    Charlie Kat needs an upgrade to his (somewhat failed) treat dispenser of many years ago.

     

    Will you be sharing the STL files for the 3D printed parts?

     

    The only major flaw I see in the post, as wolfgangfriedrich pointed out, is the lack of cats image

     

    Best,

    -Nico

     

    ps, I found my much less refined project from 5 years ago. I think the "hardware" is still in the basement somewhere. Charlie never did learn to press the mouse button. Or he learned it was easier to just get us to do the work image

    Charlie and the Treat Dispenser

    • Cancel
    • Vote Up +6 Vote Down
    • Sign in to reply
    • More
    • Cancel
Comment
  • ntewinkel
    ntewinkel over 4 years ago

    This is amazing, Frank!!

     

    I totally want to follow in your footsteps on this one!

    Charlie Kat needs an upgrade to his (somewhat failed) treat dispenser of many years ago.

     

    Will you be sharing the STL files for the 3D printed parts?

     

    The only major flaw I see in the post, as wolfgangfriedrich pointed out, is the lack of cats image

     

    Best,

    -Nico

     

    ps, I found my much less refined project from 5 years ago. I think the "hardware" is still in the basement somewhere. Charlie never did learn to press the mouse button. Or he learned it was easier to just get us to do the work image

    Charlie and the Treat Dispenser

    • Cancel
    • Vote Up +6 Vote Down
    • Sign in to reply
    • More
    • Cancel
Children
  • fmilburn
    fmilburn over 4 years ago in reply to ntewinkel

    I like your project!!  I am happy to send you the STL files although as noted in the writeup there are things I am not entirely happy with and may be changing in the near future.  It is one of those projects that follow the Pareto principle.  I got to 80 percent with 20% of the effort and to get most of the remaining issues cleared will take at least as much time as what I already have invested.  Do you have Fusion 360?  Maybe we can collaborate on an improved version.  I think the cost can be cut considerably with a custom PCB and less expensive LCD as well.

    • Cancel
    • Vote Up +7 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • ntewinkel
    ntewinkel over 4 years ago in reply to fmilburn

    Hi Frank!

     

    I see I have Fusion360 installed, but I don't know if I've ever really used it LOL.

    Most of my 3D prints so far have been direct from Thingiverse, with a few that I've modified using TinkerCAD.

     

    It's mostly the mechanisms I was going to borrow, with a naive hope to still get that cat to push a "mouse" button for treats.

    I don't think I'd get any sleep at night if I didn't have their kibble dishes completely full before going to bed - there'd be too much loud complaining happening - so timed feedings aren't really needed here.

    That's not to say the timed setup wouldn't find other uses around here - like feeding the birds maybe.

     

    I wonder if the use of a Wemos / Lolin board and shields would help reduce costs? Even on Amazon the D1 minis are only $5 CAD each now with next day delivery if I buy 5. Even less if direct from China, but that takes nearly 6 months to get here now!

     

    In any case, I'd be happy to help figure things out where I can image

     

    ps, I live my life on the 80-20 rule... I forgot it was named the Pareto principle image  Just the other day I cleaned up 80% of the branches off the lawn. good enough. Half an hour to fill up 3 bins image

     

    Best,

    -Nico

    • Cancel
    • Vote Up +5 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • fmilburn
    fmilburn over 4 years ago in reply to ntewinkel

    Hi Nico!

     

    Fusion 360 has a steep learning curve and I am nowhere near the top but it really is powerful and has been rewarding for me.

     

    Let me know which mechanisms you would like and I will send you what I have or we can discuss what to modify first.  Below is a more detailed list of what I think could be improved and why:

    • Storage:  From an aesthetic point of view I would make the 3 rocket sections all the same height and the fins longer on the lower section.  From a stability point of view I would also make the "skirt" section of the tail that goes over the tee longer.
    • Metering:  Mechanically, the kibble can occasionally catch on the front mount which doesn't stop it from working but still.  I think this can be fixed by shortening the auger blades just a bit.  This is a bit hard to describe and maybe a bit of grinding can be expected when pumping solids.  The other issue I would like to address is easier disassembly for cleaning.
    • Mounts:  The screws which attach it to the wooden base are hard to access.  Since at least one side needs to be removed for cleaning this is part of the last issue above.
    • Power:  A power supply with a LDO regulator for the microcontroller is the way to go rather than what I frankensteined together.
    • Panel and Enclosure:  I'd like to move the screen for aesthetic reasons.
    • Microcontroller and Screen:  The Arduino MKR1010 is about $20 and the RGB matrix is about $30 and they drive the cost.  They work fine though and I like the dot matrix print from an aesthetic viewpoint.  A single color matrix display is much less expensive but I wonder if a TFT screen could be used with a scrolling dot font could be used if you get where I am coming from.  I would think a ESP8266 or ESP32 would work fine.
    • Cancel
    • Vote Up +4 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • dubbie
    dubbie over 4 years ago in reply to fmilburn

    Frank,

     

    Ahhh, the old 80:20 split. I think this is why I didn't stay an engineer, I just couldn't be fussed with that last 20% bit. Once it was (functionally) working I just lose interest.

     

    Dubbie

    • Cancel
    • Vote Up +4 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • neilk
    neilk over 4 years ago in reply to dubbie

    dubbie  wrote:

     

    Ahhh, the old 80:20 split. I think this is why I didn't stay an engineer, I just couldn't be fussed with that last 20% bit. Once it was (functionally) working I just lose interest.

     

    Dubbie,

     

    Comforting to find someone else who admits to failure with the last 20%!!!!!!

     

    Story of my life, let alone my career!

     

    Neil

    • Cancel
    • Vote Up +5 Vote Down
    • Sign in to reply
    • More
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube