I need to detect the zero cross of AC main (220V - 50Hz) with an ESP32 to make a phase shift control of a resistive load. Searching the web I found this circuit but I have some doubts on how to dimensions the resistor values properly.
Can you please tell me if my reasoning is right or wrong?

enter image description here

In order to calculate the values of R1 and R2 I made this calculations: $$ V_{peak}=220*\sqrt{2} \simeq 312V \\ I_f=\frac{312V}{220 k\Omega} = 1,41 mA \\ P_{R} = V_{peak}*I_f = 312V * 1,41 mA \simeq 440 mW $$

I want to limit the forward current to the diode in the bridge rectifier and also the power dissipation through the input resistors (R1 and R2).
With the same approach R3 should limit the current into the anode of the photodiode inside the H11L1:

$$ I_F^{max} = 30mA \\ R_3 = \frac{V_{peak}}{10mA} = \frac{312V}{10mA} = 31,2\Omega \simeq 33\Omega \\ P_{R_3} = 312 * 10mA = 3,120 W $$

This is the first doubt that I have: Shouldn't the current be limited to 1.41mA because of R1 and R2? I'm asking this because 3W of power is huge for a single resistor. If you wondering why I'm using H11L1 instead a common optocoupler (e.g 4N35), thats because I need a "clean" square wave output to use ESP32 interrupt on raising edge. ESP32 is too fast for the AC frequency and if you use a 4N35 you'll get a lot of false positive triggering. Arduino, that is much slower than ESP32, doesn't have that issue.

Lets move to the phase control circuit to dim a 220V heater:

enter image description here

R5 is 1K because the $$I_{TSM}^{max} $$ of the Triac in the MOC3021 is 1A, with $$R_5=1K\Omega \to I_{TSM} = \frac{312V}{1K\Omega} = 312 mA$$

Do I also have to limit the current that flows into the BT139's gate? If not why?

  • 1
    \$\begingroup\$ Do not forget that R1 and R2 must withstand the 220 V rms. Resistors have a 200 V limit, so use at least 3 serial resistors. \$\endgroup\$
    – Antonio51
    Commented Sep 13, 2023 at 9:53
  • 1
    \$\begingroup\$ Resistor Vmax varies with type. See spec sheets. \$\endgroup\$
    – Russell McMahon
    Commented Sep 13, 2023 at 11:03

1 Answer 1


Shouldn't the current be limited to 1.41mA because of R1 and R2?

Well, it is limited. R3 is entirely optional, since it is effectively in series with R1, R2 and the LED in the optoisolator.

The rectifier bridge is just a voltage-controlled reversing switch. In the approximate model it can be ignored as if it wasn't there. Its only job is to protect the LED from high reverse voltage.

But all that power dissipation is not necessary. We can have a circuit that really sips power:


simulate this circuit – Schematic created using CircuitLab

The two plots are for 90VRMS and 250VRMS - it works well across the usual international voltage range.

The idea is that the LED in the optocoupler is only turned on at the beginning and at the end of one half-cycle. Here's the LED current plotted for one line cycle at 50Hz:

enter image description here

The peak power dissipated across R4 and Q1 is about 0.1W:

enter image description here

The total dissipation across the critical path - R4 and Q1 - in one second is about 5mJ maximum - that's 5mW average power:

enter image description here

The MCU will be getting two pulses - one at the beginning and one at the end of the positive line half-cycle. The mid-point between the pulses is at 90 degrees phase angle. The average pulse period is 180 degrees of phase angle.

So, for any pair of pulses you get the 90 or 270 degree phase angle at their midpoint. And for any two consecutive pairs of pulses you get the 360 degree phase angle. So it's easy to derive everything else with just one timer and an interrupt routine. The interrupt routine captures the pulse edges. The timer itself is configured for PWM operation and generates the phase-controlled pulses - once sync is achieved.

If there are two timers available, things are easier:

  1. TIMER1 is free-running in capture mode, and captures each rising and falling edge on the optocoupler output. An interrupt triggered after each capture reads out the captured time and uses it to update the PWM phase reference and period.

  2. TIMER2 is used for PWM output and runs at 1/2 line period - either 100Hz or 120Hz. The line period is exact and derived using TIMER1, the firmware doesn't need to know whether it's 50Hz, 60Hz, or something in-between.

The MCU controls the heater phase, it's not directly coupled to the optocoupler.

Another benefit of this circuit is that it will ignore staircase AC output from "pseudo-sine" inverters/UPSes. The staircase rises too fast to trigger the optocoupler long enough to capture the input. Thus you're protected from misbehavior with incorrect mains waveform - although this has to be validated of course.

But all of this seems overkill anyway.

All you need to get this going is a small, 1W or 2W PCB-mounted step-down transformer that will both power the ESP, and provide the mains waveform reference for the ADC. The ADC can sample at 1kHz or so, and the software then can find zero crossings etc. Note that the resolution of zero-crossing detection is much better than 1ms. The voltage samples immediately adjacent to the sign change determine exactly where the zero crossing was. You'd use that to adjust the timer period to ensure that the PWM timer is phase-locked to mains.

No optocouplers needed, and the software can be as fancy as you wish in determining whether the mains has usable waveform for phase control.

  • \$\begingroup\$ Many thanks for the detailed explanation an for the alternatives that you suggested. Can you please explain why the current is limited from the bridge rectifier and why I don't need to dissipate the power with resistors R1, R2 and R3 (looking at my circuit)? I would like also understand if I need to add a resistor before the gate of the BT139 and if not why I don't need to limit the current that flows inside the gate. I have recently approached circuit design \$\endgroup\$
    – Angel0ne
    Commented Sep 14, 2023 at 5:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.