-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathindex.html
executable file
·1006 lines (929 loc) · 66.5 KB
/
index.html
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
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="">
<title>ECE 5725 Franklin</title>
<!-- Bootstrap core CSS -->
<link href="vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet">
<!-- Custom fonts for this template -->
<link href="vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,700" rel="stylesheet" type="text/css">
<link href="https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic" rel="stylesheet" type="text/css">
<!-- Plugin CSS -->
<link href="vendor/magnific-popup/magnific-popup.css" rel="stylesheet" type="text/css">
<!-- Custom styles for this template -->
<link href="css/freelancer.css" rel="stylesheet">
</head>
<body id="page-top">
<!-- Navigation -->
<nav class="navbar navbar-expand-lg bg-secondary fixed-top text-uppercase" id="mainNav">
<div class="container">
<a class="navbar-brand js-scroll-trigger" href="#page-top">Franklin</a>
<button class="navbar-toggler navbar-toggler-right text-uppercase bg-primary text-white rounded" type="button" data-toggle="collapse" data-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation">
Menu
<i class="fas fa-bars"></i>
</button>
<div class="collapse navbar-collapse" id="navbarResponsive">
<ul class="navbar-nav ml-auto">
<li class="nav-item mx-0 mx-lg-1">
<a class="nav-link py-3 px-0 px-lg-3 rounded js-scroll-trigger" href="#about">About</a>
</li>
<li class="nav-item mx-0 mx-lg-1">
<a class="nav-link py-3 px-0 px-lg-3 rounded js-scroll-trigger" href="#design">Design</a>
</li>
<li class="nav-item mx-0 mx-lg-1">
<a class="nav-link py-3 px-0 px-lg-3 rounded js-scroll-trigger" href="#results">Results</a>
</li>
<li class="nav-item mx-0 mx-lg-1">
<a class="nav-link py-3 px-0 px-lg-3 rounded js-scroll-trigger" href="#conclusion">Conclusion</a>
</li>
<li class="nav-item mx-0 mx-lg-1">
<a class="nav-link py-3 px-0 px-lg-3 rounded js-scroll-trigger" href="#future">Future</a>
</li>
<li class="nav-item mx-0 mx-lg-1">
<a class="nav-link py-3 px-0 px-lg-3 rounded js-scroll-trigger" href="#portfolio">Code</a>
</li>
<li class="nav-item mx-0 mx-lg-1">
<a class="nav-link py-3 px-0 px-lg-3 rounded js-scroll-trigger" href="#references">References</a>
</li>
<li class="nav-item mx-0 mx-lg-1">
<a class="nav-link py-3 px-0 px-lg-3 rounded js-scroll-trigger" href="#contact">Team</a>
</li>
</ul>
</div>
</div>
</nav>
<!-- Header -->
<header class="masthead bg-primary text-white text-center">
<div class="container" style="text-shadow: 1px 1px 10px #000">
<h1 class="text-uppercase mb-0">Franklin</h1>
<br>
<h2 class="font-weight-light mb-0">ECE 5725 SP 19 Final Project</h2>
<h2 class="font-weight-light mb-0">Caitlin Stanton (cs968) and Brandon Quinlan (bmq4)</h2>
</div>
</header>
<!-- About Section -->
<section class="portfolio" id="about">
<div class="container">
<h2 class="text-center text-uppercase text-secondary mb-0">Objective</h2>
<hr class="star-dark mb-5">
<div class="row">
<p class="lead">Many dog owners need to be away from the house for long periods of the day for work or school, and may worry about their companion while they’re out. The goal of Franklin is to alleviate some of these worries by keeping a dog happy and healthy automatically. Franklin has three features that can assist a dog owner in the daily task of caring for their pet.</p>
</div>
</div>
</section>
<section class="bg-primary text-white mb-0">
<div class="container">
<h2 class="text-center text-uppercase text-white">Introduction</h2>
<hr class="star-light mb-5">
<div class="row">
<p class="lead">We designed and implemented three different systems for automatic dog maintenance. The first of which is a food refill system. At a pre-programmed time of day, the food tank will open up and release food into a bowl until its full, indicated by an IR sensor embedded in the bowl. The second part is a fetch playing system. We use a DC motor to accelerate a ping pong ball inside a cylindrical cage. Using a magnet attached to the rim of the cage and a hall effect sensor we can determine when the cage has reached its maximum speed. At the maximum speed we use a servo motor to lift the ball over the edge of the cage, causing it to fly in a random direction. The final system is an automatic petting arm. When something comes within range of the arm, it begins making a petting motion. The arm has to joints, giving two degrees of freedom. The three parts combined compose a comprehensive system for automatic dog maintenance.</p>
<img class="img-fluid" src="img/system_diagram.png" alt="">
</div>
<p class="text-center"><i>Figure 1: System diagram for Franklin</i></p>
</div>
</section>
<!--Design and Testing Section-->
<section class="portfolio" id="design">
<div class="container">
<h2 class="text-center text-uppercase text-secondary mb-0">Design and Testing</h2>
<hr class="star-dark mb-5">
<h3 class="text-center text-uppercase text-secondary mb-0">Construction</h3>
<div class="row">
<p class="lead">We built our project physically in the same pattern that we wrote our software, incrementally. We started off with the food refill system, for which a few different physical components were needed. The first was a reservoir to hold the food that will be used to refill the bowl. This tank has to be larger than the food bowl so it can hold multiple refills at once, and also had to be shaped in a way that would facilitate easy dispensing of its contents. Our original plan was to make this tank out of wood, however to save time and material cost, we decided instead to use a 2 liter soda bottle, with both ends cut off. The next step was to build a sort of valve which we could use to control whether food is allowed to leave the tank or not. To fill this purpose we cut a hole into the bottom of the bottle and embedded a mini servo motor into it. We then made a small door out of index cards and attached it to the arm of the servo. Then by controlling the position of the servo motor we could either allow the food to fall into the bowl or not. For the bowl, we cut the bottom off of a cardboard box. We then screwed a pair of IR sensors directly across from each other, one emitter and one receiver. The line between the two is broken when the food fills above that height of the bowl, and we know we can close the door again. </p>
<p class="lead">For the fetch part of our project, the first step of the construction was to create cylindrical piece to place the ball in as it accelerates. Rather than design one, we decided to buy a squirrel cage blower on the suggestion of Prof Skovira. To keep the ball in place as the cage accelerates, we cut a piece of cardboard to size and wedged it into one of the slits of the cage and secured it with tape. We also built a small platform to keep the ball level inside the cage because the original bottom of the cage was sloped. We found that this change helped the ball move more freely to the wall we had built in when the cage was spinning. In order to lift the ball up over the edge of the cage after reaching top speed, we cut a hole in that platform and replaced it with a small lever attached to a servo. With this adjustment the ball would now fall onto the lever instead of remaining on the platform, so we could lift the ball out of the cage using the servo motor. To control the servo we decided to use a Raspberry Pi Zero, which would communicate wirelessly to our other Pi. The only space that the Pi Zero would fit was on the outside of the cage, so we taped it to the side with electrical tape. To power this Pi we attached a portable battery pack with a USB power connection. However the battery was fairly heavy, so we decided to counter-balance it with another battery on the opposite side of the cage. We decided that the other components were light enough to not cause much of a balance issue. </p>
<p class="lead">To actually spin the cage, our plan was to use the motor of a box fan. However we found that it was difficult to securely attach the cage to the motor, and additionally the motor struggled to actually spin the cage when it was attached by itself. Instead we found that we could tape the cage to the center of the fan blades which worked very well. To cover up the fan blades, we decided to put the motor back into the fan and just replace one side of the cover with cardboard, with an opening big enough for the cage attached to the motor to protrude. The body of the fan also gave us a base to build the rest of our project off of. We attached a plank of wood to the side of the fan and then attached the food tank to that, and placed the bowl underneath.</p>
<p class="lead">For the last part of the project, the petting arm, we used a long strip of cardboard which we cut into two pieces are the arm, and two standard servo motors as the joints. We used the cross-shaped attachment for the servo and screwed it to the cardboard. We were worried that the servo might not have the torque required to hold up both arms and the other servo, so we made the “upper” arm shorter to reduce the required torque. We attached the full arm to the body of the fan on the corner near the food tank, with the idea that a dog could be pet as it eats.</p>
<img class="img-fluid" src="img/franklin.png" alt="">
</div>
<p class="text-center text-secondary"><i>Figure 2: Finished Franklin</i></p>
<h3 class="text-center text-uppercase text-secondary mb-0">Notifications</h3>
<div class="row">
<p class="lead">Every action in Franklin provides a notification to the user with regards to whether the food is being refilled, your dog is playing fetch, or Franklin is petting your dog. This is all done with the Twilio library, which provides the ability to send SMS messages to any phone number. The library itself is very simple to use (the tutorial is linked below in “Resources”) and only required a Twilio account to get a free phone number from which to send the SMS messages. The overview of <span class="snippet">messages.py</span> is that an authorized connection to the Twilio Client object is made using a valid account’s SSID and authorization token. Once that’s been done, messages can now be sent using a REST API call. </p>
<p class="lead">The only drawback is that messages on a free Twilio account can only be sent to the phone number on the account itself. Additionally, Twilio can be easily hacked if your authorization token and SSID are posted publicly (i.e. on GitHub)—we learned this the hard way. Make sure to keep your tokens safe, whether through encryption or a private code repository.</p>
</div>
<h3 class="text-center text-uppercase text-secondary mb-0">Food Refill</h3>
<div class="row">
<p class="lead">The idea behind the food refill system is that there can be a specific time hard coded into a python script which will open the food tank at a specific time, and leave it open until the food bowl is full. To get the time, we use the <span class="snippet">datetime</span> Python library. We call the <span class="snippet">datatime.now()</span> function, and extract the hour and minute from the tuple that gets returned and compare to the pre-programmed time. If they match up we open the tank by changing the PWM signal using the <span class="snippet">RPi.GPIO</span> library. Once opened, we begin polling the GPIO pin connected to the linebreak IR receiver. Once we read that the pin value is low, indicating the bowl is full, we again change the PWM signal to the original value.</p>
<img class="img-fluid mb-5" src="img/feeding.png" alt="">
</div>
<p class="text-center text-secondary"><i>Figure 3: Food dispenser system</i></p>
<div class="row">
<p class="lead">We tested the different parts of this system incrementally, beginning with correctly identifying a specific time. We then moved on to calibrating the PWM to move the servo to the correct positions. Once we had the servo opening the tank at the correct time, we started working with the IR sensors. Again we begin by just seeing if we could identify a break by printing to the display. Once this was working we integrated it into the rest of the code so we could change the PWM signal upon the line break.</p>
</div>
<h3 class="text-center text-uppercase text-secondary mb-0">Fetch</h3>
<div class="row">
<p class="lead">The system we built to implement the fetch functionality of Franklin involved a motorized container to spin and catch the ball, as well as a mechanism to throw the ball out. The former was accomplished with a cage, typically used in cars, attached to a motor from a box fan. With a little extra cardboard and duct tape, the cage was made to effectively contain the ping pong ball by maintaining it at a height level that wouldn’t get the ball thrown out naturally while also allowing some range of motion to help our mechanism throw the ball. This mechanism involved a triangle of cardboard attached to a mini servo located in the central axis of the cage.</p>
<p class="lead">The flow of the system first started with turning on the fan motor to get the cage spinning. Attached to the cage was a stack of magnets, and these were used to determine how fast the cage was spinning. As the cage spun, these magnets passed by a hall effect sensor, which outputs a voltage based on the presence of a magnetic field. If a magnetic field was detected by the hall effect sensor (within a range of about two centimeters), it would output a low voltage into one of the GPIO pins of the Pi 3.</p>
<img class="img-fluid" src="img/hall_sensor_circuit.png" alt="">
</div>
<p class="text-center text-secondary"><i>Figure 4: Given circuit from hall effect sensor datasheet</i></p>
<div class="row">
<p class="lead">Every time the hall effect sensor registered a magnetic field, the time at which this occurred was stored in a two-element array. This array was continually updated to hold the two most recent times the sensor was triggered. These readings allowed for us to calculate the velocity of the cage using our function <span class="snippet">calculate()</span>; classical mechanics tells us that velocity is equal to distance divided by time, so we only needed those two values at any point to calculate. The distance was simply the circumference of the cage, found to be 15.24 centimeters. The period was the difference between the two times stored in the array mentioned earlier.</p>
<img class="img-fluid mb-5" src="img/hall.png" alt="">
</div>
<p class="text-center text-secondary"><i>Figure 5: Close-up of soldered circuit</i></p>
<div class="row">
<p class="lead">The <span class="snippet">calculate()</span> function was called using <span class="snippet">fetchCallback()</span>, a GPIO callback function attached both the rising and falling edge of GPIO 12, the pin connected to the output of the hall effect sensor. This callback function was linked to both edges to increase the efficiency of the hall effect sensor—later on in the project, we noticed that if many sensors and servos were running simultaneously, the hall effect sensor would only trigger if no magnet was present. Having the callback function triggered on both the rising and falling edge could allow for us to change the code around and have all of the functionality surrounding fetch be initiated when the hall effect sensor left the stack of magnets, not when it first saw it.</p>
<p class="lead">Within <span class="snippet">fetchCallback()</span> the velocity of the cage was calculated and then a conditional was placed on it to see if the conditions were right to throw the ball. In our case, that was done by checking to see if the global variable <span class="snippet">velocity</span> was holding a value greater than 200 cm/s. If that was true, then a series of steps were taken to throw the ball.</p>
<p class="lead">While the main Pi, our Pi 3, was running the code in <span class="snippet">fetch.py</span> to read the hall effect sensor and calculate the cage’s velocity, there was another Pi on Franklin running its own program, <span class="snippet">client.py</span>—this was a Raspberry Pi Zero W, a smaller Pi with WiFi functionality. The Pi Zero was headless, meaning that it wasn’t attached to a keyboard, mouse, monitor, or Ethernet connection. Instead, it was hooked up to a handheld power supply and attached to the side of the cage. Using an additional Pi meant that the servo within the cage could be controlled without the fear of tangled wires or broken equipment.</p>
<p class="lead">The sole purpose of the Pi Zero was to trigger the micro servo, specifically an SG90, and throw the ball. However, our design relied on the Pi 3 to determine if the cage was spinning at a high enough rate. This meant that some sort of data connection needed to be established between the two: this was done using a socket. Sockets allow connection between two nodes, one listening and one establishing the connection for data transfer, on the same network to communicate with each other. The Pi Zero was the server, meaning that it opened up a specific port and was waiting for a connection, while the Pi 3 was the client, the node that would reach out to establish the socket connection. Once <span class="snippet">client.py</span> was run, it bound itself to port 5725 and waited for a connection, which would be created by the Pi 3 saw that the cage was spinning at a rate faster than 200 cm/s. The socket connection occurring then alerted the Pi Zero that it was time to flip the ball out of the cage, and the micro servo was moved using a PWM signal.</p>
<img class="img-fluid mb-5" src="img/fetch.png" alt="">
</div>
<p class="text-center text-secondary"><i>Figure 6: Rotating cage with Pi Zero attached</i></p>
<h3 class="text-center text-uppercase text-secondary mb-0">Petting Arm</h3>
<div class="row">
<p class="lead">This feature of Franklin was the simplest to implement: it only needed to detect if a pet was nearby and then respond accordingly. We used a Pololu digital distance sensor to output a low voltage if it saw an object within the range of two to ten centimeters. Similar to the <span class="snippet">fetchCallback()</span> function, the GPIO pin connected to the distance sensor’s output was set to call the function <span class="snippet">petCallback()</span> on both the rising and falling edges of its output. Within that function was a while loop to check and see if the voltage output was still low; this was done to ensure that the petting motion of our arm was continuous while the object was still in range. The motion of the arm was controlled using two standard parallax servos, each connected to a separate part of the arm. The lower servo had a more limited range of motion, oscillating between PWM pulse widths of 1.45 ms and 1.55 ms, while the upper servo switched between 1.3 ms and 1.7 ms.</p>
<img class="img-fluid mb-5" src="img/petting.png" alt="">
</div>
<p class="text-center text-secondary"><i>Figure 7: Petting arm with distance sensor circuit</i></p>
</div>
</section>
<!-- Results -->
<section class="bg-primary text-white mb-0" id="results">
<div class="container">
<h2 class="text-center text-uppercase text-white">Results</h2>
<hr class="star-light mb-5">
<div class="row">
<p class="lead">We were glad to be able to implement all of the systems we had originally outlined in our project proposal. We were also able to extend this to include the text notifications using Twilio. While all of the systems did work, not all of them worked exactly as intended. For our demo, we used balled up pieces of paper in place of dog food to show the food refill system. However, we found that the balls frequently clogged up in the tank and wouldn’t fall out even if the tank was open. Additionally, when anything broke the line the tank would close, even if it was just a stray ball. We have a few ideas that remedy this observations discussed in the Future Work section. For the fetch system we were actually pleasantly surprised that it worked as well as it did. We expected it to be the hardest part of our project, which we were right about, but we were very pleased with how we were able to throw the ball. However we were disappointed that we could not make it fully automated. We had wanted the motor to start up automatically, in response to a sensor. We were not able to separate the power cord from the fan, which meant we had to manually switch it on and off. With respect to the petting arm, we always expected that it would be difficult to replicate the motion of a human arm using two servos, but we were pleased with the results that we got.</p>
<p class="lead">Our demo video, outlining what we were able to accomplish with Franklin, can be found below:</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/F-BLPiqjex0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
</div>
</section>
<!-- Conclusion -->
<section class="portfolio" id="conclusion">
<div class="container">
<h2 class="text-center text-uppercase text-secondary mb-0">Conclusion</h2>
<hr class="star-dark mb-5">
<div class="row">
<p class="lead">While we were able to get all of the different systems working in isolation, we were disappointed not to be able to integrate all of the systems together. We found that because of the way we read the time for the food refill system, we could not attach that trigger to a hardware interrupt as we were for the other sensors. This meant we had to poll the time. We found that this caused issues with the PWM signals to the servos, causing a lot of jitters, to the point where they were no longer really usable. We also found that it caused issues with the reading from other sensors, in particular the hall effect sensor, meaning that we were not able to integrate all of the systems together. Otherwise everything worked as expected. </p>
</div>
</div>
</section>
<!--Future -->
<section class="bg-primary text-white mb-0" id="future">
<div class="container">
<h2 class="text-center text-uppercase text-white">Future Work</h2>
<hr class="star-light mb-5">
<div class="row">
<p class="lead">If we had more time to work on this project, our first goal would of course be integration of all of the different parts. We think that the piece holding back the integration was the polling of the time for food refill. To get around this our idea is to use the crontab to schedule a task which would open the tank and wait for the IR beam to be broken. We suspect that this would lower the computational requirements such that they wouldn’t interfere with the PWM or other GPIO readings. This should allow us to integrate the different systems more cleanly. </p>
<p class="lead">We also would like to improve the functionality of a few of the systems themselves. The first is that we would change the way the food tank closes. We want to change it so that the tank will only close if the beam stays broken for some contiguous amount of time. This would be a better indicator that the bowl is actually full, and be more robust to a stray piece of food falling in front of the beam.</p>
<p class="lead">One other thing we would like to do is try to implement our stretch goals. One such goal was to integrate a camera into our system that would allow a pet owner to see a live feed of their dog. This would have involved many additional steps, namely getting the camera working, getting the Pi able to communicate the camera using WiFi, and then developing an app that a user could download to access the data. With more time, we would have liked to finish integrating all of these systems together and making these improvements.</p>
</div>
</div>
</section>
<!-- Portfolio Grid Section
<section class="portfolio" id="portfolio">
<div class="container">
<h2 class="text-center text-uppercase text-secondary mb-0">Code Appendix</h2>
<hr class="star-dark mb-5">
<div class="row">
<div class="col-md-6 col-lg-4">
<a class="portfolio-item d-block mx-auto" href="#portfolio-modal-1">
<div class="portfolio-item-caption d-flex position-absolute h-100 w-100">
<div class="portfolio-item-caption-content my-auto w-100 text-center text-white">
<i class="fas fa-search-plus fa-3x"></i>
</div>
</div>
<img class="img-fluid" src="img/portfolio/cabin.png" alt="">
</a>
</div>
<div class="col-md-6 col-lg-4">
<a class="portfolio-item d-block mx-auto" href="#portfolio-modal-2">
<div class="portfolio-item-caption d-flex position-absolute h-100 w-100">
<div class="portfolio-item-caption-content my-auto w-100 text-center text-white">
<i class="fas fa-search-plus fa-3x"></i>
</div>
</div>
<img class="img-fluid" src="img/portfolio/cake.png" alt="">
</a>
</div>
<div class="col-md-6 col-lg-4">
<a class="portfolio-item d-block mx-auto" href="#portfolio-modal-3">
<div class="portfolio-item-caption d-flex position-absolute h-100 w-100">
<div class="portfolio-item-caption-content my-auto w-100 text-center text-white">
<i class="fas fa-search-plus fa-3x"></i>
</div>
</div>
<img class="img-fluid" src="img/portfolio/circus.png" alt="">
</a>
</div>
<div class="col-md-6 col-lg-4">
<a class="portfolio-item d-block mx-auto" href="#portfolio-modal-4">
<div class="portfolio-item-caption d-flex position-absolute h-100 w-100">
<div class="portfolio-item-caption-content my-auto w-100 text-center text-white">
<i class="fas fa-search-plus fa-3x"></i>
</div>
</div>
<img class="img-fluid" src="img/portfolio/game.png" alt="">
</a>
</div>
<div class="col-md-6 col-lg-4">
<a class="portfolio-item d-block mx-auto" href="#portfolio-modal-5">
<div class="portfolio-item-caption d-flex position-absolute h-100 w-100">
<div class="portfolio-item-caption-content my-auto w-100 text-center text-white">
<i class="fas fa-search-plus fa-3x"></i>
</div>
</div>
<img class="img-fluid" src="img/portfolio/safe.png" alt="">
</a>
</div>
<div class="col-md-6 col-lg-4">
<a class="portfolio-item d-block mx-auto" href="#portfolio-modal-6">
<div class="portfolio-item-caption d-flex position-absolute h-100 w-100">
<div class="portfolio-item-caption-content my-auto w-100 text-center text-white">
<i class="fas fa-search-plus fa-3x"></i>
</div>
</div>
<img class="img-fluid" src="img/portfolio/submarine.png" alt="">
</a>
</div>
</div>
</div>
</section>-->
<!--Code Appendix-->
<section class="portfolio" id="portfolio">
<div class="container">
<h2 class="text-center text-uppercase text-secondary mb-0">Code Appendix</h2>
<hr class="star-dark mb-5">
<p class="lead">All programs used are located below or in <a href="https://github.com/caitlinstanton/ece-5725/tree/master/final_project">our Github repository</a>.</p>
<h3 class="snippet text-center text-uppercase text-secondary mb-0">feed.py</h3>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><table><tr><td><pre style="margin: 0; line-height: 125%"> 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</pre></td><td><pre style="margin: 0; line-height: 125%"><span style="color: #888888"># Brandon Quinlan (bmq4) and Caitlin Stanton (cs968)</span>
<span style="color: #888888"># ECE5725, Final Project</span>
<span style="color: #008800; font-weight: bold">import</span> <span style="color: #0e84b5; font-weight: bold">datetime</span>
<span style="color: #008800; font-weight: bold">import</span> <span style="color: #0e84b5; font-weight: bold">time</span>
<span style="color: #008800; font-weight: bold">from</span> <span style="color: #0e84b5; font-weight: bold">twilio.rest</span> <span style="color: #008800; font-weight: bold">import</span> Client
<span style="color: #008800; font-weight: bold">import</span> <span style="color: #0e84b5; font-weight: bold">RPi.GPIO</span> <span style="color: #008800; font-weight: bold">as</span> <span style="color: #0e84b5; font-weight: bold">GPIO</span>
<span style="color: #008800; font-weight: bold">import</span> <span style="color: #0e84b5; font-weight: bold">messages</span>
<span style="color: #888888"># Update PWM signal of p</span>
<span style="color: #008800; font-weight: bold">def</span> <span style="color: #0066BB; font-weight: bold">change_PWM</span>(on_time, p):
freq <span style="color: #333333">=</span> <span style="color: #6600EE; font-weight: bold">1000.0</span><span style="color: #333333">/</span>(<span style="color: #6600EE; font-weight: bold">20.0</span><span style="color: #333333">+</span>on_time)
dc <span style="color: #333333">=</span> <span style="color: #6600EE; font-weight: bold">100.0</span><span style="color: #333333">*</span>(on_time<span style="color: #333333">/</span>(<span style="color: #6600EE; font-weight: bold">20.0</span><span style="color: #333333">+</span>on_time))
p<span style="color: #333333">.</span>ChangeFrequency(freq)
p<span style="color: #333333">.</span>ChangeDutyCycle(dc)
<span style="color: #888888"># Set up GPIO</span>
GPIO<span style="color: #333333">.</span>setmode(GPIO<span style="color: #333333">.</span>BCM)
GPIO<span style="color: #333333">.</span>setup(<span style="color: #0000DD; font-weight: bold">27</span>, GPIO<span style="color: #333333">.</span>IN, pull_up_down<span style="color: #333333">=</span>GPIO<span style="color: #333333">.</span>PUD_UP)
GPIO<span style="color: #333333">.</span>setup(<span style="color: #0000DD; font-weight: bold">13</span>, GPIO<span style="color: #333333">.</span>OUT)
GPIO<span style="color: #333333">.</span>setup(<span style="color: #0000DD; font-weight: bold">5</span>,GPIO<span style="color: #333333">.</span>IN, pull_up_down<span style="color: #333333">=</span>GPIO<span style="color: #333333">.</span>PUD_UP)
<span style="color: #888888"># Define constants</span>
GPIO_pin <span style="color: #333333">=</span> <span style="color: #0000DD; font-weight: bold">13</span>
on_time <span style="color: #333333">=</span> <span style="color: #6600EE; font-weight: bold">1.2</span>
freq <span style="color: #333333">=</span> <span style="color: #6600EE; font-weight: bold">1000.0</span><span style="color: #333333">/</span>(<span style="color: #6600EE; font-weight: bold">20.0</span><span style="color: #333333">+</span>on_time)
dc <span style="color: #333333">=</span> <span style="color: #6600EE; font-weight: bold">100.0</span><span style="color: #333333">*</span>(on_time<span style="color: #333333">/</span>(<span style="color: #6600EE; font-weight: bold">20.0</span><span style="color: #333333">+</span>on_time))
p <span style="color: #333333">=</span> GPIO<span style="color: #333333">.</span>PWM(GPIO_pin, freq)
p<span style="color: #333333">.</span>start(dc)
<span style="color: #888888"># Initialize desired food time</span>
food_time <span style="color: #333333">=</span> (<span style="color: #0000DD; font-weight: bold">18</span>,<span style="color: #0000DD; font-weight: bold">24</span>)
current_time <span style="color: #333333">=</span> (datetime<span style="color: #333333">.</span>datetime<span style="color: #333333">.</span>now()<span style="color: #333333">.</span>time()<span style="color: #333333">.</span>hour, datetime<span style="color: #333333">.</span>datetime<span style="color: #333333">.</span>now()<span style="color: #333333">.</span>time()<span style="color: #333333">.</span>minute)
<span style="color: #008800; font-weight: bold">while</span> (food_time <span style="color: #333333">!=</span> current_time):
<span style="color: #888888"># wait for feeding time</span>
current_time <span style="color: #333333">=</span> (datetime<span style="color: #333333">.</span>datetime<span style="color: #333333">.</span>now()<span style="color: #333333">.</span>time()<span style="color: #333333">.</span>hour, datetime<span style="color: #333333">.</span>datetime<span style="color: #333333">.</span>now()<span style="color: #333333">.</span>time()<span style="color: #333333">.</span>minute)
messages<span style="color: #333333">.</span>send_sms(<span style="background-color: #fff0f0">"Time for food!"</span>)
<span style="color: #888888"># open tank</span>
change_PWM(<span style="color: #0000DD; font-weight: bold">2</span>, p)
<span style="color: #008800; font-weight: bold">while</span> GPIO<span style="color: #333333">.</span>input(<span style="color: #0000DD; font-weight: bold">5</span>):
<span style="color: #888888"># wait for line break</span>
<span style="color: #008800; font-weight: bold">pass</span>
<span style="color: #888888"># Close tank</span>
change_PWM(<span style="color: #6600EE; font-weight: bold">1.2</span>, p)
time<span style="color: #333333">.</span>sleep(<span style="color: #0000DD; font-weight: bold">3</span>)
p<span style="color: #333333">.</span>stop()
GPIO<span style="color: #333333">.</span>cleanup()
</pre></td></tr></table></div>
<h3 class="snippet text-center text-uppercase text-secondary mb-0">fetch.py</h3>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><table><tr><td><pre style="margin: 0; line-height: 125%"> 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</pre></td><td><pre style="margin: 0; line-height: 125%"><span style="color: #888888"># Brandon Quinlan (bmq4) and Caitlin Stanton (cs968)</span>
<span style="color: #888888"># ECE5725, Final Project</span>
<span style="color: #008800; font-weight: bold">import</span> <span style="color: #0e84b5; font-weight: bold">time</span>
<span style="color: #008800; font-weight: bold">import</span> <span style="color: #0e84b5; font-weight: bold">datetime</span>
<span style="color: #008800; font-weight: bold">import</span> <span style="color: #0e84b5; font-weight: bold">RPi.GPIO</span> <span style="color: #008800; font-weight: bold">as</span> <span style="color: #0e84b5; font-weight: bold">GPIO</span>
<span style="color: #008800; font-weight: bold">import</span> <span style="color: #0e84b5; font-weight: bold">math</span>
<span style="color: #008800; font-weight: bold">import</span> <span style="color: #0e84b5; font-weight: bold">socket</span>
<span style="color: #008800; font-weight: bold">import</span> <span style="color: #0e84b5; font-weight: bold">messages</span>
GPIO<span style="color: #333333">.</span>setmode(GPIO<span style="color: #333333">.</span>BCM)
<span style="color: #888888"># Variables for fetch</span>
timeVal <span style="color: #333333">=</span> [<span style="color: #0000DD; font-weight: bold">0</span>,<span style="color: #0000DD; font-weight: bold">0</span>]
diameter <span style="color: #333333">=</span> <span style="color: #6600EE; font-weight: bold">15.24</span> <span style="color: #888888">#centimeters</span>
circumference <span style="color: #333333">=</span> math<span style="color: #333333">.</span>pi<span style="color: #333333">*</span>diameter
numPasses <span style="color: #333333">=</span> <span style="color: #0000DD; font-weight: bold">0</span>
velocity <span style="color: #333333">=</span> <span style="color: #0000DD; font-weight: bold">0</span> <span style="color: #888888">#cm/s</span>
<span style="color: #888888"># ISR to be called</span>
<span style="color: #008800; font-weight: bold">def</span> <span style="color: #0066BB; font-weight: bold">fetchCallback</span>(channel):
<span style="color: #888888"># Called if sensor output changes</span>
stamp <span style="color: #333333">=</span> time<span style="color: #333333">.</span>time()
<span style="color: #008800; font-weight: bold">if</span> GPIO<span style="color: #333333">.</span>input(channel):
<span style="color: #888888"># No magnet</span>
<span style="color: #008800; font-weight: bold">print</span>(<span style="background-color: #fff0f0">"Sensor HIGH"</span>)
<span style="color: #008800; font-weight: bold">else</span>:
<span style="color: #888888"># Magnet</span>
<span style="color: #008800; font-weight: bold">print</span>(<span style="background-color: #fff0f0">"Sensor LOW"</span>)
calculate(stamp)
<span style="color: #008800; font-weight: bold">global</span> velocity
<span style="color: #008800; font-weight: bold">if</span> velocity <span style="color: #333333">></span> <span style="color: #0000DD; font-weight: bold">200</span>:
<span style="color: #008800; font-weight: bold">print</span> <span style="background-color: #fff0f0">"hall"</span>
<span style="color: #888888"># Connect to Pi zero</span>
messages<span style="color: #333333">.</span>send_sms(<span style="background-color: #fff0f0">"Playing fetch!"</span>)
s <span style="color: #333333">=</span> socket<span style="color: #333333">.</span>socket()
s<span style="color: #333333">.</span>connect((<span style="background-color: #fff0f0">'10.148.12.144'</span>,<span style="color: #0000DD; font-weight: bold">5725</span>))
<span style="color: #008800; font-weight: bold">print</span> <span style="background-color: #fff0f0">"connected"</span>
server <span style="color: #333333">=</span> s<span style="color: #333333">.</span>recv(<span style="color: #0000DD; font-weight: bold">1024</span>)
s<span style="color: #333333">.</span>close()
velocity <span style="color: #333333">=</span> <span style="color: #0000DD; font-weight: bold">0</span>
<span style="color: #888888"># Update velocity</span>
<span style="color: #008800; font-weight: bold">def</span> <span style="color: #0066BB; font-weight: bold">calculate</span>(magnetPass):
<span style="color: #008800; font-weight: bold">global</span> numPasses
numPasses <span style="color: #333333">=</span> numPasses <span style="color: #333333">+</span> <span style="color: #0000DD; font-weight: bold">1</span>
timeVal[<span style="color: #0000DD; font-weight: bold">0</span>] <span style="color: #333333">=</span> timeVal[<span style="color: #0000DD; font-weight: bold">1</span>]
timeVal[<span style="color: #0000DD; font-weight: bold">1</span>] <span style="color: #333333">=</span> magnetPass
period <span style="color: #333333">=</span> timeVal[<span style="color: #0000DD; font-weight: bold">1</span>]<span style="color: #333333">-</span>timeVal[<span style="color: #0000DD; font-weight: bold">0</span>]
<span style="color: #008800; font-weight: bold">global</span> velocity
velocity <span style="color: #333333">=</span> circumference<span style="color: #333333">/</span>period
<span style="color: #008800; font-weight: bold">def</span> <span style="color: #0066BB; font-weight: bold">main</span>():
<span style="color: #888888"># Wrap main content in a try block so we can</span>
<span style="color: #888888"># catch the user pressing CTRL-C and run the</span>
<span style="color: #888888"># GPIO cleanup function. This will also prevent</span>
<span style="color: #888888"># the user seeing lots of unnecessary error</span>
<span style="color: #888888"># messages.</span>
<span style="color: #888888"># Get initial reading</span>
fetchCallback(<span style="color: #0000DD; font-weight: bold">12</span>)
<span style="color: #008800; font-weight: bold">try</span>:
<span style="color: #888888"># Loop until users quits with CTRL-C</span>
<span style="color: #008800; font-weight: bold">while</span> <span style="color: #007020">True</span> :
time<span style="color: #333333">.</span>sleep(<span style="color: #6600EE; font-weight: bold">0.1</span>)
<span style="color: #008800; font-weight: bold">except</span> <span style="color: #FF0000; font-weight: bold">KeyboardInterrupt</span>:
<span style="color: #888888"># Reset GPIO settings</span>
GPIO<span style="color: #333333">.</span>cleanup()
<span style="color: #888888"># Set Switch GPIO as input</span>
<span style="color: #888888"># Pull high by default</span>
GPIO<span style="color: #333333">.</span>setup(<span style="color: #0000DD; font-weight: bold">12</span>, GPIO<span style="color: #333333">.</span>IN, pull_up_down<span style="color: #333333">=</span>GPIO<span style="color: #333333">.</span>PUD_UP)
GPIO<span style="color: #333333">.</span>add_event_detect(<span style="color: #0000DD; font-weight: bold">12</span>, GPIO<span style="color: #333333">.</span>BOTH, callback<span style="color: #333333">=</span>fetchCallback, bouncetime<span style="color: #333333">=</span><span style="color: #0000DD; font-weight: bold">200</span>)
<span style="color: #008800; font-weight: bold">if</span> __name__<span style="color: #333333">==</span><span style="background-color: #fff0f0">"__main__"</span>:
main()
</pre></td></tr></table></div>
<h3 class="snippet text-center text-uppercase text-secondary mb-0">client.py</h3>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><table><tr><td><pre style="margin: 0; line-height: 125%"> 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</pre></td><td><pre style="margin: 0; line-height: 125%"><span style="color: #888888"># Brandon Quinlan (bmq4) and Caitlin Stanton (cs968)</span>
<span style="color: #888888"># ECE5725, Final Project</span>
<span style="color: #888888"># Python script to be run on the Pi Zero</span>
<span style="color: #008800; font-weight: bold">import</span> <span style="color: #0e84b5; font-weight: bold">socket</span>
<span style="color: #008800; font-weight: bold">import</span> <span style="color: #0e84b5; font-weight: bold">RPi.GPIO</span> <span style="color: #008800; font-weight: bold">as</span> <span style="color: #0e84b5; font-weight: bold">GPIO</span>
servo <span style="color: #333333">=</span> <span style="color: #007020">False</span>
s <span style="color: #333333">=</span> socket<span style="color: #333333">.</span>socket()
<span style="color: #888888"># Connect to Pi 3</span>
<span style="color: #008800; font-weight: bold">def</span> <span style="color: #0066BB; font-weight: bold">connection</span>():
<span style="color: #008800; font-weight: bold">global</span> s
s<span style="color: #333333">.</span>bind((<span style="background-color: #fff0f0">''</span>,<span style="color: #0000DD; font-weight: bold">5725</span>))
<span style="color: #888888"># Setup GPIO and PWM</span>
GPIO<span style="color: #333333">.</span>setmode(GPIO<span style="color: #333333">.</span>BCM)
GPIO<span style="color: #333333">.</span>setup(<span style="color: #0000DD; font-weight: bold">3</span>,GPIO<span style="color: #333333">.</span>OUT)
freq<span style="color: #333333">=</span><span style="color: #6600EE; font-weight: bold">1000.0</span><span style="color: #333333">/</span><span style="color: #6600EE; font-weight: bold">21.5</span>
p<span style="color: #333333">=</span>GPIO<span style="color: #333333">.</span>PWM(<span style="color: #0000DD; font-weight: bold">3</span>,freq)
dc<span style="color: #333333">=</span><span style="color: #6600EE; font-weight: bold">100.0</span><span style="color: #333333">*</span>(<span style="color: #6600EE; font-weight: bold">1.5</span><span style="color: #333333">/</span><span style="color: #6600EE; font-weight: bold">21.5</span>)
p<span style="color: #333333">.</span>start(dc)
<span style="color: #888888"># Wait for connection</span>
<span style="color: #008800; font-weight: bold">def</span> <span style="color: #0066BB; font-weight: bold">waiting</span>():
s<span style="color: #333333">.</span>listen(<span style="color: #0000DD; font-weight: bold">5</span>)
c,addr <span style="color: #333333">=</span> s<span style="color: #333333">.</span>accept()
<span style="color: #008800; font-weight: bold">print</span> <span style="background-color: #fff0f0">"got connection </span><span style="background-color: #eeeeee">%s</span><span style="background-color: #fff0f0"> </span><span style="background-color: #eeeeee">%s</span><span style="background-color: #fff0f0">"</span> <span style="color: #333333">%</span>(c,addr)
<span style="color: #008800; font-weight: bold">global</span> servo
servo <span style="color: #333333">=</span> <span style="color: #007020">True</span>
<span style="color: #888888"># Change servo position</span>
<span style="color: #008800; font-weight: bold">def</span> <span style="color: #0066BB; font-weight: bold">playFetch</span>():
<span style="color: #008800; font-weight: bold">print</span> <span style="background-color: #fff0f0">"yeet"</span>
p<span style="color: #333333">.</span>ChangeFrequency(<span style="color: #6600EE; font-weight: bold">1000.0</span><span style="color: #333333">/</span><span style="color: #6600EE; font-weight: bold">21.0</span>)
p<span style="color: #333333">.</span>ChangeDutyCycle(<span style="color: #6600EE; font-weight: bold">100.0</span><span style="color: #333333">*</span>(<span style="color: #6600EE; font-weight: bold">1.0</span><span style="color: #333333">/</span><span style="color: #6600EE; font-weight: bold">21.0</span>))
<span style="color: #008800; font-weight: bold">if</span> __name__<span style="color: #333333">==</span><span style="background-color: #fff0f0">"__main__"</span>:
connection()
<span style="color: #008800; font-weight: bold">while</span> <span style="color: #007020">True</span>:
<span style="color: #008800; font-weight: bold">if</span> servo:
playFetch()
servo <span style="color: #333333">=</span> <span style="color: #007020">False</span>
<span style="color: #008800; font-weight: bold">else</span>:
waiting()
</pre></td></tr></table></div>
<h3 class="snippet text-center text-uppercase text-secondary mb-0">petting.py</h3>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><table><tr><td><pre style="margin: 0; line-height: 125%"> 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</pre></td><td><pre style="margin: 0; line-height: 125%"><span style="color: #888888"># Brandon Quinlan (bmq4) and Caitlin Stanton (cs968)</span>
<span style="color: #888888"># ECE5725, Final Project</span>
<span style="color: #008800; font-weight: bold">import</span> <span style="color: #0e84b5; font-weight: bold">RPi.GPIO</span> <span style="color: #008800; font-weight: bold">as</span> <span style="color: #0e84b5; font-weight: bold">GPIO</span>
<span style="color: #008800; font-weight: bold">import</span> <span style="color: #0e84b5; font-weight: bold">time</span>
<span style="color: #008800; font-weight: bold">import</span> <span style="color: #0e84b5; font-weight: bold">messages</span>
<span style="color: #888888"># Set up GPIO</span>
GPIO<span style="color: #333333">.</span>setmode(GPIO<span style="color: #333333">.</span>BCM)
GPIO<span style="color: #333333">.</span>setup(<span style="color: #0000DD; font-weight: bold">20</span>,GPIO<span style="color: #333333">.</span>OUT)
GPIO<span style="color: #333333">.</span>setup(<span style="color: #0000DD; font-weight: bold">21</span>,GPIO<span style="color: #333333">.</span>OUT)
<span style="color: #888888"># Set initial PWM</span>
on_time <span style="color: #333333">=</span> <span style="color: #6600EE; font-weight: bold">1.5</span>
freq <span style="color: #333333">=</span> <span style="color: #6600EE; font-weight: bold">1000.0</span><span style="color: #333333">/</span>(<span style="color: #6600EE; font-weight: bold">20.0</span><span style="color: #333333">+</span>on_time)
dc <span style="color: #333333">=</span> <span style="color: #6600EE; font-weight: bold">100.0</span><span style="color: #333333">*</span>(on_time<span style="color: #333333">/</span>(<span style="color: #6600EE; font-weight: bold">20.0</span><span style="color: #333333">+</span>on_time))
pet1 <span style="color: #333333">=</span> GPIO<span style="color: #333333">.</span>PWM(<span style="color: #0000DD; font-weight: bold">20</span>, freq)
pet2 <span style="color: #333333">=</span> GPIO<span style="color: #333333">.</span>PWM(<span style="color: #0000DD; font-weight: bold">21</span>,freq)
pet1<span style="color: #333333">.</span>start(dc)
pet2<span style="color: #333333">.</span>start(dc)
<span style="color: #888888"># Changes PWN signal of p to be high for "on_time" microseconds</span>
<span style="color: #008800; font-weight: bold">def</span> <span style="color: #0066BB; font-weight: bold">change_PWM</span>(on_time, p):
freq <span style="color: #333333">=</span> <span style="color: #6600EE; font-weight: bold">1000.0</span><span style="color: #333333">/</span>(<span style="color: #6600EE; font-weight: bold">20.0</span><span style="color: #333333">+</span>on_time)
dc <span style="color: #333333">=</span> <span style="color: #6600EE; font-weight: bold">100.0</span><span style="color: #333333">*</span>(on_time<span style="color: #333333">/</span>(<span style="color: #6600EE; font-weight: bold">20.0</span><span style="color: #333333">+</span>on_time))
p<span style="color: #333333">.</span>ChangeFrequency(freq)
p<span style="color: #333333">.</span>ChangeDutyCycle(dc)
<span style="color: #888888"># ISR for petting arm</span>
<span style="color: #008800; font-weight: bold">def</span> <span style="color: #0066BB; font-weight: bold">petCallback</span>(channel):
motion2 <span style="color: #333333">=</span> [<span style="color: #6600EE; font-weight: bold">1.3</span>,<span style="color: #6600EE; font-weight: bold">1.7</span>]
motion1 <span style="color: #333333">=</span> [<span style="color: #6600EE; font-weight: bold">1.45</span>,<span style="color: #6600EE; font-weight: bold">1.55</span>]
i <span style="color: #333333">=</span> <span style="color: #0000DD; font-weight: bold">0</span>
messages<span style="color: #333333">.</span>send_sms(<span style="background-color: #fff0f0">"Pet in range"</span>)
<span style="color: #008800; font-weight: bold">while</span> <span style="color: #000000; font-weight: bold">not</span> (GPIO<span style="color: #333333">.</span>input(channel)):
change_PWM(motion1[i<span style="color: #333333">%</span><span style="color: #0000DD; font-weight: bold">2</span>],pet1)
change_PWM(motion2[i<span style="color: #333333">%</span><span style="color: #0000DD; font-weight: bold">2</span>],pet2)
i <span style="color: #333333">=</span> i <span style="color: #333333">+</span> <span style="color: #0000DD; font-weight: bold">1</span>
time<span style="color: #333333">.</span>sleep(<span style="color: #6600EE; font-weight: bold">0.2</span>)
<span style="color: #008800; font-weight: bold">def</span> <span style="color: #0066BB; font-weight: bold">main</span>():
petCallback(<span style="color: #0000DD; font-weight: bold">19</span>)
<span style="color: #008800; font-weight: bold">try</span>:
<span style="color: #888888"># Loop until users quits with CTRL-C</span>
<span style="color: #008800; font-weight: bold">while</span> <span style="color: #007020">True</span> :
time<span style="color: #333333">.</span>sleep(<span style="color: #6600EE; font-weight: bold">0.1</span>)
<span style="color: #008800; font-weight: bold">except</span> <span style="color: #FF0000; font-weight: bold">KeyboardInterrupt</span>:
<span style="color: #888888"># Reset GPIO settings</span>
pet1<span style="color: #333333">.</span>stop()
pet2<span style="color: #333333">.</span>stop()
GPIO<span style="color: #333333">.</span>cleanup()
<span style="color: #888888"># Set up ISR</span>
GPIO<span style="color: #333333">.</span>setup(<span style="color: #0000DD; font-weight: bold">19</span>,GPIO<span style="color: #333333">.</span>IN,pull_up_down<span style="color: #333333">=</span>GPIO<span style="color: #333333">.</span>PUD_UP)
GPIO<span style="color: #333333">.</span>add_event_detect(<span style="color: #0000DD; font-weight: bold">19</span>,GPIO<span style="color: #333333">.</span>BOTH,callback<span style="color: #333333">=</span>petCallback,bouncetime<span style="color: #333333">=</span><span style="color: #0000DD; font-weight: bold">200</span>)
<span style="color: #008800; font-weight: bold">if</span> __name__<span style="color: #333333">==</span><span style="background-color: #fff0f0">"__main__"</span>:
main()
</pre></td></tr></table></div>
<h3 class="snippet text-center text-uppercase text-secondary mb-0">messages.py</h3>
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><table><tr><td><pre style="margin: 0; line-height: 125%"> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17</pre></td><td><pre style="margin: 0; line-height: 125%"><span style="color: #888888"># Brandon Quinlan (bmq4) and Caitlin Stanton (cs968)</span>
<span style="color: #888888"># ECE5725, Final Project</span>
<span style="color: #008800; font-weight: bold">from</span> <span style="color: #0e84b5; font-weight: bold">twilio.rest</span> <span style="color: #008800; font-weight: bold">import</span> Client
account_sid <span style="color: #333333">=</span> <span style="background-color: #fff0f0">'AC4bda313b35fa302d7ec0e1ae151c8505'</span>
auth_token <span style="color: #333333">=</span> <span style="background-color: #fff0f0">'aff8936c41459ba1b0f98452ead78c4d'</span>
client <span style="color: #333333">=</span> Client(account_sid,auth_token)
<span style="color: #888888"># Send "text" to Brandon's phone</span>
<span style="color: #008800; font-weight: bold">def</span> <span style="color: #0066BB; font-weight: bold">send_sms</span>(text):
message <span style="color: #333333">=</span> client<span style="color: #333333">.</span>messages<span style="color: #333333">.</span>create(
body<span style="color: #333333">=</span>text,
from_<span style="color: #333333">=</span><span style="background-color: #fff0f0">'+17326482248'</span>,
to<span style="color: #333333">=</span><span style="background-color: #fff0f0">'+17326093709'</span>
)
<span style="color: #008800; font-weight: bold">print</span>(message<span style="color: #333333">.</span>sid)
</pre></td></tr></table></div>
</div>
</section>
<!--References -->
<section id="references">
<div class="container">
<h2 class="text-center text-uppercase text-secondary mb-0">References</h2>
<hr class="star-dark mb-5">
<div class="row">
<ul class="lead">
<li><a href=" https://www.twilio.com/docs/sms/send-messages">Twilio tutorial</a></li>
<li><a href="http://www.allegromicro.com/~/media/Files/Datasheets/A3213-4-Datasheet.ashx">Hall effect sensor datasheet</a></li>
<li><a href="https://www.allegromicro.com/en/Design-Center/Technical-Documents/Hall-Effect-Sensor-IC-Publications/Hall-Effect-IC-Applications-Guide.aspx#Q19">Hall effect sensor guide</a></li>
<li><a href="https://www.raspberrypi-spy.co.uk/2015/09/how-to-use-a-hall-effect-sensor-with-the-raspberry-pi/">Hall effect sensor code</a></li>
<li><a href="https://circuitdigest.com/microcontroller-projects/interfacing-hall-sensor-with-raspberry-pi ">More hall effect sensor code</a></li>
<li><a href="http://www.ee.ic.ac.uk/pcheung/teaching/DE1_EE/stores/sg90_datasheet.pdf ">Micro servo SG90 datasheet</a></li>
<li><a href="https://learn.adafruit.com/raspberry-pi-zero-creation/text-file-editing">Setting up a headless Pi Zero W</a></li>
<li><a href="https://medium.com/@jay_proulx/headless-raspberry-pi-zero-w-setup-with-ssh-and-wi-fi-8ddd8c4d2742 ">More on setting up a headless Pi Zero W</a></li>
<li><a href=" https://www.pololu.com/product/1134 ">Pololu distance sensor datasheet</a></li>
</ul>
</div>
<h3 class="text-center text-uppercase text-secondary mb-0">Work Distribution</h3>
<div class="row">
<p class="lead">During the implementation of this project, Caitlin worked on the code and circuitry for the fetch and petting systems, as well as the Trilio communication. Brandon spent more time working on the construction of the physical components of the lab and the code for the food refill system. For the report we each wrote about the parts that we worked on and Brandon wrote the other parts while Caitlin did the HTML formatting.</p>
</div>
<h3 class="text-center text-uppercase text-secondary mb-0">Materials and Budget</h3>
<div class="row">
<img class="img-fluid mb-5" src="img/budget.png" alt="">
</div>
</div>
</section>
<!-- Contact Section -->
<section id="contact">
<div class="container">
<h2 class="text-center text-uppercase text-secondary mb-0">Meet the Team</h2>
<hr class="star-dark mb-5">
<div class="row">
<img class="img-fluid mb-5" src="img/team.png" alt="">
<p class="lead">Here's the team behind Franklin! To the left is Brandon Quinlan, senior double ECE/CS major, and to the right is Caitlin Stanton, junior ECE major.</p>
</div>
</div>
</section>
<!-- Footer -->
<footer class="footer text-center">
<div class="container">
<div class="row">
<div class="col-md-4 mb-5 mb-lg-0">
<h4 class="text-uppercase mb-4">Location</h4>
<p class="lead mb-0">Phillips Hall 239</p>
</div>
<div class="col-md-4 mb-5 mb-lg-0">
<h4 class="text-uppercase mb-4">Our Code</h4>
<ul class="list-inline mb-0">
<li class="list-inline-item">
<a class="btn btn-outline-light btn-social text-center rounded-circle" href="https://github.com/caitlinstanton/ece-5725/tree/master/final_project">
<i class="fab fa-fw fa-github"></i>
</a>
</li>
</ul>
</div>
<div class="col-md-4">
<h4 class="text-uppercase mb-4">About ECE 5725</h4>
<p class="lead mb-0">Design of microcontroller based systems using embedded Linux.
Find out more <a href="http://skovira.ece.cornell.edu/ece5725/">here</a>.</p>
</div>
</div>
</div>
</footer>
<!-- Scroll to Top Button (Only visible on small and extra-small screen sizes) -->
<div class="scroll-to-top d-lg-none position-fixed ">
<a class="js-scroll-trigger d-block text-center text-white rounded" href="#page-top">
<i class="fa fa-chevron-up"></i>
</a>
</div>
<!-- Portfolio Modals -->
<!-- Portfolio Modal 1 -->
<div class="portfolio-modal mfp-hide" id="portfolio-modal-1">
<div class="portfolio-modal-dialog bg-white">
<a class="close-button d-none d-md-block portfolio-modal-dismiss" href="#">
<i class="fa fa-3x fa-times"></i>
</a>
<div class="container text-center">
<div class="row">
<div class="col-lg-8 mx-auto">
<h2 class="text-secondary text-uppercase mb-0">Project Name</h2>
<hr class="star-dark mb-5">
<img class="img-fluid mb-5" src="img/portfolio/cabin.png" alt="">
<p class="mb-5">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Mollitia neque assumenda ipsam nihil, molestias magnam, recusandae quos quis inventore quisquam velit asperiores, vitae? Reprehenderit soluta, eos quod consequuntur itaque. Nam.</p>
<a class="btn btn-primary btn-lg rounded-pill portfolio-modal-dismiss" href="#">
<i class="fa fa-close"></i>
Close Project</a>
</div>
</div>
</div>
</div>
</div>
<!-- Portfolio Modal 2 -->
<div class="portfolio-modal mfp-hide" id="portfolio-modal-2">
<div class="portfolio-modal-dialog bg-white">
<a class="close-button d-none d-md-block portfolio-modal-dismiss" href="#">
<i class="fa fa-3x fa-times"></i>
</a>
<div class="container text-center">
<div class="row">
<div class="col-lg-8 mx-auto">
<h2 class="text-secondary text-uppercase mb-0">Project Name</h2>
<hr class="star-dark mb-5">
<img class="img-fluid mb-5" src="img/portfolio/cake.png" alt="">
<p class="mb-5">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Mollitia neque assumenda ipsam nihil, molestias magnam, recusandae quos quis inventore quisquam velit asperiores, vitae? Reprehenderit soluta, eos quod consequuntur itaque. Nam.</p>
<a class="btn btn-primary btn-lg rounded-pill portfolio-modal-dismiss" href="#">
<i class="fa fa-close"></i>
Close Project</a>
</div>
</div>
</div>
</div>
</div>
<!-- Portfolio Modal 3 -->
<div class="portfolio-modal mfp-hide" id="portfolio-modal-3">
<div class="portfolio-modal-dialog bg-white">
<a class="close-button d-none d-md-block portfolio-modal-dismiss" href="#">
<i class="fa fa-3x fa-times"></i>
</a>
<div class="container text-center">
<div class="row">
<div class="col-lg-8 mx-auto">
<h2 class="text-secondary text-uppercase mb-0">Project Name</h2>
<hr class="star-dark mb-5">
<img class="img-fluid mb-5" src="img/portfolio/circus.png" alt="">
<p class="mb-5">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Mollitia neque assumenda ipsam nihil, molestias magnam, recusandae quos quis inventore quisquam velit asperiores, vitae? Reprehenderit soluta, eos quod consequuntur itaque. Nam.</p>
<a class="btn btn-primary btn-lg rounded-pill portfolio-modal-dismiss" href="#">
<i class="fa fa-close"></i>
Close Project</a>
</div>
</div>
</div>
</div>
</div>
<!-- Portfolio Modal 4 -->
<div class="portfolio-modal mfp-hide" id="portfolio-modal-4">
<div class="portfolio-modal-dialog bg-white">
<a class="close-button d-none d-md-block portfolio-modal-dismiss" href="#">
<i class="fa fa-3x fa-times"></i>
</a>
<div class="container text-center">
<div class="row">
<div class="col-lg-8 mx-auto">
<h2 class="text-secondary text-uppercase mb-0">Project Name</h2>
<hr class="star-dark mb-5">
<img class="img-fluid mb-5" src="img/portfolio/game.png" alt="">
<p class="mb-5">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Mollitia neque assumenda ipsam nihil, molestias magnam, recusandae quos quis inventore quisquam velit asperiores, vitae? Reprehenderit soluta, eos quod consequuntur itaque. Nam.</p>
<a class="btn btn-primary btn-lg rounded-pill portfolio-modal-dismiss" href="#">
<i class="fa fa-close"></i>
Close Project</a>
</div>
</div>
</div>
</div>
</div>
<!-- Portfolio Modal 5 -->
<div class="portfolio-modal mfp-hide" id="portfolio-modal-5">
<div class="portfolio-modal-dialog bg-white">
<a class="close-button d-none d-md-block portfolio-modal-dismiss" href="#">
<i class="fa fa-3x fa-times"></i>
</a>
<div class="container text-center">
<div class="row">
<div class="col-lg-8 mx-auto">
<h2 class="text-secondary text-uppercase mb-0">Project Name</h2>
<hr class="star-dark mb-5">
<img class="img-fluid mb-5" src="img/portfolio/safe.png" alt="">
<p class="mb-5">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Mollitia neque assumenda ipsam nihil, molestias magnam, recusandae quos quis inventore quisquam velit asperiores, vitae? Reprehenderit soluta, eos quod consequuntur itaque. Nam.</p>
<a class="btn btn-primary btn-lg rounded-pill portfolio-modal-dismiss" href="#">
<i class="fa fa-close"></i>
Close Project</a>
</div>
</div>
</div>
</div>
</div>
<!-- Portfolio Modal 6 -->
<div class="portfolio-modal mfp-hide" id="portfolio-modal-6">
<div class="portfolio-modal-dialog bg-white">
<a class="close-button d-none d-md-block portfolio-modal-dismiss" href="#">
<i class="fa fa-3x fa-times"></i>
</a>
<div class="container text-center">
<div class="row">
<div class="col-lg-8 mx-auto">
<h2 class="text-secondary text-uppercase mb-0">Project Name</h2>
<hr class="star-dark mb-5">
<img class="img-fluid mb-5" src="img/portfolio/submarine.png" alt="">
<p class="mb-5">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Mollitia neque assumenda ipsam nihil, molestias magnam, recusandae quos quis inventore quisquam velit asperiores, vitae? Reprehenderit soluta, eos quod consequuntur itaque. Nam.</p>
<a class="btn btn-primary btn-lg rounded-pill portfolio-modal-dismiss" href="#">
<i class="fa fa-close"></i>
Close Project</a>
</div>
</div>
</div>
</div>
</div>
<!-- Bootstrap core JavaScript -->
<script src="vendor/jquery/jquery.min.js"></script>
<script src="vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
<!-- Plugin JavaScript -->
<script src="vendor/jquery-easing/jquery.easing.min.js"></script>
<script src="vendor/magnific-popup/jquery.magnific-popup.min.js"></script>
<!-- Contact Form JavaScript -->
<script src="js/jqBootstrapValidation.js"></script>
<script src="js/contact_me.js"></script>