The opioid crisis is a widespread issue, affecting millions of Americans every year. In 2019 alone, almost 2.1 million people in the US had an opioid use disorder, resulting in over 70,000 deaths. The current system of over-prescription combined with a lack of strong regulation make it easier than ever for a patient to abuse their prescription medications. As a result of misaligned incentives provided by the government, insurance companies, and opioid manufacturers themselves, doctors often prescribe opioids when unnecessary, opting for short term efficacy at the cost of long-term patient health.

Combine the highly addictive nature of opioids with this essentially unrestricted access to opioids, and it is no wonder that the US is facing an opioid epidemic: as a result of this skewed system, every year, over 200 million opioid prescriptions are written for noncancerous chronic pain, despite the fact that opioid therapy is a last resort treatment option; furthermore, 1 in 4 of these prescriptions results in opioid misuse. As such, the opioid crisis in the United States is increasing in severity at an alarming rate.

What it does

PillBot prevents addiction and overdose to opioids in chronic pain patients by enforcing prescription regimens at home, while collecting critical medical adherence data that can be used to iteratively improve patient outcomes. The PillBot Device is a handheld pill dispenser that dispenses pills according to the patient’s prescription regimen. When a patient is supposed to take their medication, the indicator light flashes. To claim their medication, press the large front-facing button twice in quick succession. If a patient wishes to claim medication outside of their prescription, they need to hold the button down for 40 seconds. This filters impulsive doses from doses that show actual need, and stopping “pill dumps” all together. Being impulse-proof also provides a richer and more useful array of data to analyze, and also discourages the patient from sourcing pills from elsewhere or breaking the device.

How we built it

In order to successfully construct the best version of the PillBot possible, we follow three general principles. First, we set clear goals and categories for each potential feature of the pillBot. Then, we isolate each component and ensure that each is functional before attempting to integrate into a larger circuit. Finally, we set an explicit time table to accomplish each task required to both assemble and present the final project. We initially outlined that the IR Sensor, Button, Servo Motor as essential, LED indicator and Battery Conservation as advanced, and IOT as ambitious features. After the Milestone, there were a few changes and additions to both the feature set and the categorization of said features. First, we were successfully able to implement the servo and button integration by the Milestone in a way that easily allowed for integrating LED indicators into the system. Next, after a more thorough exploration, we discovered that the IR sensor used a digital output and different timings to detect a signal from an IR sensor, meaning that the ADC wouldn’t be used for that sensor. Luckily we had the requisite two additional digital I/O pins available to supply the 38KHz carrier signal for the IR LED and the digital input pin to capture interruptions to that carrier signal by the IR sensor. This also allowed us to re-use the analog input port and logic to implement the Battery Conservation circuit which required an ADC for battery level measurement. Finally, we decided to add an RTC module to the ambitious feature list, as we discovered that we had easy access to the equipment. These changes adjusted our goals and reframed our methodology post-milstone. With all these categorization changes, our “divide and conquer” approach really became valuable. Since both team members lived in different parts of the country, we were able to delegate work on the components based on who was more comfortable with the respective equipment. The work was clearly split up where Sid was in charge of the Timers, Servos, Interrupts, and eventually the RTC module. Meanwhile, Chris conducted work on the Battery conservation circuit, the LED wiring, the Physical Enclosure, and the IR sensor. Since the device would eventually be assembled by Chris, after the milestone, we decided to send all of the components that Sid worked with to Chris as soon as possible, eventually making debugging easier. Finally, we mostly stuck with the timeline initially outlined in the project proposal. However, we switched to a more full featured version of the timeline as and when we outpaced the deadline we set in the proposal. We eventually adjusted the timeline so that the advanced level was near finalized by the beginning of the last weekend, allowing for extra time to be committed to both the video and some of the dream level features, namely the RTC.

What we learned

In our final project, we implemented all of the essential and advanced features outlined in our proposal. Furthermore, we were able to implement the RTC module, an ambitious/dream feature. Our final project ended up using Timers, Interrupts, ADC, I2C, and Serial Communication concepts. We used the following components in our final project:

Arduino Nano (ATMega328p) Elegoo Multicolor LED (with Current Limiting Resistor) Parallax Continuous Rotation Servo Gikfun Infrared Diode Led IR Emission and Receiver Elegoo Momentary Button Battery Power and Conservation Circuit FQP27P06 P-Channel MOSFET 2N2222 NPN transistor to flip-flop gate signal to MOSFET 1N4007 Diodes to isolate signals 1Mohm Resistor to trickle-charge the capacitor 2.2uF capacitor to introduce enough delay for Arduino to get past bootloader Adafruit PowerBoost 1000c boost converter to raise 3.7VDC LiPo to 5.0VDC for the circuit and to allow for safe recharging of the LiPo cell.

DS3231 RTC Module with SQW (alarm) Interrupt pin to ‘wake up’ power circuit 3D Printed Enclosure (PETG Plastic)

The final circuit for our device is shown below:

We used the ATMega328p on the Arduino Nano as the MCU for the project. This gave us the same power and functionality as an Arduino Uno while having a much smaller footprint.

IR Sensor The IR sensor is leveraged to detect a pill drop. It works on the principle of signaling on interruption to the 38kHz+/- 1kHz carrier signal emitting from the IR LED. The IR LED was set up using the 328p’s 8 bit timer unscaled on CTC mode to send the 38kHz signal that the pill would disrupt. Although the IR sensor worked as designed in unit testing (see video: ) in practicality it must work flawlessly. This was where we made the realization that using white PLA plastic was not going to suffice due to IR LED light bleeding. In fact the white plastid acted like fibre-optics, bending the light around the corners/sides, resulting in more false negatives than our test bench video above.

What looked fine to the human eye lit up like a Christmas Tree to an IR camera, bending the 38khz carrier signal around the cylinder well enough to fool the IR sensor to give false negatives on pill drop.

Naked eye view of IR LED & Sensor IR Camera

The quick answer was to use a black permanent pen and simply color in the sections containing IR components black. The better solution was to reprint the electronics compartment in a darker (blue) 100% opaque color. (Like below)

Low Battery Sensor This leverages a basic voltage divider circuit. Although such a basic measuring methodology introduces a bit of a constant drain on the 3.7 LiPo battery pack, it basically consists of a very high resistance of a 1Mohm resistor in series with a 100Kohm resistor tied to the A0 ADC input (with the ADC running continuously) between the two resistors to measure relative battery voltage levels. With an ammeter attached, there was no appreciable / no measurable current draw given the sensitivity of the meter being used, evn at the μA setting.

Because the circuit requires 5VDC for select components, a boost converter was deployed. The boost converter chosen has one additional function that has proved useful in that when power is applied to the integrated microUSB port. When the battery is fully charged, the YELLOW LED will turn off. The Boost Converter has an additional integrated RED LED to indicate a Low Battery state.

Although a diminutive 600mAh LiPo cell is being used to power the entire circuit, the circuit has been tested to dispense several pills on a single charge. Due to the unit completely powering down automatically on idle timeout, it is expected that the Pillbot can operate for a number of weeks or longer on a single charge if dispensing is confined to no more than 4 times a day. (the usual max dosage for most prescriptions.)

Testing of the low battery was accomplished by checking the threshold voltage (see pic above, the blue in-line USB meter reads 4.93VDC on a LiPo battery source of ~3.68 Volts

This yielded an ADC value of ~796 as a threshold across our voltage divider circuit to the onboard ADC converter.

Status LED The basic RGB LED from the Elegoo kit was leveraged as the status indicator as the three colors allowed us to quickly show different status modes cheaply/easily. This LED has a unique behavior where it can only show one color at a time. Each subsequent color has a higher priority than the predecessor despite having individual anodes to light up each color independently. In this case, the highest priority color was Red. If the Red anode goes high, even if the Green or Blue anodes are also high, the LED will only shine with the RED color. The next highest priority color is Green. So even if the Blue color LED goes high, the LED will only show up as Green unless the Red lead is also high, in which case it’ll only show up as Red. The lowest priority color is Blue. If no other color is trying to be displayed, then Blue will shine thru. The advantage of this LED is that a single common resistor to the cathode can be used for all three colors with relatively similar and consistent brightness regardless if one, two or all three colors are selected as active.

In general, the Red, Green and Blue colors were chosen to depict select states. RED indicates some sort of error.

Red Color: In this case, these errors could be SOLID RED color to indicate it’s NOT time yet for your next dose, with a FLASHING RED color to indicate a low battery or out-of-pills error condition. The flashing red color happens independently of a button press. So if the unit powers on, but is low on battery, it will immediately just start flashing Red until the timeout period (40 seconds) , at which point the Pillbot will automatically power off.

Green Color: Green is typically associated with success. So in this case, the Green color is to indicate that a pill was successfully dispensed.

Blue Color: The color blue is used to indicate work-in-progress trying to dispense a pill. In this case, when you press the button to dispense a pill, the LED will light up Blue as the button is pressed. If the button is pressed long enough, the unit will take this to mean that you wish to power-off the unit, in which case the unit will simply turn off. The behavior of this LED of only showing one color at a time in priority sequence worked in our favor for select scenarios. In particular, the pillbot will light up BLUE if it’s time for your next dose, but then alternatively flash RED if the battery was too low to guarantee proper servo motor operation to dispense a pill. This gave the pillbot a familiar alternating Red/Blue status pattern reminiscent to lights on a police car with minimal coding, showing both “it’s OK to get a pill” but you need to plug the unit into a microUSB power source so it has enough power to run the full dispense cycle.

Servo and Push Button (Timer and Interrupts) To control the servo motor, we developed a separate servo library in the servo.c file. In the library’s setup function, the 16-bit timer/counter 1 is enabled at a prescale of 8 and Mode 11 phase-correct PWM. Using the compare matches for timer 1, the frequency was set to 50Hz. In the setServo function, an input degree value from 0 to 180 degrees is translated into a duty cycle that’s high from 1 to 2 ms per cycle. The library was initially designed for regular servos, but was completely functional for continuous servos. Through experimentation, we found that the neutral position for the continuous servo was at 88 degrees. With the push button attached directly to the PD2 pin and ground, the PD2 is set as an input with the pull-up resistor enabled. The Pin Change Interrupt 2 is enabled, and PD2 is unmasked, allowing us to use PD2 in conjunction with an interrupt as opposed to polling constantly. We used the timer1 from the servo library to also time the length of button presses. The timer1’s compare match interrupt was enabled, and whenever the button was pressed, that interrupt would increment a counter, timing the button’s press at a resolution of 1/50th of a second. The counter is then reset when the button is released. Thus, in the main code, we can have two timed conditions depending on how long the button is pressed. When the button is pressed for the equivalent of 1 second, it's time to dispense (determined by a variable) and it’s not already been dispensed in this active time period (also determined by a variable), the servo activates until the IR segment detect the pill (which is explained in the IR section). Also, if the button is pressed for 40 seconds (implemented in the project as 5 seconds), the pill is dispensed regardless of those other conditions.

Power control and Auto-Shutoff is implemented via the MOSFET power control circuit. You can see this in action here:

When no button is pressed for 40 seconds, the PillBot will automatically power down, however the RTC (Real-Time-Clock) will keep track of the current date/time for prescription mgmt via the CR2032 watch battery.

RTC (Serial Communication) We used the DS3231 RTC module to add real time pill dispensing functionality to our project. It contains a built in battery, making it perfect for when we want to maintain time but shut off the system. We based our efforts heavily off of the following RTC library designed to deal with this specific RTC module within the AVR toolkit: First, we used a self-made serial library. This library wasn’t directly used, but benefited the RTC library that we used. We set the baud rate to 9600 based on the CPU clock speed and placed them into the UBRR0 registers. Then, we set the signal to 1 start bit, 8 data bits, and 2 stop bits. Finally, we enabled the RX and TX communication register values along with interrupts (which were required for the RTC library to work). We also coded a Serial send and putstring function, but that wasn’t used in our final iteration of the project. From the RTC library, we used the initialize function to determine the specific RTC module, the set time function, the get time function, the set alarm function, and the SQW enable function. The actual use of the library was fairly simple. We called the initialization function, and set the time of the clock if it hadn’t been set previously. Then, we set the alarm of the clock to the specified time (we chose 1 for testing purposes) and called the RTC SQW function so that the DS3231’s SQW pin acted as an interrupt whenever the alarm activated. Finally, in the main loop checked if the time was within the specified hour using the get time function, and enabled the 1 second pill dispensing ability through a variable. The library's details are explained in the appendix.

3D Enclosure PillBot’s external shell and internal mechanics were completely redesigned for this project to fit the specified hardware requirements. This included an upgrade to the device with a clear container, for patients to visibly see how much medication was left, and an overhaul of the reusable electronics module, which was modified to fit the new motor and circuitry. In addition, a path to install and mount the IR sensor was integrated into the electronic module itself. Pillbot uses purely PETG for any materials that come into contact with pills or patients, as this is the only food-safe 3D printable material available. This complies with FDA regulations for plastics that come into contact with materials that may be digested by humans.

What's next for PillBot

Over the course of this project, we got hands-on experience developing a customized circuit layout and design to interface with a complex, 3D-modeled hardware product. We were especially proud of being able to finish not just the base requirements on time, but also be able to implement some of the additional features we considered from the start, such as every single advanced feature and even the RTC module, which we considered to be a “dream” feature. Over the course of development, several minor course corrections and modifications were made, including having to order a continuous servo motor last-minute to ensure the dispensing mechanism could function properly and shorten the dispense time, as well as modifying the hardware itself to support an IR sensor without the color leaking through from the LED. In terms of next steps for this project, since this is the core product to a startup, there are a number of ways to use the insight gained from this process to upgrade the final device in the future. Outlined as follows are just some of the many improvements that could be made to this device. Pill drop sensor & pill dispense tray improvements: Although we’ve had decent success with the IR sensor, as the pilldrop sensor needs to work with 100% reliability, a future version may involve going to an ultra-sensitive pressure sensor, such as the SEN-13879 Load Cell Amplifier along with the implementation of a pill drop tray for such a sensor. As the current design simply drops a pill out of the bottom of the unit, this tray has the added benefit of helping ensure the user does not let the dispensed pill drop to the ground instead of into his/her hand.

(Ultra-sensitive digital pressure sensor/scale)

Status LED There is an additional LED that could be either fibre-optically displayed outside the unit or run electronically for external display to indicate the power state of the Pillbot. As the Pillbot has an auto-off feature after it’s been idle for a number of minutes, or can ‘wake up’ at a pre-determined time when your next dose is available for dispensing, routing of the onboard LED on the Arduino Nano can be leveraged showing a Yellow color by default.
This can also be implemented as part of a custom PCB for visible mounting thru the otherwise somewhat translucent casing. An additional improvement could be the addition of a buzzer to act as either an alarm clock to notify the user of his/her next dose and/or to enhance upon the “Success” (Green) or “Failure” (Red) status LED. Although this integrated yellow LED is already called out in the final schematic, it is not visible outside of the case.

Built With

  • arduino/avr
  • c
  • cad
Share this project: