Espresso maker hack on the cheap!

What to do if you have too much time on your hands?
How about optimizing the brewing temperature of a quite cheap espresso maker.

The idea came from here. So I tested my own machine and saw, to my great dismay, the following graph:

Graph of shot pulling with bi-metals.

Graph of shot pulling with bi-metals.

These measurements are done with a temperature probe that has most of it’s precision in room temperature. At this stage I had not yet implemented oversampling to increase precision. Also, I can’t remember the sampling time but the warmup phase should be around 70 sec.

  • I turned the machine on @ 650.
  • The bimetal switch turned heater off @ 900.
  • Started puring shot @ 1300.
  • Done pouring @ 1400.
  • Turning knob to steam mode @ 1450.
  • Steaming @ 1600.

Espresso is to be brewed at 94° C or so I’ve heard. Here it was being brewed at between 90 and 76. Way too low. Also the temp readings are not calibrated at this high temperature.


  • Much better temperature control
  • Display
  • Self calibration
  • Remote logging

Off to eBay and

Lets see here… what stuff do I need?

You might think “on the cheap” would exclude extravagant features such as Bluetooth and a display. You’re right. It does.
Without these the cost goes down by about 10$. The parts are that cheap.
Luckily i already had an Arduino, some wires, thermal paste, solder, electrical tape, shrink tubing and a perfboard.
My espresso machine already had a small light on it to indicate when the heater is on. Let’s keep it that way.
Using a solid state relay to be able to implement a slow kind of PWM in a good way.

Order stuff. Wait. Wait. Wait. Wait. Wait. Wait some more. Wait. Wait. Wait. Wait for it. It arrives. Yay!


  • Take machine apart.
  • Lose vital bits to be able to put it back together properly. If pressed for time this step can be skipped. Actually… it should be.
  • Unhook bi-metal switch and substitue with SSR controlled by Arduino.
  • Hook up bimetal to Arduino to figure out what original bi-metal is doing.
  • Put in thermal sensor with lots of thermal paste and secure with duck tape.
  • Find vital bits to be able to put it back together properly.

Next step is software. Used built in PID library from Arduino and used conservative values to not damage anything.
Starting by using only P part. Building up with I and D. Sending all measurements over serial and ploting.
To control the output I used a sort of slow PWM solution. The output goes from 0 to 1024 (why not).
In a cycle of 1024 milliseconds it simply turns the relay on for that amount of time. More thoughts on this later.

Warm up phase:

Before pulling the shot the metal has to warm up to form a sort of heat reservoir to warm the subsequent influx of cold water.

First thing I noticed was that this system is quite non linear and that whilst raising the temperature is quite quick the cool off is very slow.
If doing straight up PID the I-part was working it self up quite a lot during warm up. Then it would overshoot and the I-part would still be quite large and the overshoot got worse. So here I chose to go for a static warmup routine. Warming with maximum effect for a predetermined amount of time and then at a lower effect until the temperature derivative is zero (temperature stops increasing). When this occurs it hands control over to a PID-controller. The integrating part is essential since the output requirement for keeping warm changes as more and more of the metal in the machine gets warm. Starts out with output at about 130 and drops to 35 in time.
To continually improve the static warmup time the result of the static warmup is stored in EEPROM. At startup all the previously stored timings are averaged out.
In my case I started by manually entering a value of 7.15 and after a while the average was 7.35.

Watching this video without being interested in PID will be like watching paint dry.

Keep warm phase:

In this phase a mildly tuned PID-controller is used to keep the temperature around 103°C. Only quirk with the PID here is that the D-part is squared but with the correct sign. This was a choice I made since most of the time the derivative part is around zero while keeping warm but changes dramatically when pulling a shot. This made it easy to detect when a shot was being pulled but did not add too much noise to the output.

Pulling a shot:

A few things are triggered when the pulling of a shot is detected.

When the D-part crosses a predefined negative threshold value:

  • Setpoint is changed to 94°C
  • Output is set to maximum
When temperature stops falling control is then handed over to an aggressively tuned PID-regulator.
  • Realize PID is bad as is, for this.
  • Feedback guy doing this with the sample-time problem.
  • Pseudo feed forward by I-part.
  • D-part^2.
  • Modify PID-library with new Get and Set methods.
  • Open loop approach to warm-up phase.
  • States and regulatory design changes.
Open loop, pseudo feedforward etc

Open loop, pseudo feedforward etc

Open loop, pseudo feedforward etc All params

Open loop, pseudo feedforward etc All params

To be done:

  • Making two cups… without reset. Detect when done pulling shot.
  • Lowering memory use (flash). Removing floats and doubles.
  • Fit in ATtiny
  • Auto calibrate. Crude. But to give a clue. Ziegler-Nichols approach?
Tagged , , , , , , ,

Rip this hack a new one...

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: