Skip to content

AutoBar

Automatic Drink Dispenser

AutoBar

Automated Drink Dispenser

Specifications

Fully automated drink dispenser was designed to serve drinks, elaborated from a simple wall mounted manual dispenser.

Only two motors are required, one servo motor  for the raft linear translation, and one stepmotor, for the serving mechanism, integrated to the raft.

Except the wall mount, the system was developed 100% in house. The spare part was concepted on a CAO software (Fusion 360) and 3D Printed on an AlfawiseU30.

Design

Invented from scratch, salvage materials were used to build the structure of the prototype. The attention was fundamentaly focused on the technicality of the prototype, rather than aesthetic aspect.

The number of motors was restricted to the minimize the cost of the finished good and its environmental impact. This project was meant to initiate the learning of Arduino & 3D Printing.

There are several rooms for improvement but the system was a succeful proof of concept.

0
Hours of conception
0
Hours of 3D Print
0
Hours of Coding
0 +
Cocktails served

Conception

Raft V2
Raft V1
Transmission Mount V1

Code

// Creative Commons - www.ben-amar.com - 2021
// This Code was written for Ben-Amar.com under CC license: BY-NC-SA  (Attribution Mandatory, NonCommercial & ShareAlike)
// You must you credit "Ben-Amar.com" to remix, adapt, and build upon your work non-commercially. You must license your new creations under the identical terms.

//====================================================
//================================ BIBLIOTHEQUES =====
//====================================================

#include <Servo.h>    //Import Bibliotheque for "Servomotor"

//====================================================
//=============== OBJETS & VARIABLES DECLARATION =====
//====================================================

Servo leServo;        // Define "Servomotor" name

//=====================================================
//============================== DEFINE CONSTANTS =====
//=====================================================

int RED = 22;       // RGB Led Pin Red (Can be declare like this: #define RED 22)
int GREEN = 23;     // RGB Led Pin Green (Can be declare like this:#define GREEN 23)
int BLUE = 24;      // RGB Led Pin Blue (Can be declare like this:#define BLUE 24)

const int trigPin = 52;      // Trigger Pin of Ultrasonic Sensor
const int echoPin = 53;      // Echo Pin of Ultrasonic Sensor
const int stepPin = 4;       // StepPin A4988 for Stepper Motor
const int dirPin = 7;        // DirPin A4988 for Stepper Motor
const int enPin = 8;         // Enable pin A4988 for Stepper (Low = enable)
const int pinFc = 50;        // End Switch Pin (Fin de course)Trigger the position of the raft when back home
const int pinServo = 45;     // variable pour stocker le pin pour la commande

//=====================================================
//============================== DEFINE VARIABLES =====
//=====================================================

int stateFc;            // Read the value of FC PIN, set as high to ensure the
int RaftFound;          // Variable for "Raft Back at Home"
int cumul = 0;          // Valeur cumul pour le temps d'appui et incrementation si besoin
long duration;          //
int distance;           //


//========================================================
//======================================== VOID SETUP ====
//========================================================

void setup() {
  
  // ---------------------------
  // ------ Define PinMode -----
  // ---------------------------
  
  pinMode(RED, OUTPUT);
  pinMode(GREEN, OUTPUT);
  pinMode(BLUE, OUTPUT);
  pinMode(stepPin, OUTPUT);
  pinMode(dirPin, OUTPUT);
  pinMode(pinFc, INPUT_PULLUP);           // Sets the Endswitch as Input Pullup
  pinMode(trigPin, OUTPUT);               // Sets the trigPin as an Output
  pinMode(echoPin, INPUT);                // Sets the echoPin as an Input
  pinMode(enPin,OUTPUT);

  // ---------------------------
  // ------ Attach Object  -----
  // ---------------------------

  leServo.attach(pinServo);                 // Attache the Servo to the Pin on the Arduino (Constant)

  // ---------------------------
  // ---- Init S. Monitor  -----
  // ---------------------------

  Serial.begin(9600);                       // Start Serial Monitor
  Serial.println("Initialisation...");      // Display Text 
  Serial.println("");                       // Display Text 
  Serial.print("FC State : ");              // Display Text 


  // ---------------------------
  // ----- Read Var Value  -----
  // ---------------------------
  
  stateFc = digitalRead(pinFc);             // Read the Value of the EndSwitch
  Serial.println(digitalRead(pinFc));       // Display the Value on Serial Monitor

  
  // ---------------------------
  // ----- Servo Position  -----
  // ---------------------------
  
  leServo.write(0);                       // Go to Position 0 (Minimum)
  delay(2000);                            // Wait
  leServo.write(180);                     // Go to Position 180 (Maximum)
  delay(1000);                            // Wait

  digitalWrite(RED, HIGH);                // Set RGB led (Raft) Color
  digitalWrite(GREEN, HIGH);              // Set RGB led (Raft) Color 
  digitalWrite(BLUE, HIGH);               // Set RGB led (Raft) Color
  digitalWrite(enPin,LOW);                // Enable the Motor

  // ---------------------------
  // ----- Bring raft Back -----
  // ---------------------------
   
  raftohome ();                           // Call Function "raftohome" 
  delay(1000);                            // Wait

  // ---------------------------
  // ----- Set Raft Color  -----
  // ---------------------------
  
  setColor(0, 255, 0);                    // Call function "setColor" & Green Means Raft Ready!
  
}

//========================================================
//========================================= VOID LOOP ====
//========================================================

void loop() {

  // ---------------------------
  // --- Detect Glass On Raft --
  // ---------------------------
  
  digitalWrite(trigPin, LOW);             // Ensure trigpin was Low before action
  digitalWrite(trigPin, HIGH);            // Sets the trigPin on HIGH state 
  delayMicroseconds(10);                  // for 10 micro seconds
  digitalWrite(trigPin, LOW);             // Set TrigPin Back to Low
  duration = pulseIn(echoPin, HIGH);      // Reads the echoPin, returns the sound wave travel time in microseconds
  distance = duration * 0.034 / 2;        // Calculating the distance   
  Serial.print("Distance: ");             // Prints the distance on the Serial Monitor
  Serial.println(distance);               // Prints the distance on the Serial Monitor

  // ---------------------------
  // - Action (Glass Detected) -
  // ---------------------------

  if (distance <= 7) {                    // If Distance < 7cm it's due to the presence of a glass
    delay(2000);                          // Wait (People Removing their hand after putting the glass)
    Serial.println("Go to Position 1");   // Print Info on S. Monitor
    digitalWrite(dirPin, HIGH);           // Enables the motor to move in a particular direction    
    setColor(255, 0, 0);                  // Call function "setColor" & Set Raft RGB Color to: Movement color
    for (int x = 0; x < 295; x++) {       // Makes x pulses for making one full cycle rotation
      digitalWrite(stepPin, HIGH);        // Motor Move One Step
      delayMicroseconds(1500);            // Change the time to Change the speed
      digitalWrite(stepPin, LOW);         // Motor Stop Step Completed
      delayMicroseconds(1500);            // Change the time to Change the speed
    }
    setColor(0, 255, 0);                  // Call function "setColor" & Set Raft RGB Color to: Serving color
    leServo.write(0);                     // Servo Pulls the Serving Mechanism
    delay(5000);                          // Wait service to be finished
    leServo.write(180);                   // Servo Releases the Serving Mechanism
    delay(1000);                          // Wait for last drop    

    Serial.println("Go to Position 2");
    digitalWrite(dirPin, HIGH);           // Enables the motor to move in a particular direction    
    setColor(255, 0, 0);                  // Call function "setColor" & Set Raft RGB Color to: Movement color
    for (int x = 0; x < 495; x++) {       // Makes x pulses for making one full cycle rotation
      digitalWrite(stepPin, HIGH);        // Motor Move One Step
      delayMicroseconds(1500);            // Change the time to Change the speed
      digitalWrite(stepPin, LOW);         // Motor Stop Step Completed
      delayMicroseconds(1500);            // Change the time to Change the speed
    }
    setColor(0, 255, 0);                  // Call function "setColor" & Set Raft RGB Color to: Serving color
    leServo.write(0);                     // Servo Pulls the Serving Mechanism
    delay(5000);                          // Wait service to be finished
    leServo.write(180);                   // Servo Releases the Serving Mechanism
    delay(1000);                          // Wait for last drop    

    Serial.println("Go to Position 3");
    digitalWrite(dirPin, HIGH);           // Enables the motor to move in a particular direction    
    setColor(255, 0, 0);                  // Call function "setColor" & Set Raft RGB Color to: Movement color
    for (int x = 0; x < 400; x++) {       // Makes x pulses for making one full cycle rotation
      digitalWrite(stepPin, HIGH);        // Motor Move One Step
      delayMicroseconds(1500);            // Change the time to Change the speed
      digitalWrite(stepPin, LOW);         // Motor Stop Step Completed
      delayMicroseconds(1500);            // Change the time to Change the speed
    }
    setColor(0, 255, 0);                  // Call function "setColor" & Set Raft RGB Color to: Serving color
    leServo.write(0);                     // Servo Pulls the Serving Mechanism
    delay(5000);                          // Wait service to be finished
    leServo.write(180);                   // Servo Releases the Serving Mechanism
    delay(1000);                          // Wait for last drop   

    Serial.println("Go to Position 4");
    digitalWrite(dirPin, HIGH);           // Enables the motor to move in a particular direction    
    setColor(255, 0, 0);                  // Call function "setColor" & Set Raft RGB Color to: Movement color
    for (int x = 0; x < 505; x++) {       // Makes x pulses for making one full cycle rotation
      digitalWrite(stepPin, HIGH);        // Motor Move One Step
      delayMicroseconds(1500);            // Change the time to Change the speed
      digitalWrite(stepPin, LOW);         // Motor Stop Step Completed
      delayMicroseconds(1500);            // Change the time to Change the speed
    }
    setColor(0, 255, 0);                  // Call function "setColor" & Set Raft RGB Color to: Serving color
    leServo.write(0);                     // Servo Pulls the Serving Mechanism
    delay(5000);                          // Wait service to be finished
    leServo.write(180);                   // Servo Releases the Serving Mechanism
    delay(1000);                          // Wait for last drop   

    raftohome ();                         // Call Function "raftohome"
    
    for (int x = 0; x < 100; x++) {       // Raft Blink: Drink it Ready 
      setColor(0, 255, 0);                // RGB Green Color       
      delay(100);                         // Wait
      setColor(0, 0, 0); // Green Color   // RGB Off
      delay(100);                         // Wait
    }
  }
}

//========================================================
//================================== Void raftohome ======
//========================================================

/* Function to Bring Raft back to Initial position - Before serving*/

void raftohome () {
  
  stateFc = digitalRead(pinFc);           // Read State of Endswitch (Fin de course)
  RaftFound = false;                      // Set "RaftFound" statement as False
  Serial.print("FC State : ");            // Display text on S. Monitor
  Serial.println(digitalRead(pinFc));     // Display pinFc Value on S. Monitor
  Serial.print("Found Raft?  ");          // Display text on S. Monitor
  Serial.println(RaftFound);              // Display the Value of the RaftFound Variable (Set to False)

  // ---------------------------
  // -- Action bring raft back -
  // ---------------------------
  
  if (RaftFound == false && stateFc == LOW) {           // If with 2 Conditions
    Serial.println("Where is the Raft");                // Display Text on S. Monitor
    setColor(150, 0, 255); // Purple Color              // Set Raft to Raft Search Color
    digitalWrite(dirPin, LOW);                          // set the motor to rotate in "Back Home" Direction
    while (RaftFound == false && stateFc == LOW) {      // Start While (with 2 statements) 
      digitalWrite(stepPin, HIGH);                      // Motor Move One Step
      delayMicroseconds(1500);                          // Change the time to Change the speed
      digitalWrite(stepPin, LOW);                       // Motor Stop Step Completed
      delayMicroseconds(1500);                          // Change the time to Change the speed
      stateFc = digitalRead(pinFc);                     // Read the value of the 
    }                                                   // End While
    RaftFound = true;                                   // If pinFC = HIGH then Raft Found = True ==> raft at Init Position
    Serial.println("Raft is Home, Ready to Work");      // Display Text on S. Monitor
    setColor(0, 255, 0);                                // Call function "setColor" Set RGB raft To "Ready" Color
  }
}

//========================================================
//================================== Void raftohome ======
//========================================================

/* Function to set the color of the RGB led of the Raft*/

void setColor(int red, int green, int blue) {
  analogWrite(RED, red);
  analogWrite(GREEN, green);
  analogWrite(BLUE, blue);

} 

The system has shown its reliability over few events.  First project realised from my 3DPrinter, I was surprised how resilient printed parts were and overall how the device has functioned  flawlessly for about 1 and a half year. Experiencing few problem with the transmission system over time, I have decided to shut it down until I have time to develop an improved version.

I imagined this project just as a way to learn more about the combination of 3D print, CAD, Arduino and coding. But experiencing the confort of the automated drink dispenser over few gatherings I found it more practical than expected and I am thinking to create a Version 2.0 in the future, with few improvements:

  1. Boxed, cleaner design
  2. Include a display & buttons to choose over different cocktails
  3. Add some extra drinks options with taps & Peristaltic pumps
  4. coat the 3D printed part to increase their lifespan
  5. Review and improve the design of all necessary parts