I have a circuit similar to this one (different component values, different uC):

enter image description here

I expect a large phase error in the ZCD. The load is purely resistive and of unknown value between 100W and 1000W.

I am reluctant to stick an oscilloscope in the mains, and do it for each device produced, and then program the measured latency in a special eeprom location.

Is there an algorithm, which through a specific test output signal and polling the input signal, the micro can measure the latency and thus estimate the true zero cross from the measured one?


This is the exact circuit, with a scope shot. Below is another shot with mains AC on CH2 and circuit output on CH1.

enter image description here

From both measurements, I conclude that regardless if the micro interrupts on a rising or falling edge, the error will very roughly be about 1.6ms (subject to temperature, mains voltage, component ageing, atmega silicon variations on the input).

As the laziest approach possible, I plan to hard-code this value in the triac control and see what happens.

In conclusion, I want to say that this worked out exceptionally well. Debounced interrupt measures the pulse width and estimates the true zc in the middle of the pulse, all in less than 200 lines of C.

  • \$\begingroup\$ I have included tag control-system because IMHO this topic is part of the science of System Identification, which is part of the Control Theory science. \$\endgroup\$ – Vorac Nov 19 '15 at 9:05
  • \$\begingroup\$ How accurate does it have to be? Might it not be enough to determine a typical value for the whole system and use that then? \$\endgroup\$ – PlasmaHH Nov 19 '15 at 10:39
  • \$\begingroup\$ @PlasmaHH, indeed, I am trying to measure the cumulative delay of the output and the sensor. Subtracting that delay from the measured ZC should not only eliminate the latency in the ZC measurement, but also in the output triac activation. \$\endgroup\$ – Vorac Nov 19 '15 at 14:33
  • \$\begingroup\$ You have been asking in some previous post abot ZCD, and I gave you the EDN article, have you at least read it? Your concept of detecting ZC with falling edge is so,so. \$\endgroup\$ – Marko Buršič Nov 20 '15 at 22:40
  • \$\begingroup\$ @MarkoBuršič, I have now. Those describe high-precision, hardware-havy (rectifier, comparator, differential voltage for it ,etc.) ZCDs, while I am looking for a few-component possibly software-heavy solution (I am lazy to solder). If anything, this looks quite like what I needed. \$\endgroup\$ – Vorac Nov 25 '15 at 9:50

A calibration value can be automatically created if you consider using a spare analogue input on the PIC. Connect this input to a potted-down and biased version of the AC and let the PIC process mean and peak levels in order to determine a reference zero cross point.

Then let your firmware make an estimate of the delay and use this as a calibration value for the opto-coupler. This would be a one-ff test and probably it would be sensible to use an AC isolating transformer because the resistive divider doesn't isolate.

Alternatively, you could "rewire" the opto temporarily and "hit" it with a PIC digital output onto the LED. Then your firmware can measure the time delay.

  • \$\begingroup\$ How does this solve the problem? I want to maintain permanent galvanic isolation between the micro and the mains. If I am to insert an isolation transformer or a second opto, those would surely be subject to latency, just as the original ZCD, right? \$\endgroup\$ – Vorac Nov 20 '15 at 10:00
  • \$\begingroup\$ This is a setup procedure in order to understand the latency of the opto. Once "calibrated" you disconnect it for normal use. I didn't mention a 2nd opto. \$\endgroup\$ – Andy aka Nov 20 '15 at 10:03
  • \$\begingroup\$ Also, if you are happy with my answer to your previous question maybe you should consider marking it as "answered"? \$\endgroup\$ – Andy aka Nov 20 '15 at 10:05

I have been recently working on a similar project. Here are the results of a zero cross detection experiment that I carried out:

(Before applying my results to your project, keep in mind that this experiment was carried out for 220V 50 Hz system and the system used 3.3V logic. Things will surely change for 110V 60V and 3.3V logic system.

Also, I felt no latency due to the load. I tested this circuit for loads in the range 20 watts - 250 watts. Last thing, you are using triacs which get pretty hot at a current of 2 amps (without heat sink). If you choose to control loads up to 1000 watts, make sure you are using a big heat sink for that application.

Aim of experiment: Implementing zero cross sensing of 220V 50 Hz ac line using opto-isolators.

Result of the experiment: There is a lag between zero cross sense and actual zero cross and hence a certain delay must be used before switching on the triacs in order to maintain a stable operation.

Conclusion: Zero cross sense circuit works flawlessly. However since logic high has a range, the sensing might be a little before the actual zero cross. This must be taken into account during coding for a robust performance. For the given circuit, a delay of minimum 2 ms will do the job. Practically a minimum delay of 3ms can be given without any loss in dimming performance. Similarly a max delay of 9 ms should be ensured. Practically a max delay of 8.5ms can be given without loss in dimming performance.

Circuit used for test:

zero cross ckt

Oscilloscope graph: Oscilloscope graph

As seen here, 0.8 V is the max voltage which confirms a definite logic LOW signal. Any signal more than that might be recorded as HIGH. Taking worst case scenario of HIGH detection at 0.8V itself, if the triac is turned on within 1.3 ms period of HIGH detection, it might lead to an unreliable behavior. If a minimum delay of 2 ms is assured in the code, it will ensure a robust dimming of the device without any flicker.

For max delay, considering the worst case scenario of zero detection at 2V, max delay can be 9.5ms. However to be on the safer side, a max delay of 9ms should be used.

Using oscilloscope with ac: Ground probe of oscilloscope is connected to earth. So, make sure you NEVER connect that directly to Live by mistake. One hacky way around is to apply tape to the earth connector of oscilloscope power supply so that it gets disconnected from earth.

Also, if you are using 10x probe and you are not able to measure 220V (waveform is clipping on top and bottom), then if you add a 10 mega-ohms resistor in series with the probe, it will act as a cheap 20x probe and can be used to measure 220V without any issues. Don't forget to set the probe attenuation as 20x on the oscilloscope.

  • \$\begingroup\$ Practically a max delay of 8.5ms can be given without loss in dimming performance. Delay from where to where? In a 10ms half-wave, 8.5ms are a lot. \$\endgroup\$ – Vorac Nov 20 '15 at 10:03
  • \$\begingroup\$ In phase control, the brightness output depends on the delay between zero cross and firing of triac. That's the delay I am referring to. That delay can range from 2ms to 8.5ms and it will map to a brightness level of approx 95% to 20%. If you want a brightness > 95%, make it full on. If you want a brightness < 20%, make it fully Off. \$\endgroup\$ – Whiskeyjack Nov 20 '15 at 20:07

You could calibrate it, but a better approach might be to only use the falling edge of the ZCD output. As you can see from the below graph, the turn-on and transition time is relatively low and invariant with load resistance (and should be similarly less in unit-to-unit variations and temperature). It should only be a few microseconds in your configuration.

With the values you show, the width of the zero crossing pulse will extend past the zero crossing by about 150usec so a few usec won't make much difference if you look at the falling edge. The output thus has a couple hundred microseconds to turn off.

enter image description here

If you're thinking of calibrating the pulse width variation (the ~150usec), I don't think that's such an easy proposition- it's dependent on CTR, which you can calibrate but CTR varies with temperature and with aging of the optocoupler so a single calibration at the factory won't help that much.

Perhaps you could measure the total width of the pulse and adjust from that, but it will have a slow turn-off time so the total width won't be all that accurate, and also it will vary with line voltage if you're most concerned with the trigger angle rather than the voltage. You could use a faster (logic output) opto and then using the pulse width would be fairly straightforward.

  • \$\begingroup\$ I ... don't understand. Please see my edited question for an actual measurement of what is happening. The error is as predicted by Andy aka. \$\endgroup\$ – Vorac Nov 25 '15 at 9:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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