DIY Connected Espresso Machine: Relays (Part 2)

Danila Loginov
5 min readJun 2, 2021


The second article continues the Connected Espresso Machine project (part 1) and will cover the question of how to control AC load via the microcontroller programmatically.


There are only two AC components in my espresso machine that can and should be managed with the microcontroller: boiler and pump. Both have two states only: on and off. So when an electric current is going through them they work, otherwise — not.

Quite simple, but you can’t directly connect them to the microcontroller and toggle state — that’s because the nature of the electric current is completely different. Microcontroller works with Direct Current (DC) and has very low voltage — the same as from your USB cable. While the boiler and pump need Alternating Current (AC) coming from the socket to operate and the voltage is much higher and even dangerous.

So we need a mediator that will commutate AC to control the boiler and pump on receiving a control signal from the microcontroller. The easiest approach is to use a relay — switch that will react to the low-power signal and turn on the AC component.


What I had in my storehouse are TTi TRV-5VDC-SC-CD relays requiring 5V control signal and able to commutate 16A of AC current. That’s quite enough for the boiler and pump I have. The datasheet is available in the GitHub repository:

Apart from the relay we also need some additional components to control the relay from the microcontroller, please refer to the sketch from the unfortunately unreleased Arduino Basic Connections book by

Connect a Relay

Also instead of the 2N2222 transistor, I used BC337 (datasheet).


Initially, the project was based on 5V Arduino Uno and it was enough to wire the relay to the 5V output pin of Arduino. Please see sketches created with a wonderful tool called Fritzing:

Relay controlled by Arduino

However, when I switched to NodeMCU I wired the relay to the Vin pin and powered up NodeMCU from the 5V voltage, so Vin provides the necessary 5V to operate the relay. The same should work if you power up NodeMCU with the USB cable from your computer.

Relay controlled by NodeMCU

The COM pin of the relay should be wired to one of the wires coming to the AC component, while the N.O. (Normally Open) pin — to another one. This will ensure when there is no control current going through the relay coil, the AC component is not working.

You may wire the relay to the AC component, but it’s not necessary at this point, since when the control current is going through the relay you’ll hear the relay click.


The hardest part of this article is done! :) Now to the software part — I will call it firmware as later we will introduce actual software like GUI or any back end components to support planned capabilities.

I highly recommend using PlatformIO as IDE to write code instead of Arduino IDE, despite some of the screenshots I made long ago demonstrating Arduino IDE Serial Monitor. PlatformIO IDE gives you an opportunity to write code with some abstraction from the used microcontroller: either you use Arduino Uno or NodeMCU board.

In this series, I also would like to demonstrate how to write not only working but also robust code even for simple projects like this one so the approaches used in this project can be scaled to execute more complex tasks. Feel free to comment on the approaches you use in the firmware code as well!

The first concept I’d like to highlight is Object-oriented programming in the Arduino ecosystem. Think about a relay — from the microcontroller perspective it’s controlled only by setting a single pin to either HIGH or LOW voltage, but from the other side, it’s a component with its own traits and commands it can execute.

In other words, it definitely deserves its own class, let’s call it Relay. To define classes we use header files and we will describe implementation behind the definitions in regular .cpp files to have clear separation.

So what we have here is a Relay class that encapsulates the relay behavior, the relay basically controlled via a single pin, but we don’t want to expose this pin to avoid direct manipulation, so we will set it in the constructor(int) with a single parameter. If we want to know the current state we can use the getState() getter and to toggle the relay we can use commands such as on(), off(), toggle().

That’s basically it for the Relay class! We operate a single pin via clear commands, and instead of working with electric concepts, we operate a particular object.


Let’s do a quick sketch to test the Relay class:

We instantiate relay object passing actual pin used, open Serial port to communicate current state and every second toggle the relay and output its state:

Test Relay

Next Steps

The next step will be to onboard the second relay and thermistors and implement a separate class to control the boiler!

The project code is available here: — it’s not finished by the moment I write this article so I will work on this during the next episodes.

That’s all for today, see you next time!

Next part: