Here is a description of the currently implemented hardware mods. Please note that these have only been tested on 120V mains – if you are attempting to implement these mods on 240V, please check all power ratings on the relevant components and let us know on the forums what changes you made so we can incorporate them!

Also, please keep in mind that some of these mods require handling high voltage/high current mains electricity. Be over cautious and triple check your component ratings, wire connections and take the habit of doing a round of visual and manual inspection of everything every single time you turn the power on. The hazards of this project include fire, explosions, toxic fumes and electrocution.


This is an essential hardware mod as most features require it. It forms the core where all sensors and relays are connected and where the software does most of the work (and minimizes required hardware). It is possible and highly recommended to also implement the display + buttons mod to provide more advanced features.

We selected the mbed LPC1768 because it seemed to offer the right balance between form-factor, power and functionality. mbed is ARM’s rendition of the Arduino project – similar price-point, API and target market, with a bunch of board options and modules. At around $50, the LPC1768 is not exactly the cheapest micro-controller on the market, but it boasts a 96 MHz Cortex-M3 with 32KB of RAM and 512KB of flash. So this gives us a lot of breathing room, possibility of adding network connectivity and generally higher precision due to that high clock speed. The truth is, if you want to go cheaper, you will probably be fine with something like the $25 FRDM-KL25Z. Basically, any micro-controller module that is supported by mbed can be used with this project’s code, but keep in mind that 0.1’s binary is 95KB, so make sure you have enough flash. Also, pick a board that has enough peripheral I/Os for all your mods (sensors, relays, etc). The hardware mods released in 0.1 require the following I/Os and power:

  • 1 analog in
  • 1 PWM out
  • 8 digital In
  • 5 digital out
  • 2 SPI (mosi/SCK)
  • regulated +3.3V
  • regulated +5V

We are using the LPC1768 as such:

You can see the full list of supported boards here:

The LPC1768 has the following features:

  • 6 analog inputs
  • 1 analog output
  • 6 high frequency range PWM outputs
  • up to 25 digital inputs/outputs
  • pull-up/pull-down resistors on digital inputs
  • native ethernet support
  • CAN, SPI, I2C for higher level communications (bluetooth, wifi, xigbee with breakout boards)
  • regulated +3.3V and +5V (when powered via USB)

Pinout looks like this LPC1768 pintout

In addition, the mbed development platform is quite easy and fast to work with, providing  a relatively high level C++ API, RTOS, multi-threading, event queues, timers and an online IDE.

The LPC1768 needs to be powered via the USB port since some of the peripherals use the +5V from pin VU which is directly taken from the USB. The LPC1768 can use up to 250mA at highest loads and the display backlight around 40mA. So make sure to use a high quality regulated 5V/1A wall-wart (the ones that come with smartphones are good).

Bill of Materials

  • LPC1768 – $52
  • Regulated wall-wart 5V/1A – $5

High Precision Temperature Sensor on Boiler

This mod is inspired by Jame’s temperature sensor mod. Using an M4 aluminium hex screw is a very elegant way of replacing the stock temperature sensors, basically plug and play (yes, we’re old school). We had to drill a little bit into our hex screw to fit the TO92 packaged sensor. It’s also a bit messy to fill that thing with thermal paste but hey, a lot of things in life are messy. We picked the TI LMT01 sensor because it offered higher accuracy at our operating temperatures (90 C to 150 C). The LMT01 has a max temperature range of 150 C (good for steam), an accuracy of +/- 0.635 C and a resolution of 0.0625 C. It is factory pre-calibrated so that’s a good time saver. The LMT01 generates a digital pulse count signal as output, so we had to write a driver for it.

Since the LPC1768 has plenty of analog inputs, an alternative would be use an analog output temperature sensor (such as the TSic 303 TO92). This would reduce the required components, circuitry, driver work & micro-controller load. The analog input ADC on the LPC1768 has a resolution of 4096 steps over the 0V to 3.3V range. For a sensor with a temperature range of 200 C (-50 to 150), we would be able get a max resolution of 0.05 C, which is good enough! If you go down this route, make sure the replace the LMT01 input circuitry with an analog input circuit (such as the one on the pressure sensor mod). You’ll then need to write the simple driver for it (see pressuresensor.cpp) and replace the LMT01 object in brewcontrol.cpp with this new one. If you pick this option, please make sure to commit your code changes and share your experience on the forums so we can include them for everyone else!

Bill of Materials

  • LMT01ELPG – $5
  • 2N3904 (transistor) – $0.25
  • 10K resistor

SSR on heaters/boiler

The Gaggia Classic has 2 heating elements on each side of it’s boiler that use around 1300W of power. In order to be able to control the heating, we need to connect an SSR before the heating elements. This is a very easy and common mod which requires buying an appropriate SSR and connecting it between the power and heating elements. The other side of the SSR is connected directly into a PWM output pin (21 to 26) on the LPC1768 (see schematic). The most commonly used SSR is the FOTEK SSR-25A, which will work for 120V and 240V machines. This SSR is zero cross type (which means it waits for a zero cross on the load signal before switching). This helps reduces power spikes so is recommended. The SSR can be bolted directly into your Gaggia Classic chassis with some thermal paste in between (the chassis acts as a heat sink!). So you’ll need a drill here. The back plate on the left side next to the pump is a good place to put it. You can find tons of pictures and examples of this mod online, but again, we refer to the excellent write up by James here.

Bill of Materials

  • FOTEK SSR-25DA – $10

Zero-cross detect circuit

An opto-coupler based circuit is used to detect the zero-cross point on the mains AC signal. The opto-coupler we selected is the Broadcom HCPL-817, but any opto-coupler should do as long as it has a reasonable CTR (100% range).

The basic mechanism of this circuit is for the LED to turn on and off as the AC signal fluctuates from positive to negative voltage. On the other side of the opto-coupler we need enough current IC to trigger a logic flip when the LED switches. The values for R1 and R2 should be set to get the LED to turn on as quickly as possible while respecting their power rating.

A normal resistor has a power rating of 0.25W, the maximum power at R1 happens on the positive AC cycle (lower circuit) because VF(DIODE) is smaller than VF(OPTO):
\[P_{R1max} = 0.25W = \frac{{V_{R1max}}^{2}}{R1} \Leftrightarrow R1 \geq \frac{(120\sqrt{2}-1.1)^{2}V}{0.25W}\approx 114k\Omega
Let’s calculate the maximum IF(OPTO) when the LED is forward biases (top circuit) with that resistor value:
\[I_{F(OPTO)max} = \frac{V-V_{F(OPTO)}}{R1} – I_{R(DIODE)} = \frac {120\sqrt{2}V – 1.4V}{114k\Omega} – 5\mu A \approx 1.471 mA\]
Our tests on the HCPL-817 give us a response time (output voltage from 10% to 90%) of approximately 850 us at IF(OPTO) of 1.5 mA. This can be reduced to sub 100 us levels if IF(DIODE) is taken up to 20 mA by reducing R1 to around 8.5 kOhm, but that would require a R1 which can handle at least 3.4 W (i.e. wirewound resistor). That resistor is 7 kOhms and has a 5 W power rating, which is sufficient since it will run at 4W on 120V mains and will limit current to 24 mA with response times of 36 us. If you are running 240V mains make sure to get the right resistor to limit IF(OPTO) to about 20 mA.

Considering we are working with AC mains running at 60 Hz, near 1 ms response times can be considered quite high (each half cycle is 8.3ms), so it makes sense to use a high power wirewound resistor to minimize them.

Alternatively, we can use use ordinary 1/4 W resistors in series to replace R1, which would allow us to split the power across multiple resistors. If we use two 1/4 W resistors in series, we can handle up to 0.5 W, which means the total resistance needs to be at least 114kOhm / 2 = 57 kOhm, with a 10% tolerance we are at 62.7 kOhm. So we can use two 33 kOhm resistors in series for a total resistance of 66 kOhm. That resistance value gives us an IFmax of 2.545 mA.

If you use another resistor value than 7 kOhms, you need to measure (with an oscilloscope) the response time and set the constant ZCD_DELAY in phasecontrol.cpp.

Bill of Materials

  • HCPL 817 – $1
  • 1N4007 – $0.25
  • 7k 5W wirewound resistor – $2
3 Comment threads
3 Thread replies
Most reacted comment
Hottest comment thread
4 Comment authors
Philippe KalafEl BartoPhilPascal Lam Recent comment authors
newest oldest most voted
Notify of
El Barto
El Barto

Hi Philippe! The data sheet of the fotek ssr (and the most types I recently found) state that they do zero cross detection out of the box and also use optoisolation. Maybe a dumb beginner question, but why the extra circuitry around then?


The aluminium standoff that James linked (Richco HTSA-M4-20-2, Farnell 1898535) does not seem to be offered anymore. Do you have an alternative suggestions? Perhaps this one: Farnell 971200476, Standoff, Aluminium, M4, Hex Male-Female, 20 mm, 28 mm?

Pascal Lam
Pascal Lam

Hi I asked a question on Reddit, but it seems that you’re not really active there anymore. May I know why did you chose LPC1768 instead of something cheaper such as ESP32? What mbed OS pros? I want to achieve what you did and will do with an ESP32 and would like to know if it would be possible.