logo-mobile

ROHM

ROHM
Menu
  • Arduino –
  • Raspberry Pi –
  • Trending –
  • Others –
  • About –
  • Contact –

Arduino

Smart Pet Feeder Part 2 – Feeding App with Speech Recognition

Tiberia Todeila
Published by Tiberia Todeila at March 17, 2017
Categories
  • Arduino
Tags
  • Arduino
  • arduino uno
  • automatic pet feeder
  • smart home
  • smart pet feeder
automatic pet feeder

Click here to read Part 1 of this article >

automatic pet feeder

In Part 1 of Smart Pet Feeder, Make a Smart Automatic Pet Feeder with Arduino Uno, we set up an automatic platform that determines whether your pet is fed or not and counts the hours to the next feed. In Part 2, we’ll try to make the system even more “smarter” by adding speech recognition feature through an app made with MIT App Inventor. We’ve used MIT App Inventor to create apps in our previous tutorials. App Inventor is an easy-to-use block-based language for designing Android Apps.

Hardware

  • Arduino UNO
  • RFID RC522
  • HC-05 Bluetooth Module

From Part 1:

  • Arduino Uno
  • Light sensor TEMT6000
  • Distance Sensor Sharp GP2Y0A21YK
  • RFID RC522
  • Buzzer
  • Motor SG90
  • RTC DS1307

Software

  • Arduino IDE
  • PetFeeder on GitHub
  • MIT App Inventor

 

Step 1: Working with RFID tag EEPROM

The tags we set up in Part 1 wanted to EEPROM – in this memory, the tags will be saved until we clear it; this feature helps us to differentiate our pets from others, giving food only to the pets with the assigned tags.

We set 2 tags in Part 1 and used EEPROM to store data. RFID tags help identify and differentiate your pets from other pets, giving food only to the pets with the assigned tags. Using EEPROM ensured that the data is securely stored in the memory even after system reboots. The following code allows you to change tag information from EEPROM:

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
#include <EEPROM.h>    
 
#include <SPI.h>        
 
#include <MFRC522.h>
 
 
 
boolean match = false;          
 
boolean programMode = false;
 
 
 
 
int isOurPet;
 
 
 
byte storedCard[4];
 
byte readCard[4];
 
byte masterCard[4];
 
 
 
#define SS_PIN 10
 
#define RST_PIN 9
 
MFRC522 mfrc522(SS_PIN, RST_PIN);
 
 
 
 
 
void setup() {
 
 Serial.begin(9600);
 
 SPI.begin();          
 
 mfrc522.PCD_Init();   
 
 if (EEPROM.read(1) != 143) {
 
   
 
   do {
 
     isOurPet = findOurPet();            
 
    
 
   }
 
   while (!isOurPet);                 
 
   for ( int j = 0; j < 4; j++ ) {        
 
     EEPROM.write( 2 + j, readCard[j] );  
 
   }
 
   EEPROM.write(1, 143);                  
 
  
 
 }
 
 
 
 for ( int i = 0; i < 4; i++ ) {          
 
   masterCard[i] = EEPROM.read(2 + i);   
 
   
 
 }
 
}
 
 
 
 
void loop () {
 
 do {
 
   isOurPet = findOurPet();
 
}
 
 while (!isOurPet);
 
 if ( master(readCard)) {  
 
     programMode = true;
 
     Serial.println(F("Our Pet - Green Tag"));
 
     int count = EEPROM.read(0);
 
    
 
   }
 
   else {
 
       Serial.println(F("Not our pet - Purple Tag"));
 
       
 
     }
 
   }
 
 
 
int findOurPet() {
 
 
 
 if ( ! mfrc522.PICC_IsNewCardPresent()) {
 
   return 0;
 
 }
 
 if ( ! mfrc522.PICC_ReadCardSerial()) {  
 
   return 0;
 
 }
 
 for (int i = 0; i < 4; i++) {  
 
   readCard[i] = mfrc522.uid.uidByte[i];
 
}
 
 mfrc522.PICC_HaltA(); // Stop reading
 
 return 1;
 
}
 
 
 
void readCollar( int number ) {
 
 int start = (number * 4 ) + 2;
 
 for ( int i = 0; i < 4; i++ ) {
 
   storedCard[i] = EEPROM.read(start + i);
 
 }
 
}
 
 
 
boolean EEpromCheck ( byte a[], byte b[] ) {
 
 if ( a[0] != NULL )
 
   match = true;
 
 for ( int k = 0; k < 4; k++ ) {
 
   if ( a[k] != b[k] )
 
     match = false;
 
 }
 
 if ( match ) {
 
   return true;
 
 }
 
 else  {
 
   return false;
 
 }
 
}
 
 
 
boolean master( byte test[] ) {
 
 if ( EEpromCheck( test, masterCard ) )
 
   return true;
 
 else
 
   return false;
 
}

automatic pet feeder

Figure 1: Our pet tags in the EEPROM

Last time, our pet was assigned to a red tag. This time, we changed the tag to a green tag.

Step 2: How to control the servo

A servo motor uses PWM (pulse width modulation) from the microcontroller in order to change its positions. The servo needs to be calibrated and it will be set to 90 degrees for opening the door.  

To control the servo, we’ll use Arduino Sweep code. The code sweeps the servo motor shaft across 180 degrees. We’re going to change the degrees, so instead of 0-180 degrees we’ll use 10-170 degrees.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <Servo.h>
 
Servo myservo; // create servo object to control a servo          
 
int pos = 0; // variable to store the servo position     
 
void setup()
 
{
 
 myservo.attach(9); // attaches the servo on pin 9 to the servo object
 
}
 
void loop()
 
{
 
 for(pos = 10; pos <= 170; pos += 1) // goes from 10 degrees to 170 degrees
 
// in steps of 1 degree
 
 {                                 
 
   myservo.write(pos); // tell servo to go to position in variable ‘pos’             
 
   delay(15); // waits 15ms for the servo to reach the position
 
 }
 
 for(pos = 170; pos>=10; pos -= 1) // goes from 170 degrees to 10 degrees
 
 {                                
 
   myservo.write(pos); // tell servo to go to position in variable ‘pos’             
 
   delay(15); // waits 15ms for the servo to reach the position
 
 }
 
}

Notes about the servo:

Sometimes, your servo may behave erratically. When you can’t execute commands because the Arduino restarts itself, it may be due to the USB ports not providing enough power to drive servos. In this case, the Arduino resets and the application becomes useless. Here are two options to avoid this problem:

  1. You can add a high value capacitor (470uF or greater) between GND and 5V on the breadboard. This capacitor is used as a temporary supply when the Arduino doesn’t have enough power to sustain it with current. The longer terminal must be connected to VDD = 5V and the short one to the GND.
  1. You can program the board from USB and disconnect it afterward. Then, you can use a phone charger to supply the setup from the plug as this has larger current capability.

Let’s briefly look at how <Servo.h> library works.

#include <Servo.h>

This command has to be included to use Servo.h library. The 2 examples that are given in the Servo library are Knob and Sweep. These two are very good for testing the servos. Using Knob, you can use a potentiometer to move your servo to a specific degree. Using Sweep, you can sweep the shaft of your servo back and forth across 180 degrees.

Servo servo;

This is a declaration of a type. It defines a variable servo of type Servo. It is similar to other types like int or float for servo.

servo.attach(servoPin);

In the block setup of the code you need to assign your servo to a specific pin. This command is used to assigns the servo variable to the pin.

servo.write(angle);  

This command sets the angle of the shaft of your servo, from 0 to 180 degrees, and actually move the servo to that degree.

 

Step 3: Adding HC-05 Bluetooth module

———-

About Bluetooth HC-05 – User Instructional Manual

Bluetooth Serial module’s operation doesn’t need drive and can communicate with the other Bluetooth device that has the serial. Communication between two Bluetooth modules requires at least two conditions:

(1) The communication must be between master and slave.
(2) The password must be correct.

Properties of this module:

  • Master and slave mode can be switched
  • Bluetooth name: HC-05
  • Password:1234

Pairing: The master device can not only make pair with the specified Bluetooth address, like cell-phone, computer adapter, slave device, but also can search and make pair with the slave device automatically.

Typical method: On some specific conditions, master device and slave device can make a pair with each other automatically. (This is the default method.)

———-

In this project, we opted for a Bluetooth connection because it’s simple to configure. This works as a serial terminal for Arduino and it will be connected to the pins TX and RX.

There are some rules for successful data transmission via Bluetooth. We need to have:

  • A start bit (usually has the value of logic 0)
  • Data bits
  • Parity bits (sum of data bits; we will compare the sum from beginning end end)
  • A stop bit (in most cases has the value of logic 1)

PIN connection:

  1. Connect the TX pin from HC-05 to the RX pin of the Arduino.
  2. Connect the RX pin from HC-05 to the TX pin of the Arduino.
  3. Connect the GND pins together.

 

Detailed instructions on HC-05 setup is covered in our previous tutorial Make Your Own Arduino RFID Door Lock – Part 2: Unlock Using Your Smartphone. If you have trouble connecting the Bluetooth module, please refer back to the above tutorial.

automatic pet feeder

Figure 2: Connection between HC-05 and Arduino Uno.

Code for Bluetooth Transmission:

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
#include <SD.h>
 
#include <Wire.h>
 
#include <Time.h>
 
#include <TimeLib.h>
 
#include <DS1307RTC.h>
 
#include <Servo.h>
 
#include <EEPROM.h>     
 
#include <SPI.h>        
 
#include <MFRC522.h>
 
 
 
String voice;
 
 
 
#define SS_PIN 10
 
#define RST_PIN 9
 
Servo myservo;
 
 
 
boolean match = false;        
 
boolean programMode = false;  
 
boolean replaceMaster = false;
 
 
 
int lightSensor = 0;
 
int distanceSensor=1;
 
int pos = 0;
 
int successRead;
 
 
 
byte storedCard[4];  
 
byte readCard[4];   
 
byte masterCard[4];
 
 
 
MFRC522 mfrc522(SS_PIN, RST_PIN);
 
 
 
void setup() {
 
 pinMode(8, OUTPUT);
 
 setSyncProvider(RTC.get);
 
 myservo.attach(9);
 
 Serial.begin(9600);  
 
 SPI.begin();           
 
 mfrc522.PCD_Init();    
 
 if (EEPROM.read(1) != 143) {
 
   do
 
   {
 
     successRead = getID();            
 
   }
 
   while (!successRead);                  
 
   for ( int j = 0; j < 4; j++ )
 
   {        
 
     EEPROM.write( 2 + j, readCard[j] );  
 
   }
 
   EEPROM.write(1, 143);                 
 
   
 
 }
 
for ( int i = 0; i < 4; i++ )
 
{          
 
   masterCard[i] = EEPROM.read(2 + i);    
 
   Serial.print(masterCard[i], HEX);
 
   Serial.println("");
 
 }
 
 
 
}
 
 
 
void loop()
 
{
 
 int valueFromLightSensor = analogRead(lightSensor);
 
 //Serial.print("Light Value= ");
 
 //Serial.println(valueFromLightSensor);
 
 //Serial.println("");
 
 //Serial.print("Distance Value= ");
 
 
 
 int valueFromDistanceSensor = analogRead(distanceSensor);
 
 int distance= 4800/(valueFromDistanceSensor - 20);
 
 //Serial.println(distance);
 
 
 
 //Serial.print("Hour= ");
 
// Serial.println(hour());
 
 while (Serial.available())
 
 {
 
 delay(10);
 
 char c = Serial.read();
 
 voice += c;
 
 }  
 
 if (voice.length() > 0)
 
 {
 
   Serial.println(voice);
 
      if(voice == "feed")
 
      {
 
        myservo.write(130);  
 
        delay(1000);             
 
        myservo.write(50);  
 
        delay(1000);                 
 
        myservo.write(130);
 
        delay(1000);  
 
        myservo.write(50);
 
        delay(1000);  
 
        digitalClockDisplay();
 
       }
 
      if(voice == "feed2")
 
      {
 
        myservo.write(130);  
 
        delay(1000);             
 
        myservo.write(50);  
 
        delay(1000);                 
 
        digitalClockDisplay();
 
       }
 
       if(voice == "feed1")
 
      {
 
        myservo.write(130);  
 
        delay(1000);             
 
        myservo.write(50);  
 
        delay(1000);
 
        myservo.write(130);  
 
        delay(1000);             
 
        myservo.write(50);  
 
        delay(1000);     
 
        myservo.write(130);  
 
        delay(1000);             
 
        myservo.write(50);  
 
        delay(1000);      
 
        digitalClockDisplay();
 
       }
 
voice="";
 
}
 
 
 
 
 
do {
 
   successRead = getID();  
 
  
 
 }
 
 while (!successRead);   
 
 if (programMode) {
 
   if ( isMaster(readCard) ) {
 
      programMode = false;
 
     return;
 
   }
 
   else {
 
     if ( findID(readCard) ) {
 
       
 
     }
 
     
 
   }
 
 }
 
 else {
 
   if ( isMaster(readCard)) {    
 
     programMode = true;
 
          int count = EEPROM.read(0);   
 
    
 
    
 
   }
 
   else {
 
     if ( findID(readCard) ) {
 
      
 
               if ((hour()>=8) && (hour()<=12 )){
 
                 if (distance>=20){
 
                  //   Serial.println(distance);
 
                     myservo.write(130);  
 
                     delay(100);             
 
                     myservo.write(50);  
 
                     delay(100);                 
 
                     myservo.write(130);
 
                     delay(100);  
 
                     myservo.write(50);
 
                     delay(100);  
 
                     digitalClockDisplay();
 
                     
 
                 }
 
               delay(300);  
 
               }
 
               
 
               
 
      if ((hour()>=12) && (hour()<=16 )){
 
                 if (distance>=20){
 
                   //  Serial.println(distance);
 
                     myservo.write(130);  
 
                     delay(100);             
 
                     myservo.write(50);  
 
                     delay(100);                 
 
                     myservo.write(130);
 
                     delay(100);  
 
                     myservo.write(50);
 
                     delay(100);  
 
                     digitalClockDisplay();
 
                     
 
                 }
 
               delay(300);  
 
         }
 
         
 
         
 
        if ((hour()>=16) && (hour()<=20 )){
 
                 if (distance>=20){
 
                   //  Serial.println(distance);
 
                     myservo.write(130);  
 
                     delay(100);             
 
                     myservo.write(50);  
 
                     delay(100);                 
 
                     myservo.write(130);
 
                     delay(100);  
 
                     myservo.write(50);
 
                     delay(100);  
 
                     digitalClockDisplay();
 
                 }
 
               delay(300);  
 
         }
 
               
 
          if ((hour()>=20) && (hour()<=8 )){
 
                 if (distance>=20){
 
                    // Serial.println(distance);
 
                     myservo.write(130);  
 
                     delay(100);             
 
                     myservo.write(50);  
 
                     delay(100);                 
 
                     myservo.write(130);
 
                     delay(100);  
 
                     myservo.write(50);
 
                     delay(100);  
 
                     digitalClockDisplay();
 
                     
 
                 }
 
               delay(300);  
 
         }      
 
               
 
               
 
     }
 
     else {      // If not, show that the ID was not valid
 
       Serial.println(F("You shall not pass"));
 
      
 
     }
 
   }
 
 }
 
}
 
 
 
int getID() {
 
 
 
 if ( ! mfrc522.PICC_IsNewCardPresent()) {
 
   return 0;
 
 }
 
 if ( ! mfrc522.PICC_ReadCardSerial()) {   
 
   return 0;
 
 }
 
// Serial.println(F("Scanned PICC's UID:"));
 
 for (int i = 0; i < 4; i++) {  //
 
   readCard[i] = mfrc522.uid.uidByte[i];
 
//   Serial.print(readCard[i], HEX);
 
 }
 
//  Serial.println("");
 
 mfrc522.PICC_HaltA(); // Stop reading
 
 return 1;
 
}
 
 
 
void readID( int number ) {
 
 int start = (number * 4 ) + 2;    
 
 for ( int i = 0; i < 4; i++ ) {     
 
   storedCard[i] = EEPROM.read(start + i);   
 
 }
 
}
 
 
 
boolean checkTwo ( byte a[], byte b[] ) {
 
 if ( a[0] != NULL )       
 
   match = true;       
 
 for ( int k = 0; k < 4; k++ ) {  
 
   if ( a[k] != b[k] )     
 
     match = false;
 
 }
 
 if ( match ) {      
 
   return true;      
 
 }
 
 else  {
 
   return false;       
 
 }
 
}
 
 
 
int findIDSLOT( byte find[] ) {
 
 int count = EEPROM.read(0);      
 
 for ( int i = 1; i <= count; i++ ) {    
 
   readID(i);                
 
   if ( checkTwo( find, storedCard ) ) {   
 
     return i;       
 
     break;          
 
   }
 
 }
 
}
 
 
 
boolean findID( byte find[] ) {
 
 int count = EEPROM.read(0);     
 
 for ( int i = 1; i <= count; i++ ) {    
 
   readID(i);          
 
   if ( checkTwo( find, storedCard ) ) {   
 
     return true;
 
     break;  
 
   }
 
   else {   
 
   }
 
 }
 
 return false;
 
}
 
 
 
boolean isMaster( byte test[] ) {
 
 if ( checkTwo( test, masterCard ) )
 
   return true;
 
 else
 
   return false;
 
}
 
 
 
void digitalClockDisplay()
 
{
 
 Serial.print(hour());
 
 printDigits(minute());
 
 //printDigits(second());
 
 Serial.print(" ");
 
 Serial.print(day());
 
 Serial.print(" ");
 
 Serial.print(month());
 
 Serial.print(" ");
 
 Serial.print(year());
 
 Serial.println();
 
}
 
 
 
void printDigits(int digits){
 
 // utility function for digital clock display: prints preceding colon and leading 0
 
 Serial.print(":");
 
 if(digits < 10)
 
   Serial.print('0');
 
 Serial.print(digits);
 
}

 

The algorithm for this code is very simple: we initialize serial and wait for the port to open. We’ll send our commands through this. If it doesn’t become available, the program will not follow its flow and the “feed” command will not be sent to the microcontroller and not be processed.

The program also compares the string from the “voice” variable and from the string read on the serial. If the two are equal, a command is sent to the motor and it triggers the SG90 servo motor.

automatic pet feeder

Figure 3: HC-05 Bluetooth module connected to Part 1 setup

Step 3: Designing the app

Now, let’s create an app! As before, we’ll be using MIT App Inventor. Our ultimate goal is to create a suite of apps connected in one application (e.g. Smart Home App that integrates with multiple connected devices).

For MIT App Inventor setup guide, please refer back to the previous tutorial Make Your Own Arduino RFID Door Lock – Part 2: Unlock Using Your Smartphone (Step 3: The application). The tutorial walks you through step-by-step on creating your own app using the App Inventor.

The app we’ll be creating here will have a simple interface, which will include the following features:

  • Connecting to the Bluetooth
  • Feed: it allows you to feed your pet remotely
  • Store: it stores the data (as a file) in your phone
  • Show the date: it shows the date information on the screen of your phone
automatic pet feeder

Figure 4: A simple user interface of Pet Feeder App

 

The block diagrams for this program is very simple and easy to understand:

  • 1st Block: The first block is used for the Bluetooth button
    • ListPicker – MIT App Inventor
      A button that, when clicked on, displays a list of texts for the user to choose among. The texts can be specified through the Designer or Blocks Editor by setting the ElementsFromString property to their string-separated concatenation (for example, choice 1, choice 2, choice 3) or by setting the Elements property to a List in the Blocks editor.
    • ListPicker displays all the bluetooth available; this functionality works before you pick an element
automatic pet feeder

Figure 5: 1st Block

  • 2nd Block: this is used to make a connection between the app and the client with a function call BluetoothClient1.Connect address. Your phone’s Bluetooth will search for devices nearby and show them in a ListPicker. You can select the device you’re trying to pair with.
automatic pet feeder

Figure 6: 2nd Block

This also has a label where a message will be displayed after the connection is made. You will see a message “Connected” on the screen if the device is successfully connected.

  • 3rd Block: it sends a message through the client, only in case of connection. This text is sent through the Bluetooth from a device to another via Serial Communication. It’s like typing a text in Arduino’s Serial Monitor.
    When we’re reading from serial, we are comparing the input from a user with a stored string which is stored in Arduino’s memory. It’s how this algorithm works.

 

automatic pet feeder

Figure 7: 3rd Block

We’re going to take a look at another set of blocks:

  • 1st Block: it saves the date from the Bluetooth transmission to a .txt file, which is stored in the phone’s memory.
automatic pet feeder

Figure 8: 1st Block

  • 2nd Block: it reads the data saved in the text file when the button is pressed.
automatic pet feeder

Figure 9: 2nd Block

  • 3rd Block: it writes the time of the feed and the tag on the screen. This information is useful because it helps us keep track of time for feeding and in case we don’t want our pet to be feed anymore, we can check the time.
automatic pet feeder

Figure 10: 3rd Block

  • 4th Block: when error occurs, it will delete all the data from the .txt file. It is important to do that because it will no longer show the previous information.
automatic pet feeder

Figure 11: 4th Block

The second part of the app introduces different feeding modes: a normal feed mode, a feed mode for baby pets and a feed mode for for adult pets. This also offers you information about how much food you need to provide to your pet. One of THE coolest functions it has is the Speech Recognition mode. We’ll discuss more about this function below.

automatic pet feeder

Figure 12: Incorrect date and time shown on app

If you want to find out the day and time of the feeding, you can to press the button ”Show the date”. The app was made in thin mode because not everyone want to see all the information and the screen looks much cleaner that way. As you can see in the picture, the date and time is not shown correctly. In order to get the exact date and time, we need to use the example Set Time from Arduino IDE. The RTC module will now indicate the correct day & time.

automatic pet feeder

Figure 13: How to find SetTime in Arduino IDE


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
Set Time code:
 
 
 
#include <Wire.h>
 
#include <TimeLib.h>
 
#include <DS1307RTC.h>
 
 
 
const char *monthName[12] = {
 
 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
 
 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
 
};
 
 
 
tmElements_t tm;
 
 
 
void setup() {
 
 bool parse=false;
 
 bool config=false;
 
 
 
 // get the date and time the compiler was run
 
 if (getDate(__DATE__) && getTime(__TIME__)) {
 
   parse = true;
 
   // and configure the RTC with this info
 
   if (RTC.write(tm)) {
 
     config = true;
 
   }
 
 }
 
 
 
 Serial.begin(9600);
 
 while (!Serial) ; // wait for Arduino Serial Monitor
 
 delay(200);
 
 if (parse && config) {
 
   Serial.print("DS1307 configured Time=");
 
   Serial.print(__TIME__);
 
   Serial.print(", Date=");
 
   Serial.println(__DATE__);
 
 } else if (parse) {
 
   Serial.println("DS1307 Communication Error :-{");
 
   Serial.println("Please check your circuitry");
 
 } else {
 
   Serial.print("Could not parse info from the compiler, Time=\"");
 
   Serial.print(__TIME__);
 
   Serial.print("\", Date=\"");
 
   Serial.print(__DATE__);
 
   Serial.println("\"");
 
 }
 
}
 
 
 
void loop() {
 
}
 
 
 
bool getTime(const char *str)
 
{
 
 int Hour, Min, Sec;
 
 
 
 if (sscanf(str, "%d:%d:%d", &Hour, &Min, &Sec) != 3) return false;
 
 tm.Hour = Hour;
 
 tm.Minute = Min;
 
 tm.Second = Sec;
 
 return true;
 
}
 
 
 
bool getDate(const char *str)
 
{
 
 char Month[12];
 
 int Day, Year;
 
 uint8_t monthIndex;
 
 
 
 if (sscanf(str, "%s %d %d", Month, &Day, &Year) != 3) return false;
 
 for (monthIndex = 0; monthIndex < 12; monthIndex++) {
 
   if (strcmp(Month, monthName[monthIndex]) == 0) break;
 
 }
 
 if (monthIndex >= 12) return false;
 
 tm.Day = Day;
 
 tm.Month = monthIndex + 1;
 
 tm.Year = CalendarYrToTm(Year);
 
 return true;
 
}

 

Figure 14 shows a final version of the app:

automatic pet feeder

Figure 14: Final version of the app

Overview of the app:

  • Needs to be connected to Bluetooth
  • Features different feeding modes depending on your pet’s age.
  • To activate speech recognition mode, all that is needed is to click on the “Speech Recognition Feed” button and speak.
    • Only when the command is spoken correctly, the feeder works. If the keyword is incorrect (it wasn’t recognized properly), it will only show on the label without executing the command.
    • In case of speech recognition, when the command “feed” is spoken/repeated twice (e.g. You didn’t wait few seconds for the system to process the information), it results in “feedfeed,” which isn’t a valid command. It will remain on the label without executing it.
    • If the command “feed” on the speech recognition works correctly, it will print the time on the label.
  • Also included is a feeding guideline diagram that you can use to find information about the quantity of food provided depending on the pet’s weight.
automatic pet feeder

Figure 15: Pet feeding guidelines / ©Fish4Dogs

All the command will also be found on the Serial Monitor of the Arduino IDE. This helps us debug the app when necessary.

automatic pet feeder

Figure 16: Feed data shown in the serial monitor

For speech recognition, we need a button to activate this mode. We can use SpeechRecognizer component already provided in the App Inventor.

 

automatic pet feeder


Figure 17: Adding SpeechRecognizer component on MIT App Interventor.

After you have those two components, it’s very simple to connect them. You need to process the text originated from the speaker. This is done with Call SpeechRecognizer. GetText. After this, you need to have a label where you can display the text to see what you said – it can be done without it, but you won’t be able to see if you said the correct command or not. In the loop you also need to transfer the speech command to the Arduino via Bluetooth; you need to use SentText text procedure.

automatic pet feeder

Figure 18: Speech recognition blocks

For every mode, you need to have buttons. Each has a different command which will be sent to the Arduino, then different amount of food will be released.

automatic pet feeder


image041Figure 19: Small Pet, Normal Feed and Adult Pet blocks

 

Click here to read Part 1 of this article >

Tiberia Todeila
Tiberia Todeila
Tiberia is currently in her final year of electrical engineering at Politehnica University of Bucharest. She is very passionate about designing and developing Smart Home devices that make our everyday lives easier.

Check us out on Social Media

  • Facebook
  • Twitter

Recommended Posts

  • Make a Smart Automatic Pet Feeder with Arduino UnoMake a Smart Automatic Pet Feeder with Arduino Uno
  • Make a Smart Automatic Pet Feeder with Arduino Uno (Cont.)Make a Smart Automatic Pet Feeder with Arduino Uno (Cont.)
  • Make Your Own Arduino RFID Door Lock – Part 2: Unlock Using Your SmartphoneMake Your Own Arduino RFID Door Lock – Part 2: Unlock Using Your Smartphone
  • DIY Arduino Home Security System using ROHM Sensor Kit Part 1 – MechanicsDIY Arduino Home Security System using ROHM Sensor Kit Part 1 – Mechanics
  • DIY Arduino Home Security System using ROHM Sensor Kit Part 2 – Cayenne SetupDIY Arduino Home Security System using ROHM Sensor Kit Part 2 – Cayenne Setup
  • Latest Smart Home Products & Innovation Awards from CES 2017Latest Smart Home Products & Innovation Awards from CES 2017
Receive update on new postsPrivacy Policy

Recommended Tutorials

  • How to integrate an RFID module with Raspberry Pi How to integrate an RFID module with Raspberry Pi
  • How to Use the NRF24l01+ Module with Arduino How to Use the NRF24l01+ Module with Arduino
  • How to Run Arduino Sketches on Raspberry Pi How to Run Arduino Sketches on Raspberry Pi
  • Setting Up Raspberry Pi as a Home Media Server Setting Up Raspberry Pi as a Home Media Server

Recommended Trends

  • SewBot Is Revolutionizing the Clothing Manufacturing Industry SewBot Is Revolutionizing the Clothing Manufacturing Industry
  • All About The Sumo Robot Competition And Technology All About The Sumo Robot Competition And Technology
  • 5 Interesting Tips to Calculating the Forward Kinematics of a Robot 5 Interesting Tips to Calculating the Forward Kinematics of a Robot
  • Go Inside the Drones That Are Changing Food Delivery Go Inside the Drones That Are Changing Food Delivery
Menu
  • Arduino –
    Arduino Beginner’s Guide
  • Raspberry Pi –
    Raspberry Pi Beginner's Guide
  • Trending –
    Updates on New Technologies
  • Others –
    Interviews / Events / Others

Check us out on Social Media

  • Facebook
  • Twitter
  • About
  • Company
  • Privacy Policy
  • Terms of Service
  • Contact
  • Japanese
  • 简体中文
  • 繁體中文
Don’t Forget to Follow Us!
© Copyright 2016-2023. Device Plus - Powered by ROHM
© 2023 Device Plus. All Rights Reserved. Muffin group

istanbul escort istanbul escort istanbul escort