Engineer Design and Society Final Project
For my first semester at the University of Florida, I enrolled in a course called Engineering Design and Society, focused around human centered design. The course was focused on teaching us how to adapt to a given user group as well as teaching us the tools to design and prototype our ideas. I became proficient in using OnShape, Arduino circuitry and C programming, as well as 3D printing and Tinkercad Circuit design.
For our final project we were to work in groups to design a product for a chosen user group. The project followed the following guidelines:
- Be created using the human-centered design process to meet a user or user group need.
- Use an Arduino Uno microcontroller development board. It must be powered and controlled by no more than two Arduino microprocessors.
- Receive input from at least one sensor (motion, sound, sunlight, temperature, etc.).
- Control at least two actuators based on input from the sensor(s).
- Incorporate at least one functional 3D printed component designed using OnShape (or an approved CAD) software
- Estimated print time of your 3D printed component, when brought into Cura at standard quality, should be 8 hours or less
- Build a physical circuit and use programming between sensors and actuators through an Arduino microprocessor. A circuit diagram will also need to be documented thorough a Tinkercad Circuits or Fritzing setup.
We were required to write a report, as well as create a presentation on how and why we created our product.
The Pill Dispenser
Our user group were students on campus who often forget to take their medication on time. Our solution to this issue was a small tabletop pill dispenser designed like a gumball machine to drop one pill on time for however many times per day the user needed to take their pill.


My portion of this project was programming the device, creating a flowchart to explain the code, 3D printing all of the CAD pieces designed by my groupmates, and then at the end to put together the video presentation to be submitted.
The Code
While I am a pretty experienced programmer, this was some of the most difficult code I’ve written, not in the sense that its incredibly complicated, but that coming up with the idea for how the script would work, as well as having only very little experience with Arduino C. Having to teach myself the programming language through documentation online made the project that much more time consuming. Eventually I came up with a script I was incredibly proud of:
#include <LiquidCrystal.h>
//Pin Variables
int SelectButton = 2; //Select
int UpButton = 3; //Left
int DownButton = 4; //Right
int motorPin = 5; //Pin for the Motor
int ledPin = 6; //Pin for the LED
int buzzerPin = 7; //Pin for the Buzzer
LiquidCrystal lcd(8, 9, 10, 11, 12, 13); //RS Pin, Enable pin, D4 pin, D5 pin, D6 pin, D7 pin, R/W pin, VSS pin, VCC pin
//Variables
bool hasStarted = false;
bool selectedNumOfTimesPerDay = false;
bool selectedTimes = false;
bool inputtedCurrentTime = false;
bool hasGoneOff = false;
int numOfTimesPerDay = 0;
int i = 0;
int hours[10] = {};
int minutes[10] = {};
int times[10] = {};
int value = 1;
int currentTimeHours = 1;
int currentTimeMinutes = 0;
unsigned long previousMillis = 0;
unsigned long offset = 0;
int Hour = 1;
int Minute = 0;
void setup()
{
//Sets the pin outputs for the arduino board
pinMode(SelectButton, INPUT);
pinMode(UpButton, INPUT);
pinMode(DownButton, INPUT);
pinMode(motorPin, OUTPUT);
pinMode(ledPin, OUTPUT);
pinMode(buzzerPin, OUTPUT);
//Set up the LCD
lcd.begin(16,2);
}
void loop()
{
if(inputtedCurrentTime == true) //checks if the user has inputted the current time when the machine starts
{
calculateTime(); //calls the calculate time method every time the system runs after the user has inputted the current time
}
if(hasStarted == false) // first iteration
{
while(inputtedCurrentTime == false) //checks if the user hasn't inputted the current time when the machine starts
{
getCurrentTime(); //calls the get current time method everytime the method hasn't set inputtedCurrentTime to true
}
while(selectedNumOfTimesPerDay == false) //checks if the user has inputted the number of times per day they need to take the pill
{
getNumOfTimesPerDay(); //calls the get num of times per day method everytime the method hasnt set selectedNumOfTimesPerDay to true
}
for(int i = 0; i < numOfTimesPerDay; i++) //runs the loop for everytime the user needs to take their pill per day
{
selectedTimes = false;
while(selectedTimes == false) //checks if the user has selected all of their times to take their pills
{
getTimesForEachPill(); //calls the get times for each pill method every time the method does not set selectedTimes to true
}
}
hasStarted = true; //confirms the first iteration has run
} else if (hasStarted == true) { // every iteration after the first
for(int i = 0; i <= numOfTimesPerDay; i++) //for every time that the user needs to take their pill per day
{
if(currentTimeHours == hours[i] && currentTimeMinutes == minutes[i]) //checks if the current time is equal to one of the set times
{
if (hasGoneOff == false) //if the alarm isn't currently going off
{
//turns on the led and the buzzer along with the motor for the delay and displays to the LCD
digitalWrite(ledPin, HIGH);
digitalWrite(buzzerPin, HIGH);
lcd.setCursor(0, 0);
lcd.print("Time to take");
lcd.setCursor(0, 1);
lcd.print("your pill");
//spin motor necessary times
digitalWrite(motorPin, HIGH);
delay(5000);
lcd.clear();
digitalWrite(ledPin, LOW);
digitalWrite(buzzerPin, LOW);
digitalWrite(motorPin, LOW);
hasGoneOff = true; //ensures the machine knows that the alarm is going off so it does not repeat
}
}
}
//when nothing else is occuring, the LCD should display the current time
lcd.setCursor(0, 0);
lcd.print("Current Time:");
lcd.setCursor(0, 1);
lcd.print(String(currentTimeHours) + " : " + String(currentTimeMinutes));
hasStarted = true;
}
}
void getCurrentTime()
{
//prompts the user for what the current time is
lcd.setCursor(0, 0);
lcd.print("What time is it?");
lcd.setCursor(0, 1);
lcd.print(String(currentTimeHours) + " : " + String(currentTimeMinutes));
if(digitalRead(UpButton) == HIGH) //press the up button
{
//adds one to the hour, if the hour is over 24 then it rolls back to 1
if(currentTimeHours < 24)
{
currentTimeHours++;
}
if(currentTimeHours >= 24)
{
currentTimeHours = 1;
}
delay(500);
}
if(digitalRead(DownButton) == HIGH) //press the down button
{
//adds one to the minute, if the minute is over 60 then it rolls back to 0
if(currentTimeMinutes < 60)
{
currentTimeMinutes++;
}
if(currentTimeMinutes >= 60)
{
currentTimeMinutes = 0;
}
delay(500);
}
if(digitalRead(SelectButton) == HIGH) //press the select button
{
//registers that the current time on the display is the current time for the machine to refer to later
lcd.clear();
inputtedCurrentTime = true;
offset = millis();
delay(500);
}
}
void getNumOfTimesPerDay()
{
//prompts the user to input how many times they need to take their pill per day
lcd.setCursor(0, 0);
lcd.print("Pills per day?");
lcd.setCursor(0, 1);
lcd.print(value);
if(digitalRead(UpButton) == HIGH) //press the up button
{
//adds to the number of pills they need to take, cannot take more than ten per day
if(value < 10)
{
value++;
}
if(value > 11)
{
value = 1;
}
delay(500);
}
else if(digitalRead(DownButton) == HIGH) //press the down button
{
//removes from the number of pills they need to take, cannot take less than one per day
if(value > 1)
{
value--;
}
delay(500);
}
else if(digitalRead(SelectButton) == HIGH) //press the select button
{
//saves the number of times the user needs to take the pills per day
numOfTimesPerDay = value;
lcd.clear();
selectedNumOfTimesPerDay = true;
delay(500);
}
}
void getTimesForEachPill()
{
//prompts the user for the time for this pill
lcd.setCursor(0, 0);
lcd.print("Time for pill? " + String(i + 1));
lcd.setCursor(0, 1);
lcd.print(String(Hour) + " : " + String(Minute));
if(digitalRead(UpButton) == HIGH)
{
//adds one to the hour, if the hour is over 24 then it rolls back to 1
if(Hour < 24)
{
Hour++;
}
if(Hour >= 24)
{
Hour = 1;
}
delay(500);
}
if(digitalRead(DownButton) == HIGH)
{
//adds one to the minute, if the minute is over 60 then it rolls back to 0
if(Minute < 60)
{
Minute++;
}
if(Minute >= 60)
{
Minute = 0;
}
delay(500);
}
if(digitalRead(SelectButton) == HIGH)
{
//saves the time to the array of times (reason for limiting it to 10), this is then referred to by the machine later
hours[i] = Hour;
minutes[i] = Minute;
i++;
lcd.clear();
Hour = 1;
Minute = 0;
selectedTimes = true;
delay(500);
}
}
void calculateTime()
{
//creates a variable that keeps track of the time plus the offset of how long it took the user to input all the information when starting the machine
//keep time based on the system millisecond tracker as well as the current time the user inputted, etc every 60000 ms it adds to the minutes of the current time
unsigned long currentMillis = millis() - offset;
if((currentMillis - previousMillis) >= 60000)
{
if(currentTimeMinutes < 60)
{
currentTimeMinutes++;
hasGoneOff = false;
}
else
{
currentTimeMinutes = 0;
if (currentTimeHours < 24)
{
currentTimeHours++;
hasGoneOff = false;
}
else
{
currentTimeHours = 0;
}
}
previousMillis += 60000;
}
}
3D Models
These were the models my groupmates designed using the CAD program SolidWorks. I omitted some of the model pieces from this article as they were unnecessary to display. My job was to print these parts and then help to assemble it when we created our prototype.
Our Final Presentation
Finished Product Images


Conclusion
Overall this project was a great introduction to engineering in college. It helped me develop many basic skills required for prototyping and design. It also helped us to develop team work skills, working with a group of people with different ideas and skill sets.
Very clever. This machine would have been very useful for my aging parents who forget to take or can’t remember if they’ve taken their very vital medications.
Next project: Build to dispense multiple pills at different frequencies.