If you love coffee, you will most likely have a beautiful home espresso machine. Maybe even a Rancilio Silvia. The Silvia is a sleek, simple, robust, high-quality machine.
However, one downside of this coffee machine is that, like many others, it uses thermostats in order to control the brew temperature. Utilising thermostats to obtain precision and continuous temperature control is not very effective. 
That is why you see high-end commercial coffee machines utilise Proportional-Integral-Derivative (PID) controllers.
This hack will show you how to create a GUI that will incorporate precision temperature control into any simple coffee machine. Hacking-it-up utilising a Raspberry Pi will also mean the capability to integrate the Internet-of-Things into the machine.
Step one will be to down a couple of double espressos. Then, it is time to get down to business. This hack will require some sweet skills in Linux, Kivy (for the front end GUI) and Python. 
But don’t worry if you’re just a beginner – this tutorial is a great way to build up your skills. You’ll also need a soldering iron, basic electronic tools and a solid supply of coffee beans (for your own consumption). 
Depending on how far you want to go with the build, you can also fabricate a new front panel (although this makes it a bit more expensive).

What you need

Hardware required for the Silvia-Pi build includes:
Why are you using an SSR? Why don’t you use a mechanical relay to control the boiler? Well…
This is because of the potentially high switching rate of the controller. In actual practice the switching rate is relatively low, and some low-end machines do use mechanical relays. However, mechanical relays typically fail open. SSRs typically fail closed. 
This is definitely something to keep in mind when thinking about safety on your application. In addition, mechanical relays are only good for a specified number of cycles. What’s more, mechanical relays make a noise, while SSRs are quiet. 
For this application a good SSR to use is the Kudom KSI240D10-L SSR: 10A 240V AC, 4–32V DC.
The K-type thermocouple temperature range is typically between –250ºC to 1250ºC, and accurate to ±1ºC. For signal processing purposes the K-type is easy to accommodate.
There are numerous varieties of Integrated Circuits that are packaged with amplifiers, filtering, cold-junction compensation and analog-to-digital converters that are specifically built for the K-type thermocouple and are low cost too.
Because of this the K-type is perfect for this coffee machine application.

The touchscreen

In order to troubleshoot, debug and get familiar with the functionality, you will need to start by setting up that 7-inch touchscreen on the Raspberry Pi. 
Go to the element14 website and check out their Raspberry Pi 7-inch Touchscreen Display Tutorial. Once you’ve got it hooked up, have a play around with how beautifully Debian, the Pi and the touchscreen work together.

 A Graphical User Interface

The GUI specification will be as follows: a real time plotting graph, a coffee button for pulling an espresso shot, a steam button to froth the milk, and a hot water button. 
The plotting graph will enable you to see how effective the tuning of your PID controller is by incorporating the set point plot and the actual brew temperature plot – plus it gives your machine the hi-tech, precision-control image it deserves. The Espresso Standard does, after all, specify 88°C at the grouphead outlet

Getting familiar with Kivy

Kivy will be used to build the GUI. Why? Kivy is based on a simple app widget system. The Kivy widget system is easy to figure out. Kivy has good API support and tutorials on the Kivy website. Kivy also has a built-in settings widget manager that makes use of JSON configuration files. 
This makes building apps quick and easy. You can modify the standard Kivy settings widget to include sleep and wake-up times. This allows you to set the grouphead to be nice and warm by the time you get out of bed and save power during off-peak times.
Kivy has a super useful plugin manager called Kivy Garden. Kivy also has cross platform functionality (Linux, Android, iOS, OS X, etc). Kivy Garden has some cool plugin widgets this hack will use, such as Graph. This hack utilises Graph for the real-time plotter. Coding with a FOSS IDE such as Eclipse and Secure Shelling into the Pi through your desktop is an effective way to implement this hack. 
This will mean you have to set up Kivy on both your desktop and on your Raspberry Pi. Go ahead and do this by logging into your terminal and inputting $ pip install kivy then $ pip install kivy-garden followed by $ garden install graph

Building your Kivy app

Once Kivy is installed you can start building Kivy apps and getting familiar with the Kivy modules. Go to the Kivy website and look through the API library, or even follow the “first app” tutorial – a Pong app – to get your head around the code and the general layout of building Kivy apps. 
Here we will be building a CoffeeApp , which will be a combination of Kivy widgets such as BoxLayout, Button, Label, Graph. So, time to get after it. In
import kivy
from import App
from kivy.uix.boxlayout import BoxLayout
class CoffeeApp(App):
 def build(self):
  # Add parent widget
  root = BoxLayout(orientation='horizontal')
  verticalBtns = BoxLayout(orientation='vertical’, size_hint_x
= 0.25)
 # Add child widgets here then add them to the parent
  return root
# Run the script
if __name__ == '__main__':
The above code will create a stock standard BoxLayout Kivy app with a parent widget named root. You will also notice verticalBtns BoxLayout – you will use this to separate your buttons from your graph and display them vertically in the right quarter of the app. 
size_hint_x = 0.25. You won’t be able to see this size hint in effect until you add the graph later on. Adding buttons and graphs into the widget is as simple as creating the widget 
and then adding it to the parent widget:
In this case you will add the three buttons (coffee, steam and water) by repeating this code for each button. You use the simple BoxLayout which handles the position and the size of the buttons within the app’s parent widget root, therefore you need to add verticalBtns to the root widget by adding the following:

The ol’ single line diagram for the Silvia Pi build. Looks a lot like hieroglyphics from Ancient Egypt. Probably because they were working on a similar project.

Buttons, bindings and events

Now to get your three buttons sorted. Run the code and you see three buttons arrayed vertically down the app. If you are running via SSH or direct to your Raspberry Pi you will see the app run straight to the 7-inch touchscreen. 
Try pressing the buttons to see what happens… Not much? You will see the buttons change from grey to light blue, but that’s about it. Time to bind those buttons to get some functionality. By using bind method and defining on_press()and on_release() methods you can specify what happens. 
Start with adding functionality to the coffeeButton in your code. Between creating the buttons and adding the buttons to root, call the following bind method by adding the following code:
coffeeButton.bind(on_press = self.coffeePress_callback)
coffeeButton.bind(on_release = self.coffeeRelease_callback)
Now you need to define the methods within the CoffeeApp class:
coffeePress_callback(self, *args)
coffeeRelease_callback(self, *args)
Do this above the build method within the class. Add some print statements in there as tracers to see if anything happens on press and release, and run the app again. 

Oh no! Looks like R2-D2 undergoing brain surgery! Nah, not really… It’s the Pi being forged into the Silvia along with the requisite relays and driver circuits.

You will now find on pressing the coffee button that your print statements will be outputted to the terminal. Repeat the above steps again for the steam and water buttons.

Outputting from the Raspberry Pi

The buttons now need to actually control mechanical or solid state relays or set points within your coffee machine. To do this you need to tell your Raspberry Pi to drive outputs high or low or just change set point values. 
Luckily this is super easy. First of all, set which GPIOs are going to be outputs. Grab that Raspberry Pi Python module by adding the following to the top of your script:
import RPi.GPIO as GPIO
In this case you will be referring to the IO pins on Raspberry Pi as per the Broadcom SOC channel, so therefore add the following directly below the previous line:
Now to set the following as outputs: coffeeButton, which will switch a Double Pole Single Throw relay GPIO 20 by adding the following below the previously explained code:
GPIO.setup(20, GPIO.OUT)
One pole will turn the pump on or off. The other pole will direct heated water through the 2-by-3 way solenoid valve’s vent or through the group head. 
Most coffee machines will have a 2-by-3 way solenoid valve to vent pressure when deactivating the coffee switch. This is a safety mechanism to ensure no trapped pressure is exerted over the user when removing the group head.
No need to use a GPIO for steam because you don’t need to output to a relay. You will only need to increase the set point. Coffee’s set point will be around 105°C and steam will be around 140°C. The set point will drive the PID controller to heat the boiler to 140°C. 
The steam pressure will be the driving force, therefore you won’t need to  activate the pump.
However you will need to control the boiler, so set the boiler to
GPIO.setup(23, GPIO.OUT)
The last output is water, which will only turn the pump on. You only need a Single Pole Single Throw relay for this output:
GPIO.setup(19, GPIO.OUT)
You could use another DPST for this to keep parts standard on the printed circuit board (as per the ingredients list).
Now that your outputs are set, time to hook them up into your button callback methods. Do this simply by calling the output() method of the GPIO class. When you press ‘coffee’ you want the pump to kick in and the 2-by-3 way solenoid valve to output to the group head. 
Therefore drive the output high under the coffeePress_callback() method by adding GPIO.output(20, 1)
When you depress the coffee button you want the pump to stop and the 2-by-3 way solenoid valve to vent, therefore drive GPIO 20 low by adding GPIO.output(20,0) under the coffeeRelease_callback() method.
For steam you are only changing the set point, therefore create and define an attribute within the CoffeeApp. Add SP = NumericProperty(105) below to define the coffee app class. 
Now add self.SP = 140 and self.SP = 105 under steam press and release methods respectively.
You want the pump to kick in/out when you press/release the water button, so therefore add GPIO.output(19, 1) and GPIO.output(19, 0) under waterPress and waterRelease respectively.

Even though the GUI looks super basic at the moment, it doesn’t take much to turn it into a visual masterpiece.

Adding a graph widget

Finally, time to get some plots plotting. Every IoT gadget needs a dashboard and every good dashboard needs a plot. 
Import that Graph and LinePlot module by adding to the top of your script:
from import Graph, LinePlot
Now create a widget class for your graph using class PlotterWidget(Graph) and of course initialise specific attributes within your plotter widget by calling the def __init__(self, **kwargs) method. 
There are a lot of attributes to define, so check out GitHub user de-man for the code. Such attributes include grid sizing, border colours, y/x max/min, etc – it’s all very customisable.
Now when you run that script you can see the coffee GUI taking form. The graph is on the left and the buttons should be arrayed vertically on the right.

Animating your graph 

Incorporate animated line plots to your graph so you can get a visual look at the temperature control and the temperature history of your coffee machine. 
You will need to add two plots to the graph. One will be called SPplot . This is the set point which will tell the PID controller what value to drive to. 
The other will be called PVplot . This is the process value that will be read by the temperature probe from your machine. You will need to add in a couple of time methods and attributes in order to animate the graph. The main code snippet to note is a Kivy clock event:
Clock.schedule_interval(plotter.update, SAMPLE_RATE)
This will call plotter.update at a defined interval set by

Binding control to your graph

Now the animated line plots are scrolling along autonomously on your graph, but they aren’t actually linked to any of the controls. 
The SPplot needs to be hooked up to the steam button which controls the actual set point. Do this by adding one simple line of code after all your previous binding calls:
code self.bind(SP = plotter.setter('currentSignal')
Go ahead and run that code. When you press the steam button now and keep it pressed the SPplot goes from 105 to 140. 
Now release the button, and you will see SPplot drop back down to 105. Success. Time for a coffee break.

Getting temperature via OneWire

Temperature control is next, and is a bit more involved. This is because you need to set up reading the temperature input from the k-type thermocouple via the amplifier – a MAX31850K. 
This thermocouple amplifier is actually an integrated circuit that combines everything needed in order to read the thermocouple accurately and in the digital form using OneWire. 
Luckily, the Raspberry Pi was built to utilise the OneWire capability. You will now need to look at setting up OneWire within the Raspberry Pi. First enable OneWire with:
$ sudo rasp-config
Go to Advanced Settings, then Enable OneWire. You can also enable OneWire via:
$ sudo nano /boot/config.txt
and adding dtoverlay=w1-gpio to the file. After either option you must then $ sudo nano reboot . Once the Raspberry Pi is back up and running, hook up the MAX31850K (as per the MAX31850K OneWire instructions) to the Raspberry Pi’s OneWire pin, which is GPIO 4. 
Now add the appropriate modules into the Linux kernel – in this case
and w1-therm: $ sudo modprobe w1-gpio then $ sudo modprobe w1-therm . Now go to the device directory where the OneWire temperature folder and file is stored: $ cd /sys/bus/w1/devices now $ ls .
Take note of the folder name as this will be specific to each OneWire device (an example would be 3b-000000191766). Navigate to that folder now and there will be a /w1_slave file. This file is where your read-in temperature value is stored.
Now read from that file by $ cat w1_slave – the output should be some hexadecimal values and if the data is being read successfully you will see for example crc=[hex_value] YES with t=23401. This is the temperature value read in by the probe, which actually means 23.401°C. Success!
Now incorporate what you have just learnt into your script. Add to your script the os module so that you can issue terminal commands within the script. Use import os , then use
os.system('modprobe w1-gpio') 
os.system('modprobe w1-therm')
Remember when running this script, you may need to execute with a sudo. With your script having direct access to the temperature you can now write the appropriate code to validate and process the temperature values. 
Don’t hesitate to borrow the kettle from the kitchen.

Building the PID controller

Lastly you need to incorporate the PID controller. Make a specific class for this named PIDcontroller 
Within the class create attributes and methods that are applicable to the controller, such as error, lastErrorSPPV and updatePID. You need to call the controller at set intervals. 
Do this by binding another clock schedule interval to the controller. Also you need to make sure the temperature plot is hooked up to the actual temperature readings. In this case you read the temperature through the PID class. Do this again by using the bind() and setter() methods to link the attributes between the classes.
So that is that. You now have a basic Kivy app that can control a coffee machine to a better standard than most mid-range machines on the market.
  • Enjoyed this article? Expand your knowledge of Linux, get more from your code, and discover the latest open source developments inside Linux Format. 


Popular posts from this blog

want to make a robot of your own

Trending tech "samsung gearfit 2 pro, samsung gear sport"