Beruflich Dokumente
Kultur Dokumente
Authored By:
Jordyn Marshall
MaryAnne Laxamana
Jennifer Xie
Oregon MESA
5/4/2018
1
Table of Contents
Results….. ...9-11
Data…… ...12-15
Appendix……. ...16-52
Bibliography……. ...53-54
2
Project Statement
Everyday, elderly people face difficulties handling day-to-day life, and these challenges
only get worse as they age. These problems include, but aren’t limited to, balance, lack of
stamina, loss of strength, arthritis, and fading memory. The goal of this project is to use
human-centered design to improve the life of an elderly person by addressing an issue a client
may have. To do so, a team consisting of three high school seniors would interview a client and
Several elderly people were interviewed, but one was selected to be the team’s client.
This ends up being MaryAnne’s grandmother, Debbie. Debbie has to take at least five different
kinds of medication per day, and she is not the only one. 32 million Americans use three or more
problem when it comes to elderly people and people in general seems to be forgetting to take
their medication. 75% of all adults fail to take their medication correctly. When it comes to
elderly people, 57% admit to forgetting to take their medication. It seems that this is more
prevalent among those who have to take five or more medication, as 63% say they forget to take
medication, compared to the 51% percent who have to take fewer medications. (“Patient
In order to solve this issue of forgetting to take medication, the team has interviewed
Debbie on criteria and expectations for the device. In general, the medicine dispenser should be
able to store medication in separate containers and dispense the correct amount when it is time
for the user to take them. The 12-hour am-pm clock was used to provide information to the client
and makes the machine more user-friendly. SInce there is a limited budget, the team purchased
3
conservatively to reduce cost as much as possible. The medicine dispenser also includes a history
of when medication was last dispensed for the user, and it is able to count the number of tablets
contained through special methods. In other words, the machine will be able to notify the user
when they need to refill the the container at least ten days in advance. The design should also be
applicable to hold around ten different types of medications, and hold at least two weeks of it.
The team would take this criteria into mind and design a medicine dispenser which would best
Design Process
The team began their interviews in October, but was unable to find their client until
November, who ended up being MaryAnne’s grandmother, Debbie. The team asked various
questions and notes were taken throughout the interview (Figure 1). Criteria and constraints were
created for the team to follow, as they are listed in the problem statement. The team had also
asked about information about her daily interactions with medications to gain background
Prior to starting the project, the team researched briefly on the problem itself. They also
did some research on struggles elderly face in general. Arduino is best described as a
“programmable logic controller”, which essentially means that it can be programmed to interact
with the world based on inputs, such as buttons, and outputs like motors (Bruce). The team had
prior experience working with Arduino when they were tasked with building a robotic prosthetic
arm from the year before. They had applied those knowledge as well as the ones learned from
engineering classes to build the medicine dispenser. The team also researched on how to use the
4
components required to allow the medicine dispenser to function, and such research is detailed
Eventually, the team started brainstorming a design and composed rough sketches within
the team’s notebook (Figures 2 and 3). The main design for the medicine dispenser was a box
with holes for an LCD and four buttons. The user would be able to input information to the
Arduino through them, such as when they need to take medication, what size the medication is,
and how many pills are being put into the container. The user would also be able to view when
the last type of medication was dispensed and which medication is in each container on the LCD.
Medication would be stored within containers on the top of the medicine dispenser. When it is
time for the medication to dispense, a small gate would move and allow the pills to fall into a
carousel, which would then be taken to a hole on the platform below the carousel, leading them
down a track where they will land into a container outside of the box. A servo would control the
carousel and four gates, which open to allow the pills within the bottles to fall into the carousel
when it is time for it to dispense. Meanwhile, the Arduino would also be connected to a
RealTimeClock module to ensure that it can keep track of the time and date, as well as a
After brainstorming, the team started gathering materials to construct the dispenser. The
first materials include the Arduino itself as well as a few components, namely the LCD, buttons,
buzzer, and RealTimeClock module. Since many elderly have bad vision, the team purchased the
biggest LCD screen within our budget availability, which was 2.5cm × 7cm. In order for them
to work, the team researched information on how each component would work. An example for
a schematic and code for the LCD(Figures 4 and 5). The exact circuit for the LCD, as well as the
5
LiquidCrystal library on Arduino, was used in the final design. The team learned how to code the
buttons from a manual that came with the Arduino (SparkFun Electronics). The RealTimeClock
module is specifically known as a DS1302, and it has three pins which connect to the Arduino.
The module was originally controlled by code on Arduino Playground (“DS1302 Real Time
Clock”), but the team eventually switched to using a library. This helps the time information
easier to program (“DS1302RTC library”). The buzzer was simply turned on and off by the
Later, the team was able to get four servos, one continuous rotation servo, the bluetooth
module and an expansion module. The four servos and continuous rotation servo were connected
and programmed easily using the servo library on the Arduino (“Servo Library”). The bluetooth
module was briefly connected and tested using information online (Stan) (Mathavan, Hariharan).
Finally, an extension module was purchased because there would not be enough pins for
everything to be connected, with the total I/O pins required being 20 and only 19 are on the
Arduino board. As such, the extension module was connected and programmed using a library
found on Github to control the buzzer (skywodd). Once each component was tested working
individually, they were all connected together in one circuit(Figure 6). Also created a code to test
this circuit (Figure 7). The only component that was not connected was the Bluetooth module,
which was hard to test for due to the lack of an app. All of the components had worked together
in a circuit, minus two of the servos. The issues with the servos involves being connected to two
I/O pins that didn’t work with them, and they eventually worked when connected to two other
pins.
6
While the circuit was being worked on, the base of the medicine dispenser was being
constructed. The team purchased plywood in order to build the base. After measuring height and
length, a miter saw was used to cut it into the necessary pieces (Figure 8). Holes were then cut
out in the front to allow for room for the LCD and buttons using a scroll saw, and holes were
also drilled out on the top to fit the containers. According to observation within the client’s
household, the most common pill sizes were between 0.7cm to 2.3cm wide. The team then
designed four different sized holes that were in diameter of 1cm, 1.3cm, 1.5cm, and 2.3cm. The
pill containers ended up being water bottles, which were cut in half then flipped over for the neck
of the bottle was face down into the drilled holes with the height of 11cm. The bottom of the
bottles was also used as lids (Figure 9). Eventually, the entire device was put together using
wood glue. However, the top was left unattached so the team would be able to access the circuit
and for maintenance. The back was attached with a hinge. The team took in consideration in the
space available in households and tried to make the final product as small as possible. A
rectangular bottom was used for easy fitting on top of counters, tables, etc. The final
measurement of the outer box is 15cm × 15.5cm and the height was 29.5cm, the addition box
Meanwhile, the team was also working on the gates and carousel to be 3D-printed. These
parts were modeled in Autodesk Fusion 360 (Figures 10, 11, and 12). They were eventually
3D-printed at our school and attached to their servos. The diameter of the carousel was around
13cm with the thickness of around 1.3cm. The gates were connected to a metal rod then to the
servo and the diameter of the gate was slightly larger than the opening of the water bottles to
7
ensure full coverage, which was 2.7cm. However, the glue would not hold the rods to the servos
so the team replaced them with plastic lego sticks which was easily connected with hot glue.
The circuit was then put into the box created for each component(Figure 13). The
carousel was attached to the continuous rotation servo with hot glue, and was being programmed
so that its position could be controlled. A continuous rotation servo has no position control,
unlike a normal servo, and only the speed and the direction of the servo could be programmed.
As such, a method in the code was planned to be created so that one could give it a degree, and
the continuous rotation servo would turn to that degree. In order for this to work, the code
needed to know the angular velocity of the servo. This exact equation and programmed method
used are contained within the Data section of this report. The servos and gates were connected at
each corner.foam was used to create more stability. In the beginning the box wasn't tall enough
for the carousel and gates. The team solved this issue by adding strips of wood to make it taller.
Eventually, everything was put together and the first iteration of the project was
completed. However there were some issues with the gates not being long or big enough to cover
the holes, and the fixed part needing a hole in the middle, so cardstock was used to make up for
these shortcomings. The project was shown to be able to dispense some of the team’s test
medication, or candies. The demo code (Figure 14), while two videos of the device are linked to
in Figure 15 and 16. However, the final code itself could not be completed as there was an issue
with the continuous rotation servo. The method written for it required for the servo to work at a
constant speed. However, the servo would not move at a constant speed, and there were even
small issues such as the angle which would be written to the servo to stop it changing, so that it
After the first iteration of the medicine dispenser, everything was taken out to be
reorganized. Two holes were drilled into the base, one for a hypothetical power cord for the
Arduino, and another for the buzzer. The carousel and gates were 3D-printed once more to fix
any measurements issues, and the fixed part having a hole in the middle for the servo to go
through. The circuit was then put back in and the machine became more organized and
In order to make the speed of the servo more consistent, the team got a more expensive
continuous rotation servo. However, upon receiving it, the servo would not respond well to the
commands passed to it on Arduino. It was supposed to respond to commands from the servo
library, but there was a communication issue between the Arduino and the servo. Due to the lack
of time to troubleshoot, the team was forced to get a motor. It could still work to control the
carousel, but a motor could only move in one direction. This would be addressed in the code, by
having everything move 360 degrees during a full rotation, but it would not be the most ideal for
this application.
Despite the team getting a new motor, they still had issues with attaching the moving part
of the carousel to the motor. This was caused by the glue the team tested. It would either attach
to the plastic or the metal, but not both efficiently enough that it would stay on after a few
seconds of use, this is what also happened to the metal rods connected to the gates and servos.
About five different types of glue was tested to connect the carousel and the motor directly, but
all methods did not work. In order to fix this problem, the team had added foam and glued it onto
the motor and carousel to act as an in between so that the motor and carousel would glue together
enough to work.
9
While everything was being constructed, the final code was being slowly worked on over
time. It works through a class which would create objects used to keep track of all information
regarding the medication, such as when it should be dispensed, how much of it should be
dispensed, what container is is in, and what size the medication is in reference to the carousel.
The final code would also include menus, so that the user would be able to input all information
without needing to code. Specifically, the interface should allow for the user to set up any
medication, add information regarding refills, and check when it was last dispensed. The final
code remains incomplete, however, as issues with the motor for the carousel both not working or
not attaching forced the testing of the device to be delayed. Nonetheless, the work in progress of
Results
The medicine dispenser is somewhat functioning. Most of the components work as they
are supposed to. The gates can move easily if the right angles are put in. Meanwhile, the buzzer
can work through being turned on and off easily, and the buttons and LCD are all functioning
very well. The clock, while not completely accurate, can still tell the time, and the team can
easily program it to easily follow the time using the Arduino Time library (“Arduino Time
Library”). The only component which is not working well is the motor. It is hard to program as it
is not moving at a consistent speed. This motor ends up being more consistent than the servos,
but it is still inconsistent enough that it is hard to program. A data table and a histogram have
been created in the data section for values used in the code for the total amount of time it took for
the motor to go one full rotation. They show that the speed of the motor was indeed changing, as
10
the distribution of the histogram is bimodal (Table 1)(Chart 1). The carousel can take the
medication to where it needs to go, but some last minute testing has shown that sometimes the
medication gets stuck. There were also issues with the glue coming off last minute as well.
Because the motor cannot be programmed to be consistent, the medicine dispenser cannot
be properly automated. All of the dispensing mechanisms work, and the medicine dispenser does
work should the motor bring the carousel to the right place at the right time. Because this is
constantly changing, the medicine dispenser does not work properly. There is code to demo the
medication dispenser by dispensing through all four containers, as well as keep track of the time
to dispense every five minutes, but it again does not work due to inconsistencies in the motor
(Figure 18).
The code itself is not complete, as the programmer was waiting to be able to use a
consistent motor to do so. Nonetheless, the work in progress is seen in the Appendix. The code is
not tested due to the lack of consistent dispensing mechanism, but the code should be able to
keep track of medication which is taken once a day, twice a day, and at several intervals
throughout the day. The amount of medication in the container is also taken into account, which
the user enters, and the Arduino uses this information accordingly to keep track of when it
should tell the user they need a refill. The main menu system has been started, but not
completely finished. Nonetheless, it is complete enough to see what the final iteration of the code
The team had complied a budget sheet of the components used for the medicine
dispenser. They are trying to add a stepper motor to the circuit, but have yet to be successful.
11
Nonetheless, the budget sheet includes the components bought for the stepper motor as opposed
to the motor used in the last iteration of the project (Figure 20).
Next Steps/Recommendations
One of the main recommendations for this project is to not use a motor or a continuous
rotation servo. It is very hard to say that the speed of either would be consistent, unless it
potentially has a high torque. As such, the best kind of motor for this application may be a
stepper motor. The main issue with a stepper motor is that it requires more pins on the Arduino.
In order to fix this, a larger Arduino would have to be used for the more input/output pins it
could provide. The solution the team is trying to use in order to get the stepper motor working is
to use a shield, which would allow for more pins on the Arduino to be used, as well as remove
the hassle of trying to put together a circuit for the stepper motor. Furthermore, more consistent
glue could be used on the 3D-printed parts to make sure that they stick on, or the parts could be
printed again to fit where they need to go, and the team would need more time to ensure each
One all of the components are working together correctly, the team had an idea to
connect the device to the user’s phone through an app. The main reason the team could not do
this is due to the lack of an app to work connect to the Arduino with. They did have a Bluetooth
module, and it was functioning, but the team could not construct an app in a timely manner that
would also ensure that the sorter itself is functioning. Nonetheless, the team feels that an app
would allow for an easier interface for the user, especially since more information could be
printed out when compared to the LCD, and buttons could be larger and easily distinguishable.
In general, a better interface for the Arduino would improve how easy it is to use, because the
12
LCD cannot print a lot of information out to the user, and the buttons limit the amount of inputs
the user could give to it, potentially making the programmer have to make unintuitive design
Data
1 11610 17 11700
2 11590 18 11710
3 11570 19 11760
4 11560 20 11770
5 11530 21 11800
6 11520 22 11780
7 11500 23 11770
8 11485 24 11760
9 11495 25 11740
10 11520 26 11750
11 11530 27 11760
12 11540 28 11780
13 11560 29 11740
14 11570 30 11720
15 11650 31 11730
16 11750
Table 1. This is a table of all the values the programmer of the team put into the code to try to
control the position of the carousel. This information was recorded to try and hone in on a
specific value which would work to control the position. It was compiled into a histogram
(below) which ends up being a visual representation that the speed was changing, and thus
position control with the motor proved to be almost impossible.
13
Chart 1. This is a histogram of the values put into the code for the time to do one full rotation.
The programmer of the team was recording these values in the notebook to keep track of what
numbers were originally put in the code, in order to find the true time to do one full rotation so
that the position of the carousel could be possibly controlled. The distribution is bimodal, which
means that there are two different times the programmer was trying to hone in on, and thus the
speed of the motor was changing. This means that the motor cannot be programmed in order to
accurately control the position of the carousel, which is what the team needs.
Calculations:
In order to program the carousel to have position control when it physically did not have
This equation finds the position of an object, in angles, by using the initial angle, initial
angular velocity, and the angular acceleration over a certain amount of time in order to find the
final position. This is actually the angular version of a popular physics equation for tangential
position:
14
In which the position is a function of time, and the initial position, velocity, and
acceleration are used to find the final position. However, for this project, the team had only
observed the angular version. Because the team assumes that the acceleration of the motor is
The Arduino needs to figure out the time for which the motor should be turned on. As
such, the equation should be written to solve for time. The equation becomes the following:
For this equation to work, the team needs to find the angular velocity of the motor that
they are using. This involves finding the time it took for the carousel to go around in a full circle,
and using that time to calculate the angular velocity. The equation to do this was the following:
This served as a starting point to experiment with the values for what the angular velocity
Later, instead of a servo, the team got a motor. A motor can only move in one direction,
so the team would need to figure how the angular velocity as well as the amount of time it takes
to go one full circle. The above equation would be used again, but instead of the motor being
turned on for that certain amount of time, the motor would be turned on for that time, turned off
for the medicine to fall into it, and then turned on for the rest of the time to go a full circle. In
15
order to make this work, the time calculated would be subtracted from the total time it would
take to go one full circle. This again, however, works only if there’s a consistent speed for the
motor, which the team ran into issues with doing so.
16
Appendix
When?
- Morning and Evening
How many?
- 5 different medications and about five different vitamins
Notes:
- Maybe portable idea with phone app?
- With antibiotic, [Debbie] would set timer as a reminder to remind
- Touch screen or buttons?
- Touch screen would be easier to use than buttons
- Money may be limited, phone may be more useful than machine, phone app could be
optional with machine.
- Would refill through provider
- AM + PM notification
- Know how to tell 24 hour, but can translate
- Tablets look alike, may be an issue
- May need a history to make sure when medication is taken
17
- Cound tablets, manually put in tablets, need some way to know if need refill.
- Hours to get refill, unless doctor permission if controlled
- State if need renewal 10 days in advance
- Should hold at least 10 different types, hold at least a week or two weeks
- Favorite color - black
Figure 1. This is a transcript of the questions asked, responses, and notes took during an
interview session with the team’s client, Debbie. The interview was conducted on November
29th, and laid out the main criteria and constraints for the team from the client.
Figure 2. This is a sketch of one of the team’s initial designs for the medicine dispenser. It
consists of several containers on top of a box, with an LCD and buttons which allow for the user
18
to interact with the dispenser. There is also a slide and place for the medication to dispense into.
There are several handwritten notes detailing several ideas on how the medicine dispenser should
be constructed.
Figure 3. This is another sketch of ideas for the medicine dispenser. This details information on
the slide, how several of the components should work, and an early sketch for the carousel, very
similar to one seen in a Skittles dispenser (The Atmel Team).
19
Figure 4. This is the “HelloWorld” circuit, which functions through the use of a Liquid Crystal
Display (LCD). A potentiometer and a resistor can also be seen in this circuit. This circuit,
combined with the code below, can be used to print “Hello World” and the amount of seconds
since the code started on the LCD screen. This circuit was retrieved from Arduino’s website
(“Hello World”).
/*
LiquidCrystal Library - Hello World
The circuit:
* LCD RS pin to digital pin 12
* LCD Enable pin to digital pin 11
* LCD D4 pin to digital pin 5
* LCD D5 pin to digital pin 4
* LCD D6 pin to digital pin 3
* LCD D7 pin to digital pin 2
* LCD R/W pin to ground
* LCD VSS pin to ground
* LCD VCC pin to 5V
* 10K resistor:
* ends to +5V and ground
* wiper to LCD VO pin (pin 3)
20
http://www.arduino.cc/en/Tutorial/LiquidCrystalHelloWorld
*/
void setup() {
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
// Print a message to the LCD.
lcd.print("hello, world!");
}
void loop() {
// set the cursor to column 0, line 1
// (note: line 1 is the second row, since counting begins with 0):
lcd.setCursor(0, 1);
// print the number of seconds since reset:
lcd.print(millis() / 1000);
}
Figure 5. This is the code for the “HelloWorld” circuit. The LiquidCrystal library is used here in
order to operate the LCD, and the functions used to do so are shown through the creation of a
LiquidCrystal object. In order words, the user can use simple functions to print information, such
as “Hello World”, to the LCD without having to be concerned about what is going on when it
comes to the machine level. This code was from Arduino’s site. (“Hello World”).
21
Figure 6. This is a picture of the complete circuit for the medicine dispenser. This circuit may
change as it is being troubleshooted, but otherwise it is the final circuit which would be used
with the medicine dispenser. In this circuit, the LCD, buttons, extension module and buzzer,
RTC module, servos, and Bluetooth module are all connected to the Arduino.
void setup() {
//Sets up the LCD object so it could now be used
lcd.begin(16, 2);
void loop() {
//Sets up the LCD to display all of the options to the user
//if loop designed to check if the menu has already been
//printed or not
if (menu == 0)
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Circuit Test");
lcd.setCursor(0,1);
lcd.print("[sr][bz][ti][bl]");
menu = 1;
}
lcd.print("Servo 3 Test");
servo3.write(180);
delay(1000);
servo3.write(0);
delay(1000);
//The fourth 180 degree servo is tested
lcd.clear();
lcd.print("Servo 4 Test");
servo4.write(180);
delay(1000);
servo4.write(0);
delay(1000);
//The 360 degree servo is tested
lcd.clear();
lcd.print("360 Servo Test");
servo360.write(180);
delay(1000);
servo360.write(0);
delay(1000);
servo360.write(90);
menu = 0;
}
//If the red button is pushed, test the buzzer
//The buzzer is turned on for a little bit,
//and then turned off.
if (redState == LOW)
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Buzzer Test");
expander.digitalWrite(buzzer, HIGH);
delay(1000);
expander.digitalWrite(buzzer, LOW);
delay(1000);
menu = 0;
}
//If the blue button is pushed, test the RTC module
//This uses the code from “DS1302RTC library”,
//and checks to see if the clock is working
//fine, before printing values out from the
//clock.
if (yellowState == LOW)
{
//Checks clock oscillation
lcd.clear();
if (RTC.haltRTC())
lcd.print("Clock stopped!");
else
lcd.print("Clock working.");
// Check write-protection
lcd.setCursor(0,1);
if (RTC.writeEN())
lcd.print("Write allowed.");
25
else
lcd.print("Write protected.");
delay ( 2000 );
delay ( 2000 );
lcd.clear();
int t = 0;
while (t != 5)
{
// Display time centered on the upper line
lcd.setCursor(3, 0);
print2digits(hour());
lcd.print(" ");
print2digits(minute());
lcd.print(" ");
print2digits(second());
// Warning!
if(timeStatus() != timeSet) {
lcd.setCursor(0, 1);
lcd.print(F("RTC ERROR: SYNC!"));
}
//Bluetooth module.
//Because the test function for the Bluetooth
//module has not yet been decided, this test is incomplete.
if (blackState == LOW)
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Sorry! No Blue");
lcd.setCursor(0,1);
lcd.print("Tooth Test");
delay(2000);
menu = 0;
}
}
Figure 8. This is the box for the base of the medicine dispenser. It has been taped together, and
would be used to store all of the components of the circuit, as well as the dispensing mechanism.
The containers for the dispenser would be stored on top.
Figure 9. This is the four containers which would be used to store medicine in the medicine
dispenser. They are made out of water bottles, which have been cut in half and glued together.
The bottom of each water bottle was kept intact to be used as a lid. In the final design, the lids of
each water bottle would be removed, and instead a gate controlled by a servo would control the
process of dispensing medication, alongside the carousel.
28
Figure 10. This is the 3D model of the gate which would be used with servos to allow medicine
to fall from the containers to the carousel. Four instances of this piece would be 3D-printed, and
would work as apart of the dispensing mechanism.
Figure 11. This is the 3D model of the moving part of the carousel. It would be used in
combination with the gate as apart of the dispensing mechanism, so that only one tablet of
medication would fall into it at a time. There are four different sizes of holes, which accounts for
four different sizes of medication.
Figure 12. This is the fixed part of the carousel. It works as apart of the dispensing mechanism. It
would not be moving, and allows for a hole for the moving part of the carousel to drag the tablet
over to, so that the tablet could leave the medicine dispenser and head to a spot where the user
would easily be able to get ahold of it and take their medication.
29
Figure 13. This is the first iteration of the circuit inside of the medicine dispenser. It is rather
messy, with little attention to organization. The main goal was to get the circuit inside of the box,
which explains the lack of clear organization.
void setup() {
//Sets up the LCD object so it could now be used
lcd.begin(16, 2);
void loop() {
//Prints out the main menu to the user, which
//just says to press any button for the demo
//to activate
if (menu == 0)
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Demo");
lcd.setCursor(0,1);
lcd.print("Press any button");
menu = 1;
}
//Checks the states of all of the buttons
blackState = digitalRead(blackButton);
redState = digitalRead(redButton);
blueState = digitalRead(blueButton);
yellowState = digitalRead(yellowButton);
https://drive.google.com/file/d/1pJTqnjajRR_viJ7kPYRCPR-ys3-EDMcf/view?usp=sharing
Figure 15. This is the first video of the first iteration of the medicine dispenser. It is the front
view of the medicine dispenser as the demo code from Figure 14 is being ran. The video is five
33
seconds long, and shows that, after the button is pushed, one of the test candies fall out of the
.slide.
https://drive.google.com/file/d/1P1ZttHtqayg9VdI4s-b-dzLHlrFoII1T/view?usp=sharing
Figure 16. This is the second video of the first iteration of the medicine dispenser. It is a top view
of the medicine dispenser as the demo code from Figure 14 is being ran. The video is five
seconds long, and shows the carousel and gate moving to dispense medication after the button is
pushed.
Figure 17. This is the inside of the medicine dispenser after everything has been pulled apart and
put back together. While the wires are not the cleanest, it is much cleaner than the first iteration
of it. A motor is also used, instead of the servo which was used in the first iteration.
/*
* Imports all needed libraries. There is a library for the extension
* module, the servo, the liquid crystal display, the real time clock
* and libraries to help keep track of the time. These are all imported
* to help control certain items easier without having to code
* the more machine-specific items.
34
*/
#include "PCF8574.h"
#include <Servo.h>
#include <LiquidCrystal.h>
#include <DS1302RTC.h>
#include <Time.h>
#include <TimeLib.h>
void setup() {
//This sets up the pin for the motor as an output
pinMode(carouselPin, OUTPUT);
//The servos ensure that the gates are at the right angles,
//so they would be covering the hole so medication does
//not fall in when it shouldn’t.
gate1.write(0);
gate2.write(110);
gate3.write(90);
gate4.write(160);
void loop() {
//calls a function to update buttons
updateButtons();
36
//This is a function to setup the clock to be used with the Time Library
//The team got this code online. (“DS1302RTC library”)
void setupClock() {
boolean resync;
lcd.clear();
do {
if (RTC.haltRTC()) {
lcd.print("Clock stopped!"); }
else {
lcd.print("Clock working."); }
delay ( 2000 );
lcd.setCursor(0,1);
lcd.print("Trying Again");
lcd.setCursor(0,0);
}
delay ( 2000 );
} while (resync);
}
gate4.write(120);
delay(1000);
gate4.write(160);
}
//The motor is then turned on for the remaining amount
//of time for it to go in a full circle.
digitalWrite(carouselPin, HIGH);
delay(11725 - onTime);
digitalWrite(carouselPin, LOW);
}
Figure 18. This is the most recent demo code for the medicine dispenser. It is designed to
dispense from one container every five minutes, but can dispense early if the user presses the
button. Here, the toAngle() function is created, in which it is designed to work with the motor by
passing the method an angle. The method would then calculate the amount of time it would take
to get to that angle, and then back to the original position.
/* Imports all external libraries for each component to function. For example,
Liquid Crystal
* Imports all external libraries for each component:
* LiquidCrystal - Helps control the Liquid Crystal Display (LCD)
* Servo - Controls the servos, in which there are five in total in this
circuit
* PCF8574 - Controls the extension module, so that the button could be
controlled
* DS1302RTC - Controls the Real Time Clock, can work with the Time library
* Time - Library to help easily display time
*/
#include <LiquidCrystal.h>
#include <Servo.h>
#include <Wire.h>
#include "PCF8574.h"
#include <DS1302RTC.h>
#include <Time.h>
#include <TimeLib.h>
/*
* Sets up pins which the LCD are connected to.
* Initiates a Liquid Crystal object, which allows for information
* to be printed to the LCD.
*/
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 1, d7 = 0;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
/*
* Sets up an object to be used with the expansion module.
* This allows it so that the buzzer could be connected
* to the expansion module, but could still be controlled
* by it through the Arduino
*/
PCF8574 expander;
/*
40
/*
* Defines all the pins for the servos defined about.
* The servos would be attached to these pins in the
* setup function. Allows for user to easily change.
*/
int servo1pin = 10;
int servo2pin = 17;
int servo3pin = 2;
int servo4pin = 3;
/*
* Creates an object which would control the servo
* which controls the carousel. This is a continuous
* rotation servo, so, while degrees could still be
* written to it, it does not have position control
*/
Servo carousel;
/*
* Defines the carousel pin, which the carousel
* servo would attach to in the setup function
*/
int carouselPin = 13;
/*
* Defines the pins for which the buttons would
* be attached to. Also defines the color
* of each button
*/
const int blackButton = 9;
const int redButton = 8;
const int blueButton = 6;
const int yellowButton = 7;
/*
* Defines the pin for the buzzer. This pin
* is technically on the expansion module
*/
const int buzzer = 4;
/*
* Defines the state of each button, which is
* used to define the state of each button:
* on or off
*/
int blackState, redState, blueState, yellowState;
41
/*
* Initiates the real time clock object.
* The pins are, in order, CE, IO, and CLK
*/
DS1302RTC RTC(16, 15, 14);
/*
* This would be where the setup for any objects
* or primitive types involving the bluetooth
* module. As the bluetooth module is not
* connected, there is no bluetooth yet.
*/
/*
* Stores the information for all of the angles
* at which the carousel would need to go to.
*/
int smallToDispense;
int mediumToDispense;
int largeToDispense;
int xLargeToDispense;
int smallToOne;
int smallToTwo;
int smallToThree;
int smallToFour;
int mediumToOne;
int mediumToTwo;
int mediumToThree;
int mediumToFour;
int largeToOne;
int largeToTwo;
int largeToThree;
int largeToFour;
int xLargeToOne;
int xLargeToTwo;
int xLargeToThree;
int xLargeToFour;
int menu = 0;
boolean mainMenu = true;
boolean containerMenu = false;
/*
* This is a class to keep track of the medicine. In this project,
* four Medicine classes would be created to reflect the four
* containers which contain the medicine
*/
class Medicine {
//medication is.
int container;
int medSize;
//Contains the information for the hour and minute the medicine
//should be dispensed at, if one takes their medication
//at a specifc time of day.
int hr;
int m;
public:
/*
* Medicine Constructor for when there is only one
* specific time for the medication to dispense.
* Adds all information inputted to the class
* contain - container which medication is located
* mSize - the size of the medication (0 is small, 1 is medium, 2 is large,
3 is extra large
* medNum - initial number of medication in container
* dispenseNum - how much medication would need to be dispensed at a time
* medHour - the hour the medication needs to be dispensed at
* medMinute - the minute the medication needs to be dispensed at
*/
Medicine (int contain, int mSize, int medNum, int dispenseNum, int medHour,
int medMinute){
container = contain;
medSize = mSize;
43
medNumber = medNum;
numDispense = dispenseNum;
//Calculates need for refill, if need to get refill two weeks in advance
medRefill = 14 * dispenseNum;
hr = medHour;
m = medMinute;
if (container == 1) {
servo = servo1;
}
else if(container == 2) {
servo = servo2;
}
else if(container == 3){
servo = servo3;
}
else if(container == 4){
servo = servo4;
}
}
/*
* Medicine Constructor for when there is are two
* specific times for the medication to dispense.
* Adds all information inputted to the class
* contain - container which medication is located
* mSize - the size of the medication (0 is small, 1 is medium, 2 is large,
3 is extra large
* medNum - initial number of medication in container
* dispenseNum - how much medication would need to be dispensed at a time
* medHour - the first hour the medication needs to be dispensed at
* medMinute - the first minute the medication needs to be dispensed at
* medHour2 - the second hour the medication needs to be dispensed at
* medMinute2 - the second minute the medication needs to be dispensed at
*/
Medicine (int contain, int mSize, int medNum, int dispenseNum, int medHour,
int medMinute, int medHour2, int medMinute2){
hourly = false;
container = contain;
medSize = mSize;
medNumber = medNum;
numDispense = dispenseNum;
//Calculates need for refill, if need to get refill two weeks in advance
medRefill = 14 * 2 * dispenseNum;
hr = medHour;
m = medMinute;
hr2 = medHour2;
m2 = medMinute2;
if (container == 1) {
servo = servo1;
}
else if(container == 2) {
servo = servo2;
}
else if(container == 3){
44
servo = servo3;
}
else if(container == 4){
servo = servo4;
}
}
/*
* Medicine Constructor for when the medication
* must be dispensed throughout the day. Adds all
* inputs to their corresponding outputs.
* contain - container which medication is located
* inter - the interval at which medication should dispense
* morn - the time at which the first medicine in the morning
* even - the time the last medication should be dispensed, or when one goes
to bed
* inter - the interval at which medication should dispense
* morn - the time at which the first medicine in the morning
* even - the time the last medication should be dispensed, or when one goes
to bed
* medNum - initial number of medication in container
* dispenseNum - how much medication would need to be dispensed at a time
*/
Medicine(int contain, int mSize, int inter, int morn, int evening, int
medNum, int dispenseNum)
{
hr = hour();
m = 0;
container = contain;
medSize = mSize;
interval = inter;
morning = morn;
night = evening;
medNumber = medNum;
numDispense = dispenseNum;
//Calculates need for refill, if need to get refill two weeks in advance
medRefill = ((evening - morn)/interval) * 14 * numDispense;
if (container == 1) {
servo = servo1;
}
else if(container == 2) {
servo = servo2;
}
else if(container == 3){
servo = servo3;
}
else if(container == 4){
servo = servo4;
}
}
/*
* Function to check if there is a need for a refill
* Returns: True if refill is needed, false if not
45
*/
boolean checkRefill()
{
if (medNumber < medRefill)
{
return true;
}
else {
return false;
}
}
/*
* Function which checks the time. If the time aligns
* with the time the medication needs to dispense,
* dispense it.
*/
void checkTime()
{
// Checks to see if the medication dispenses at an interval.
if (interval)
{
//Checks the hour and minute the medication needs to dispense.
if (hour() == hr) {
if (minute() == m) {
for (numDispense; numDispense > 0; numDispense--)
{
//If conditions are met, dispenses the medication
dispenseMed();
}
//Changes the time the medication needs to dispense next.
//This time is based on the interval
hr += interval;
//If the next time would be during the night
//Changes the time to the morning time.
if (hr > night)
{
hr = morning;
}
}
}
}
}
//Otherwise, just checks the time the medication
//needs to dispense at.
else {
if (hour() == hr) {
if (minute() == m) {
for (numDispense; numDispense > 0; numDispense--) {
//Dispenses the medication at the right time.
dispenseMed();
}
//If there is a second dispensing time, changes
//the current time with it so that it would
46
private:
void dispenseMed() {
if (medSize == 1)
{
if (container == 1) {
dispense(smallToOne, smallToDispense);
}
if (container == 2) {
dispense(smallToTwo, smallToDispense);
}
if (container == 3) {
dispense(smallToThree, smallToDispense);
}
if (container == 4) {
dispense(smallToFour, smallToDispense);
}
}
if (medSize == 2) {
if (container == 1) {
dispense(mediumToOne, mediumToDispense);
}
if (container == 2) {
dispense(mediumToTwo, mediumToDispense);
}
if (container == 3) {
dispense(mediumToThree, mediumToDispense);
}
if (container == 4) {
dispense(mediumToFour, mediumToDispense);
}
}
if (medSize == 3) {
if (container == 1) {
dispense(largeToOne, largeToDispense);
}
if (container == 2) {
dispense(largeToTwo, largeToDispense);
}
47
if (container == 3) {
dispense(largeToThree, largeToDispense);
}
if (container == 4) {
dispense(largeToFour, largeToDispense);
}
}
if (medSize == 4) {
if (container == 1) {
dispense(xLargeToOne, xLargeToDispense);
}
if (container == 2) {
dispense(xLargeToTwo, xLargeToDispense);
}
if (container == 3) {
dispense(xLargeToThree, xLargeToDispense);
}
if (container == 4) {
dispense(xLargeToFour, xLargeToDispense);
}
}
}
void setup() {
//Sets up the LCD object so it could now be used
lcd.begin(16, 2);
pinMode(blueButton, INPUT);
pinMode(yellowButton, INPUT);
setupClock();
}
void loop() {
updateButtons();
if (mainMenu)
{
if (menu == 0)
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Dispenser Menu")
lcd.setCursor(0,1);
//1 is set, 2 is check, 3 is log, 4 is bluetooth
lcd.print("[st][ch][lg][bl]")
menu = 1;
if(redState == LOW)
{
mainMenu = false;
containerMenu = true;
menu = 0;
}
if(blackState == LOW)
{
mainMenu = false;
checkMenu = true;
menu = 0;
}
if(blueState == LOW)
{
mainMenu = false;
logMenu = true;
menu = 0;
}
if(yellowState == LOW)
{
mainMenu = false;
bluetoothMenu = true;
menu = 0;
}
}
}
if (containerMenu)
{
if(menu == 0)
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print("What Container")
lcd.setCursor(0,1);
//1 is set, 2 is check, 3 is log, 4 is bluetooth
49
lcd.print("[1][2][3][4]")
menu = 1;
}
if(redState == LOW)
{
containerMenu = false;
sizeMenu = true;
menu = 0;
tempContainer = 1;
}
if(blackState == LOW)
{
containerMenu = false;
sizeMenu = true;
menu = 0;
tempContainer = 2;
}
if(blueState == LOW)
{
containerMenu = false;
sizeMenu = true;
menu = 0;
tempContainer = 3;
}
if(yellowState == LOW)
{
containerMenu = false;
sizeMenu = true;
menu = 0;
tempContrainer = 4;
}
}
if (sizeMenu)
{
if(menu == 0)
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print("What Size")
lcd.setCursor(0,1);
//1 is set, 2 is check, 3 is log, 4 is bluetooth
lcd.print("[sm][md][la][xl]")
menu = 1;
}
if(redState == LOW)
{
sizeMenu = false;
numMenu = true;
menu = 0;
tempSize = 1;
}
if(blackState == LOW)
{
containerMenu = false;
50
numMenu = true;
menu = 0;
tempSize = 2;
}
if(blueState == LOW)
{
containerMenu = false;
numMenu = true;
menu = 0;
tempSize = 3;
}
if(yellowState == LOW)
{
containerMenu = false;
numMenu = true;
menu = 0;
tempSize = 4;
}
}
if (checkMenu)
{
if(menu == 0)
{
}
}
}
void setupClock() {
boolean resync;
lcd.clear();
do {
if (RTC.haltRTC()) {
lcd.print("Clock stopped!"); }
else {
lcd.print("Clock working."); }
delay ( 2000 );
delay ( 2000 );
} while (resync);
}
void updateButtons()
{
//Checks the states of all of the buttons
blackState = digitalRead(blackButton);
redState = digitalRead(redButton);
blueState = digitalRead(blueButton);
yellowState = digitalRead(yellowButton);
}
Figure 19. This is a work in progress of the final code for the medicine dispenser. The user
should be able to input information into the LCD, and then the Arduino should be able to keep
track of when it needs to dispense. There is also an option for the user to check the information
for the medication in each container, and check a log for when medication was last dispensed.
There is also a button allocated to bluetooth, in which it would, in theory, allow the user to sync
the device with their phone. As stated before, this code is a work in progress and thus is not
complete, and has not been tested.
ucts/11884
Total $144.03
Figure 20. This is the team’s itemized budget sheet. It includes all everything used to build the
device, including the stepper motor and the stepper motor shield the team plans to add to the
final iteration.
53
Bibliography
“Arduino Time Library.” Arduino. Arduino. N.d. Web. Accessed 28 November 2017.
<http://playground.arduino.cc/Code/Time>
Atmel Team, The. “ATmega328 is under the hood of this sweet candy sorting machine”. Atmel |
Bits and Pieces. WordPress.com. 3 November 2014. Web. Accessed 19 March 2018
<https://atmelcorporation.wordpress.com/2014/11/03/atmega328-is-under-the-hood-of-th
is-candy-sorting-machine%E2%80%A8%E2%80%A8/>
Bruce, James. “What is Arduino & What Can You Do With It?”. Make Use Of. Make Use Of. 25
<http://www.makeuseof.com/tag/arduino-technology-explained/>
“DS1302 Real Time Clock”. Arduino Playground. Arduino. N.d. Web. Accessed 19 March
2018.
<https://playground.arduino.cc/Main/DS1302>
“DS1302RTC library”. Arduino Playground. Arduino. N.d. Web. Accessed 19 March 2018.
<https://playground.arduino.cc/Main/DS1302RTC>
<https://www.arduino.cc/en/Tutorial/HelloWorld>
Mathavan, Hariharan. “Control an Arduino Using Bluetooth.” All About Circuits. EETech
Media,
<https://www.allaboutcircuits.com/projects/control-an-arduino-using-your-phone/>
“Patient Compliance + Medication Adherence Statistics”. E-pill. E-pill. N.d. Web. Accessed 19
54
<https://www.arduino.cc/en/Reference/Servo>
skywodd. “pcf8574_arduino_library”. Github. Github, Inc. N.d. Web. Accessed 19 March 2018.
<https://github.com/skywodd/pcf8574_arduino_library>
SparkFun Electronics, inc. Sik Guide ver. 3.2. SparkFun Electronics, inc. N.d. Print.
Stan. “HC-06 Bluetooth module datasheet and configuration with Arduino”. 42 Bots. Wordpress.
<http://42bots.com/tutorials/hc-06-bluetooth-module-datasheet-and-configuration-with-ar
duino/>