Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Manufacturing Technology >> Proceso de manufactura

Comedero para mascotas fácil de construir

Componentes y suministros

Arduino Nano R3
Es mejor usar un Arduino Nano si desea usar una carcasa compacta
× 1
Adafruit Real Time Clock
× 1
Servo de rotación continua
× 1
Dispensador de cereales
× 1
Sensor de pasillo UNIPOLAR
× 1
Imanes de varilla de 3 mm de diámetro, 5 mm de largo
× 6
LCD retroiluminado Adafruit RGB - 16x2
× 1
mochila lcd i2c
× 1
Apem Pulsador momentáneo IP67
× 1
Pequeños pulsadores momentáneos
× 1
LED (genérico)
× 6
Carcasa Hammond Multi ABS con brida
× 1

Aplicaciones y servicios en línea

Generador de caracteres LCD

Acerca de este proyecto

Actualización 2018-09-06

Mis dos comederos para mascotas funcionan sin problemas durante los últimos 7 meses. Cuidamos a nuestras mascotas durante el día, por supuesto, pero ahora reciben su alimento en horarios regulares. ¡Muy feliz con el sistema!

¿Por qué otro comedero para mascotas?

Mi versión de un comedero para mascotas se basa en un microcontrolador Arduino. Los materiales utilizados son relativamente baratos y creo que es fácil de construir.

Por supuesto, hay muchas versiones, pero no pude encontrar un proyecto completo, listo para construir con las características que necesitaba, así que comencé desde cero.

Estas son las características:

  • * ¡Porciones precisas * entregadas cada vez! (mediante el uso de un sensor Hall)
  • Dos veces al día para comer
  • * Reloj en tiempo real extremadamente * preciso (solo con chip DS3231 genuino)
  • Puede cancelar una próxima alimentación individualmente para ambos temporizadores con pantalla e indicador LED. La cancelación se restablece automáticamente una vez transcurrido el tiempo establecido.
  • Función de alimentación manual (una porción por pulsación de botón)
  • Porciones ajustables para cada uno de los dos tiempos de alimentación (1-9 porciones)
  • Descripción general de todos los parámetros establecidos en la pantalla principal
  • Sistema de menú fácil de navegar
  • Indicación LED si la alimentación fue exitosa
  • Temporizador de luz de fondo de la pantalla LCD (se apaga después de 30 segundos, se enciende con cualquier botón)
  • La hora y otras configuraciones se almacenan de forma segura en la memoria (EEPROM)

VIDEOS de demostración:

para ver el video, haga clic AQUÍ

video explicativo más detallado:haga clic AQUÍ

el alimentador de mascotas en acción a cámara lenta! haga clic AQUÍ

Fotos:

Piezas necesarias:

  • 1 dispensador de cereales (barato en Ebay)
  • algo de madera (de desecho) para construir el soporte del dispensador de cereales
  • 1x Arduino Uno
  • 1x I2C DS3231 (extremadamente preciso) o reloj en tiempo real DS1307
  • 1x pantalla LCD de 16 caracteres / 2 líneas
  • 1x mochila I2C para la pantalla LCD
  • 1x Servo de rotación continua (¡compre uno bueno!)
  • 1x sensor de pasillo unipolar Honeywell SS443R
  • 1x fuente de alimentación externa de 12 voltios / 1 amperio (verruga de pared)
  • 7 botones pulsadores:momentáneos
  • 6x LED (2x ROJO, 3x VERDE, 1 AMARILLO)
  • 2x resistencia de 1KΩ (para los LED rojos)
  • Resistencia 4x 560Ω (para los LED verde y amarillo)
  • 1x caja para la electrónica
  • enchufe de alimentación hembra y conectores para conectar el servo externo y el sensor de pasillo
  • montones, montones de HOT GLUE.

Es mejor usar un voltaje más alto para el servo si es posible. ¡Más poder! Mi HSR-2645CRH Servo puede tomar 7,4 voltios, por lo que si también desea hacer esto, necesita:

  • Tablero perfilado
  • Regulador de voltaje variable LM317T
  • 3 resistencias para configurar el voltaje de salida (1KΩ, 150kΩ y 4K7)
  • 2 condensadores polarizados (220 µF, 10 µF)
  • no se necesita disipador de calor, el servo girará 1-2 solo segundos cada día;)

En línea puede encontrar muchas calculadoras LM317.

El contenedor de alimento para mascotas

Los más baratos y fáciles de usar son los dispensadores de cereales que puedes encontrar en muchas tiendas y en Ebay. Compré un dispensador de cereales doble en Ebay por 15 euros incluido el envío (Reino Unido a los Países Bajos)

El desafío era hacer una montura para el comedero y mirar a mi alrededor en Internet no me ayudó mucho, así que miré a mi alrededor en mi cobertizo y encontré algunas hermosas piezas de madera de cedro.

La madera que sostiene el dispensador de cereales de plástico tiene un grosor de 3 cm, por lo que no se tambalea. Debe asegurarse de que el orificio (la base de mi alimentador es de 86 mm) esté apretado, ¡así que mida antes de perforar! Es mejor perforar un agujero más pequeño y darle un poco de forma que un agujero demasiado grande.

Mire las fotos para tener una idea de por qué y cómo encajan.

El servo y el accesorio a la rueda de paletas del dispensador

Asegúrate de comprar un buen servo. Primero compré un servo MG996R que modifiqué para rotación continua pero eso fue una pérdida de dinero ... Luego obtuve uno de calidad, en mi caso el HSR-2645CRH Servo

¡¡TIENE QUE SER un modelo de rotación continua !! No intente modificar un servo normal como hice yo. No funcionó lo suficientemente bien y cuando se detuvo, no fue inmediato.

video de la prueba del servo:haga clic AQUÍ

La conexión del Servo a la rueda de paletas del dispensador

Así que ahora estaba la pregunta:¿cómo conectar el servo a la rueda de paletas del alimentador? Al principio parecía la parte más difícil del proyecto, pero de hecho fue muy simple.

Tomé un trozo de policarbonato de 5 mm y con una sierra de marquetería corté un disco redondo de unos 6 cm. En el centro hice un agujero de 8 mm (el grosor del eje del alimentador. Este eje de plástico es extraíble de la rueda de paletas)

En el exterior taladro 6 agujeros de 3 mm, el grosor de los imanes. Estos se utilizan para dar retroalimentación a Arduino sobre la posición de la rueda del alimentador.

Debido a que la rueda de paletas tenía 6 paletas de goma, usé 6 imanes y los dividí alrededor del borde del disco de policarbonato. 360 grados divididos por 6 son 60 grados. Los imanes de varilla encajarán perfectamente.

El sensor de pasillo detectará cada uno de los 6 imanes para que podamos usar esa información para posicionar y detener con precisión la rueda de paletas. La variable de tiempo de retardo de la parada del servo se usa para agregar un retardo después de alimentando, antes de parar el servo. Entonces, con este retraso, puede ajustar la posición exacta de la rueda de paletas. Esto es importante porque si la posición de 'parada' es incorrecta, la alimentación no saldrá completamente de la rueda de paletas. Además, la posición del sensor de pasillo puede ser diferente en su caso. Ajustar el tiempo de la variable de retardo de parada del servo resolverá esto.

Ahora podemos pegar el eje de la rueda de paletas en el disco de policarbonato.

La bocina del servo redonda blanca está atornillada al disco de policarbonato con 3 pernos M3. use algunas tuercas adicionales como espaciadores y no apriete demasiado.

Ahora el servo es parte del ensamblaje del alimentador, por lo que podemos colocarlo en el soporte de madera y medir la altura que debe tener la pieza de madera debajo del servo.

El sensor Hall

El sensor de pasillo que utilicé es del tipo UNIPOLAR. Dará una salida BAJA si hay un imán cerca y NO necesita la polaridad inversa del imán para restablecer la salida a ALTA nuevamente. Por lo tanto, use un sensor de pasillo unipolar, mucho más fácil.

!!! El sensor de pasillo necesita una resistencia pull up de 10 KΩ.

Instalé una resistencia SMD 0805 justo encima del sensor de pasillo, pero puedes hacerlo a tu manera. ¡No olvide esta resistencia!

Luego tomé un bolígrafo viejo y usé el plástico como soporte para el sensor.

La carcasa de la electrónica

Usé una carcasa de ABS Hammond con brida. 120 x 65 x 40 mm

para las conexiones externas utilicé conectores hembra de precisión, no los chinos baratos. Los uso mucho en todos mis proyectos. Nada peor que las malas conexiones que causan fallas (difíciles de encontrar).

Para facilitar la programación del Arduino, tengo una conexión FTDI externa:

El panel frontal

Intenté muchas formas de hacer un panel frontal barato y atractivo ...

Primero utilicé Mod Podge para pegar una impresión láser de papel en la parte frontal de la carcasa y cubrirla con más Mod Podge. -> FALLO

Luego probé un barniz transparente, a base de dispersión de acrilato de poliuretano. Muy duradero y fuerte cuando se seca. Pegué muy bien el papel en la carcasa y barnizar la parte superior de la impresión del panel frontal se veía muy bien, PERO no se adhería a las partes de tóner de la impresora láser de la impresión. -> FALLO

Después de eso, tomé la impresión láser del panel frontal y solo laminé la parte superior con laminado pcv. Muy buen acabado, protegiendo el frente y realzando los colores maravillosamente. Por otra parte, pegué el papel laminado en la carcasa con el barniz. Mi idea era que el barniz impregnara el papel haciéndolo resistente al agua. Pero debido a que utilicé papel grueso que no funcionó y lo mojé para probar la resistencia al agua, el papel se curvó y salió de la carcasa. -> PARCIALMENTE FALLADO, para ser investigado más a fondo.

Otro intento:compré papel de aluminio especial, hecho para impresión láser. 2,25 euros por hoja. El resultado fue excelente, pero quería proteger el tóner con una lámina transparente especial. Eso no fue un éxito porque no pude deshacerme de las imperfecciones como se ve en la foto 1:

Luego, otro intento de proteger con el barniz transparente, ¡hizo que la lámina de aluminio tuviera un brillo muy alto! PERO ... de nuevo, el barniz no se adhería al tóner, así que dejé el barniz de forma permanente ...

FINALMENTE ... utilicé la impresión de papel de aluminio sin protección ... Mostrará impresiones vinger cuando se manipula con frecuencia (mire debajo del botón ATRÁS de la foto en la parte superior de esta página, alojamiento en el alimento para pollos), por lo que no es ideal, pero sigue siendo bueno suficiente para mí.

Al parecer, no se permiten más fotos, así que ...

Eso es todo amigos ... tener ¡divertido!

Código

  • Pet Feed-O-Matic v 1.1 - 20-02-2018
Pet Feed-O-Matic v 1.1 - 20-02-2018 Arduino
v 1.1:presionar los botones Cancelar1 o 2 mostrará una explicación
 // cosas de c ++ ... // # incluir  // # línea 1 // # línea 1 "/ Usuarios / Erik / Documentos / PlatformIO / Projects / 180202-151127-uno / src / Pet_Feeder_1_1_ENG.cpp "/ * _ _ / \ | | (_) / \ _ __ __ | | _ _ _ _ __ ___ / / \ \ | '__ / _` | | | | | '_ \ / _ \ / ____ \ | | | (_ | | | _ | | | | | | (_) | / _ / \ _ \ _ | \ __, _ | \ __, _ | _ | _ | | _ | \ ___ / _____ _ ______ _ | __ \ | | | ____ | | | | | __) | __ | | _ | | __ ___ ___ __ | | ___ _ __ | ___ / _ \ __ | | __ / _ \ / _ \ / _` | / _ \ '__ | | | | __ / | _ | | | __ / __ / (_ | | __ / | | _ | \ ___ | \ __ | | _ | \ ___ | \ ___ | \ __, _ | \ ___ | _ | Erik de Ruiter -------- -------------------------------------------------- ------------------- Para hacer:- ¿Alimentación remota? - Retardo de parada del alimentador como elemento editable del menú Último cambio:dinsdag 20 februari 2018-17:20:28 CARACTERÍSTICAS:- * ¡Porciones precisas * cada vez! (Usando un sensor Hall) - Dos tiempos de alimentación, una vez al día - * Reloj en tiempo real extremadamente * preciso (solo con el chip DS3231 genuino) - Cancele la próxima alimentación individualmente para ambos temporizadores con pantalla e indicador LED . Restablecimiento automático después de que haya pasado el tiempo. - Función de alimentación manual (una porción por cada botón) - Porciones ajustables para cada uno de los dos tiempos de alimentación (1-9 porciones) - Resumen de todos los parámetros establecidos en la pantalla principal - Menú fácil de navegar sistema - Indicación LED si la alimentación fue exitosa - Temporizador de luz de fondo LCD (se apaga después de 30 segundos, se enciende al presionar cualquier botón) - Copia de seguridad en caso de falla del sensor Hall - El LED del sensor Hass parpadeará hasta la medianoche si el sensor Hall ha fallado - El tiempo y otras configuraciones se almacenan de forma segura en los SITIOS WEB EEPROM:Sitio web del generador de caracteres LCD HD44780 para crear sus propios símbolos lcd https://omerk.github.io/lcdchargen/ Bosquejo de Arduino Generador de comentarios de letras grandes http://patorjk.com / software / taag / # p =display &c =c% 2B% 2B &f =Big &t =Revisiones de comentarios:zondag 28 de enero de 2018 - 20:17:10 * //////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////// /////////////// VARIABLES CAMBIABLES POR EL USUARIO ////////////////////////////////// //////////////////////////////////////////////////// utilizado para la función de respaldo de falla del sensor Hall. // el tiempo de intervalo debe ser algo mayor que un 60 grados // vuelta del alimentador (una porción) #define HALL_SENSOR_BACKUP_VALUE 300 // retardo antes de detener el servo del alimentador después de la alimentación. De esta manera puede // dejar que la rueda giratoria se detenga en la posición correcta # definir FEEDER_STOP_DELAY 100 // retroiluminación de la pantalla LCD encendida después de presionar un botón # definir LCD_BACKLIGHT_ON_TIME 30000 // salir del menú sin guardar después de un período de tiempo establecido aquí en ms # definir MENU_TIMEOUT_VALUE 7000 ////////////////////////////////////////////////// //////////////////////////////////// https:// github.com/fdebrabander/Arduino-LiquidCrystal-I2C- library # include  // https:// github.com/JChristensen/Button#include  // http:// github.com/JChristensen/DS3232RTC#include  // http:// www.arduino.cc/playground/Code/Time#include  // http:// arduino.cc/en/Reference/Wire (incluido con Arduino IDE) #include  #include  // CONNECTIONS://// LCD (módulo I2C):// SCL - A5 // SDA - A4 // VCC // GND // pin del sensor de interrupción hal # define HALL_SENSOR_PIN 3 # define BUTTON_BACK_PIN 4 # definir BUTTON_UP_PIN 5 # definir BUTTON_DOWN_PIN 6 # definir BUTTON_SELECT_PIN 7 # definir BUTTON_CANCEL1_PI N 8 # define BUTTON_CANCEL2_PIN 9 # define BUTTON_MANUAL_PIN 10 # define LED_CANCEL1_PIN A0 # define LED_CANCEL2_PIN A1 # define LED_SUCCESS1_PIN A2 # define LED_SUCCESS2_PIN A3 // alimentador Servo salida Pin # define LED_OUTPIN_PIN_PIN_ (16x2) 0x27 o 0x3FLiquidCrystal_I2C lcd (0x3F, 16, 2); // definir la configuración de la biblioteca de botones // Un tiempo de antirrebote de 20 milisegundos generalmente funciona bien // para interruptores de botones táctiles. # Definir DEBOUNCE_MS 20 // ms requeridos antes de repetir en pulsación larga # define REPEAT_FIRST 1000 // intervalo de repetición para pulsación larga # define REPEAT_INCR 200 // Para simplificar las cosas, usamos la resistencia pullup interna de Arduino. # define PULLUP true # define INVERT true // Declara los botonesButton buttonSelect (BUTTON_SELECT_PIN, PULLUP , INVERT, DEBOUNCE_MS); Botón buttonUp (BUTTON_UP_PIN, PULLUP, INVERT, DEBOUNCE_MS); Botón buttonDown (BUTTON_DOWN_PIN, PULLUP, INVERT, DEBOUNCE_MS); Botón buttonBack (BUTTON_BACK_PIN, PULLBOUNCE_MS,); Button buttonCancel1 (BUTTON_CANCEL1_PIN, PULLUP, INVERT, DEBOUNCE_MS); Button buttonCancel2 (BUTTON_CANCEL2_PIN, PULLUP, INVERT, DEBOUNCE_MS); Button buttonManual (BUTTON_MANUAL_PIN, PULLUP, INVERTMS, valor anterior DEBOUN); // El número que se ajusta al valor anterior DEBOUN; // count (inicializado para asegurarse de que sea diferente cuando // comienza el boceto) int lastCount =-1; // Un tiempo variable que se usa para impulsar las repeticiones para presiones largas unsigned long rpt =REPEAT_FIRST; // usado para el menú time-outunsigned long timeoutValue =0; // manual cancelar tiempos de alimentación variablesboolean manualCancelFeed1 =false; boolean manualCancelFeed2 =false; // opción de alimentación Manaual boolean manualFeed =false; // cantidad de alimento (en porciones) int feedAmount1 =1; int feedAmount2 =1; bool feederSuccess =false; // alimentador porcionesint porciones =0; int turnos =0; // entrada actionsenum {btnSELECT, btnUP, btnDOWN, btnBACK, btnCANCEL1, btnCANCEL2, btnMANUAL, trigTIMEOUT}; // Estados de la máquina de estados finitos (FSM) enum STATES {PRINCIPAL, MENU_EDIT _FEEDTIME1, MENU_EDIT_FEEDTIME2, MENU_EDIT_FEEDAMOUNT, MENU_EDIT_TIME, MENU_EDIT_DATE, MENU_EDIT_SETTINGS, EDIT_FEED_TIME1_HOUR, EDIT_FEED_TIME1_MINUTE, EDIT_FEED_TIME1_ON_OFF, EDIT_FEED_TIME2_HOUR, EDIT_FEED_TIME2_MINUTE, EDIT_FEED_TIME2_ON_OFF, EDIT_FEED_AMOUNT1, EDIT_FEED_AMOUNT2, EDIT_HOUR, EDIT_MINUTE, EDIT_DAY, EDIT_MONTH, EDIT_YEAR, EDIT_SERVO_STOP_DELAY, EDIT_SERVO_BACKUP_DELAY,}; // Mantiene el estado actual del estado del sistema STATES; int8_t userInput; int8_t trigger; int Second; int Minute; int Hour; int Day; int Month; int Year; int8_t DoW; String day_of_week; unsigned char address, data; int testt =0; int feed_time1_hour; int feed_time1_minute; bool feed_time1_active =false; bool alarm1Activated =false; int feed_time2_hour; int feed_time2_minute; bool feed_time2_active =false; bool alarm2Activated =false; // utilizado para la función de parpadeo al editar valores 0; boolean blink_state =false; // usado para el Función de parpadeo al editar valores uint32_t spinningWheel_interval =170; uint32_t spinningWheel_previousMillis =0; uint32_t spinningWheel_currentMillis =0; int spinningWheelSymbol =0; // utilizado para la función de respaldo de falla del sensor Hall // el tiempo del intervalo debe ser algo mayor a un 60 grados // giro del alimentador (una porción) .uint32_t hallSensorBackup_interval =HALL_SENSOR_BACKUP_VALUE; uint32_t hallSensorBackup_currentMillis =0; boolean hallSensorFail =false; // utilizado para la iluminación Pantalla timeruint32_t lcdBacklight_interval =LCD_BACKLIGHT_ON_TIME; uint32_t lcdBacklight_currentMillis =0; boolean RTC_error =true; long_press_button boolean =false; // Definir símbolos personalizados para la pantalla LCD byte bell_symbol_Char [8] ={B00100, B01110, B01110, B01110, B11111, B00100, B00000, B00000}; byte inverted_one_Char [8] ={0b11111, 0b11011, 0b10011, 0b1101111 , 0b10001, 0b11111}; byte inverted_two_Char [8] ={0b11111, 0b11011, 0b10101, 0b11101, 0b11011, 0b10111, 0b10001, 0b11111}; por te arrow_up_Char [8] ={0b00100, 0b01110, 0b11111, 0b01110, 0b01110, 0b01110, 0b01110, 0b00000}; byte arrow_down_Char [8] ={0b00000, 0b01110, 0b01110, 0b1101110, 0b01110, 0b11011110, 0b11_p [8] ={0b11111, 0b10001, 0b10101, 0b10001, 0b10111, 0b10111, 0b11111, 0b00000}; byte backslash_Char [8] ={0b00000, 0b10000, 0b01000, 0b00100, 0b00010, 0b00001; byteb00Dash [8] ] ={0b00000, 0b00000, 0b11111, 0b11111, 0b11111, 0b00000, 0b00000, 0b00000}; volátil booleano hallSensorActivated =false; // Interrupción 1void HallSensorIsr () {hallSensorActivated =true; // enciende el sensor Hall LED digitalWrite (LED_HALL_SENSOR_PIN, HIGH);} // Estas líneas son necesarias para hacer de este boceto un archivo C ++ .// Lo uso porque edito el código con el editor de texto Atom // y el complemento PlatformIO -onvoid HallSensorIsr (); void setup (); void loop (); void change_states (); void check_inputs (); void transición (int trigger); void check_alarm (); void check_manual_feed (); void display_menu_option_set_feedtime1 (); void display2 (); void display_menu_option_set_feed_amount (); void display_menu_option_set_time (); void display_menu_option_set_date (); void midnight_reset (); void display_time (); void displayFeedingAmouts (); void displayFeeding_option_set_time; (); void set_feeding1_time (); void set_feeding2_time (); void get_time (); void get_date (); void write_time (); void write_date (); void write_feeding_time1 (); void write_feeding_time2 (); void writemount_feedamount (da); void get_date (); anular get_feed_time1 (); anular get_feed_time2 (); anular check_RTC (); byte decToBcd (byte val); byte bcdToDec (byte val); void lead_zero (int digits); void blinkFunction (); void displaySpinningWheel (); void startFeederServo (); void stopFeederServo (); void activeFeeder (int porciones); void check_LcdBacklight (); void lcd_backlight_ON (); void ledsAndLcdDisplayStartup (); void hallSensorCheck (); # línea 355 // ************************** *********************************************** ** // SETUPvoid ​​setup () {// activar la pantalla lcd lcd.begin (); // enciende la luz de fondo de la pantalla LCD e inicia el temporizador de apagado de la luz de fondo lcd_backlight_ON (); // iniciar I2C Wire.begin (); // entrada del sensor de pasillo para detectar la rotación del alimentador / salida de cantidad de alimento comprobar pinMode (HALL_SENSOR_PIN, INPUT_PULLUP); pinMode (LED_HALL_SENSOR_PIN, SALIDA); pinMode (SERVO_OUTPUT_PIN, SALIDA); pinMode (LED_CANCEL1_PIN, SALIDA); pinMode (LED_CANCEL2_PIN, SALIDA); pinMode (LED_SUCCESS1_PIN, SALIDA); pinMode (LED_SUCCESS2_PIN, SALIDA); // establece el estado predeterminado de los LED en APAGADO digitalWrite (LED_CANCEL1_PIN, LOW); digitalWrite (LED_CANCEL2_PIN, BAJO); digitalWrite (LED_SUCCESS1_PIN, BAJO); digitalWrite (LED_SUCCESS2_PIN, BAJO); digitalWrite (LED_HALL_SENSOR_PIN, LOW); lcd.createChar (0, ThickDash_Char); lcd.createChar (1, bell_symbol_Char); lcd.createChar (2, barra invertida_Char); lcd.createChar (3, inverted_p_Char); lcd.createChar (4, inverted_one_Char); lcd.createChar (5, inverted_two_Char); lcd.createChar (6, arrow_up_Char); lcd.createChar (7, arrow_down_Char); // establece el Servo del alimentador en el estado predeterminado OFF stopFeederServo (); Wire.begin (); // establece RTC como Syncprovider setSyncProvider (RTC.get); // tiempo en segundos de resincronización con RTC setSyncInterval (60); // Deshabilita la onda cuadrada predeterminada del pin SQW. RTC.squareWave (SQWAVE_NONE); // Adjuntar una interrupción en el sensor Hall (cuando unput se vuelve BAJO) // Cada giro de 60 grados del eje del alimentador, el sensor Hall // debería generar una interrupción attachInterrupt (INT1, HallSensorIsr, FALLING); // muestra la prueba ledsAndLcdDisplayStartup (); // Estado inicial del FSM state =MAIN; // lee el valor de alarma almacenado en la memoria Arduino get_feed_time1 (); get_feed_time2 ();} // Finalizar CONFIGURACIÓN // ************************************* ************************************** // LOOPvoid ​​loop () {// cambiar estados de FSM change_states (); // comprobar entradas (botones) check_inputs (); // verifica si la alarma se llamó check_alarm (); // comprobar si se solicitó la alimentación manual check_manual_feed (); // at midnight, reset some variables midnight_reset(); // check connection RTC check_RTC(); // Check the Hall sensor function hallSensorCheck(); // check if lcd backlight must be turned off check_LcdBacklight();}// End of LOOP// ******************************************************************************// ******************************************************************************// ******************************************************************************// ******************************************************************************//******************************************************************************// Finite State Machinevoid change_states(){ // states switch (state) { //--------------------------------------- case MAIN:display_time(); displayFeedingAmouts(); displayFeedingTimes(); descanso; //--------------------------------------- case MENU_EDIT_FEEDTIME1:display_menu_option_set_feedtime1(); descanso; //--------------------------------------- case MENU_EDIT_FEEDTIME2:display_menu_option_set_feedtime2(); descanso; //--------------------------------------- case MENU_EDIT_FEEDAMOUNT:display_menu_option_set_feed_amount(); descanso; //--------------------------------------- case MENU_EDIT_TIME:display_menu_option_set_time(); descanso; //--------------------------------------- case MENU_EDIT_DATE:display_menu_option_set_date(); descanso; //--------------------------------------- case EDIT_FEED_TIME1_HOUR:set_feeding1_time(); descanso; //--------------------------------------- case EDIT_FEED_TIME1_MINUTE:set_feeding1_time(); descanso; //--------------------------------------- case EDIT_FEED_TIME1_ON_OFF:set_feeding1_time(); descanso; //--------------------------------------- case EDIT_FEED_TIME2_HOUR:set_feeding2_time(); descanso; //--------------------------------------- case EDIT_FEED_TIME2_MINUTE:set_feeding2_time(); descanso; //--------------------------------------- case EDIT_FEED_TIME2_ON_OFF:set_feeding2_time(); descanso; //--------------------------------------- case EDIT_FEED_AMOUNT1:set_feedAmount(); descanso; //--------------------------------------- case EDIT_FEED_AMOUNT2:set_feedAmount(); descanso; //--------------------------------------- case EDIT_HOUR:set_time(); descanso; //--------------------------------------- case EDIT_MINUTE:set_time(); descanso; //--------------------------------------- case EDIT_DAY:set_date(); descanso; //--------------------------------------- case EDIT_MONTH:set_date(); descanso; //--------------------------------------- case EDIT_YEAR:set_date(); descanso; //--------------------------------------- }}//******************************************************************************// Check INPUTSvoid check_inputs(){ // first check if timeout has occurred if ( millis() - timeoutValue> MENU_TIMEOUT_VALUE ) { userInput =trigTIMEOUT; transition(userInput); } // check state of buttons buttonSelect.read(); buttonUp.read(); buttonDown.read(); buttonBack.read(); buttonManual.read(); buttonCancel1.read(); buttonCancel2.read(); // check manual cancel Feed1 button switch (buttonCancel1.wasPressed()) { case 1:// invert variable value (true to false and vise versa) manualCancelFeed1 =!manualCancelFeed1; //turn on lcd backlight manually lcd_backlight_ON(); // message when Cancel1 button is pressed if (manualCancelFeed1 ==1) { lcd.clear(); lcd.setCursor (0, 0); // 0123456789012345 - LCD screen character counter lcd.print("Upcoming Feed #1"); lcd.setCursor (0, 1); lcd.print("cancelled once "); retraso (2000); lcd.clear (); } else if (manualCancelFeed1 ==0) { lcd.clear(); lcd.setCursor (0, 0); // 0123456789012345 - LCD screen character counter lcd.print("Upcoming Feed #1"); lcd.setCursor (0, 1); lcd.print("canceling undone"); retraso (2000); lcd.clear (); } descanso; } // check manual cancel Feed2 button switch (buttonCancel2.wasPressed()) { case 1:// invert variable value (true to false and vise versa) manualCancelFeed2 =!manualCancelFeed2; //turn on lcd backlight manually lcd_backlight_ON(); // message when Cancel1 button is pressed if (manualCancelFeed2 ==1) { lcd.clear(); lcd.setCursor (0, 0); // 0123456789012345 - LCD screen character counter lcd.print("Upcoming Feed #2"); lcd.setCursor (0, 1); lcd.print("cancelled once "); retraso (2000); lcd.clear (); } else if (manualCancelFeed2 ==0) { lcd.clear(); lcd.setCursor (0, 0); // 0123456789012345 - LCD screen character counter lcd.print("Upcoming Feed #2"); lcd.setCursor (0, 1); lcd.print("canceling undone"); retraso (2000); lcd.clear (); } descanso; } // check manual Feed button switch (buttonManual.wasPressed()) { case 1:manualFeed =true; //turn on lcd backlight manually lcd_backlight_ON(); descanso; } // check MENU/SELECT button switch (buttonSelect.wasPressed()) { case 1:userInput =btnSELECT; //turn on lcd backlight manually lcd_backlight_ON(); transition(userInput); descanso; } // check UP button switch (buttonUp.wasPressed()) { case 1:userInput =btnUP; transition(userInput); //turn on lcd backlight manually lcd_backlight_ON(); descanso; } // check long press UP button switch (buttonUp.wasReleased()) { case 1:long_press_button =false; rpt =REPEAT_FIRST; descanso; } switch (buttonUp.pressedFor(rpt)) { case 1:// increment the long press interval rpt +=REPEAT_INCR; long_press_button =true; userInput =btnUP; transition(userInput); descanso; } // check DOWN button switch (buttonDown.wasPressed()) { case 1:userInput =btnDOWN; transition(userInput); //turn on lcd backlight manually lcd_backlight_ON(); descanso; } // check long press DOWN button switch (buttonDown.wasReleased()) { case 1:long_press_button =false; rpt =REPEAT_FIRST; descanso; } switch (buttonDown.pressedFor(rpt)) { case 1:// increment the long press interval rpt +=REPEAT_INCR; long_press_button =true; userInput =btnDOWN; transition(userInput); descanso; } // check btnBACK button switch (buttonBack.wasPressed()) { case 1:userInput =btnBACK; transition(userInput); //turn on lcd backlight manually lcd_backlight_ON(); descanso; }}//******************************************************************************// Check for state transition triggervoid transition(int trigger){ switch (state) { //--------------------------------------- case MAIN:// set time-out timr timeoutValue =millis(); if (trigger ==btnSELECT) { lcd.clear(); state =MENU_EDIT_FEEDTIME1; } else if (trigger ==btnBACK) { //lcd.clear(); //state =ALARM1_AND_2_TIME; } descanso; //--------------------------------------- case MENU_EDIT_FEEDTIME1:// set time-out timer timeoutValue =millis(); // check for time-out 'button' trigger if (trigger ==trigTIMEOUT) { lcd.clear(); state =MAIN; } // Now check for button triggers if (trigger ==btnUP) { //no action, this is the first menu } else if (trigger ==btnDOWN) { lcd.clear(); state =MENU_EDIT_FEEDTIME2; } if (trigger ==btnSELECT) { lcd.clear(); state =EDIT_FEED_TIME1_HOUR; } if (trigger ==btnBACK) { lcd.clear(); state =MAIN; } descanso; //--------------------------------------- case MENU_EDIT_FEEDTIME2:// set time-out timer timeoutValue =millis(); // check for time-out 'button' trigger if (trigger ==trigTIMEOUT) { lcd.clear(); state =MAIN; } // Now check for button triggers if (trigger ==btnUP) { lcd.clear(); state =MENU_EDIT_FEEDTIME1; } else if (trigger ==btnDOWN) { lcd.clear(); state =MENU_EDIT_FEEDAMOUNT; } if (trigger ==btnSELECT) { lcd.clear(); state =EDIT_FEED_TIME2_HOUR; } if (trigger ==btnBACK) { lcd.clear(); state =MAIN; } descanso; //--------------------------------------- case MENU_EDIT_FEEDAMOUNT:// set time-out timer timeoutValue =millis(); // check for time-out 'button' trigger if (trigger ==trigTIMEOUT) { lcd.clear(); state =MAIN; } // Now check for button triggers if (trigger ==btnUP) { lcd.clear(); state =MENU_EDIT_FEEDTIME2; } else if (trigger ==btnDOWN) { lcd.clear(); state =MENU_EDIT_TIME; } if (trigger ==btnSELECT) { lcd.clear(); state =EDIT_FEED_AMOUNT1; } if (trigger ==btnBACK) { lcd.clear(); state =MAIN; } descanso; //--------------------------------------- case MENU_EDIT_TIME:// set time-out timer timeoutValue =millis(); // check for time-out 'button' trigger if (trigger ==trigTIMEOUT) { lcd.clear(); state =MAIN; } // Now check for button triggers if (trigger ==btnUP) { lcd.clear(); state =MENU_EDIT_FEEDTIME2; } if (trigger ==btnDOWN) { lcd.clear(); state =MENU_EDIT_DATE; } if (trigger ==btnSELECT) { lcd.clear(); state =EDIT_HOUR; } if (trigger ==btnBACK) { lcd.clear(); state =MAIN; } descanso; //--------------------------------------- case MENU_EDIT_DATE:// set time-out timer timeoutValue =millis(); // check for time-out 'button' trigger if (trigger ==trigTIMEOUT) { lcd.clear(); state =MAIN; } // Now check for button triggers if (trigger ==btnUP) { lcd.clear(); state =MENU_EDIT_TIME; } else if (trigger ==btnDOWN) { //no action, end of menu items! } if (trigger ==btnSELECT) { lcd.clear(); state =EDIT_DAY; } if (trigger ==btnBACK) { lcd.clear(); state =MAIN; } descanso; //--------------------------------------- case EDIT_FEED_TIME1_HOUR:// set time-out timer timeoutValue =millis(); // check for time-out 'button' trigger if (trigger ==trigTIMEOUT) { lcd.clear(); state =MAIN; } // Now check for button triggers...This file has been truncated, please download it to see its full contents.

Esquemas

Arduino based Pet Feeder I used Arduino IDE 1.8.2. BE CAREFUL NOT TO HAVE TWO VERSIONS OF THE SAME LIBRARIES IN YOUR LIBRARIES FOLDER!! arduino_pet_feeder_final_eng_v1_0-ino_hex_libraries_dsoo0HscCr.zip

Proceso de manufactura

  1. Comida para mascotas
  2. Consola de edición de Photoshop DIY con Arduino Nano RP 2040
  3. Arduino Spybot
  4. Flores - Arduino Nano, CrazyCircuits, DFRobot
  5. Arduino Nano Tetris Game en una matriz casera de 16x8
  6. Clon Arduino Tamagotchi - Mascota digital
  7. Arduino Nano:Controla 2 motores paso a paso con joystick
  8. Comedero para mascotas con control remoto
  9. Contador Geiger de mano con Arduino Nano
  10. TFT Shield para Arduino Nano - Iniciar
  11. Comedero para mascotas con piezas impresas en 3D