Automatic Bartender Using Raspberry Pi
A Smart IoT-Based Beverage Dispensing System
Introduction
In the era of smart devices and automation, the Automatic Bartender presents an
intelligent, contactless solution for drink dispensing using Raspberry Pi. This project
leverages embedded systems, IoT, and basic fluid control logic to mix and dispense
drinks based on user selection.
The system allows users to choose drinks and custom volumes via a web interface
hosted on the Raspberry Pi. Predefined and custom mocktail recipes are supported,
and the entire operation is fully automated using relay-controlled DC pumps.
Objectives
Automate the process of drink selection and dispensing
Offer a contactless and user-friendly drink interface
Support custom volume control and predefined recipes
Build a low-cost, scalable, and IoT-enabled prototype
Learn and demonstrate hardware-software integration
Motivation
Manual drink mixing is time-consuming and lacks consistency. The need for a
hygienic, contactless solution became especially evident during and after the COVID-
19 pandemic. This project is a fun, practical automation that has applications in
homes, parties, and cafes.
Hardware Components
Component Description
Raspberry Pi 3/4 Core controller with Wi-Fi hosting
Relay Module (3-Channel) Controls the pumps via GPIO
DC Water Pumps (x3) Dispenses different liquids
Breadboard + Jumper Wires Circuit connections
Food-Grade Silicone Pipes For safe drink transfer
Power Supply (5V, 3A) Powers pumps and Raspberry Pi
Software Stack
Python (GPIO & Web): Controls the hardware and serves the local web server
Flask (Web Framework): Handles HTTP requests and renders HTML
HTML/CSS (Bootstrap): Frontend for drink selection and UI
Raspbian OS: Operating system for Raspberry Pi
Libraries Used:
Library Name Purpose
RPi.GPIO To control GPIO pins (turn relays on/off for pumps)
Flask To run a lightweight web server on Raspberry Pi
HTML templating used by Flask (required for rendering variables
jinja2
in HTML)
To process form data (used for recipe creation via
python-multipart
dropdown/input fields)
time (built-in) For managing delays (e.g., controlling pump timing)
threading (built-in) For background tasks (e.g., running mocktail pumps in parallel)
System Overview
Working Principle
If one drink is selected, it is dispensed for 5 seconds (200 ml)
If two drinks: 2.5 seconds each (100 ml per drink)
If three drinks: 1.5 seconds each (~66 ml per drink)
Mocktail: All three pumps run simultaneously for 1.5 seconds
Web Interface
The system runs a local server using Flask. Users connect to the Raspberry Pi's IP
(e.g., http://192.168.1.42:8000) to access the interface.
Features
Drink checkboxes and volume dropdowns
Auto-selection of checkboxes on dropdown change
Predefined mocktail buttons
Add and dispense custom recipes instantly
Results
Successful creation of a fully working web-controlled bartender system
Real-time control of 3 pumps
Predefined + custom mocktail execution
Cool user interface with Bootstrap styling
Compact plywood prototype made for demonstration
Applications
Smart home kitchen
Parties and events
Cafes or quick-service stations
College tech demos & learning IoT
Future Improvements
Add flow sensors for precise ml detection
Implement voice control using Google Assistant
OLED display showing selection in real time
NFC card reader to dispense pre-registered user favorites
Integrate payment gateway for cafes
Conclusion
This project is a creative implementation of automation, IoT, and embedded
systems. It bridges software and hardware in a practical, engaging way while being
scalable and affordable. It demonstrates how even simple setups can deliver
impactful solutions.
Code Structure
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
const char* ssid = "Papakawifi";
const char* password = "";
const int pump1 = D1;
const int pump2 = D2;
const int pump3 = D3;
ESP8266WebServer server(80);
String recipeNames[10];
int vol1[10], vol2[10], vol3[10];
int recipeCount = 6;
String generateHTML() {
String html = R"=====(
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>🍹 Automatic Bartender</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
rel="stylesheet">
<style>
body {
background: linear-gradient(to right, #f7f8f8, #acbb78);
font-family: 'Segoe UI', sans-serif;
padding: 30px 10px;
}
.container {
max-width: 600px;
margin: auto;
background: #ffffffcc;
padding: 30px;
border-radius: 12px;
box-shadow: 0 8px 16px rgba(0,0,0,0.2);
}
.recipe-btn {
margin: 6px 0;
background-color: #f1f2f6;
border: 2px solid #ced6e0;
border-radius: 8px;
padding: 10px;
font-weight: 500;
width: 100%;
}
</style>
<script>
function autoCheck(selectId, checkId) {
document.getElementById(selectId).addEventListener('change', function() {
if (this.value !== "") {
document.getElementById(checkId).checked = true;
}
});
}
window.onload = function() {
autoCheck('v1', 'd1');
autoCheck('v2', 'd2');
autoCheck('v3', 'd3');
};
</script>
</head>
<body>
<div class="container text-center">
<h2>🍹 Automatic Bartender</h2>
<hr>
<form action="/manual" method="GET">
<div class="form-check">
<input class="form-check-input" type="checkbox" name="d1" id="d1">
<label class="form-check-label">Drink 1</label>
<select class="form-select" name="v1" id="v1">
<option value="">Volume</option><option value="50">50ml</option><option
value="100">100ml</option><option value="150">150ml</option><option
value="200">200ml</option>
</select>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" name="d2" id="d2">
<label class="form-check-label">Drink 2</label>
<select class="form-select" name="v2" id="v2">
<option value="">Volume</option><option value="50">50ml</option><option
value="100">100ml</option><option value="150">150ml</option><option
value="200">200ml</option>
</select>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" name="d3" id="d3">
<label class="form-check-label">Drink 3</label>
<select class="form-select" name="v3" id="v3">
<option value="">Volume</option><option value="50">50ml</option><option
value="100">100ml</option><option value="150">150ml</option><option
value="200">200ml</option>
</select>
</div>
<button type="submit" class="btn btn-primary mb-3">Dispense Selected</button>
</form>
<form action="/mocktail"><button class="btn btn-warning mb-4">🍹 Mocktail (All for
1.5s)</button></form>
)=====";
html += R"=====(
<h4>🍸 Recipes</h4>
<form action='/dispenseNow' method='GET'>
<input type='hidden' name='v1' value='50'>
<input type='hidden' name='v2' value='50'>
<input type='hidden' name='v3' value='100'>
<button type='submit' class='btn recipe-btn'>🧡 Sunset Twist (50,50,100)</button>
</form>
<form action='/dispenseNow' method='GET'>
<input type='hidden' name='v1' value='100'>
<input type='hidden' name='v2' value='50'>
<input type='hidden' name='v3' value='50'>
<button type='submit' class='btn recipe-btn'>💚 Zesty Splash (100,50,50)</button>
</form>
<form action='/dispenseNow' method='GET'>
<input type='hidden' name='v1' value='100'>
<input type='hidden' name='v2' value='100'>
<input type='hidden' name='v3' value='50'>
<button type='submit' class='btn recipe-btn'>💛 Golden Rush (100,100,50)</button>
</form>
<form action='/dispenseNow' method='GET'>
<input type='hidden' name='v1' value='75'>
<input type='hidden' name='v2' value='75'>
<input type='hidden' name='v3' value='50'>
<button type='submit' class='btn recipe-btn'>💙 Tropical Rain (75,75,50)</button>
</form>
<form action='/dispenseNow' method='GET'>
<input type='hidden' name='v1' value='50'>
<input type='hidden' name='v2' value='100'>
<input type='hidden' name='v3' value='50'>
<button type='submit' class='btn recipe-btn'>💜 Berry Bomb (50,100,50)</button>
</form>
<form action='/dispenseNow' method='GET'>
<input type='hidden' name='v1' value='80'>
<input type='hidden' name='v2' value='60'>
<input type='hidden' name='v3' value='60'>
<button type='submit' class='btn recipe-btn'>❤️Crimson Bloom (80,60,60)</button>
</form>
)=====";
for (int i = 6; i < recipeCount; i++) {
html += "<form action='/dispenseNow' method='GET'>";
html += "<input type='hidden' name='v1' value='" + String(vol1[i]) + "'>";
html += "<input type='hidden' name='v2' value='" + String(vol2[i]) + "'>";
html += "<input type='hidden' name='v3' value='" + String(vol3[i]) + "'>";
html += "<button type='submit' class='btn recipe-btn'>" + recipeNames[i] + " (" +
String(vol1[i]) + "," + String(vol2[i]) + "," + String(vol3[i]) + ")</button>";
html += "</form>";
}
html += R"=====(
<hr><h5>Add Custom Recipe</h5>
<form action="/addRecipe" method="GET">
<input type="text" name="name" class="form-control mb-2" placeholder="Name (with
emoji)" required>
<div class="row mb-2">
<div class="col"><select name="cv1" class="form-select"><option
value="0">0</option><option value="50">50</option><option
value="100">100</option><option value="150">150</option><option
value="200">200</option></select></div>
<div class="col"><select name="cv2" class="form-select"><option
value="0">0</option><option value="50">50</option><option
value="100">100</option><option value="150">150</option><option
value="200">200</option></select></div>
<div class="col"><select name="cv3" class="form-select"><option
value="0">0</option><option value="50">50</option><option
value="100">100</option><option value="150">150</option><option
value="200">200</option></select></div>
</div>
<button class="btn btn-outline-dark">Save Recipe</button>
</form>
<hr><p class='text-muted'>© 2025 AutoBartender | ESP8266 + Bootstrap</p>
</div>
</body>
</html>
)=====";
return html;
}
void setup() {
Serial.begin(115200);
pinMode(pump1, OUTPUT);
pinMode(pump2, OUTPUT);
pinMode(pump3, OUTPUT);
digitalWrite(pump1, HIGH);
digitalWrite(pump2, HIGH);
digitalWrite(pump3, HIGH);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500); Serial.print(".");
}
Serial.println("\nConnected! IP: " + WiFi.localIP().toString());
server.on("/", []() {
server.send(200, "text/html", generateHTML());
});
server.on("/manual", []() {
bool d1 = server.hasArg("d1");
bool d2 = server.hasArg("d2");
bool d3 = server.hasArg("d3");
int v1 = server.arg("v1").toInt();
int v2 = server.arg("v2").toInt();
int v3 = server.arg("v3").toInt();
int count = d1 + d2 + d3;
int fallback = (count > 0) ? 200 / count : 0;
if (d1 && v1 == 0) v1 = fallback;
if (d2 && v2 == 0) v2 = fallback;
if (d3 && v3 == 0) v3 = fallback;
if (d1) { digitalWrite(pump1, LOW); delay(v1 * 1000 / 50); digitalWrite(pump1,
HIGH); }
if (d2) { digitalWrite(pump2, LOW); delay(v2 * 1000 / 50); digitalWrite(pump2,
HIGH); }
if (d3) { digitalWrite(pump3, LOW); delay(v3 * 1000 / 50); digitalWrite(pump3,
HIGH); }
server.sendHeader("Location", "/"); server.send(303);
});
server.on("/dispenseNow", []() {
int v1 = server.arg("v1").toInt();
int v2 = server.arg("v2").toInt();
int v3 = server.arg("v3").toInt();
if (v1 > 0) { digitalWrite(pump1, LOW); delay(v1 * 1000 / 50); digitalWrite(pump1,
HIGH); }
if (v2 > 0) { digitalWrite(pump2, LOW); delay(v2 * 1000 / 50); digitalWrite(pump2,
HIGH); }
if (v3 > 0) { digitalWrite(pump3, LOW); delay(v3 * 1000 / 50); digitalWrite(pump3,
HIGH); }
server.sendHeader("Location", "/"); server.send(303);
});
server.on("/mocktail", []() {
digitalWrite(pump1, LOW);
digitalWrite(pump2, LOW);
digitalWrite(pump3, LOW);
delay(1500);
digitalWrite(pump1, HIGH);
digitalWrite(pump2, HIGH);
digitalWrite(pump3, HIGH);
server.sendHeader("Location", "/"); server.send(303);
});
server.on("/addRecipe", []() {
if (recipeCount < 10) {
recipeNames[recipeCount] = server.arg("name");
vol1[recipeCount] = server.arg("cv1").toInt();
vol2[recipeCount] = server.arg("cv2").toInt();
vol3[recipeCount] = server.arg("cv3").toInt();
recipeCount++;
}
server.sendHeader("Location", "/"); server.send(303);
});
server.begin();
}
void loop() {
server.handleClient();
}
Screenshots
Conclusion
This project represents a creative and practical implementation of
automation, IoT, and embedded systems through the development of an
Automatic Bartender using Raspberry Pi. By combining hardware control
with a modern, user-friendly web interface, the system successfully
demonstrates how real-world tasks like drink dispensing can be
automated in a clean, precise, and interactive manner.
Through the integration of Python, Flask, and GPIO-based hardware, we
have built a system that not only works efficiently but is also easily
scalable and cost-effective. The ability to customize drink combinations,
save and use recipes, and provide contactless control makes it both
functional and fun — ideal for parties, restaurants, and educational
setups.
Most importantly, this project highlights how even simple components
and technologies, when put together with the right logic and creativity,
can deliver meaningful and impactful solutions. It serves as an excellent
demonstration of embedded innovation and opens doors for further
enhancements such as AI integration, voice control, payment
automation, and more in the future.
Made By
Ashutosh Rao - 1032222566
Om Nimbalkar - 1032222696
Sarvagya - 1032222788