Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Un dispensador
automático de comida para
mascotas con Arduino
POR ADMIN · ABRIL 11, 2019
Contenidos
1. Introducción
2. Autoría
3. Componentes utilizados
4. Montaje
5. Código
6. Conclusiones
7. Anexo: Manual de funcionamiento
Introducción
Autoría
Componentes utilizados
Los componentes de los que no se indica el precio son aquellos que
ya teníamos o hemos reciclado.
Componentes electrónicos
Componentes no electrónicos
Montaje
Diseño inicial
Hemos utilizado una pantalla LCD para mostrar la hora actual y la hora
programada para la dispensa de comida. También se muestra un
mensaje cuando se sirve la comida y otro cuando termina de servirse.
La pantalla cuenta con unos botones que se utilizarán para modificar
la hora de la comida.
Problemas encontrados
Posibles mejoras
Código
Librerías utilizadas
Sketch principal
1 #include <Arduino.h>
2 #include <LiquidCrystal.h> /* Library for the LCD */
3
4 #include <Wire.h>
5 #include "RTClib.h"
6
7 #include <Servo.h>
8
9 /* Initialize the library with interface pins numbers: */
10 LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
11 int val;
12
13 /* Speaker (buzzer): */
14 int speakerPin = 13;
15
16 /* Real time clock: */
17 RTC_DS3231 rtc;
18
19 /* Servo: */
20 Servo myservo;
21 int pos = 0; /* Variable to store the servo position */
22 int servoPin = 10;
23
24 DateTime now;
25 byte hour, minute;
26 String h, m;
27
28 int feedHour = 14;
29 int feedMin = 0;
30 boolean foodTime = true;
31
32 void setup() {
33
34 /* Set speaker pin as an output pin: */
35 pinMode(speakerPin, OUTPUT);
36 /* Set up LCD's number of columns and rows: */
37 lcd.begin(16, 2);
38 /* Start RTC: */
39 rtc.begin();
40
41 }
42
43 void loop() {
44
45 now = rtc.now();
46 printTime(now);
47
48 /* LCD buttons are all connected to A0 pin with this values:
49 * 0-50: UP
50 * 50-150: RIGHT
51 * 150-300: DOWN
52 * 300-500: LEFT
53 * 500-750: SELECT
54 */
55 val = analogRead(A0);
56 if ((val >= 500) && (val <= 750)) { // SELECT
57 setFeedHour();
58 delay(1000);
59 }
60
61 now = rtc.now();
62 printTime(now);
63
64 delay(2000);
65
66 if ((feedHour == now.hour()) && (feedMin == now.minute())
67 && foodTime) {
68 feed();
69 }
70
71 /* We use 'foodTime' so food doesn't get served twice
72 * if the feed routine ends in less than a minute. */
73 if (feedMin != now.minute()) {
74 foodTime = true;
75 }
76
77 }
78
79 void feed() {
80
81 lcd.clear();
82 lcd.setCursor(0, 0);
83 lcd.print("Sirviendo comida");
84
85 /* Food gets served: */
86 /* Attach servo on pin 10 (We attach servo only when
87 * we need it and detach it afterwards to stop it
88 * from shaking) */
89 myservo.attach(servoPin);
90 /* Servo moves to open lid for food to fall through.
91 * 'pos' goes from 0 to 180 degrees in steps of 1 degree
92 * and then gets written to servo*/
93 for (pos = 0; pos <= 120; pos += 1) {
94 myservo.write(pos);
95 /* Wait 15ms for the servo to reach the position */
96 delay(15);
97 }
98 delay(1000);
99 /* Go back from 180 to 0 degrees to close the lid: */
100 for (pos = 120; pos >= 0; pos -= 1) {
101 myservo.write(pos);
102 delay(15);
103 }
104 delay(3000);
105 /* Detach servo: */
106 myservo.detach();
107
108 bell();
109
110 foodTime = false;
111
112 }
113
114 void bell() {
115
116 for (int i=0; i<6; i++) {
117
118 /* Bell sound: */
119 tone(speakerPin, 1915);
120 delay(700);
121 tone(speakerPin, 1700);
122 delay(700);
123 tone(speakerPin, 1519);
124 delay(700);
125 noTone(speakerPin);
126
127 lcd.clear();
128 lcd.setCursor(0, 0);
129 lcd.print("Hora de la");
130 lcd.setCursor(0, 1);
131 lcd.print("comida!!!!");
132
133 delay(5000);
134
135 now = rtc.now();
136 printTime(now);
137
138 delay(5000);
139
140 }
141
142 }
143
144 /* Prints actual time and feed time.
145 * If hour or minute is just one digit, a zero
146 * will be added for formatting purposes */
147 void printTime(DateTime t) {
148
149 /* Actual time */
150 lcd.setCursor(0, 0);
151 lcd.print("H. actual: ");
152 hour = t.hour();
153 if (hour < 10) {
154 h = "0" + String(hour);
155 } else {
156 h = String(hour);
157 }
158 lcd.print(h);
159 lcd.print(':');
160 minute = t.minute();
161 if (minute < 10) {
162 m = "0" + String(minute);
163 } else {
164 m = String(minute);
165 }
166 lcd.print(m);
167
168 /* Feed hour */
169 lcd.setCursor(0, 1);
170 lcd.print("H. comida: ");
171 if (feedHour < 10) {
172 h = "0" + String(feedHour);
173 } else {
174 h = String(feedHour);
175 }
176 lcd.print(h);
177 lcd.print(':');
178 if (feedMin < 10) {
179 m = "0" + String(feedMin);
180 } else {
181 m = String(feedMin);
182 }
183 lcd.print(m);
184
185 return;
186
187 }
188
189 void setFeedHour() {
190
191 lcd.clear();
192 lcd.setCursor(0, 0);
193 lcd.print("Cambiar hora de");
194 lcd.setCursor(0, 1);
195 lcd.print("comida: ");
196
197 int hourAux = feedHour;
198
199 while(true) {
200
201 lcd.setCursor(8, 1);
202 if (hourAux < 10) {
203 lcd.print("0");
204 lcd.print(hourAux);
205 } else {
206 lcd.print(hourAux);
207 }
208 lcd.setCursor(10, 1);
209 lcd.print(':');
210 lcd.setCursor(11, 1);
211 if (feedMin < 10) {
212 m = "0" + String(feedMin);
213 } else {
214 m = String(feedMin);
215 }
216 lcd.print(m);
217
218 delay(200);
219
220 /* We check which button is being pressed */
221 val=analogRead(A0);
222 if ((val>=50) && (val<=150)) { /* UP + 1 hour */
223 hourAux = (hourAux + 1) % 24;
224 } else if ((val>=150) && (val<=300)) { /* DOWN - 1 hour */
225 hourAux = hourAux - 1;
226 if (hourAux < 0) {
227 hourAux = 23;
228 }
229 }
230 else if ((val>=300)&&(val<=500)) { /* LEFT cancel */
231 break;
232 }
233 if ((val>=0)&&(val<=50)) { /* RIGHT save */
234 feedHour = hourAux;
235 setFeedMin();
236 break;
237 }
238
239 }
240
241 return;
242
243 }
244
245 void setFeedMin() {
246
247 lcd.clear();
248 lcd.setCursor(0, 0);
249 lcd.print("Cambiar min. de");
250 lcd.setCursor(0, 1);
251 lcd.print("comida: ");
252
253 int minAux = feedMin;
254
255 while(true) {
256
lcd.setCursor(8, 1);
257
if (feedHour < 10) {
258
h = "0" + String(feedHour);
259
} else {
260
h = String(feedHour);
261
}
262
lcd.print(h);
263
lcd.setCursor(10, 1);
264
lcd.print(':');
265
lcd.setCursor(11, 1);
266
if (minAux < 10) {
267
m = "0" + String(minAux);
268
} else {
269
m = String(minAux);
270
}
271
lcd.print(m);
272
273
delay(200);
274
275
276 /* We check which button is being pressed */
val = analogRead(A0);
277
if((val>=50) && (val<=150)) { /* UP + 1 min */
278
minAux = (minAux + 1) % 60;
279
} else if((val>=150) && (val<=300)) { /* DOWN - 1 min */
280
minAux = minAux - 1;
281
if (minAux < 0) {
282
minAux = 59;
283
}
284
} else if((val>=300) && (val<=500)) { /* LEFT cancel */
285
break;
286
} else if((val>=500) &&( val<=750)) { /* SELECT save */
287
feedMin = minAux;
288
break;
289
}
290
291
}
292
293
return;
294
295
}
296
Este código solo necesita ejecutarse una vez para inicializar el chip
RTC con la hora actual. El chip RTC mantendrá la hora gracias a la
pila que lleva incorporada.
#include <Wire.h>
1
#include "RTClib.h"
2
3
RTC_DS3231 rtc;
4
5
void setup() {
6
7
rtc.begin();
8
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
9
10
11 /* The rest of the code is not necessary to set the time,
12 * we're just making sure it was set correctly: */
Serial.begin(9600);
13
14
DateTime now = rtc.now();
15
printDate(now);
16
17
}
18
19
void loop() {
20
21
}
22
23
void printDate(DateTime date) {
24
25
Serial.print(date.year(), DEC);
26
Serial.print('/');
27
Serial.print(date.month(), DEC);
28
Serial.print('/');
29
Serial.print(date.day(), DEC);
30
Serial.print(" ");
31
Serial.print(date.hour(), DEC);
32
Serial.print(':');
33
Serial.print(date.minute(), DEC);
34
Serial.print(':');
35
Serial.print(date.second(), DEC);
36
Serial.println();
37
38
}
39
Conclusiones