Ashley He (ach238) & Amelia Myers (arm293)
Ever craved a mixed drink without the hard work of making it yourself? With our Automatic Drink Dispenser, you can select a drink from a menu and be served almost instantaneously! You can also create your own custom drink by mixing together four different ingredients of your desired amounts. Our system has four juices (peach, ginger, lime, and lemonade) and three preset menu items, Peach Ginger, Limeade, and Starburst.
We drew our initial inspiration for this project from having guests over at our apartments and repeatedly having them spill liquids as they were trying to pour themselves a drink. Traditional drink or soda dispensers cost hundreds or even thousands of dollars, and are not easily maintainable. Being able to serve guests without ever worrying about potential spillage while also maintaining a low budget was something that we wanted to tackle with our project.
To achieve the described drink dispensing functionality, we used a simple mechanical design that allowed us to control liquid amounts with relative precision and repeatability. For each different liquid, we decided to use a servo zip-tied to the spigot of a plastic container, and with rotations of servos in different directions, we could either open or close the spigot. We also designed a GUI that would encapsulate any implementation complexity so a user could simply choose the drink they wanted without worrying about mixing in the proper amount of each ingredient themselves. For those who were more creative, the GUI also allowed for a user to dispense each liquid for as long as they tapped and held the button down. The system was entirely controlled with a Raspberry Pi unit, with four servos powered by two external 6V battery packs and controlled by the Pi’s GPIO pins. The system’s high level block design is summarized below:
The components were all placed on top of a wooden shelf so that the liquids dispensed could flow through silicon tubing, combine in a funnel, and finally be dispensed into a cup underneath the shelf. Our final system design is shown in the image below:
As described above, we built a simple wooden shelf to contain the system. In the beginning, we did some initial testing that involved filling the containers with water. We found that they had to be filled to a certain level (above the spigot) for the liquid to be dispensed without having to tilt the container. At that point, there was quite a bit of liquid in the container, with each weighing at least two pounds. To maintain our initial design, we needed to construct a sturdy base for the system; we eventually chose to use ¼” scrap wood to construct a shelf strong enough to support a minimum of eight pounds.
We placed four liquid dispensing containers with spigots onto the wooden shelf and connected the spigots to silicon tubing to ensure more consistent liquid flow. The spigots are attached to standard servos (rotating about 90 degrees) with zip-ties pulling them down to open the valve. When the spigots are opened, the liquid pours down a tube into a funnel which fills up a cup with the desired drink. An image of the servo/container setup can be seen below:
The circuitry for our system was relatively simple, as we only needed to utilize four servos for spigot control. The four servos were connected to and controlled by four different GPIO pins on the Raspberry Pi. Each servo was powered by a battery pack connected to a switch; the input was connected to a GPIO pin on the Pi with a 1k current limiting resistor in series to protect the GPIO pin. An example circuit with a single servo is shown below, and we implemented this four times for our system:
This acts as an embedded system as it takes user input through the GUI and maps that to an action for the servos and drink dispensing system.
As we wanted a user to have a simple visual for interacting with our system, we used pygame to implement a menu interface. Using while loops, we created different menu interfaces and swapped to different screens depending on what button the user pressed. We began with a welcome screen that would allow a user to choose between either a preset drink on our menu, or a custom drink option that would allow them to dispense liquids of any amount. The main menu screen can be seen below:
From the main menu, if a user tapped drink menu, it would set the welcome screen flag false and the drink menu flag to true, entering a new while loop that continuously displayed the new menu screen with preset drink options instead. A similar action occurred if a user tapped custom drink, but the next menu displayed the four different ingredients a user could include instead. Additionally, a user could backtrack through any of the screens by touching the back button. Screenshots of both menus are shown below:
To control the standard servos to actually dispense the ingredients, we used the rpi.GPIO library to control PWM instances on four different GPIO pins. Since we used standard servos, sending a 0.75 ms pulse every 20 ms would rotate the servo clockwise, and sending a 2.25 ms pulse every 20 ms would rotate the servo counterclockwise. To open the spigot, the servo arm rotated clockwise 90 degrees and stayed open for however long the recipe called for. To close the spigot, the servo arm rotated counterclockwise 90 degrees. To maintain the spigot as open or closed for a set amount of time, we added sleep methods that would suspend execution for a given number of seconds. The smallest amount of liquid we could dispense was a third of an ounce with a 0.75 sleep time. From there, we experimented with more sleep times to find that one ounce was approximately 1.5 seconds, two ounces was 3 seconds, and three ounces was 4.5 seconds.
For the preset menu page, we had three buttons corresponding to three drinks (Peach Ginger, Limeade, and Starburst). When one button was pressed, the recipe’s ingredients were displayed along with the amounts of each ingredient. For the custom drink page, we created four buttons corresponding to the four different ingredients a user could use. When the touch screen detected a MOUSEBUTTONDOWN event, our program called the open spigot function. Then, when the touch screen detected a MOUSEBUTTONUP event, it called the close spigot function.
To ensure our system would function as expected, we performed tests at each stage of development, starting with the servo spigot control. First, we ensured that the servos worked correctly by hooking them up to physical buttons on the PiTFT. We made sure that they rotated the correct amount (90 degrees in either direction) and that they were strong enough to pull the spigot open, since the spigot had quite a bit of resistance to opening. We experimented with different servo arm lengths and connections to the spigot. Eventually, we settled with using a standard plastic servo arm zip-tied to the spigot tab. We also checked the location for which the servos needed to be mounted to reach the spigot. Once we finalized the design of the servos, we moved onto the GUI design.
After writing up initial pygame setup code, we made sure that all the buttons were placed in appropriate locations and functioned correctly. To check button placement, we hooked up the Raspberry Pi to a monitor and displayed the mouse on the screen. When we found spots that we wanted to place buttons, we clicked the positions and printed the mouse click coordinates. From there, it was easy to draw the button shapes and text based on the clicked boundaries. We then tested that the two options “drink menu” and “custom drink” correctly displayed their respective pages, and that the “back” button successfully directed a user to the previous menu. Finally, we tested that the correct servos were responding to their button counterparts. As described in the software section, we experimented with different times that the servos opened the spigot to be true to the recipe. For example, a “dash” of liquid was equivalent to opening the spigot for 0.75 seconds while an ounce was equivalent to opening it for 1.5 seconds.
We then moved the GUI onto the PiTFT to implement the touchscreen aspect. We ran into some issues with the PiTFT not recognizing a user’s touch, but that was fixed with removing and re-adding the touch screen driver. We also found that using a resistive touch screen meant that user interactions had to be more deliberate, as they are not as sensitive to light touch.
Our system worked perfectly once we implemented everything. Both the preset drink menu and custom drink operations performed as expected, dispensing the correct amount of liquids reliably. We occasionally ran into touchscreen problems such as the PiTFT not detecting one specific person’s finger, but with a resistive touchscreen a user needed to be more deliberate in the MOUSEBUTTONUP and DOWN actions.
Although we were happy with our final product, we had a few areas we wanted to improve for the next iteration. We originally wanted to have 6 different liquid containers and more preset menu options, but due to budgeting and time, we could only implement a system with 4 liquids. In the future, we would have more drink options and combinations and also could use a conveyor belt system to move a user’s cup rather than use a funnel. The conveyor belt would move the drink to the spigot that is dispensing so that there would be no cross contamination of liquids from using one communal funnel.
Another thing we could explore in the future would be the use of peristaltic pumps. Initially, we thought of using peristaltic pumps as that would allow us to dispense liquids without having to rely on gravity or the use of spigots. With the pump, we could pump liquids directly from their original containers to a user’s cup or funnel. However, given that peristaltic pumps are relatively expensive compared to servos and draw more power, we chose to use servos for the scope of this project.
Overall, we were happy with the outcome of our project and had a lot of fun in building a successful automatic drink dispenser. This is definitely a project that is useful outside of being a final project, and we’re proud that it could work so smoothly and reliably!
Ashley built the wooden frame and mounted the servos onto it. She also worked with Amelia on coding and testing the machine, and the website.
Amelia worked with Ashley on coding and testing the machine, and the website.