=======Dispensador de comida para mascotas======= **Integrantes:** Luis Diego Fernández, B22492 Alejandro Rojas, B36049 =====Descripción del proyecto===== Crear un dispensador de comida para mascotas. Se diseñará la estructura del dispensador así como su mecánica de dispensado de comida. Se utilizará un microcontrolador Raspberry Pi y una llave de Wi-fi para que funcione mediante una aplicación móvil. En dicha aplicación se podrán controlar todos los parámetros necesarios para que el dispensador sea adecuado para cualquier mascota. =====Obejtivos===== ====Objetivo general==== Crear un dispensador de comida para mascotas. ====Objetivos específicos==== **Primera parte** - Investigar qué tipo de problemas presentan los dispensadores de comida actuales. - Aprender a trabajar con un microcontrolador Raspberry Pi y con un Piface. - Diseñar un modelo virtual del dispensador de comida. - Aprender a utilizar el programa Android Studio para el desarrollo de aplicaciones en esta plataforma. **Segunda parte** - Encontrar un método de dispensado efectivo y libre de problemas. - Controlar el sistema mecánico de dispensado de comida por medio del Raspberry Pi. - Desarrollar una aplicación móvil que logre controlar el dispensador. - Conectar y manejar el Raspberry Pi por medio de la aplicación móvil =====Problemas de los dispensadores===== Se encontraron algunas críticas a los dispensadores de comida que hay en el mercado, específicamente los detectamos por medio del sistema de comentarios y críticas de Amazon. Entre los principales problemas encontramos: * Cantidad de porciones de comida es limitada, con esto se refiere a el número de veces que se puede proporcionar una comida. [1] * Después de unos días de uso, las mascotas descubren como sacar las comida del dispensador. [2] * La comida se queda pegada. [3] * No se dispensa la cantidad de comida adecuada. [4] =====Trabajo con el Raspberry Pi y Piface===== Se descargó el sistema operativo Raspbian, con el cual funcionan los microcontroladores Raspberry Pi. Raspbian es un sistema operativo libre que se basa en Debian, optimizando sus usos para el Hardware del Raspberry Pi. Se instaló Raspbian en una tarjeta SD de 8gb de memoria. Luego se instalaron las aplicaciones necesarias para poder hacer uso de Piface por medio de la siguiente guía: http://www.piface.org.uk/guides/Install_PiFace_Software/Enabling_SPI/ Al término de la guía mostrada anteriormente ya se puede probar el Piface por medio de un emulador y también con programas sencillos para familiarizarse con su forma de ser programado. La importancia del Piface es que este posee 2 relays, estos sirven como switch, (se activan gracias a un campo magnético) para poder utilizar fuentes de poder externas. En este caso se utilizó una fuente de 12 V en CD y está maneja un motor. Se armó un circuito como el de la siguiente imagen: {{ :ie0117_proyectos_i_2015:proyecto_1:piface-relay-connection.png?300 |{{ :ie0117_proyectos_i_2015:proyecto_1:piface-relay-connection.png?300 |}} =====Trabajo con el Andorid Studio===== Se descargó el programa y se corrieron algunos progamas de prueba para aprender a utilizarlo. De esta manera se creó el primer diseño de la aplicación que se utilizará, esta se hizo con el siguiente código: import android.app.TimePickerDialog; import android.support.v7.app.ActionBarActivity; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.Spinner; import android.widget.EditText; import android.widget.TextView; import android.widget.ArrayAdapter; import android.widget.AdapterView; public class dispensador extends ActionBarActivity { private EditText Valor1,Valor2; private TextView Resultado; private Spinner cmbOpciones; private String Valores; private int select; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_dispensador); final String[] datos = new String[] {"1/2 Taza","1 Taza","1 y 1/2 Tazas","2 Tazas","2 y 1/2 Tazas"}; ArrayAdapter adaptador = new ArrayAdapter(this, android.R.layout.simple_spinner_item, datos); cmbOpciones= (Spinner)findViewById(R.id.spinner); adaptador.setDropDownViewResource( android.R.layout.simple_spinner_dropdown_item); cmbOpciones.setAdapter(adaptador); cmbOpciones.setOnItemSelectedListener( new AdapterView.OnItemSelectedListener() { public void onItemSelected(AdapterView parent, android.view.View v, int position, long id) { Valores = datos[position]; if (Valores == "1/2 Taza") { select = 1; } if (Valores == "1 Taza") { select = 2; } if (Valores == "1 y 1/2 Tazas") { select = 3; } if (Valores == "2 Tazas") { select = 4; } if (Valores == "2 y 1/2 Tazas") { select = 5; } } public void onNothingSelected(AdapterView parent) { } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_dispensador, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } } Una vez que compilaba y la emulación funcionaba correctamente se procedió a descargar la aplicación: {{ :ie0117_proyectos_i_2015:proyecto_1:aplicacion_foto.jpg?150 |}} =====Diseño del modelo===== Se hizo un diseño virtual en 3D y otro en borrador de los posibles dispensadores de comida que se quieren utilizar, ambos son modelos de pared, que dispensan la comida verticalmente y esta cae en un tazón. Aquí están ambos modelos: {{ :ie0117_proyectos_i_2015:proyecto_1:diseno.png?200 |}} {{ :ie0117_proyectos_i_2015:proyecto_1:diseno_2.jpg?200 |}} ======PARTE 2====== =====Método de dispensado efectivo y libre de problemas===== En un inicio se planteo el método de usar un tornillo sin fin con franjas pequeñas que a la hora de girar dejara caer la comida hacia el plato o hacia donde se quisiera. Aquí se encontró el primer problema del proyecto, nos dimos cuenta que de esta manera sucedían varias cosas: -La comida que tenía un tamaño superior al de las franjas se quedaba dando vueltas y no caía nunca. -La comida muy pequeña pasaba sola por las franjas y caía. -Ciertos tamaños de comida trababan el tornillo, cuando la comida quedaba en una posicion donde se metía en medio de la franja y el borde del dispensador. Debido a este inconveniente tuvimos que replantearnos un nuevo diseño mecánico para el correcto funcionamiento de dispensado. Entonces investigamos en Internet que soluciones podíamos tener, sin muchas ideas que no dieran problemas como los anteriores. De esta manera y con un poco de suerte, encontramos un contacto en una compañia de alimentos (por asuntos de confidencialidad nos reservamos el nombre de ellos) el cual nos comentó sobre un método que podría servir de mejor forma. Así fue entonces como llegamos a la idea de utilizar de nuevo un tornillo sin fin, esta vez con franjas mucho más grandes y espaciadas entre sí. Debajo del tornillo se pone un "piso" en el cual cae alimento y el tornillo lo que hace es trasladarlo hacia un lado, donde hay un hueco y de esta manera la comida cae hacia el plato. Esto se puede observar en la siguiente fotografía: {{ :ie0117_proyectos_i_2015:proyecto_1:disp.jpg?200 |}} =====Controlar el sistema mecánico de dispensado de comida por medio del Raspberry Pi===== Ahora con el diseño de la mecánica de dispensado listo se acudió a un taller de mecánica de precisión, a ellos se les explicó la idea del proyecto, se les comentó lo que se quería y ellos se encargaron de montar el dispensador. De esta manera, con el dispensador listo, se procedió a pegarle el motor que se había comprado anteriormente. Siguiente a esto, con el dispensador montado junto al motor, llegó la hora de comprobar que el conjunto sirviera. Por lo tanto se armó el circuito correspondiente con el Raspberry Pi + Piface + fuente de voltaje DC. Con todo listo, se procedió a correr el siguiente script de Python, el cual activa el relay 0 por una cantidad variable de tiempo: #!-usr-bin-python import time import pifacedigitalio as p p.init() p.digital_write(0,1) time.sleep(10) p.digital_write(0.0) En efecto todo salió como se esperaba. De esta manera y de modo demostrativo, se tiene el siguiente video donde se observa el dispositivo en funcionamiento: https://www.youtube.com/watch?v=Yic9f-db-54&feature=youtu.be =====Desarrollar una aplicación móvil que logre controlar el dispensador==== Para esta parte del proyecto se siguió trabajando con el Android Studio, logrando que la aplicación generara un entero al escoger la cantidad de tazas que se deseen dispensar, esto para que ese dato sea recibido por el servidor el cuál activará el programa del raspberry pi que mueve el motor para servir el alimento. El código de la aplicación es el siguiente: package com.example.alejandro.dispensador; import android.support.v7.app.ActionBarActivity; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.HttpClient; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicNameValuePair; import android.os.AsyncTask; import android.view.View; import android.widget.Spinner; import android.widget.EditText; import android.widget.TextView; import android.widget.ArrayAdapter; import android.widget.AdapterView; import android.widget.Toast; public class dispensador extends ActionBarActivity { private Spinner cmbOpciones; private String Valores; private int select; private TextView Resultado; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_dispensador); Resultado=(TextView)findViewById(R.id.textView_Resultado); final String[] datos = new String[] {"1/2 Taza","1 Taza","1 y 1/2 Tazas","2 Tazas","2 y 1/2 Tazas"}; ArrayAdapter adaptador = new ArrayAdapter(this, android.R.layout.simple_spinner_item, datos); cmbOpciones= (Spinner)findViewById(R.id.spinner); adaptador.setDropDownViewResource( android.R.layout.simple_spinner_dropdown_item); cmbOpciones.setAdapter(adaptador); cmbOpciones.setOnItemSelectedListener( new AdapterView.OnItemSelectedListener() { public void onItemSelected(AdapterView parent, android.view.View v, int position, long id) { Valores = datos[position]; if (Valores == "1/2 Taza") { select = 1; } if (Valores == "1 Taza") { select = 2; } if (Valores == "1 y 1/2 Tazas") { select = 3; } if (Valores == "2 Tazas") { select = 4; } if (Valores == "2 y 1/2 Tazas") { select = 5; } } public void onNothingSelected(AdapterView parent) { } }); } public void Operaciones(View view){ int operacion = 0; switch (select){ case 1: operacion= 1; break; case 2: operacion= 2; break; case 3: operacion= 3; break; case 4: operacion= 4; break; case 5: operacion= 5; break; } String resultado = String.valueOf(operacion); Resultado.setText(resultado); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_dispensador, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); }} El código del Layout(Parte gráfica) es el siguiente: