Herramientas de línea de comandos para diseñadores. Parte I.

Como automatizar la creación de gráficos para web y aplicaciones móviles usando herramientas de línea de comandos en OSX

Introducción

Un diseñador se dedica a su profesión porque su interés se enfoca principalmente en lo visual y lo auditivo, en utilizar su creatividad para el deleite de los sentidos. Al diseñador no le interesa hablar de lenguajes de programación ni de código fuente, ni bases de datos, para eso están los programadores.

Una de las razones por las que los diseñadores no se enfrentan a temas de programación es porque la mayoría de las aplicaciones utilizan interfases gráficas para todo (para la edición fotográfica, generación de gráficos vectorizados, animación, etc.). Si deseas animar un objeto de tal forma que se mueva de un lado a otro de la pantalla en línea recta, y que comience su movimiento acelerando y finalmente desacelerando, es muy fácil hacerlo a través de una interfase gráfica o un asisitente que te lleva de la mano, escondiendo toda la dificultad, las ecuaciones y el cálculo de trayectorias. Sin embargo, si quieres hacer una animación más caprichosa, digamos mover un objeto en espiral, tal vez no exista un asistente o funcion predefinida para esto. Es entonces cuando te metes en las partes más obscuras del manual de usuario y te das cuenta que la aplicación permite hacer cosas mucho más avanzadas pero tienes que hacerlo a través de un lenguaje de programación propio de la aplicación.

Este tipo de lenguajes existen en muchas de las aplicaciones de diseño más populares como Photoshop e Illustrator, y en general en las principales aplicaciones de compañías como Adobe, Corel o Autodesk. Javascript es otro ejemplo de lenguaje de programación al que los diseñadores web se enfrentan constantemente, ya que hoy en dia es muy difícil encontrar un sitio web que no utilice esta tecnología para desplegar contenido dinámico.

La programación en el mundo del diseño no solo sirve para empujar la parte creativa, sino también para ayudarnos en las partes más aburridas de nuestro trabajo, y este es precisamente el objetivo de esta serie de artículos. Ayudarte a automatizar las tareas repetitivas, como por ejemplo:

  • Transformar 30 imagenes de color a blanco y negro, y bajar la resolución.
  • Convertir un montón de imagenes de jpg a png y ponerles una marca de agua con el logotipo de la empresa.
  • Hacer 40 iconos para una aplicación móvil, y hacer 6 versiones de cada uno, para diferentes dispositivos y diferentes densidades de pantalla, todos en negro con soporte para transparencia.
  • Modificar el color de todos los iconos de la aplicación porque el cliente decidió cambiar la imagen de su marca.

Tu jefe te pregunta “¿cuanto te tardas en hacer x tarea?” y le contestas que necesitas un par de horas, porque el trabajo no es difícil pero es laborioso. En esta serie de artículos te voy a decir como hacer cada una de estas tareas en un par de minutos para que puedas ver esa nueva serie de Netflix mientras tu jefe cree que sigues dando miles de clics.

Misión

Vamos a suponer que el Project Manager te pide que entregues 10 iconos para una aplicación de iOS. Cada icono debe entregarse en formato png con transparencia y en 3 resoluciones diferentes: 24×24, 48×48 y 72×72. Además quiere todos los iconos de 24×24 estén en una carpeta llamada 1x, los de 48×48 en una carpeta llamada 2x y los de 72×72 en una carpeta llamada 3x.

Abres tu editor favorito y comienzas con la parte divertida del trabajo, aquella en la que te llega la inspiración divina y creas verdaderas obras de arte. Terminada esta etapa llega la parte aburrida de exportar los archivos en las diferentes resoluciones y carpetas. Pero en lugar de hacer todo esto manualmente lo vas a hacer como te voy a explicar ahora.

Para este tutorial exporta algunos de tus iconos en formato png en una resolución base (digamos 512×512) y guardalos en una carpeta, ya que los usaremos en la última parte.

Para esta tarea estaremos utilizando tres herramientas que iré explicando poco a poco: terminal, sips, y shell scripts.

La terminal de OSX

(Si ya has usado la terminal antes, puedes saltarte esta sección).

En las primeras computadoras no existian los ambientes gráficos como los conocemos hoy, y toda interacción entre el usuario y la computadora era a través de comandos de texto. El sistema operativo reconocía un conjunto predefinido de comandos y cada uno tenía una forma específica de usarse. Algunos comandos se utilizaban para la manipulación de archivos (monstrar los archivos existentes, copiar, mover, borrar), otros para mostrar información del sistema, y otros para funciones más especializadas.

Todos los sistemas operativos modernos incluyen una aplicación llamada terminal que no es más que un programa que nos permite introducir comandos, como en los viejos tiempos. Otros nombres para la terminal son: línea de comandos, símbolo del sistema o consola.

Existen muchos tutoriales que te enseñarán lo básico de la línea de comandos como por ejemplo: http://foro-mac.com.ar/tutorial-como-usar-la-terminal-en-mac/

Lo ideal es que sepas como utilizar los siguientes comandos básicos:

cd, ls, pwd, man, cp, mv, rm, echo, mkdir, rmdir, sh

Ahora si… ¡manos a la obra!

Abre la terminal (desde el menu Aplicaciones -> Utilities -> Terminal, o bien escribe “Terminal” en Spotlight). Automáticamente estarás posicionado en tu directorio de usuario (home), y ese será tu directorio de trabajo inicial.

screen-shot-2016-12-15-at-10-24-12Te recomiendo que tengas abiertas simultaneamente terminal y Finder y que los acomodes en la pantalla de tal forma que en todo momento puedas ver las dos. El objetivo es que conforme vayas tecleando los comandos vayas viendo los efectos en Finder.

Primero vamos a crear un directorio con el comando mkdir.

$ mkdir ejemplo

Comprueba que puedas ver esta carpeta en Finder. A continuación hacemos que este directorio sea nuestro directorio de trabajo con el comando cd.

$ cd ejemplo

Para verificar que estamos en el directorio correcto escribimos el comando pwd, este comando lo único que hace es mostrar nuestro directorio de trabajo.

$ pwd
/Users/jorge/ejemplo

Usaremos una imagen de la página iconfinder.com como ejemplo. Desde tu navegador descarga el archivo que está en la siguiente dirección: https://cdn4.iconfinder.com/data/icons/glyphs/24/icons_user2-512.png. Una vez que has descargado la imagen, abre Finder y encuentra el archivo descargado y muévelo a la carpeta ejemplo que creamos anteriormente y que está ubicado directamente en tu directorio de usuario.

screen-shot-2016-12-15-at-09-46-10

Nuevamente en la terminal, vamos a teclear el comando ls -l, que enlistará todos los archivos que están en nuestro directorio actual. Debemos de ver la imagen que descargamos anteriormente.

$ ls -l
total 16
-rw-r--r--@ 1 jorge staff 8128 Dec 14 22:30 icons_user2-512.pn

Ahora utilizaremos un programa que se llama sips, que es una herramienta que sirve para procesar imágenes. La imagen que descargamos tiene una resolución de 512×512 pixeles y vamos a crear una version de 24×24, escribiendo el siguiente comando.

$ sips -Z 24 icons_user2-512.png --out ejemplo1_24.png
/Users/jorge/ejemplo/icons_user2-512.png
 /Users/jorge/ejemplo/ejemplo1_24.png

Vamos a explicar este comando paso a paso: sips es el nombre del programa, -Z 24 es una opción con el que indicamos que deseamos cambiar el tamaño de la imagen de modo que ni la altura ni la anchura excedan de 24 pixeles, icons_user2-512.png es el nombre del archivo que deseamos manipular, y finalmente --out ejemplo1_24.png significa que queremos que el resultado se guarde en un archivo nuevo con el nombre especificado (si omitimos esta última parte, el programa sobreescribirá la imagen original).

Como podrás adivinar para hacer las versiones de 48×48 y 72×72 usamos los siguientes comandos.

$ sips -Z 48 icons_user2-512.png --out ejemplo1_48.png
/Users/jorge/ejemplo/icons_user2-512.png
 /Users/jorge/ejemplo/ejemplo1_48.png
$ sips -Z 72 icons_user2-512.png --out ejemplo1_72.png
/Users/jorge/ejemplo/icons_user2-512.png
 /Users/jorge/ejemplo/ejemplo1_72.pn

Ahora nuestro directorio de trabajo deberá tener 4 imagenes (la imagen original y las 3 versiones nuevas), asi que vamos a comprobarlo enlistando los archivos. No olvides tambien comprobarlo en Finder.

$ ls -l
total 40
-rw-r--r-- 1 jorge staff 593 Dec 15 09:55 ejemplo1_24.png
-rw-r--r-- 1 jorge staff 1204 Dec 15 09:56 ejemplo1_48.png
-rw-r--r-- 1 jorge staff 1897 Dec 15 09:56 ejemplo1_72.png
-rw-r--r--@ 1 jorge staff 8128 Dec 14 22:30 icons_user2-512.pn

Ahora vamos a modificar nuestros comandos para que los archivos se guarden en las carpetas adecuadas.

Primero limpiamos nuestro directorio de trabajo borrando los archivos que generamos.

$ rm ejemplo1*.png

El comando anterior utliza el caracter * como comodín, es decir, borrará cualquier archivo cuyo nombre tenga el formato “ejemplo1 + cualquier cosa + .png”

Ahora creamos los tres directorios donde guardaremos nuestros iconos.

$ mkdir 1x 2x 3x

Finalmente generamos nuestros iconos y los guardamos en las carpetas correctas

$ sips -Z 24 icons_user2-512.png --out 1x/ejemplo1_24.png
/Users/jorge/ejemplo/icons_user2-512.png
  /Users/jorge/ejemplo/1x/ejemplo1_24.png
$ sips -Z 48 icons_user2-512.png --out 2x/ejemplo1_48.png
/Users/jorge/ejemplo/icons_user2-512.png
  /Users/jorge/ejemplo/2x/ejemplo1_48.png
$ sips -Z 72 icons_user2-512.png --out 3x/ejemplo1_72.png
/Users/jorge/ejemplo/icons_user2-512.png
  /Users/jorge/ejemplo/3x/ejemplo1_72.png

Verifica en Finder que se hayan creado las carpetas y que en cada una de ellas tengas un icono.

Automatización de tareas utilizando shell scripts

Para automatizar nuestras tareas podemos utilizar cualquier lenguaje de programación de scripts. Algunos ejemplos son perl, php, ruby, javascript, y python. En esta ocasión utilizaremos algo que se llama shell scripts, cuya sintáxis básica ya conoces porque consiste en hacer un script con los comandos que hemos usado en este artículo.

Quiero mencionar que los shell scripts son muy poderosos, pero su sintáxis puede llegar a ser muy complicada y confusa, y es por eso que muchas veces es mejor utilizar algun otro lenguaje como los que mencioné anteriormente.

Antes de escribir nuestro primer programa vamos a limpiar nuevamente nuestro entorno de trabajo borrando todo lo que hemos hecho hasta ahora, excepto nuestra imagen original.

$ rm -fr 1x 2x 3x

Crea un archivo nuevo en tu editor de texto favorito e ingresa el siguiente texto. Como podrás ver, estamos escribiendo todos los comandos que hemos utilizado hasta ahora, cada uno en una línea nueva. Guarda el archivo con el nombre ejemplo1.sh en la carpeta ejemplo, y asegúrate que lo guardes como texto sin formato.

mkdir -p 1x 2x 3x
sips -Z 24 icons_user2-512.png --out 1x/ejemplo1_24.png
sips -Z 48 icons_user2-512.png --out 2x/ejemplo1_48.png
sips -Z 72 icons_user2-512.png --out 3x/ejemplo1_72.png

Para ejecutar el script utilizamos el comando sh.

$ sh ejemplo1.sh
/Users/jorge/ejemplo/icons_user2-512.png
 /Users/jorge/ejemplo/1x/ejemplo1_24.png
/Users/jorge/ejemplo/icons_user2-512.png
 /Users/jorge/ejemplo/2x/ejemplo1_48.png
/Users/jorge/ejemplo/icons_user2-512.png
 /Users/jorge/ejemplo/3x/ejemplo1_72.png

Como verás el resultado es el mismo que obtuvimos cuando hicimos las cosas paso por paso. Para comprobarlo verifica como quedaron los archivos en Finder.

screen-shot-2016-12-15-at-10-14-42Ahora para el paso final, coloca en el directorio ejemplo otras imagenes con formato png (las puedes descargar de iconfinder.com o bien coloca algunas de tus propias creaciones). A continuación crea un script llamado ejemplo2.sh y escribe el siguiente código y guardalo en la carpeta ejemplo.

for IMAGEN in *.png
do
    sips -Z 24 $IMAGEN --out 1x/$IMAGEN
    sips -Z 48 $IMAGEN --out 2x/$IMAGEN
    sips -Z 72 $IMAGEN --out 3x/$IMAGEN
done

Ejecuta el script con el comando

$ sh ejemplo2.sh

Ahora, desde Finder, verifica el contenido de la carpeta ejemplo y sus subcarpetas. Hemos logrado nuestro objetivo! Para cada imagen, hemos creado 3 versiones y las hemos colocado en los directorios adecuados, todo en un par de segundos.

Antes de concluir vamos a analizar lo que hace este pequeño programa. La palabra for inicia un ciclo o bucle, y ejecuta el código que se encuentra entre las palabras do y done para cada iteración. Las iteraciones están determinadas por la expresión for IMAGEN in *.png, que indica al programa tomar cada uno de los archivos cuyo nombre se puede representar con *.png (es decir, todas las imagenes con extension png), guardar temporalmente el nombre de cada archivo encontrado en la variable IMAGEN (esta variable la puedes llamar como quieras) y ejecuta los comandos especificados. Dentro de los comandos se utiliza la variable $IMAGEN que contiene el nombre del archivo en turno (el simbolo $ denota que es una variable, de lo contrario el programa buscará un archivo llamado IMAGEN).

Conclusión

Hemos visto que a través de un script y algunos comandos sencillos podemos ahorrar un montón de tiempo en las tareas más repetitivas de nuestro trabajo.

El ejemplo que vimos hoy es tan solo una pequeña probada de lo que se puede lograr con un pequeño script, pero aprendiendo a utilizar estas herramientas no solo podremos cambiar de tamaño imágenes, sino tambien podemos cambiar el color, añadir texto, añadir marcas de agua, organizarlos en directorios, enviarlos por FTP a un servidor remoto, enviarlos por mail, etc.

Dual Pet Food Dispenser

Introduction

You’re a proud pet owner, and on a nice Friday afternoon:

M: Hey George, how about grabbing some beers tonight, right after work? There will be some nice girls that we can impress with our programming skills!
G: Sorry dude, I have to go home and feed Rocky and Hulk, otherwise they’ll eat my furniture.
M: You suck, bro!
G: I know, I’m sorry!

If this (or a similar situation) has ever happened to you, and you’re a geek, this might be of your interest!

In this article I’m going to talk a little bit about the automatic pet food dispenser, and I’ll dig a little bit deeper into both mechanical and electronic design. I’ll also explain a little bit about the details for it’s physical construction. If you want just to build this thing, you can download the 3D physical design, the electronic schematic diagram, the PCB design and the firmware and you’re ready to go, but I want to focus this article on how I came up with the design, the decisions that I had to make regarding component choice and building materials and the variables that lead to those decisions. You can think of this as a little tutorial on how to design an electronic/mechanical gadget.

Description

We’re talking about a “dual pet food dispenser”, a device that feeds two bowls of food for two different pets on the same diet, although different quantities are allowed for each pet. The system would have a real-time clock keeping track of time, and the user can program an alarm, which when triggered at a specific programmed time, starts serving food through a mechanism that pulls food from a container, and another mechanism allows the food to be dispensed to the appropriate bowl.

The system would have a status LED as a visual indication that it’s turned on.
The user would interact with the system using four push-buttons: a button to select the function, a button to selected the parameter within the function, and two buttons (UP and DOWN) to increment or decrement the parameter being edited. The user would have feedback of his inputs by means of a 16×2 LCD display.

A 3D model of the device would look like this:DogFeeder02The food would be placed in the upper container, fall through the circular hole into the pipe with the helix (in red) which would push the food to the other end and finally fall into one of both bowls, depending on the position of the  bowl selector (in yellow).

User interface

The user’s input via the four push-buttons and the visual feedback through the LCD is designed in a menu-like fashion. The fist button iterates through all possible functions, the second button iterates through all possible parameters within a selected function, and the last two buttons modify the value being edited, as summarized in the following table:

Function                                     Parameter                    Up/Down
Display time/date                            N/A                          N/A
Display time/date when last dispensed        N/A                          N/A
Manual mode                                  Left bowl dispensing time    Enabled
                                             Right bowl dispensing time   Enabled
                                             Start/Stop                   Enabled
Set Timer 1                                  Hour                         Enabled
                                             Minutes                      Enabled
                                             Bowl A dispensing time       Enabled
                                             Bowl B dispensing time       Enabled
Set Timer 2                                  Hour                         Enabled
                                             Minutes                      Enabled
                                             Bowl A dispensing time       Enabled
                                             Bowl B dispensing time       Enabled
Set Time                                     Hour                         Enabled
                                             Minutes                      Enabled
                                             Seconds                      Enabled
Set Date                                     Day                          Enabled
                                             Month                        Enabled
                                             Year                         Enabled

Other nice features considered in the design:

  • LCD backlight that turns off after 20 seconds of no user interaction
  • Backup battery that saves the time and date in case of a power outage
  • Up and Down buttons allow a long press for fast value increments/decrements

 

Electronic Design

Let’s start by sharing the electronic diagrams. Down here you’ll find the PROTEUS Isis schematic diagram used for testing the firmware. It’s important to notice that the hex code provided (see below) doesn’t work on the simulation, basically because it’s not the real processor. The simulation proved to be extremely useful for testing isolated portions of the code, however the full production code only works on the real hardware. Particularly I couldn’t get the I2C protocol to work on the simulation.

DogFeeder
Click to download PROTEUS schematic

I wrote the schematic twice: the one above, and the schematic for the PCB design using EAGLE. Both schematics differ because for simulation we can omit a great deal of components, such as the power source details. The diagram for the PCB includes connection points for external components rather that components themselves, an example would be placing male jumpers instead of the LCD display (which will be connected to the jumpers with wires).

schematic

circuit

circuit_all
Click to download EAGLE PCB desgin (zip)
Click to download the hex file to write on the PIC MCU (zip)

Inputs and Outputs

The first thing you need to determine is WHAT and HOW the system does what it does, and how the user interacts with it. As you can read in the previous section, a simple yet appropriate system description in plain-English leads to determine the inputs and outputs and other features of the system. In the description above, I’ve highlighted in bold the keywords that lead to determine the I/O peripherals needed:

  • Real-time clock – keeps track of time
  • LED – visual indication of the system power state
  • LCD display –  give feedback to the user
  • 4 push-buttons – allow the user to interact
  • motor – get food from a container
  • servo – select a bowl

Component choice, as explained further, is mainly based on price, availability, component reuse possibility, and available documentation.

Real Time clock

To have a real-time clock (RTC) you have many options: having a dedicated RTC chip, using your main MCU (with an additional crystal oscillator) and write some extra code, or even connect your device to the Web and get the time from a server. The last option is too far-fetched for my purposes while using the main CPU would have complicated the code by writing a bunch of date/time routines and keeping exact track of the CPU cycles and other complications (but it’s still possible).

I choose to have a dedicated chip with it’s own 32KHz crystal. Of the various options I found that the DS1307 was quite popular and it has a lot of related resources on the web, but most important, it’s available on local stores.
There are other chips that already have some alarm functionality built in, these can be very good alternatives to the design.

Most of these chips, including the DS1307, communicate using the I2C protocol. This is the very moment when I had to add the ‘I2C protocol’ to the list of features needed by the MCU.

Motors

The mechanical work is being done by two devices.

The first device spins an axis with a helix-shaped piece to make the food travel from the food container to an intermediate outlet. This device could be a stepper motor, a plain DC motor, a continuous servo or any other motor that you like. I’m planning to let the user select the food portion in terms of time, e.g., how many seconds should the motor spin to serve the food portion? For this purpose a plain old DC motor will do the job, I turn it on for the specified amount of time and tadaaa!… the food is on the table (if you prefer to let the user specify how many turns the device should make, then you could opt for a stepper motor).

I found a cheap 12V motor (reused from an old printer probably) with a very nice reduction gearbox having an output of ~0.3 rpm (or one revolution every 3 seconds) and a hell of a torque that makes it impossible to cause a motor-stall with bare hands.

The power transmission from the motor to the helix is achieved with gears and a belt. I did not use any bearings between the spinning parts and the frame, because I considered that I had enough torque to overcome any possible friction, and also because for such a slow speed, friction wouldn’t raise the temperature to a worrying level, but, needless to say, bearings are an enhancement you could add to your own design.

The second device positions a plate that makes the food travel from the intermediate outlet to any of the two bowls. For this you need to have a precise control of the angle, and once again, you can use a servo, a stepper motor, or even a plain DC motor (with some position feedback such as force-stop switches, optical switches, or any form of encoder). The easiest of course was the servo, which needs to be calibrated appropriately after installing, and for this purpose I included nice calibration routine in the firmware that is activated when plugging the device while pressing the FUNCTION button.

Other peripherals

The remaining peripherals to explain are the push-buttons, status LED and LCD display. I assume there’s no need to explain too much about the push-buttons or the LED: the push-buttons are simple circuit shorters, each MCU pin is connected to +5v via a pullup resistor, hence pushing the button grounds the pin driving it low. It’s important to note that the firmware includes some debouncing code for the buttons (debouncing could also be achieved in hardware, if you prefer). The LED might also need a resistor connected in series.

For the users feedback I decided to use a 16×2 LCD based on the very popular Hitachi HD44780 controller. There are many examples out there on how to drive such a display driver from a microcontroller, and you’ll find many different libraries on the web for pretty much any MCU flavor.

Power supply

Wait a second… you said 12v motor??? But the whole circuit runs on 5v! Yep, that means that the main power supply should be 12v, and we need to provide a step-down circuit using our good old friend the 7805, to bring the voltage down to 5v and have a dual (12v and 5v) power supply. I used an out-of-the-box 12v power supply that has a transformer, rectifiers and filters in one single piece.

Microcontroller Capabilities

Some of the important microcontroller capabilities I’m using are:

  • PWM. Pulse Width Modulation is the technique used to drive the servo, and optionally you can use it to control the speed of the main motor. In my design, the motor at full speed coupled with the reduction gearbox is slow enough for my purposes so no PWM needed here. To drive the servo, on the other hand, I realized after many attempts (and as backed by many other people in blogs and forums) that generating a proper PWM signal (with a kinda-standard period of ~20ms) was rather tricky using the integrated PWM module combined witht the 4MHz crystal oscillator and the prescaler options from the PWM timer, that’s why I decided to generate the PWM signal for the servo with my own code using timers. As a side consecuence, the PWM module wasn’t doing any job so I used it to create a pulsing status LED that slowly fades in and out by changing the PWM duty cycle.
  • Timers. The timers are probably the most important MCU features used, for the following purposes:
    • Debouncing of push buttons
    • Keeping track of a long press on a UP/DOWN button to rapidly increment or decrement a parameter’s value
    • Turn off LCD backlight after 20 seconds of no user interaction
    • Generate PWM to drive the servo (and optionally the motor, if you want it to run slower)
  • I2C. If you want to talk to a man that only speaks chinese, then you have to learn chinese. If our real-time-clock talks I2C, then the MCU needs to talk I2C. The I2C protocol is a very clever way of having a bidirectional communication between two devices using only two wires, and is used widely by EEPROMs and our beloved real-time clock integrated circuit. The protocol itself is rather complex and you could eventually do without integrated I2C support, but why would you want to reinvent the wheel?

Which microcontroller to use?

The first challenge for any microcontroller driven circuit is to choose an appropriate microcontroller. Appropriate means not to small that it can barely cope with the demanded work and not to big that it would be like shooting a fly with a cannon.
This step is the core of the design but it’s considerably easier than you might think, it’s just a matter of knowing the device capabilities that you will be needing (timers, PWM modules, communication protocols, A/D conversion…) and a clear understanding of all the input and output ports (I/O pins) that you will be using. The inputs and outputs, as well as the device capabilities are described earlier.

Needless to say, you can use any microprocessor technology, the one you feel the most comfortable with, such as the popular Arduino and Atmel chips, Microchip and others. I decided to go for Microchip over Arduino because I’ve used the Microchip platform in the past and also because I think that Arduino it has two major disadvantages: first it’s expensive compared to Microchip, and second, I like to have more control and better understanding of the bits and bytes of the firmware and the electronic design.

My design is built around the PIC18F2420 microprocessor from Microchip. To come up with this choice, I looked up in the Microchip’s website, filtered all MCUs using criteria such as: having at least the number of I/O of pins needed, I2C availability, PWM module, number of timers, flash memory size (very important) and EEPROM size. I came up with a reduced list of options. I wrote down a couple of the smallest ones fitting my criteria and went to the store. Picking the smallest is easy because the smart Microchip web site designers/programmers list all microcontrollers in an order based on price by default, so, in a way, the first ones listed should be your best options. The PIC18F2420 was my second option, because my first option (don’t remember which one) was not available locally.

The construction process for the electronics is pretty much self-explanatory for those who have some experience building electronic stuff. Just etch the PCB, solder all components, burn the firmware in the microcontroller, connect the motors and other peripherals to the PCB using headers and you’re ready to go.

 

Mechanical Design & Construction

There are many different mechanical ways of dispensing food to your pet. I considered, amongst others, a conveyor belt, a screw shaped device, a mill-type thing… just let go your imagination. I went for the screw shaped device to push the food, and a tilted plate to select direction, as shown in the 3D models.

DogFeeder01

DogFeeder03

DogFeeder04

The difficult thing about a home-made mechanical design is that you can’t really have a precise mechanical design until you have pretty much all electronic components in hand. For example, you know you need a 12v motor, but you don’t know how it will look like until you have it in your hands, especially when you’re reusing parts from old printers. Motors have screw holes to attach them to their enclosure, but they can come in many different shapes or positions. Needless to say this problem also holds for servos, LCD and even the PCB. The bottom line is: you design the enclosure and the whole physical assembly once you have certainty of the components you’ll use, and, in fact, for me the physical design was a cyclical process where I had to modify the design as I was building it.

The two main mechanic parts are the motor that drives the helix, and the servo that drives the bowl selector.

The helix (and its shaft) is a two-piece 3D printed part: two parts resulting from cutting the piece along it’s axis, mainly because the 3D printer can’t easily print everything in one single piece. This piece is enclosed in a U-shaped structure made using an acrylic 3″ pipe (as explained further) and driven by the 12v motor via a belt.

DogFeeder06
Download STL files for 3D printing

The bowl selector is driven by a servo as you can see in the following image, which is pretty much self-explanatory.

DogFeeder05

The structure, enclosing case, and pretty much the whole thing is built out of acrylic (plexi glass). I had some nice acrylic sheets (3mm and 4mm thick) at home, so this was the main reason for this choice, and a very convenient one since it’s an easy yet robust material to work with and, as an additional advantage, you don’t need very sophisticated tools to cut and shape the sheets. I used some very basic gear: a hand saw, sandpaper, drill, and a torch to bend the acrylic. If you have access to laser cutter and other nice tools the job will be easier and hopefully more precise.

Another design bullet on my wishlist was the fact that I wanted the device to be transparent so I could see the guts of the device while working, it’s a nice spectacle! Needless to say you can work with any material of your choice.

All acrylic parts are either screwed or glued to each other. The choice between glue and screws is only dependent on the assembly process, e.g., I should be able to disassemble the whole machine to access, modify, change some of the parts. Parts that might stay together during assembly/disassembly are glued to each other, parts that need to be separated are joined using screws. Make sure you use acrylic glue or cement; I tried superglue resulting in white-ish stained parts, and I tried another very good epoxic substance but it’s messy and takes more than 10 hours to dry and cure.

Also be careful when you make holes in acrylic, because it melts due to the friction heat. I ran into problems when stopping the drill while making holes, because the acrylic would melt and then solidify stuck to the bit. Sometimes to remove the bit I had to break the acrylic part, throw it to the trash can, and start the part from scratch.

Problems Encountered

Obviously building this thing couldn’t go without any bugs. And I’m not talking about firmware bugs that are easy to solve by correcting the code, compiling, burning in to the chip and running. I’m talking here about major issues.

The biggest problem I encountered was related to the food getting stuck in the container and not wanting to fall through the circular hole into the U-shaped pipe. My good old friend Manuel predicted I would have this problem and suggested to add some vibrator to the food container, this would make the food shake and fall. I tried with some vibrators connected in parallel with the main motor and physically attached to the container in different ways but the problem was still there. The solution I found was to stir the food by adding a shaft with some screws inside the food container. This shaft is driven by the main motor for which I replaced the original short belt for a long one that would drive both the helix and the stirring shaft, as you can see in the following image. In the video you can see this piece at work.

20150514_105302