This week, my book Where to Drink Coffee was published by Phaidon Books. If you’ve met me, it’s obvious within the first 30 seconds that I am a coffee nerd.
I am also a DIY electronics junkie. Past projects have included a live-tweeting BBQ smoker and an industrial pizza oven with superchargers. When I build stuff, it’s often in the pursuit the most consistent and high quality food and drink possible. My latest project has been a closed-loop espresso machine hack in pursuit of the perfect espresso shot.
Here is the challenge: when most baristas pull a “shot” of espresso, they simply use a measuring cup to identify 2 fluid ounces of espresso. As anyone who loves espresso knows, the same volume of espresso doesn’t remain consistent because crema — the foam on every shot — can vary widely. Volume is not the best way to measure a shot of espresso.
Walk into enough serious cafes and you will notice that the baristas are using scales in every step of the process. What coffee experts have discovered is that mass is a much more accurate measure for pulling consistent espresso shots (if you want a deep technical analysis, this post by Ben Kaminski is the most rigorous analysis I’ve seen). When you ask a roaster for a “recipe” on a specific roast, they will respond with something along the lines of “18 grams in, 27 seconds, 35 grams out”. They can state recipes this way because nearly everyone standardizes their machines to 201°F and 9 bars of pressure. This leaves grind size as the only variable for a barista to tweak.
We started out with a great machine, a La Marzocco GS3 from eBay that need some TLC. However, the principal of this hack can be applied to just about any high quality espresso machine.
The plan was to override the manual “make espresso” button and instead send commands to the machine based on the real time mass of the espresso. The first thing we needed was a microcontroller with wifi connectivity. Thankfully, the open-source Particle Photon was ready to use with a robust web-based IDE and firmware manager (we are also one of their largest investors, along with Spark Capital).
With a microcontroller selected, the next step was finding a way to measure the output of the espresso feedback loop: mass. Unfortunately, the GS3 has no mass sensors (although La Marzocco’s high-end cafe models do). We needed a precise scale that we could pull digital data off of. Here we were aided by our friends at Acaia, makers of the Lunar — an awesome water-resistant digital scale. Acaia provided us the communication spec of the Lunar for this project, enabling us to measure and transmit the real time mass of an espresso shot over bluetooth.
To receive data from the scale, we used an EnzyTek bluetooth module. With the espresso-feedback-loop-output (mass) measured, transmitted, and received, the final hardware step was controlling the espresso machine itself.
Initially we thought we would jack into the GS3’s interal debug RS232 port and reverse-engineer its digital commands, but after some port-sniffing we realized we were over-complicating the solution. We could simply mechanically emulate a press of the “make espresso” button and then emulate a stop signal when the espresso was done. The addition of a basic relay to the Particle allowed us to this.
With the hardware done, it was time for some custom firmware to tie the GS3, the Acaia, and the relay together. The Particle Photon’s web IDE made this almost trivial compared to other micro-controller projects. Via a web API we exposed on the Particle, we are able to initiate a “smart brew” with a single argument: target output mass.
When we run our “smart brew” function, the firmware emulates a “make espresso” button press; the mass of the espresso shot is then continuously sensed by the Acaia scale and sent to our firmware. The firmware waits until the shot has reached the target mass, and then shuts off the machine. The function then reports the amount of time used to pull the shot to the target mass. If the target mass is achieved faster than the recipe specifies, we need to adjust the coffee grinds finer; If it takes too long, we loosen the grind. The result: an espresso shot created based on realtime mass instead of water volume, which better matches the roaster’s recipe.
With our API controlled GS3, we are more precise with our shots and closer to our goal achieving a fully closed-loop espresso. The human-in-the-loop step that remains in our system is grind adjustment. The operator still has to manually interpret the shot time compared to the recipe and adjust the grinder accordingly. As you can imagine, the next part of this project is to send instructions to a custom controller and motor on the grinder to adjust the grind automatically based on output mass and time!