Due to an investigation on thermal systems, for another project, I needed to read a signal that controls a water pump in order to detect how much power was effectively used as well as the real flow based on different pump curves depending on different power percentages. After several research with the technical schema of the control unit that regulates the pump, I came across the TRIAC dimming. So, before understating how to read such signals, I have to understand better how the TRIAC control works.

If you want to know more about why I need to read the output from this triac controller have a look at: On the thermo-fluid-dynamics of small thermal systems


How do triacs work?

Triacs (Triodes for Alternating Current) are electronic devices commonly used in dimmer circuits to control the intensity of lights or the speed of motors. They play a crucial role in dimming because they allow the adjustment of the power delivered to the load by controlling the conduction of current.

Triac conduction

The basic switch circuit uses a simple DC to trigger the triac. When a Gate current is applied to the triac it is driven into full conduction acting as a closed circuit.

The triac is usually triggered into conduction by a positive gate current but shows symmetric conduction also for a negative current allowing for alternating current driving.

Another common type of switch circuit uses phase control to vary the amount of voltage, i.e. the total power delivered to a load. It requires also a variable resistor to control the amount of phase shift. Through a diac and a capacitor, we can deliver the triac’s triggering voltage. The diac is a bidirectional semiconductor and it is put in conducting by the voltage across the capacitor. For each AC cycle, the capacitor starts charging through the variable resistor and when the voltage reaches the diac conducting threshold it allows the capacitor to discharge through the triac gate turning the triac ON.

At the end of each AC cycle, the triac turns off automatically by facing a voltage lower than its threshold. For the second half-cycle, we can see a symmetrical behavior, however, the trigger threshold may be different due to the asymmetrical conduction current of the triac.

Phase cut application

Here, we are trying to read how a control unit for a solar heating system regulates a pump. This main pump is driven by an AC triac dimming. I have not analyzed the signal initially and the following is based on the specs given to me by the tech support of the control unit manufacturing.

To dimmering the pump power it uses a phase cut to provide less apparent power. The AC current is based on a frequency of 50Hz and it completes cycles in 20 ms. That dimming method cuts the signal by triggering a triac with a predefined voltage threshold corresponding to the desired shift angle. Then the provided power is proportional to the squared RMS voltage, i.e. the squared time average of the voltage:

V_{\operatorname{RMS}}= \sqrt{{1\over T}\int _0^T\left[ \sin (t) \right]^2 dt}

While for a perfect sine wave VPK=VRMS × √2, with the RMS voltage known as the common 230V in Europe, in this case, the peak voltage remains 310V however the RMS values change due to the phase cut.

The Vrms could be expressed with respect to the phase shift angle α by a simple time integration as:

V_{\operatorname{rms}}=\sqrt{2\pi-2\alpha+\sin 2\alpha\over 4\pi}

Triac output reading

By following the theoretical signal we want to read these AC curves and detect the power delivered to the load in order to understand the actual pump power and the fluid flow. First of all, this is an ACC 230V current that could be very dangerous for human health so we use a transformer to decouple this circuit to the low-voltage one.

By relying on available devices, we use a transformer that gives us a 10V signal and we proceed towards a rectification with a diode bridge. After that, we can use a simple voltage divider to scale it in the range readable from Arduino (i.e. 5V).

Phase cut at 45°
Reading circuit

With Arduino, we can sample the analog port and compute the root mean square voltage that is related to the delivered power as the squared root mean square voltage.

Timer enabled

After some tests, we decided to use an oscilloscope to check the control signal and we discovered that the triac is currently driven with a system based on time and not on voltage threshold.

This is another typical technique to drive a triac dimming. It used a timer to turn OFF or ON the main switch that put the triac in conduction. However, instead of commuting for each AC cycles it is based on a multiple of the AC period. For instance, if we considered a timer period of 10 times the AC ones, i.e. of 200 ms we can turn off 5 AC cycles and for the 50% of the power.

50% power time controlled. The timer (red) could only be ON or OFF.

With that introduction in mind, we can try to read the real signal of interest. Off course by analyzing real signals measurements are a little more complex and noisy than expected.

Case studies - Control Unit for thermal solar system

As mentioned before the main purpose is to read the control signal that drives an AC pump. This pump is part of a solar system and allows for heat transfer between the solar panel and a puffer where the sun's energy is stored as hot water. Yes, pretty cool and green, but we want to know the pump speed and the current flow in order to estimate how much power the sun is giving to the water, and more realistically the daily energy. This is better explained in the aforementioned article about thermal systems.

As you can see from the figure the system is pretty simple however it requires a control unit to drive the pump based on the temperature difference between the inlet and outlet of the thermal fluid that connects the panels with the water tank.

Furthermore, before reading the signal of interest I had the opportunity to test a real solar control unit in laboratory conditions. The following is a pretty standard control unit for solar heating systems but we can simulate the environment in order to obtain the desired pump modulation.

AC current security switch panel, control unit, scope, resistive and inductive loads

As expressed in the following table the control module is based on three temperature thresholds triggered by the temperature difference of the panel probes. Without judging the control logic, it relies on two settable parameters: PAR13 and PAR14. It is possible to set them in the settings menu to optimize the heat transfer.

SpeedΔT (Ts3-Ts4)Speed step
1< PAR1340%
2> PAR1355%
3> PAR13 + PAR1470%
4> PAR13+2*PAR1485%
5> PAR13+3*PAR14100%

Triac driving

By a visual inspection of the control unit PCB following backward the pump connection it is possible to find the main triac as well as its driver. It is an optocoupler, the MOC3052M. It consists of an infrared emitting diode optically coupled with the triac allowing for random-phase triac driving. The random-phase control is basically a control without zero-cross detection and so it is a timer-based control.

Basic driver circuit

And we can read both the signal before and after the optocoupler. For instance, at 70% of power, the signals are:

Lov voltage control signal from the control unit
Dimmered AC current delivered to the LOAD


Before sampling these signals could be interesting a little flashback on the temperature sensors used by the control unit. The first type is resistance thermometers, also known as resistance temperature detectors (RTDs). They are based on the resistance variability of metals due to temperature. The resistivity follows a linear law like:

\rho(T)=\rho(T_0)\left[1+\alpha (T-T_0)\right]

PT100 and PT1000 are based on platinum (Pt) shaped to get different resistance at =°C, for instance, PT1000 shows 1000Ω at 0°C. So we can simulate 82°C with typical resistors of 1kΩ+330Ω.


While for panel probes RTD detectors are used, the tank probes are thermistors. A thermistor is a semiconductor-based resistor whose resistance is strongly dependent on temperature. In fact, temperature and conductivity are related by an exponential relation due to electrons density (η), moreover, also mobility (μ) could be affected.

R=\frac{1}{\sigma(T)} \cdot \frac{l}{A}=\frac{1}{q \cdot n(T) \cdot \mu(T)} \cdot \frac{l}{A}

For metals and highly doped semiconductors, electron density does not depend on temperature and so the temperature affects only the mobility with the conductivity decreasing when temperature increases leading to PTC sensors. In intrinsic or lightly doped semiconductors the density of electrons and holes increased with the temperature with an exponential function.

Resistance curves

Metals and highly doped semiconductors lead to PTC sensors:

R=\frac{1}{\sigma(T)} \cdot \frac{l}{A}=\frac{1}{q \cdot n \cdot \mu_0 T^{-2}} \cdot \frac{l}{A}

Intrinsic or lightly doped semiconductors lead to NTC sensors:

R=\frac{1}{q \cdot n_0 \cdot \exp \left(-\frac{\alpha}{T}\right) \cdot \mu_0 T^{-2}} \cdot \frac{l}{A}

These relations are strongly non-linear however they could be linearized. For an NTC or negative temperature coefficient, the typical relations could be expressed with respect to a reference resistance, relative to a reference temperature T0, as:

R(T)=R\left(T_0\right) \cdot \exp \left[B\left(\frac{1}{T}-\frac{1}{T_0}\right)\right]

So, we can linearize the variation near the temperature of interest as:

\alpha=\frac{1}{R_0} \frac{d R}{d T}=\frac{d}{d T} \frac{R}{R_0}=-\frac{B}{T^2}
R_{\operatorname{linearized}}(T)=R_0 \cdot\left[1+\alpha \cdot\left(T-T_0\right)\right]

Where α represent the line slope. Clearly, it is valid only for a limited range of temperatures near T0.

It is possible to find tabulated or log-log chart data for commercial thermistors.

Here, the control unit requires an NTC sensor with 10kΩ (at 25°C) and β=3977. Then, with a simple 10kΩ resistor it is possible to simulate a 25°C temperature in the tank that will automatically put the control unit in the active state requiring heating from the hotter solar panels.

Temperature vs effective resistance for NTC or PT1000 normalized to the rispective resistance at 25°C.

With these foundations, we can simulate the entire environment, from the solar panel probes to the temperature of the water inside the tank by forcing the control unit to control the pump with the desired amount of power.

Signal reading

It is time to read the signal and compute the actual power and we can use Arduino. Arduino ADC converter sample at 125 kHz so the Nyquits's criterium is certainly satisfied and we can sample 2500 samples for each AC cycle. The following code works both with timer-based or phase-shift triac driving. It samples the AC signal for 240ms to read the average across 12 AC cycles. Then it sums all the squared samples and divides by the number of samples to obtain the discrete root mean squared voltage as:

V_{\operatorname{rms}}=\sqrt{{1\over N}\sum_{i=1}^N \left(V[i]\right)^2}

When the dimming is at 100% it should be 230V, the RMS values of the AC current with a peak voltage of 310V. It also requires to be scaled from the analog values of Arduino made of integers between 0 and 1023. We know that the maximum values correspond to the AC peak of 310V and so we can express it as a fraction of the current power that is related to the squared rms voltage:

P=100{{{1\over N}\sum_{i=1}^N \left(V[i]\right)^2} \over 230^2}\quad[\%]

What are we reading?

As explained before we can see the dimming effect.

100% of power
70% of power
55% of power

Initially, we tested the circuit with a purely resistive load, the simple one, a filament lamp. The signal is pretty clean representing the AC classical wave at 50 Hz. The dimmer acts on a period of 400-450 ms and this is clearly visible from the lamp blinking.

Inductive load distortion

To reduce this perceptible blinking effect we tried a different load cable to show a certain mass inertia. We use a simple AC fan to simulate the pump. However, an inductive load induces a phase lag between the triac current and the mains voltage.

Clean AC 50 Hz
AC distortion
Current and voltage waveforms for inductive loads

Here, a capacitor act as a filter liming the variation of voltage in time as in an RLC circuit.


As expressed before the prop variable allows scaling the Vrms in the correct range with respect to the AC peak. Furthermore, also a low pass filter is added by computing the actual power as the average of 10 (sizeAV) samples that were taken every 20 milliseconds.

If you want to know more about the following code we discussed it on the Arduino forum: 50Hz phase cut (triac dimmer) detection.

float prop=900.000;
float power=0;
unsigned long previousMillis = 0;
const short sizeAV=10.00;
const short timeToSample=240; // it samples two times the pattern
float v=0;
unsigned long sum = 0;
SoftwareSerial mySUART(4,5); 
int readElSens() {
  int n = 0;
  unsigned long start_time = millis();
  while (millis() - start_time < 100) { 
    v = 310.000*analogRead(A1)/prop;
    sum += v * v;
  return ((double) (100*sum/(230.00*230.00*n)));
void setup() {
void loop() {
    for (int i = 0; i < sizeAV; i++) {

In this code, the data about the power are printed in a software serial to be read from a post-processing framework that integrates all the information about the thermal systems under investigation.

Data elaboration

In the end, all the data are read by Home Assistant which proceeds to several post-processing to estimate the current power delivered to the water as well as the total energy.

1h pump dynamics
3h pump dynamics with lowpass filtering
24h pump dynamics

More information about these configurations inside Home Assistant is present in the relative articles.

Weekly sun thermal energy used to heat the puffer
Energy dashboard in Home Assistant