DEV Community

Simon Aubury
Simon Aubury

Posted on

๐Ÿน Cocktail Pi

Originally published Mon May 18 2020 at https://medium.com/@simon.aubury/cocktail-pi-6cc05ce7804c

๐Ÿน Cocktail Pi

Cocktails based on your mood created by a Raspberry Pi bartender. Drinks are selected based on your emotion and multilingual voice prompts let you know when your drink is available.

How to build a fully automated home build cocktail maker. Code available at **https://github.com/saubury/cocktail-pi**๐Ÿธ

Pumps

I used 4 peristaltic pumps to provide a โ€œfood safeโ€ way to pump the liquids from the drink bottles. These pumps provide a steady rate of flow of liquids when powered. By carefully timing the โ€œonโ€ time for the pump I can precisely deliver the ideal amount of spirits or mixers for the perfect ๐Ÿธ

A quick search on AliExpressA quick search on AliExpress

Pumps โ€” straight from the postPumps โ€” straight from the post

The pumps are mounted on a basic wooden frame higher than the tallest bottle. My children helped to build the frame, labelling and installing the pumps.

The important task of adding labels to pumpsThe important task of adding labels to pumps

A view from the rear show the placement of pumps and liquids. A manual electrical switch allow the pumps to be run independently from the Raspberry Pi (helpful for cleaning).

Rear view of Cocktail makerRear view of Cocktail maker

The pumps use 12 volt motors. To operate them via the Raspberry Pi I used a 4 Channel 12V Relay Module. This allows the pumps to be switched on and off independently with the 5 volt signals from the GPIO pins of the Raspberry Pi.

Relay boardRelay board

The Raspberry Pi is mounted with the relay board. The relays switch 12 volt power on and off for the pump motors. The signals for the relay board are taken directly from the GPIO header of the Raspberry Pi.

Board placementBoard placement

Software โ€” Storing Recipes

Recipes are stored as a map of ingredients with the number of millilitres required for the perfect drink. My idea of a great Vodka Lime Soda is 20ml of Vodka, 70ml of Tonic and 30ml of Lime cordial. The code mapping for this is noted below.

pump_map = {"PUMP_A": "Vodka", "PUMP_B": "Cranberry", "PUMP_C": "Tonic", "PUMP_D": "Lime"}

recipe_vodkasoda = {"Name": "Vodka Soda", "Vodka": 20, "Tonic": 70}
recipe_vodkasodacranburry = {"Name": "Vodka Soda Cranberry", "Vodka": 20, "Tonic": 70, "Cranberry": 40}
recipe_vodkalimesoda = {"Name": "Vodka Lime Soda", "Vodka": 20, "Tonic": 70, "Lime": 30}
recipe_limesoda = {"Name": "Lime Soda", "Tonic": 70, "Lime": 30}
recipe_test = {"Name": "Test", "Vodka": 10, "Cranberry": 20, "Tonic": 30, "Lime":40}

Enter fullscreen mode Exit fullscreen mode




Dispensing the perfect amount

The pumps Iโ€™m using dispense 1.9mL of liquid per second. I can delegate each pump to a thread timer so it knows how long to operate for once the drink is selected. Have a look at pump.py for complete code

# Return the number of seconds to run
def lookup_time(drink_name, pump_name):
ML_per_second = 1.9
num_ML = drink_name[pump_map[pump_name]]
return num_ML / ML_per_second

# Run a pump for given number of seconds
def pump_thread_runner(gpio_pump_name, run_seconds):
GPIO.output(gpio_pump_name, GPIO.HIGH)
time.sleep(run_seconds)
GPIO.output(gpio_pump_name, GPIO.LOW)

# Pick a drink
this_drink = recipe_vodkasoda

# How long to run each pump ...
duration_a = lookup_time(this_drink, "PUMP_A")
duration_b = lookup_time(this_drink, "PUMP_B")

# these threads start in background
pump_thread_start(config.gpio_pump_a, duration_a)
pump_thread_start(config.gpio_pump_b, duration_b)

Enter fullscreen mode Exit fullscreen mode




Emotion and Age

I use the AWS Rekognition service to determine likely emotion and approximate age. A photo is saved as a jpeg. Uploaded to the AWS Rekognition service I get a JSON string describing the emotion, gender and ago. Have a look at cloud.py for complete code

# Save camera image to file file_jpg
with picamera.PiCamera() as camera:
camera.capture(file_jpg)

# Process file_jpg using AWS rekognition to extract emotion and age
with open(file_jpg, 'rb') as f_file_jpg:
b_a_jpg = bytearray(f_file_jpg.read())
rclient = boto3.client('rekognition')
response = rclient.detect_faces(Image={'Bytes': b_a_jpg}, Attributes=['ALL'])

Enter fullscreen mode Exit fullscreen mode




Spoken words

For text to speech I used the AWS Polly service. A text string can be converted into with a spoken voice saved as an mp3 audio file. Selecting the appropriate โ€œvoiceโ€ is language specific (although it is fun to have the English works spoken with a French accent). Have a look at cloud.py for complete code

# Using "Emma" as am English voice, generate text to voice
voice='Emma'
client = boto3.client('polly')
response = client.synthesize_speech(OutputFormat='mp3', Text=audiotext, VoiceId=voice)

thebytes = response['AudioStream'].read()
thefile = open(file_mp3, 'wb')
thefile.write(thebytes)
thefile.close()

# Play mp3 file via speaker
os.system('mpg123 -q {}'.format(file_mp3))

Enter fullscreen mode Exit fullscreen mode




Summary

A few hours and a bit of programming and you too can enjoy a ๐Ÿน cocktail pi. Enjoy!

Project code โ€” **https://github.com/saubury/cocktail-pi**

Drinks are readyDrinks are ready

Top comments (0)