The Duvel Robot

by avdeede in Circuits > Robots

1762 Views, 4 Favorites, 0 Comments

The Duvel Robot

Screen Shot 2017-12-29 at 01.32.54.png
IMG_0215.jpg

Nowadays, it searches to facilitate the life of humans. To obtain it, the human beings try to automate the daily tasks that surround them like: cook, clean, cut vegetables, manage the house, control the car etc.

In this case, the project consists on a robot that is able of pouring beer. It’s a simple activity in our life, but this repetitive process can and should be automated. With this robot, we will be able to effortlessly obtain perfect beers.

It can look like a simple project but there is multitude of difficulties that we are in front of: conceptual design, mechanical design, electronic programming, and control. In addition, to design the robot, it is necessary to bear in mind that the components must be easily available and for what type of beer we want to build the robot for.

There were two options: to realize a general robot for all the beers or to realize a robot for a specific type or brand of beer (since every beer possesses a different bottle shape). As the robot name gives in, we decided to make un custom robot that only works with one kind of beer, but in an elegant fashion. We decided to only work with Duvel, one of Belgium's greatest beer, easily recognisable thanks to its particular bottle shape.

Read this tutorial if you want to make such a robot, and serve perfect Duvels to your friends and family.

Team presentation

This team is composed of Alejandro Tardio Palacios, Astrid Tepie Zepe, Anthony Vande Eede and Elistin Yongmene Foue. We are ULB/VUB/BruFace students, all following the mechatronics course taught by Prof. Bram Vandenborght.

Work organization

To start anything, a brainstorming is necessary. The purpose here is to familiarize with the project state of the art and the already existing beer robots, so that we can inspire our design on it. We decided to split the project in three main parts:

  • Mechanical Design by Elistin and Astrid, with the help of Anthony,
  • Electronics by Alejandro,
  • Programming and Control by Anthony.

This project was realised in about 2 months. To keep everyone updated, team meetings were planned on a weekly basis.

Conceptual Design

26103129_10214298297518886_1622836685_n.jpg
26105245_10214298295918846_355360293_n.jpg
26178965_10214298292078750_1167259437_o.jpg

The images above show some of the early conceptual drawings we used for the Duvel robot.

The aim of this project is to design a robot which is able to raise a glass and a bottle to predefined required positions/angles in order to pour beer from a bottle to a glass. For easier accomplishment of the project the goal of this project were subdivided into several steps listed below:

  1. Raise the glass to a required height and maintain its position.
  2. Raise the bottle to a required height and maintain its position.
  3. Pour beer into the glass
  4. Lower the glass to it’s fixed position.
  5. Lower the bottle to it’s initial position.

The execution of these tasks are dependant on the mechanical and the electronics part. The mechanical design require to take into account:

  1. How will the elevation be done? The easiest way to go is by rotation, as it is the case when pouring beer. The tip of the bottle remaining at it’s position the bottom raise, creates the downward flow of fluid. Rotation motion has to be powered with motors, which means that shafts are required. To decrease the amount of torque whitheld by a shaft, it is better to use a motor per rotation motion.
  2. How will the bottle and glass be held ?The bottle needs to be fixed during elevation, and be raised without falling or slipping.

The overall has to be fixed into a solid, rigid structure, while allowing it s rotation. Several connections will be designed(shaft to holders, shafts to servo) to connect each parts of the design.

Mechanical Design

26177843_10215345621332449_1877058417_o.png
26179263_10215345621292448_1106221097_o.png
26194480_10215346259828411_1306617375_o.png
26142323_10215345668053617_1757095584_o.png
26194534_10215345668013616_262054458_o.png
26133117_1545209985534234_1799767267_n.png
26176163_1545209978867568_730177606_n.png
26176925_1545209958867570_400599071_n.png
26133148_1545209938867572_1516084482_n.png
26134929_1545209915534241_779359856_n.png
26236681_10215350905504550_355007422_o.png
26194347_10215350577176342_1724638566_o.png
26178333_10215350825262544_2000330660_o.png
26178824_10215350944985537_167508756_o.png
Torque.png

Overview

The mechanical design deals with the design and assembly of each individual parts of the design as mentionned before. A 10mm filled shaft will be used along with servo-motors. The choice is servo motors is related to it’s implemented sensors. The choice of the type of servo motors to use is related to price and torque and will be discussed later on. The design consists of several parts:

  1. Bottle holder
  2. Glass holder
  3. Connections
  4. Base structure

Parts design

The parts are designed on Solidworks and will either be laser cutted or 3D printed. The laser cut parts are made of 4mm plexiglass, and the 3D printed parts in PLA. Bolts and nuts used in this project have either an M3 or an M2.5 diameter, with different lengths. For more info on the mechanical parts, please download the final CAD model (available in the last step).

Bottle Holder

The design of the bottle and glass holder is inspired of the 3D puzzle configuration.

The holder has to be strong enough to maintain a 33cl filled duvel glass bottle, into several orientations.

It consist of 16 pieces assembled together with glue. Considering the puzzle configuration, it has to be strong enough.

Glass Holder

This consists of 11 parts encastrated into each other to follow the shape of a duvel glass. It was designed following the bottle holder design.

Connections

All connections are 3D printed in PLA.

  • Shaft to holders: The same configuration were used for both holders. a rectangular shape block with a 9.8 mm hole and four bolts holds for fixations. It consists of two pieces held together by bolts, whose fastening increases the clamping of the holder to the shaft.
  • Shaft to motor: It is generally called a coupler, it is designed as a cylinder which can hold and clamp tightly the shaft halfway through the cylinder. The part of thebase of the cylinder is connecting the shaft to the motor. The base which has holes designed after the servo horn, where the horn fits perfectly. This is accompanied with holes that are pierced and are used for the fastening of the horn to the coupler.
  • Ball bearing mount: A 2 bolts ball bearing mount is designed of ID 10.2mm. The mounts are fixed on the base structure. The ball bearing is prevented from falling or slipping at the upper and lower surfaces of the mount. The mount is designed for the shaft to fit tightly inside, the ball bearing is fixed in it’s position and doesn’t slide or slip.

Base structure

The base is a 5 plated structure with smaller plates for stability. The smaller plates are also used as holders and provide additional support for the holders. Two of the plates are used as a basal support meanwhile the other 3 are held horizontally on the basal support. The Horizontal plates are cutted to have the requied shape and possess holes for both shafts.

Torque measurement

To find the right motor for the filling process, the maximum torque is necessary. Here the approach used is that if the mass of the bottle holder is known, the weight can be deduced using the following formula:

Weight = Mass * Gravity acceleration

Then the torque can be also deduced by multiplying the weight by the distance that separates the center of mass of the holder to the axis of rotation.

But to have a better accuracy on the result, the maximum torque is compute on Solidworks. This software considers the influence of the whole structure, to compute the maximum torque. The results are following: Torque calculations

Degrees of freedom

To have something that can be easily controlled, the bottle axis is separated from the glass axis. This decouple one problem with 2 DOF into 2 single problems each with one DOF. In this case the angular position. This position is encoded by the servo motor, thanks to his integrated position sensor.

This allows to use 2 servos and controlled the position of the glass independently of the position of the bottle.

Finite Element analysis of the structure

Here the goal is to validate our design in term of materials mechanics. To do so, we did the simulation on the critical parts of the structure. By applying the right forces at the right position in Solidworks, it can be observe that the structure has been well design. In fact the maximum displacement is around 1.83e-3 millimeters for the side plate. Here are some graphs, the studying variable is the displacement.

Manufacturing

26178972_10215351874488774_812275967_o.png
26178263_10215351874528775_1523588558_o.png
26178835_10215351874568776_1991849889_o.png
26194715_10215351874608777_571737589_o.png
26195227_10215351874648778_1075341096_o.png
26235848_10215351907169591_1390600695_o.png
26194132_10215351907129590_1201678020_o.png
26179180_10215351907209592_1638270041_o.png
26195015_10215351907289594_2086068485_o.png
26237567_10215351907329595_1595009794_o.png
26179360_10215351944850533_794195982_o.png
26178584_10215351944770531_1250156588_o.png
26194655_10215351944810532_867822384_o.png
26179156_10215351944890534_865974306_o.png
26194359_10215351944730530_1760648511_o.png
26195046_10215352041532950_916307567_o.png
26194677_10215352041692954_167810519_o.png
26236950_10215352041652953_858857373_o.png
26238084_10215352041612952_38698916_o.png
26194456_10215352041852958_1200138487_o.png
26238583_10215352041812957_1689968335_o.png
26235743_10215352042212967_2133233757_o.png
26179445_10215352042412972_1157381295_o.png
26177850_10215352042372971_1884244166_o.png

Now that the final assembly design is available thanks to solids works, it is possible to manufacture the Duvel robot. Two types of part can be distinguished:

  • The ones which are cut by laser
  • The ones which are printed by Ultimaker (3D printer).

The ball bearing mounting, the shaft to servo couplers, and the shaft holder are printed in 3D and the rest of the parts are cut using the FabLab Laser. More information can be found in the design of the part section.

Assembly process

Since the different parts should be cut with the laser which have a good accuracy, the mechanical design need also to be manage such as the assembly process can evolve rapidly.

How? By including directly on the design, the space for the bolts in each plate instead of cutting the sheet and then wear through with a drill machine.

Bottle Holder Assembly

The different parts of the bottle and glass holder are glues together. As a refresher, the design of the holders is inspired by the 3D puzzle and the main purpose is that the curve part need to fit as much as possible the bottle/glass and the whole design need to be strong enough. That is why, there are 4 combs that are added (2 by side) to increase the stiffness of the holders.Here are the different step of the holders assembly.

Glass Holder assembly

The different steps are :

Render of the glass Holder

Holder and the shaft.

The shaft holder helps here to assemble these two parts. But to be strong enough, there are 4 holes on the holder and the shaft holder that allows us to put a bolt (male and female) on it (see figures below).

The same approach is used for the bottle holder and the shaft.

The servo and the shaft.

The shaft and the servo can be easily joined together, thanks to the 3D printed shaft coupler. The following figure illustrates how to do it in practice.

The Arduino on the bottom plate.

The arduino is fixed on the bottom plate of the base using arduino spacers, as shown in this figure.

The base assembly
Here are the different steps to assemble the base of the robot.

We used the bolts to fixed all this parts as shown in the figure.

Electronics

Arduino_Uno_-_R3.jpg
71IgKKFHYwL._SX522_.jpg
F0594628-01.jpg
F0489021-01.jpg
Y1612428-01.jpg
bb.png
IMG_0193.jpg
IMG_0199.jpg
DuvelRobotProto2_pb.png
UNADJUSTEDNONRAW_thumb_1d27.jpg

Now that the mechanical design has been completed, it is time to take care of the electronics. We will first select each electronics component to comply with our constraints and then assemble them together.

Components selection

The brain – Microcontroller

The processing power of the Duvel Robot can be supplied by either a Raspberry Pi or an Arduino board. The task we have to accomplish being very simple and repetitive, we decided to use the simple Arduino Uno.

SEE ARDUINO PIC (1)

The muscles – Motors

We need to rotate both the glass and the bottle holders to specific angles to perform a foamless filling. To do this, two solutions could be used: servomotors or DC motors with encoder. Since the required torque is not to high, we chose a high torque hobby servomotor: the LewanSoul LD-20MG.

SEE SERVO PIC (2)

This servomotor has the following characteristics:

  • Weight: 65g(2.32OZ)
  • Dimension: 1.57*0.78*1.59inch
  • Speed: 0.16sec/60°(7.4V)
  • Torque: 20 kg·cm (277.6 oz/in) @6.6V
  • Accuracy: 0.3°
  • Working Voltage: 6-7.4V
  • Min Working Current: 1-1.5A
  • No-load Current: 100mA

We can see that this servo has a stall torque of 20 kg·cm, which corresponds to 1.96 Nm, which is more than two times the max needed torque (0.67 Nm). Such a high torque comes with some disadvantages: the servo box is a little larger than standard hobby servos, and it draws electricity at at least 6V and 1A when functioning.

The lungs – Power supply

Since the two servomotors require between 1A and 1.5A each, we need an additional power supply. 4 AA rechargeable batteries can be used and linked in series with a battery holder and a connector in order to get a 6V power supply.

SEE BATTERY HOLDER PIC (3)

SEE BATTERY CONNECTOR PIC (4)

Of course, the Arduino Uno board must also be powered. For that matter, a simple USB-B to USB-A and an USB-A power adapter can be used.

The senses – Switches

Three switches are needed: two to detect if the glass and the bottle are indeed on their holder, and one to start the filling process. The easiest way to detect the bottle and glass presence is to use snap action micro switches with lever.

SEE SWITCH PIC (5)

To reduce the number of different unique parts, we can use such a switch for the start button too.

Electronics assembly

Schematics have been made using Fritzing.

Phase 1 – Breadboard

The first phase consists in assembling all the components on a breadboard with plug and play cables to test them and the code.

Filename: Duvel-Breadboard.fzz

SEE BREADBOARD SCHEMATIC (6)

SEE BREADBOARD PIC 1 (7)

SEE BREADBOARD PIC 2 (8)

The red cables are used to transmit power, the blue and yellow ones to transmit some signal, and the black ones are the ground cables.

For the servos, the white cables must be connected to digital pins 5 and 6 (resp. for the glass and the bottle servos), the red cables must be connected to the red cable of the battery power supply, and the black ones to the ground.

For the switches, the blue cables must be connected to digital pins 2, 3 and 4 (resp. for the glass, the bottle and the start switches) and the red cables must be connected to the 5V built in power supply of the Arduino.

For the external battery power supply, the red cable must be connected to the servos red cables, and the black one to the ground. Note that the ground of the Arduino and the power supply must be connected together.

Phase 2 – Protoboard or soldered cables

Once all components have been tested (see next step), it's time to make a protoboard, i.e. a prototype PCB of our electronics assembly. The idea is to compactly solder all components together on a board that can be stacked on the Arduino.

Filename: Duvel-Protoboard.fzz

SEE PROTOBOARD SCHEMATIC (9)

On the Duvel Robot however, all components are placed away from the Arduino: the servos are attached to their respective shafts, the switches are attached to different parts of the structure and the battery pack must be amovible so batteries can be easily charged. For this reason, another approach can be used: ditch the protoboard and replace it by cables only. In our case, the protoboard would indeed only serve as a connection between all components.

SEE SOLDERED CABLES PIC (10)

Programming

Screen Shot 2017-12-28 at 23.54.55.png
Screen Shot 2017-12-29 at 00.02.22.png
Screen Shot 2017-12-29 at 00.03.43.png
Screen Shot 2017-12-29 at 00.05.49.png
Screen Shot 2017-12-29 at 00.06.35.png
Screen Shot 2017-12-28 at 23.54.55 copy.png

The programming step consists in thoroughly testing each and every component and then develop and code an algorithm to articulate all components together to reach the goal of pouring a perfect Duvel.

Components testing

Each component must be independently tested to make sure they are not damaged and that they are compatible with the code. Upload the following snippets of code into the Arduino and display the Serial monitor to check if your components behave as expected.

All the following scripts basically follow the same structure. It starts with importing the required libraries (only in the servo case), then it sets the constants that will be used (such as preset positions and values) and the connections by specifying analog and digital pin numbers. The setup attaches all pins numbers to their hardware components and initiates the Serial communication. Finally, the loop performs the core of the test. As usual, setup() is only run once, and loop() run in a loop once the setup is finished.

Servomotors

This code will rotate the servo connected on digital pin 5. To test the servo connected on digital pin 6, simply change the mainServoPin value to 6 and re-upload the code on the Arduino. The servos should rotate in a loop, first counter clockwise, then clockwise, and finally back to its center position, with a delay of 2 seconds between each rotation.

Filename: duvelbot_servo_test.ino
#include <Servo.h>

//----- Digital Pins -----
const int mainServoPin = 5;

//----- Servomotors -----
Servo mainServo;

void setup() {
  Serial.begin(9600);
  Serial.println("Starting experiment!");
  mainServo.attach(mainServoPin); // Associate servo to pin
  Serial.println("Setup finished!");
  mainServo.write(0); // Impose initial position to servo
}

void loop() {
  mainServo.write(-180); // Rotate servo counter clockwise
  delay(2000); // Wait 2 seconds
  mainServo.write(0); // Rotate servo clockwise
  delay(2000);
  mainServo.write(-90); // Rotate servo to center
  delay(2000); 
}

LED

The following code uses the built-in LED (which corresponds to digital pin 13). Once the code is running, the LED should be blinking every second, and you should see "*** BLINKING ***" on the Serial Monitor every time the LED blinks.

Filename: duvelbot_led_test.ino
//----- Digital Pins -----
const int ledPin = 13;

void setup() {
  Serial.begin(9600);
  printMessage("Starting experiment!");
  pinMode(ledPin, OUTPUT); // Associate LED to pin as an actuator
  printMessage("Setup finished!");
}

void loop() {
  Serial.println("*** BLINKING ***");
  digitalWrite(ledPin, HIGH); // Turn the LED on
  delay(500); // Wait 0.5 second
  digitalWrite(ledPin, LOW); // Turn the LED off<br>
  delay(500);
}

Switches

This code tests all 3 switches at the same time. It should show a 0 next to each open switch and a 1 next to each closed ones.

Filename: duvelbot_switch_test.ino
//----- Digital Pins -----
const int switchPin2 = 2;
const int switchPin3 = 3;
const int switchPin4 = 4;

//----- Readings -----
int switchState2 = 0;
int switchState3 = 0;
int switchState4 = 0;

void setup() {
  Serial.begin(9600);
  Serial.println("Starting experiment!");
  pinMode(switchPin2, INPUT); // Associate switch to pin as a sensor
  pinMode(switchPin3, INPUT);
  pinMode(switchPin4, INPUT);
  Serial.println("Setup finished!");
}

void loop() {
  switchState2 = digitalRead(switchPin2); // Read switch state
  switchState3 = digitalRead(switchPin3);
  switchState4 = digitalRead(switchPin4);
  Serial.println("Switch 2: " + String(switchState2) + " - Switch 3: " + String(switchState3) + " - Switch 4: " + String(switchState4));
}

Algorithm

Filename: duvelbot_final.ino

Now that every component has been tested and validated, it is time to talk about the algorithm that will be used for the pouring of the beer. Let's dig right in!

The first portion of the code sets all the constants, such as all the different needed angles for the glass and the bottle holders and the digital pin numbers for the switches (2, 3, 4), both the servos (5, 6) and the built-in LED (13). The servos objects are initiated and all reading states are set to 0.

#include <Servo.h>

//----- Constants -----
const int glassStartingPos = 180;
const int glassPos1 = 135;
const int glassPos2 = 160;
const int bottleStartingPos = 0;
const int bottlePos1 = 70;
const int bottlePos2 = 110;
const int bottlePos3 = 120;

//----- Analog Pins -----

//----- Digital Pins -----
const int glassButtonPin = 2;
const int bottleButtonPin = 3;
const int powerButtonPin = 4;
const int glassServoPin = 5;
const int bottleServoPin = 6;
const int ledPin = 13;

//----- Servomotors -----
Servo glassServo;
Servo bottleServo;

//----- Readings -----
int state = 0;
int glassButtonState = 0;
int bottleButtonState = 0;
int powerButtonState = 0;
int glassCurrentPos = glassStartingPos;
int bottleCurrentPos = bottleStartingPos; 

The setup function enables the Serial communication, and links the 3 switches, the LED and the servos to their associated pins.

void setup() {
  Serial.begin(9600);
  printMessage("Starting experiment!");
  
  pinMode(glassButtonPin, INPUT);
  pinMode(bottleButtonPin, INPUT);
  pinMode(powerButtonPin, INPUT);
  pinMode(ledPin, OUTPUT);
  
  glassServo.attach(glassServoPin);
  bottleServo.attach(bottleServoPin);
  printMessage("Setup finished!");
} 

The loop function first retrieves the last state of each switch, and then reacts accordingly to the current state of the system.

void loop() {
  glassButtonState = digitalRead(glassButtonPin);
  bottleButtonState = digitalRead(bottleButtonPin);
  powerButtonState = digitalRead(powerButtonPin);
  
  switch (state) {
    // Case based reasoning here...
  }
} 

Here is a description of all possible states:

  • State 0 – Waiting for user input: the robot waits until it senses the presence of a bottle and a beer and that the start/power button has been pressed. Once it is the case, the system state value becomes 1 and we go to the next state.

SEE PIC (1)

    case 0: // Waiting for user input (power button)
      {
        printMessage("User inputs: " + String(powerButtonState) + "-" + String(glassButtonState) + "-" + String(bottleButtonState));
        glassServo.write(glassStartingPos);
        bottleServo.write(bottleStartingPos);
        
        if (powerButtonState == HIGH && glassButtonState == HIGH && bottleButtonState == HIGH) {
          printMessage("Starting experiment!");
          state += 1;
          blinkStatus();
        }
      }
      break;
  • State 1 – Moving glass and bottle position to glassPos1 and bottlePos1: the glass holder rotates to its position 1 (it rotates clockwise of 45 degrees) and then the bottle holder rotates to its position 1 (it rotates counter clockwise of 70 degrees).

SEE PIC (2)

    case 1: // Moving glass and bottle to position glassPos1 and bottlePos1
      {
        rotateServo(glassServo, glassCurrentPos, glassStartingPos, glassPos1, 0, "glass");
        printMessage("Glass at glass position 1!");
        
        rotateServo(bottleServo, bottleCurrentPos, bottleStartingPos, bottlePos1, 0, "bottle");
        printMessage("Bottle at bottle position 1!");
        
        state += 1;
        blinkStatus();
      }
      break;
  • State 2 – Pour beer in 7 small steps: The bottle quickly rotates clockwise of 40 degrees (position 2), then directly back to position 1. It repeats these rotations for 7 times with a delay of 15 seconds between each repetition, to make sure the beer in the glass has some time to unfoam.

SEE PIC (3)

    case 2: // Pour beer in 7 small steps
      {
        for (int i = 0; i < 7; i++) {
          rotateServo(bottleServo, bottleCurrentPos, bottlePos1, bottlePos2, 0, "bottle");
          rotateServo(bottleServo, bottleCurrentPos, bottlePos2, bottlePos1, 0, "bottle");
          printMessage("Waiting 15 seconds to unfoam... Step " + String(i + 1) + " of 7.");
          delay(15000);
        }
        rotateServo(bottleServo, bottleCurrentPos, bottlePos1, bottlePos2, 0, "bottle");
  
        state += 1;
        blinkStatus();
      }
      break;
  • State 3 – Move glass to glassPos2: The glass rotates clockwise of 25 degrees (position 2) to allow the bottle to reach its final position to end the filling process.

SEE PIC (4)

    case 3: // Move glass to glassPos2
      {
        rotateServo(glassServo, glassCurrentPos, glassPos1, glassPos2, 5, "glass");
        printMessage("Glass at glass position 2!");
	state += 1;
      }
      break;
  • State 4 – Move glass to initial position and bottle to bottlePos3: The bottle rotates clockwise of 10 degrees to reach its final filling position, and then the glass slowly goes back to its initial position, so no liquid is lost out of the glass

SEE PIC (5)

    case 4: // Move glass to initial position and bottle to bottlePos3
      {
        rotateServo(bottleServo, bottleCurrentPos, bottlePos2, bottlePos3, 0, "bottle");
        printMessage("Bottle at bottle position 3!");
        
        rotateServo(glassServo, glassCurrentPos, glassPos2, glassStartingPos, 5, "glass");
        printMessage("Glass at starting position!");
	delay(5000);
        
        state += 1;
      }
      break;
  • State 5 – Move bottle to initial position: Finally, the empty bottle goes back to its final position. The robot waits for 20 seconds until it goes back to state 0 so the user has time to unload the glass and the bottle.

SEE PIC (6)

    case 5: // Move bottle to initial position
      {        
        rotateServo(bottleServo, bottleCurrentPos, bottlePos3, bottleStartingPos, 0, "bottle");
        printMessage("Bottle at starting position!");
	printMessage("ENJOY YOUR DUVEL!");
        printMessage("Please wait for 20 seconds until pouring a new beer...");
        state = 0;
        delay(20000);
      }
      break;

Almost every state calls the rotateServo() function, which is detailed below. It takes into argument:

  1. servo: the servo object that must be rotated
  2. currentPos: the current position of the servo
  3. initPos: the position/rotation/angle at which the rotation should start
  4. finalPos: the position/rotation/angle at which the rotation should start
  5. duration: the required duration of the movement. If it is equal to zero, the duration will be 15 ms times the angle in degrees
  6. label: the name of the servo that should be displayed in Serial communication

This function computes the delay that the Arduino should wait between each degree of rotation based on the requested duration and the total angle (which is equal to abs(finalPos-initPos)). If duration = 0, the delay is 15 ms by default. Then it rotates the servo degree by degree with a for loop (the direction is given by comparing the final and initial positions).

void rotateServo(Servo servo, float currentPos, float initPos, float finalPos, float duration, String label) { // Rotates a servo so it reaches its final destination in a specified duration
  int steps = abs(finalPos - initPos); // Computes the amount of steps of the rotation (1 deg per step)
  int tempDelay = ((duration == 0) ? 15 : 1000 * duration / steps); // Computes the delay between steps to match the specified duration. If duration = 0, the time delay is 15 ms
  
  if (initPos < finalPos) { // If rotating clockwise...
    for (currentPos = initPos; currentPos <= finalPos; currentPos += 1) {
      servo.write(currentPos);
      printMessage("Current " + label + " position: " + String(currentPos));
      delay(tempDelay);
    }
  }
  else if (initPos > finalPos) { // If rotating counter clockwise...
    for (currentPos = initPos; currentPos >= finalPos; currentPos -= 1) {
      servo.write(currentPos);
      printMessage("Current " + label + " position: " + String(currentPos));
      delay(tempDelay);
    }
  }
} 

Finally, a short explanation on the last two functions of the code:

  • blinkStatus(): This function is used to visualise the current state. When called, it blinks the LED as many times as the current state. Just like in the LED test function, it blinks every second for 0.5 second.
  • printMessage(): This very simple function displays the number of the current state, followed by the message that was provided in argument.
void blinkStatus() { // Blinks the built in LED according to the current state
  Serial.println("*** BLINKING ***");
  for (int i = 0; i <= state; i += 1) {
    digitalWrite(ledPin, HIGH);
    delay(500);
    digitalWrite(ledPin, LOW);
    delay(500);
  }
}

void printMessage(String message) { // Sends to serial communication <state>". "<message>
  Serial.print(state);
  Serial.print(". ");
  Serial.println(message);
}

Result

IMG_0215.jpg
IMG_0214.jpg
IMG_0209.jpg
IMG_0210.jpg
IMG_0211.jpg
IMG_0212.jpg
IMG_0213.jpg
Screen Shot 2017-12-29 at 01.32.54.png
Screen Shot 2017-12-29 at 01.32.40.png
Screen Shot 2017-12-29 at 01.31.40.png
Screen Shot 2017-12-29 at 01.32.07.png
Screen Shot 2017-12-29 at 01.31.10.png
COSTS.PNG
Duvel Robot - Test with water
Duvel Robot - Test with old beer
Duvel Robot - Test with fresh beer (1/2)
Duvel Robot - Test with fresh beer (2/2)

Final Prototype

You can download our CAD files in .STEP or Solidworks format.

Filename: Duvel-Robot-Final.STEP
Filename: Duvel-Robot-Final.zip (Solidworks)

SEE VIDEO "Duvel Robot - Test with water"

SEE VIDEO "Duvel Robot - Test with old beer"

SEE VIDEO "Duvel Robot - Test with fresh beer (1/2)"

SEE VIDEO "Duvel Robot - Test with fresh beer (2/2)"

Cost breakdown

In this part of the tutorial, a table appears where there are gathered all the components that are used in the project and his respective cost:

SEE COST TABLE

It is necessary to explain some aspects in the calculation of the price of some components.

In first twelve components, the price that appears is the unitary price of every component multiplied by the number of used components. But, the components 13 (Structure of plexiglass) and 14 (Pieces of plastic), are calculated in a different way. These components have been obtained by laser cutting and 3D printing, as it explains in this tutorial. For this reason, to calculate the price of these components, it is necessary to calculate the price of the base material.

In case of the structure of plexiglass, as it is commented in this tutorial, the pieces are obtained cutting with laser a plate of plexiglass. For this project, 0,45 m2 were used of plexiglass and the price of the plexiglass is 45 €/m2. In conclusion, the final price is 20,25 €.

In case of the pieces of plastic, as it is commented in this tutorial, the pieces are done by a printer 3D that uses a roll of thread of plastic. The price of 1 roll of 1 Kg is of 20 €. The pieces that have been printed, approximately, weigh 250 g. Therefore, the final price of the pieces printed is of 5 €.

Problems encountered

The shaft couplers which didn’t clamp the shaft very well. This is because the
inner surface was smooth (PLA material used for the 3D print), and the shaft also. So, we start first by reducing the inner diameter, it doesn’t work. We add then a tape to have a better friction, that also didn’t work due to the high weight and torque necessary. So finally, we glue the shaft and the coupler with epoxy and it works.

The axis had another problem. The problem was that the dimension of the diameter along the length was not constant, was changing slightly. This was doing that depending on what part of the axis was in use, the bearings were fitting well or not. To place in the correct position the bearings that were not fitting good, we had to use lubricant and the force. But another problem appeared. Since we use the force, there was danger of which some piece was breaking. Ultimately, this happened. Due to the great force that we had to do to place the bearings, some pieces broke and we had to return to make them.

The selection of the servomotors was another problem. The first thing that we did, was to calculate the static torque that would have the project. With the result that we obtained, we did the selection of the servomotors that we were going to use and bought them. When the servomotors came, we tested and verified that they did not have the necessary force. We re-did the calculations and realized that we had to use the dynamic torque to select the servomotors. We had to buy new others and these yes that worked.

Further improvements

This project is designed specifically for a Duvel bottle and a Duvel glass. An important improvement might be to realize different supports that would be adaptable to different types of bottles and glasses.

To improve the electronics and the appearance of the project, we might design a real PCB in which we would weld the different components. A LCD to be able to monitor and control the robot would be another possible improvement that might be done.

The connections between the servomotors and the axes it is different of the things might be improved. The problem is not the design of the piece, but the connection between the piece and the axis. Due to the smooth finish of the axis and the plastic 3d printed pieces, the surfaces slip. To improve it, we might have designed the piece of connection with some cracks and have added to the axes wedges to achieve a mechanical connection.