“Pimping” my coffee machine

I have a Gaggia Baby Class. She may not look like much, but she’s got it where it counts. I’ve made a lot of special modifications myself1And, like the Millennium Falcon, she’s broken down more times than I can count, to which I’ve said “It’s not my fault!” more times than I can count. But things have settled down and, except whenever I start tinkering again, she consistently produces coffee happiness with no trouble at all.. This page documents the results of years of tinkering research. The same ideas would work with many other coffee machines, and will work, especially, with other Baby and Classic Gaggia machines.

Before I go on. If any of this inspires you, be very very aware that there’s 240VAC2For North American readers, 120VAC can also be quite nasty and, even, mortiferous. inside your coffee machine and this many VACs can make you very very dead3Yes, I know it’s the current that kills you. But it’s the potential difference that drives the current.. Never take the machine apart without switching it off, removing the mains cable, switching off the mains socket, removing the plug from the socket and double checking you’ve done all of these. Also remember that coffee machines contain water and water conducts electricity4Not mention all the other dangers of dihydrogen monoxide.. Be ever vigilant.

The heart of my mods is an Arduino-based5Arduino Nano, specifically controller, for which all you need to know is below. But I’ve also made some other changes, which I’ll also mention. But first: what can this machine do that it could not do new from the factory? Here are the features:

  • Double the boiler power. This is crazy stuff, but rather fun. It speeds up the preheat, heating to steam temperature and, especially, milk steaming.
  • Brew temperature control: to within a fraction of a degree, which is critical for the perfect crema (honestly, I’ve done a lot of experimentation). The bimetallic disc thermostat from the factory has a hysteresis of around 10°C!
  • And fast! The controller goes straight to temperature with no oscillations in minimal time.
  • Steam temperature control: again, the factory thermostat is rubbish and the temperature oscillates between about 125°C and 140°C, but you only get decent steam flow above about 135°C.
  • Pulsing the pump in steam mode: so the boiler remains full. Straight from the factory, steam pressure rapidly drops off as the boiler empties, making frothing of any reasonable volume of milk tricky.
  • Pump control for optimal water flow rate: also important for a good brew. Left to its own devices, the machine drives water through the puck too quickly. (As anyone who has experienced the Gaggia coffee spurt phenomenon could tell you.)
  • Measured shot volume: fire & forget brew.
  • Single and double shot modes with different volume and flow settings.
  • Automatic switch into steam mode after shot completes: even more fire & forget.
  • Preheat routine to get the entire brew head up to temperature in minimal time.
  • Soft-off at the end of a shot to keep the brewhead clean from coffee reflux.
  • Automated backflush routine (to clean up such reflux as still manages to happen).
  • Idle time-out with warning buzzer for when you forget to switch the machine off.
  • USB interface: for diagnostics and programming. And, with suitable code, anything you like: how about a coffee machine which is internet connected via your PC?
  • Way better steam wand than the factory version.
  • Insulated boiler: lower power usage, faster warm-up, more steam.

All told, I can produce a pair of perfect Flat Whites in just over six minutes from switching the machine on cold. Which makes Mrs Tom happy.


Not a stock photo. I made these!

The non-Arduino-based mods

First off, ditch the outer plastic sheath on the pannarello frother. That whole assembly is for people who do not know how to steam milk6And who have better things to do with their lives than learn how.. It produces a foam of sorts, but nothing like the glorious micro-foam you’ll get in a good coffee shop. Just use the inner plastic bit, which has a lovely fine nozzle you can float just on or under the milk surface. With the right jug and a little practice you’ll be frothing beautiful milk.

Second, and more adventurous, ditch the entire steam wand. Replace it with a Rancilio Silvia wand. These are longer (better reach into the jug) and have a larger and well-formed injection nozzle. They also fit both the Gaggia Classic and the Gaggia Baby ranges. (Google for instructions – with the Baby, it’s a matter of pulling the wand out of the black plastic ball assembly with brute force – it’s just held in with a small plastic clip.) These wands are always available on ebay. Here, however, you hit a problem. The Gaggia boiler does not produce enough steam pressure most of the time for this wand to work because a) the thermostat keeps the temperature below 135°C most of the time and b) the boiler rapidly begins to run dry and steam pressure drops off. So if you want this wand, you need a decent temperature controller (hint: keep reading).

Third, and really wonderfully life-transforming, remove the silly little rubber sleeve from the Silvia wand and buy some Teflon tubing with 6mm internal diameter, unscrew the nozzle, shove the sleeving onto the wand and replace the nozzle. Teflon is amazing:

  • It can handle high temperatures: way higher than the temperature of the steam.
  • It doesn’t conduct heat well: so no more burning yourself on the metal wand. And, also, less heat loss from the steam as it passes through the wand.
  • Nothing sticks to Teflon7So how do they get it to stick to saucepans?: burnt-on milk is the bane of frother wands – my wand doesn’t get hot enough and the milk wouldn’t stick if it did.
  • It has a very low coefficient of friction: so with enough elbow grease you can shove it past the bends and all the way up to the top of the wand.



Fourth, increase the heat conduction between the boiler shell and the brew head. Full details here.

Fifth, if you are very brave and adventurous and careful and probably only after you’ve also done the Arduino mods, double the boiler power. It gets the machine up to temperature so much quicker and also steams the milk more quickly.

Finally, put some heat insulation around the boiler. This means faster warm up (especially for the second8or third or fourth, fifth, etc. cup of the day), lower electricity usage and better steam. Better steam because, with the Silvia wand and full steam flow, the full machine’s 1300W cannot heat the boiler as far as 140°C, which I take to be a reasonable upper bound for safe operating temperature9Well, a bit more than that actually, but not too much more.. Insulation helps a little with this. (Although if you double the boiler power this point becomes extremely moot.)

The key thing you want in heat insulation is low thermal conductivity and the ability to withstand well over 140°C without melting or bursting into flame (bear in mind that the hottest exposed parts of the heating elements will be higher than the water/steam temperature). I used some wool carpet offcuts because firefighters wear wool explicitly for its amazing high temperature properties10If you really want to impress visitors with your pimped kitchen appliances, why not cover the entire machine in sheepskin?.


Oh, and if you’re worried about losing the cup warmer on the top of the machine, just run some water into the cups before brewing.

The Arduino-based mods

My first version of the controller had an Atmel AVR microcontroller soldered directly onto the board and I had to muck about with serial to USB converters. These days Arduino boards can be bought cheap (for less than a pound on ebay if you’re willing to wait for one to come from China11And if you’re okay with importing from China. I worry about this kind of thing.).

So here are the Eagle CAD files for an Arduino Nano “shield” I designed to do the job: coffeepidshield.zip.

Or if you just want to get a board printed, here are the Gerber files. (I have some spare boards as the cheapest price I could get for printing was for 10 boards. Let me know if you want one.): coffeepidshield.gerber.zip. (Caveat Emptor: I discovered some things I would change about the board if I printed more. See my comments below.)

And here is the Arduino project file for driving the wee beastie: coffeepid.ino. (Here’s an older one I originally posted: coffeepid.ino.)

Parts list

I got most of my parts at CPC, so I include CPC part numbers:

  • C1: 1000uF 16V CA05731.
  • C4: 1nF 0603 CA06574.
  • C5: 470nF 0603 CA06405.
  • All other caps: 10nF 0603 CA06573. (Note: you probably won’t populate C10-C15, see below.)
  • D3: 1A diode SC11345. (Can’t for the life of me think why I picked this rectifier diode, a 200mA one would do.)
  • IC1: LM2904D SC07981.
  • OK1-OK3: MOC3022-M optocouple SC12309.
  • R1-R3: 470Ω 1206 RE03984.
  • R4-R6: 330Ω 240VAC 1/4W carbon film. (e.g. RE03797. Don’t buy them individually, buy an assortment pack).
  • R10, R11, R20: 2.7kΩ 240VAC 1/4W carbon film. (Ditto.)
  • R7: 1.2kΩ 0805 RE03939.
  • R9: 2kΩ 1% 0805 RE03941.
  • R12: 270kΩ 1% 0805 RE03968.
  • R14: 1.5MΩ 1% 0805 RE07151.
  • R15: 47kΩ 1% 0805 RE03959.
  • R16: 3.3MΩ 1% 0805 RE07153.
  • R18: 330kΩ 0805 RE03970.
  • R19: 100kΩ 0805 RE03963.
  • SG1: piezo buzzer LS03804. (Make sure it is one that makes a tone when you apply a DC voltage, rather than one that needs a waveform. Also look for one that is loud at 5V.)
  • T1, T3: 8A snubberless isolated triac BTA08-600CWRG SC11522.
  • T2: 24A isolated triac BTA24-600BWRG SC11517.
  • TR1: 1.5VA 2x9V isolation transformer TF01239.
  • U1: not populated (see below about making solder bridges).
  • 2 x 15 pin female headers for Arduino Nano (something like CN18766 but with more contacts).
  • 3 x 2-pin male headers for brew & steam switches and for temperature probe (gold plated in latter case). (Break them off one of these: CN18761.)
  • 1 x 3-pin male header for flow meter. (Ditto.)
  • 4 x M3 PCB standoffs (e.g. PC01257 or anything to fit a 3mm hole).
  • Heater, solenoid and pump 2-pin terminals: CN11533.
  • Mains (live, neutral, earth) 3-pin terminal: CN11534.

I make that a little over £15, although some components have to be bought in bulk, which will make it more expensive and give you spares. Why not buy extra and make up some kits for your friends for Christmas?


For all of this to be any value, you will at least need some kind of temperature probe. These are, frankly, a bit of a pest. No one makes a nice probe you can just attach to a Gaggia machine. I have designed the circuit and firmware for a PT100 device (like SN36364). The resistor network around IC1 is carefully arranged so that for resistances from about 97Ω to 163Ω, ADC pin A0 will read values in the range 0 to 1023. This corresponds to temperatures from just below 0°C to around 160°C. With suitable resistors and firmware, any kind of NTC, PTC or thermocouple probe could be used.

I leave the construction of a suitable probe to the reader. (Top tip, though, don’t mount your probe in the fat chunks of aluminium where the original bimetallic thermostats are mounted – it takes a long time for temperature changes to propagate through these. Go for half way up one of the side walls where the boiler shell is thinnest.)

You will also, likely, want a flow meter, although some of the goodness can happen even without one. I used a Digmesa device like this, but they’re hard to get hold of in their own right. The trick is to buy (ebay again) one as a spare part for a common coffee machine, search, for example, for “saeco flow meter”. Many of the devices on ebay have a min flow rate of 300ml/min. That is way too high, so watch out for that. What I really wanted was a Digmesa device with a 1mm nozzle, but I got one with a 1.2mm nozzle, which is okay for double shots, but very much on the edge of okay for single shots. See my comments below under caveats for pinouts of the flow meter header.

For both temperature probe and flow meter, you’ll get best results if you calibrate them and update the constants in the firmware source code. If you get a different flow meter from mine, you’ll definitely need to calibrate it. I did my calibration by playing with the source code and taking measurements with a multimeter (temp probe) and graduated beaker (flow meter). Have fun with that.


Finally, you need to do some wiring. You’ll need wires with two and three pin header connectors. I ripped some out of old PC cases. You could also buy them on ebay. All the wire pairs should be twisted to reduce electromagnetic noise. (Really: fast switching of high currents into the boiler element, for example, can trigger all sorts of nasty pulses on the digital inputs, with all kinds of odd results like the Arduino rebooting.) Ideally make twisted pairs out of the wires to the temperature probe, the brew and steam switches, the flow meter (a twisted triple) and all the mains wire pairs.

Connect the PUMP_SW and STEAM_SW headers to the pump and steam switches (after carefully disconnecting the mains voltage cables that come connected to these switches from the factory).


The temperature probe should be connected to PROBE1 (PROBE2 is for later expansion).

The mains supply 3-pin terminal is marked LNE for live, neutral and earth, which is the order of the pins with earth closest to the corner of the board.

The HEATER (i.e. boiler element), SOLENOID and PUMP terminals have one pin connected to mains neutral the other to a triac which switches mains live to the device. So, ideally, connect the two ends of the device to the two pins of the terminal. Having said that, a really good idea is to keep the steam mode thermostat in series with the boiler. That way, the boiler cannot be overheated. I have saved myself from bad firmware and other design errors countless times with this trick. And, very very definitely keep the thermal fuse inline with the boiler wiring: this is your last bastion of defence against stupidity. (Thankfully I’ve never needed it owing to the aforementioned steam thermostat.)

Important note: in the version of the software above, I have swapped the SOLENOID and HEATER pinouts so the heater is now the centre terminal. (See caveats below for an explanation.)

In principle, you could rip out all of the old wiring. I left mine in, but disconnected most of the connectors because a) I didn’t have a crimp connector for the boiler’s terminal pins, b) it was the easiest way to keep the thermal fuse in line and c) I wanted two of the neon lights still in the circuit so I could see whether the machine was switched on and whether the boiler is being heated. Your wiring may differ to mine (one day I might post more details), but for my Gaggia Baby Class, this entailed leaving the orange and blue wires connected to live and neutral, leaving the blue wires connected to the boiler and the solenoid and leaving the red wire connected to the boiler and steam thermostat. This also meant only connecting one wire from the HEATER and SOLENOID terminals to the positive side of the boiler (i.e. the steam thermostat) and the solenoid because they were already connected to neutral via the blue wires.



You’ll always regret your design and want to do something different just as soon as the physical product is set in stone. One set of things I wish to change is connector labelling. You can’t see the labels HEATER, SOLENOID, PUMP and MAINS_LNE once the terminals are soldered onto the board. Doh! You might want to write these onto the terminals with a permanent marker during assembly.

And then there’s the flow meter, which requires 5V, GND and count pins. I haven’t labelled these. So, for reference, 5V is closest to the edge of the board, GND is the middle pin and count is furthest from the edge of the board.

The other daft, daft design flaw was not leaving space for a heatsink on T2. This triac switches the boiler element, which conducts about 5A when on full time (i.e. during preheat and when steaming milk). Suitable triacs will drop around a volt at this current, generating in the order of 5W. Hmm, how hot will a bare TO-220 get at 5W? Well, as expected, the datasheets tell you this, but I didn’t look. The answer is 60°C/W, or 300°C above ambient. Rookie error number 1. Rookie error number 2 follows close behind: triacs must never, never get hotter than 125°C, otherwise they just switch on permanently until they cool down again or heat to self-destruct temperature.

So, T2 needs a heatsink. This can be contrived, despite space not being left for one (not the mess in the picture above – although that does work). By bending a zig-zag into the triac pins, you can get about 2.5mm between the terminals and the triacs. This leaves space for a 40mmx40mm heatsink to be placed vertically behind all three triacs. Get one with fins and a sticky pad, file off the bottom 7mm of the fins so the thickness is less than 2.5mm. To reduce the overall height and increase the efficiency, you can also cut the top 13mm off the heatsink and stick it onto the top of the remaining piece back to back. Or even on to the front of the metal heatsink tabs on the triacs. I didn’t make a particularly pretty job of this, but it works okay (using a nifty ceramic heat sink which is easy to work – although also more fragile than aluminium):


It is also a good idea to spec T2 for as high a current as you can because higher spec triacs tend to produce less power for a given current. This is why I spec a 24A triac for T2. An improved board layout would have more space between the triacs and the terminals. I have already made one improvement by moving the HEATER terminal to the middle in software, so the SOLENOID and HEATER labels on the board are now wrong.

Finally, be aware that triacs come in insulated and uninsulated versions. The latter have the metal tab connected to pin 2, which is at mains live voltage. So you’d have exposed metal bits connected to 240VAC. And with a metal heatsink, quite large exposed metal bits. The insulated ones are slightly less efficient at cooling but they don’t kill people. The triacs I spec above are all insulated.

Unpopulated parts

I have visions of using two temperature probes one day, one at the top of the boiler and one at the bottom. This way I can better determine whether the boiler is full and/or whether temperatures have stabilised. The board is designed to use a SN74CBTLV3257PW multiplexer to switch between probes. For now, the firmware knows nothing of this and I have not populated this device on my board. Instead, I have made a solder bridge between pins 6 and 7 and another one between pins 9 and 10. I have also not populated the PROBE2 header or its associated noise reduction 10nF capacitor C10.

In planning, I also wondered whether I might, one day, think up other clever things to do which might need some of the presently unused Arduino pins. So I expose some of these via the DIGITALIO and ANALOGIO headers. These, too, I have not populated and neither have I populated C11-C15, their 10nF caps.

Things I think I might do in the future

  1. Calibration mode in the firmware for the temperature probe and flow meter. It’s got a USB port, after all, so why not? I could write calibration values into EEPROM rather than hard coding them.
  2. I also want to implement some kind of water level warning. Because the only time I mess up shots is when I forget to check and the reservoir runs empty mid-shot. I am half-way through experimenting with a cheap pressure transducer attached to a T-piece below the reservoir. I think this will work, but I am finding it is quite weather dependent. On a windy day, the pressure fluctuates widely compared to the 1kPa difference between a full and empty reservoir.
  3. Add a second temperature sensor (as mentioned above). So I know how full the boiler is. And how stable the temperature is.
  4. Design a simple, easy to replicate temperature probe.
  5. Implement a simple, cheap temperature-based flow meter.
  6. Preinfusion: is this of any real value? Would be good to know.

See also

I am not alone in all this madness. In putting this post together I found this post. Some interesting ideas there.

   [ + ]

1. And, like the Millennium Falcon, she’s broken down more times than I can count, to which I’ve said “It’s not my fault!” more times than I can count. But things have settled down and, except whenever I start tinkering again, she consistently produces coffee happiness with no trouble at all.
2. For North American readers, 120VAC can also be quite nasty and, even, mortiferous.
3. Yes, I know it’s the current that kills you. But it’s the potential difference that drives the current.
4. Not mention all the other dangers of dihydrogen monoxide.
5. Arduino Nano, specifically
6. And who have better things to do with their lives than learn how.
7. So how do they get it to stick to saucepans?
8. or third or fourth, fifth, etc.
9. Well, a bit more than that actually, but not too much more.
10. If you really want to impress visitors with your pimped kitchen appliances, why not cover the entire machine in sheepskin?
11. And if you’re okay with importing from China. I worry about this kind of thing.

8 thoughts on ““Pimping” my coffee machine

  1. Hi Tom,

    Found your blog through http://int03.co.uk/blog/

    I’m about to embark on a similar project – is there a chance I could buy a board (ideally two in case I screw up) off of you? That’d save me a lot of time in terms of getting a prototype up and running. Please let me know if there’s a better way for me to get in touch to arrange payment – I’m in Canada but I’d obviously be happy to cover postage and handling as well.



    • What would you like to know? The Eagle schematic is downloadable from the link I gave. I could do a PDF as well, if you’d prefer that. I have several spare bare boards still as well.

  2. I have some questions.
    1 – Will you update the “doubling the Gaggia boiler power” with some schematics?
    2 – Are you using your own PCB with triacs as a substitute to external power supply for arduino and SSRs to save space?

    • 1. I can do that, yes. But not this week. It’s easy to describe, though, place a high-current diode in parallel with each heating element, but with the diodes back to back. I also added a second thermal fuse, so there’s one on each side and I added a 13A quick blow fuse. The quick blow and thermal fuses are in series with the power to the element/diode circuit. This configuration causes twice the voltage to be applied over each element (i.e. four times the power) but for only half of the mains AC cycles (so a net effect of twice the power). The fuses are intended to protect against various diode failure scenarios (especially blowing short circuit which would cause one element to get very hot). I found that the diodes needed heatsinks.

      2. The SSRs and opto-isolaters on my PCB are exactly what you find in an external SSR, but they’re a lot cheaper and more customised to my needs. My PCB does also provide power to the Arduino. In addition, it contains an analogue circuit for conditioning the heat sensor signal and another circuit for detecting mains zero-crossover and a piezo-buzzer and all the necessary capacitors on I/O lines to suppress electromagnetic noise and possibly more I can’t recall off the top of my head.

      • Thanks.
        1 – A photo or picture with comments wil;l help alot.
        2 – So my idea to use just PID and another one for secvond moiler in my Baby twin is ok. with less features.

        For mor hustle and pimpimg I suggest you install the preheat coil and replace the OPV with external one located before preheat coil. not on boiler. This will prevent hot water discharge through OPV – cold only will go back to tank.
        Additional SSR or triac control line with U shaped boiler to keep the water actively pre heated will make the machine travel faster than light.

        • I’ve written a post documenting the double boiler power here.

          In principle, my board could control both heaters, but then you’re one TRIAC short. If you don’t want to control the pump, that’s okay. I have not tested the dual temperature probe circuit, but it ought to work.

Leave a Reply to tom Cancel reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>