WARNING: Some people try to build this with an optocoupler with zerocrossing coz 'that is better' right? Some are even told in electronics shops it is better to use such an optocoupler. WRONG. This will only work with a random fire optocoupler: NOT igniting at zerocrossing is the principle of this dimmer.

Switching an AC load with an Arduino is rather simpel: either a mechanical relay or a solid state relay with an optically isolated Triac. (if you use an 8051 or PIC16F877A microcontroller, there is stuff for you too here.)

It becomes a bit more tricky if one wants to dim a mains AC lamp with an arduino: just limiting the current through e.g. a transistor is not really possible due to the large power the transistor then will need to dissipate, resulting in much heat and it is also not efficient from an energy use point of view.

One way of doing it is through phase control with a Triac: the Triac then is fully opened, but only during a part of the sinus AC wave. This is called leading edge cutting.
One could let an Arduino just open the Triac for a number of microseconds, but that has the problem that it is unpredictable during what part of the sinus wave the triac opens and therefore the dimming level is unpredictable. One needs a reference point in the sinus wave.
For that a zero crossing detector is necessary. This is a circuit that tells the Arduino (or another micro controller) when the sinus-wave goes through zero and therefore gives a defined point on that sinus wave.
Opening the Triac for a number of microseconds delay starting from the zero crossing therefore gives a predictable level of dimming.

Another way of doing this is by Pulse Skip Modulation. With PSM, one or more full cycles (sinuswaves) are transferred to the load and then one or more cycles are not. Though effective, it is not a good way to dim lights as there is a chance for flickering. Though it might be tempting, in PSM one should always allow a full sinuswave to be passed to the load, not a half sinus as in that case the load will be fed factually from DC which is not a good thing for most AC loads. The difference between leading edge cutting and PSM is mainly in the software: in both cases one will need a circuit that detects the zero crossing and that can control a triac.

Such a circuit is easy to build: The zero crossing is directly derived from the rectified mains AC lines – via an optocoupler ofcourse- and gives a signal every time the wave goes through zero. Because the sine wave first goes through double phased rectification, the zero-crossing signal is given regardless whether the sinus wave goes up through zero or down through zero. This signal then can be used to trigger an interrupt in the Arduino.

It goes without saying that there needs to be a galvanic separation between the Arduino side of things and anything connected to the mains. For those who do not understand 'galvanic separation' it means 'no metal connections' thus ---> opto-couplers. BUT, if you do not understand 'galvanic separation', maybe you should not build this.

The circuit pictured here does just that. The mains 220Volt voltage is led through two 30k resistors to a bridge rectifier that gives a double phased rectified signal to a 4N25 opto-coupler. The LED in this opto-coupler thus goes low with a frequency of 100Hz and the signal on the collector is going high with a frequency of 100Hz, in line with the sinusoid wave on the mains net. The signal of the 4N25 is fed to an interrupt pin in the Arduino (or other microprocessor). The interrupt routine feeds a signal of a specific length to one of the I/O pins. The I/O pin signal goes back to our circuit and opens the LED and a MOC3021, that triggers the Opto-Thyristor briefly. The LED in series with the MOC3021 indicates if there is any current going through the MOC3021. Mind you though that in dimming operation that light will not be very visible because it is very short lasting. Should you chose to use the triac switch for continuous use, the LED will light up clearly.

Mind you that only regular incandescent lamps are truly suitable for dimming. It will work with a halogen lamp as well, but it will shorten the life span of the halogen lamp. It will not work with any cfl lamps, unless they are specifically stated to be suited for a dimmer.

If you are interested in an AC dimmer such as this but you do not want to try building it yourself, there is a somewhat similar dimmer available at, however, that is a 110 Volt 60Hz version (but adaptable for 220 50Hz), that has been out of stock for a while. You will also find a schedule here.

NOTE! It is possible that depending on the LED that is used, the steering signal just does not cut it and you may end up with a lamp that just flickrs rather than being smoothly regulated. Replacing the LED with a wire bridge will cure that. The LED is not really necessary. increase the 220 ohm resistor to 470 then

STOP: This circuit is attached to a 110-220 Voltage. Do not build this if you are not confident about what you are doing. Unplug it before coming even close to the PCB. The cooling plate of the Triac is attached to the mains. Do not touch it while in operation. Put it in a proper enclosure/container.

WAIT: Let me just add a stronger warning here: This circuit is safe if it is built and implemented only by people who know what they are doing. If you have no clue or if you are doubting about what you do, chances are you are going to be DEAD!

4N25 €0.25 or H11AA1 or IL250, IL251, IL252, LTV814 (see text in the next step)
Resistor 10k €0.10
bridge rectifier 400 Volt €0.30
2x 30 k resistor 1/2 Watt (resistors will probably dissipate 400mW max each €0.30
1 connector €0.20
5.1 Volt zenerdiode (optional)

Lamp driver
LED (Note: you can replace the LED with a wire bridge as the LED may sometimes cause the lamp to flicker rather than to regulate smoothly)
MOC3021 If you chose another type, make sure it has NO zero-crossing detection)
Resistor 220 Ohm €0.10 (I actually used a 330 Ohm and that worked fine)
Resistor 470 Ohm-1k (I ended up using a 560 Ohm and that worked well)
TRIAC TIC206 €1.20 or BR136 €0.50
1 connector €0.20

Piece of PCB 6x3cm
electric wiring

That is about €3 in parts

Remove these adsRemove these ads by Signing Up
1-40 of 346Next »
Knakworst28 days ago

Hi everybody,

I am building an Arduino terrarium climate controller and I've some problems with the TRIAC dimmer.

Maybe I have overlooked the solution in the comments but I have not found a solution yet. I built the analog board and tested it with several different software solutions, all went well until I integrated it into my own software.
In the software several temperature sensors are checked in the terrarium, during those checks the lamp flickers slightly. When I change the firing calculated value for 50Hz from 75 to 60 it looks ok but only for one dimming value if I want to dim more or want to have more light the problem occurs again.

Does this sound familiar to someone? I hope somebody can help.

thanks Rob

diy_bloke (author)  Knakworst28 days ago
there are a number of possibilities.
which sensors are you using? can you post the code you are using?

Thanks for your response.

Since this is an addition to an already running climate control unit I created a test setup with a onewire DS18B20 temperature sensor. Below you see the code I created for the test setup. I basically took your code and modified it a bit. When I comment out the call to the temperature sensor all goes well, but with the call the light starts flickering.

#include <OneWire.h>

#include <DallasTemperature.h>

float tempMeasured = 0;

int AC_LOAD = 3; // Output to Opto Triac pin

int dimming = 115; // Dimming level (0-128) 0 = ON, 128 = OFF

// Data wire of the OneWire is plugged into pin 10 on the Arduino

#define ONE_WIRE_BUS 10

// Setup a oneWire instance to communicate with any OneWire devices

// (not just Maxim/Dallas temperature ICs)

OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.

DallasTemperature sensors(&oneWire);

void setup()



pinMode(AC_LOAD, OUTPUT);// Set AC Load pin as output

attachInterrupt(0, zero_crosss_int, RISING); // Choose the zero cross interrupt # from the table above


//the interrupt function must take no parameters and return nothing

void zero_crosss_int() //function to be fired at the zero crossing to dim the light


// Firing angle calculation : 1 full 50Hz wave =1/50=20ms

// Every zerocrossing thus: (50Hz)-> 10ms (1/2 Cycle)

// For 60Hz => 8.33ms (10.000/120)

// 10ms=10000us

// (10000us - 10us) / 128 = 75 (Approx) For 60Hz =>65

int dimtime = (60*dimming); // For 60Hz =>65

delayMicroseconds(dimtime); // Wait till firing the TRIAC

digitalWrite(AC_LOAD, HIGH); // Fire the TRIAC

delayMicroseconds(10); // triac On propogation delay (for 60Hz use 8.33)

digitalWrite(AC_LOAD, LOW); // No longer trigger the TRIAC (the next zero crossing will swith it off) TRIAC


void loop() {

tempMeasured = temperatureSensor1();

if (tempMeasured > 26){

dimming = 75;




void getSensorData(){

// call sensors.requestTemperatures() to issue a global temperature

// request to all devices on the bus




float temperatureSensor1(){

// Basking sensor (blue wire)


float tempS1 = sensors.getTempCByIndex(0);


return (tempS1);


diy_bloke (author)  Knakworst28 days ago

Thanks for yr posting.

Let me begin by saying that the code I gave only serves as an example and it is not the most optimal code as it spends most of its time waiting. Your problem is akin to what commenter МихаилК describes below.

As I understand the onewire and Ds18b20 library can cause some problems with interrupts... at least, that is what various people have reported.
Other than that there is a timing problem because of what I mentioned at the beginning.
The time that you have to let the processor do everything you want is a half cycle=10mSecs. (at 50 Hz)
if you have your dimming level set at 115, that means that you are in a waiting loop for 8.9mS and have 1.1 mS left to do something.
Add to that that a reading of the DS18b20 can take up to 50mSec or more and you see the problem.
Sure, interrupts are made for that, to interrupt the processor for the Interrupt service routine, but as said,,, the OneWire library seems to screw up interrupts (see here). In the OneWire.cpp file you will find the following description for a modification that was made:
"Disable interrupts during timing critical sections
(this solves many random communication errors)"
Further studying of the cpp file shows that regularly the interrupts are disabled for over 50 uSec and sometimes even for more than 500uSec
I would start with using the other code that I describe in my ibble, that uses a timer interrupt to keep track of the dim time, rather than a waiting loop. That might already take care of yr problem to some extent. but probably not completely

Another thing to consider is to change the flow of your code: now you read your temperature sensor continuously. I understand that as it is the easiest, but in a terrarium the temperature probably will not become critical within a second, or a minute, or 5 minutes so you could decide to not read your sensor continuously but say every 5 minutes, at least you would not have the problem continuously.

You could also opt for another sensor(if that is practical). One that doesn’t take much time to read, possibly even an ntc if that is accurate enough for yr purpose.

You could take the interrupt disable out of the .cpp file

You could take a more drastic solution and let the DS18B20 be read by say an Attiny 13/45/85, that then sends that to yr arduino, either as a treshhold, or as complete temp info.

If you have further questions, please do not hesitate to ask

ok, thanks. I have already tried the other code and with same result, so no Onewire, everything OK, but with the Onewire the flickering occurs again. Replacing the Onewire is not an option, at least not anymore. Disable the interrupt sounds interesting in combination with altering the temperature sample rate. I am going to try that and see what happens.

Thanks for the info.


diy_bloke (author)  Knakworst27 days ago

If you consider to maybe read yr sensors say every 10 secs, remember that you can use the built-in ISRs to extend timer
functionality. For example, if you wanted to read a sensor every 10
seconds, there’s no timer setup that can go this long without
overflowing. However, you can use the ISR to increment a counter
variable in your program once per second, then read the sensor when the
variable hits 10. The ISR would look something like this:




if(seconds == 10)


seconds = 0;




For a variable to be modified within an ISR, it must be declared as volatile. In this case, you need to declare volatile byte seconds; or similar at the start of the program.

For full description, check here:

diy_bloke (author)  diy_bloke27 days ago

If your system happens to have an RTC, say the DS1307, it would be worth considering to use the sqw to trigger an interrupt every second and use that in an interrupt routine to count to say 5 or 10 secs.
You would need to set the RTC SQW to 1 sec, which you do with:

void sqw1() // set to 1Hz
Wire.write(0x07); // move pointer to SQW address
Wire.write(0x10); // sends 0x10 (hex) 00010000 (binary)

both options are a possibility. I have to look at the pros and cons and figure out which option works best with the current code. But definitly good suggestions, thanks.


H, I solved this taking out the delay from the ISR, you could do:

volatile byte ZCD=0;

void zero_crosss_int()




void loop() {


tempMeasured = temperatureSensor1();

if (tempMeasured > 26){

dimming = 75;






// Firing angle calculation : 1 full 50Hz wave =1/50=20ms

// Every zerocrossing thus: (50Hz)-> 10ms (1/2 Cycle)

// For 60Hz => 8.33ms (10.000/120)

// 10ms=10000us

// (10000us - 10us) / 128 = 75 (Approx) For 60Hz =>65

int dimtime = (60*dimming); // For 60Hz =>65

delayMicroseconds(dimtime); // Wait till firing the TRIAC

digitalWrite(AC_LOAD, HIGH); // Fire the TRIAC

delayMicroseconds(10); // triac On propogation delay (for 60Hz use 8.33)

digitalWrite(AC_LOAD, LOW); // No longer trigger the TRIAC (the next zero crossing will swith it off) TRIAC



- This would free the ISR system.

- This would only work if the main_loop < 8.3 ms

If I were you:

after detect the zero_crosss_int() I would only start a timer (for example timer 1) for the dimtime, and in the ISR(of the timer), turn on, delay 10 us and off exit (fast, no wait).

My problem was to wait INSIDE the ISR.

Actually works like a charm, I can dim and I can use comm libs, (serial, Wire, ISP,etc) at any speed without any problems, also external interrupts.

Hope it helps.


mcwareg mcwareg27 days ago

Sorry, inside:





all code



thanks for your input. I've decided to create a master-slave configuration with an ATtiny85. The fact is I don't have 1 sensor but 4 in the terrarium, also for future extensions I think that is the safest way to go.


diy_bloke (author)  Knakworst26 days ago

good luck. wld like to get some feedback later how you did :-) tnx

OK, no luck so far :(

diy_bloke (author)  Knakworst24 days ago

OK thanks. did you try mcwareg's suggestion as well?

thank you)

diy_bloke (author)  МихаилК26 days ago

Looks very nice. thanks for showing. I always like seeing what other people eventually made

How can I use this scheme and IR Control?

diy_bloke (author)  МихаилК1 month ago

not difficult at all. include the IR library (from Ken Shirriff, include an IR diode and make the value of the 'dimming' variable change by e.g. pressing the up and down buttons on your remote

diy_bloke (author)  МихаилК1 month ago

Have given it some more thought in the mean time and i will post the same answer here as I have done on the stackexchange website:

It seems that the jaydeep might have been building my circuit and used the provided code:
so obviously this problem has my interest.
With regard to the 'dimming' variable, that will not go beyond 128 so I might as well have used 'byte' to define it.
The IR remote library is I presume that of Ken Shirrif and that one uses the Timer2 interrupt. In principle, combining those two interrupts shouldnt necessarily cause a problem as I have done so as well (in using the timer interrupt rather than 'delay to trigger the TRIAC).
But in that case the entire timer interrupt was handled within the period of the mains wavelength (100 or 83 ms depending on frequency).

I don’t think the access to the 'dimming' variable -as jfpoilpret mentions- is the problem (though he makes some sound remarks), as that will just remain as is for a specific light level.

The problem -as is also suggested above- might well be in the fact that the IR receive takes too long.

So... disregarding interrupt priority for a moment, if the code is hanging around in the timer interrupt routine and there is a zerocrossing, that won't be detected, or, if the code is just doing a zero crossing detection, the timer is screwed up.

In comes interrupt priority: The external interrupt has the highest priority (other than reset). So.. when the IR receive routine is busy in the Timer service routine and a zerocrossing arrives, it will be taken out of that routine, zerocrossing will be handled and ideally, it should continue with the timer routine again.
However, your remote has no idea what is going on in the Arduino and some of the code sent will be missed.

all of this shouldn’t need to be a problem if the external interrupt was fast, but as most of the waiting is actually done within this interrupt, it could take up to almost 10mS/8.3mS (when 'dimming' approaches 128).

Well, I can't say much about the Timer2 interrupts in Ken's library, But on 'my side' of the software, what could be done is to shorten the external interrupt by removing the delays and use (yet another) timer interrupt.
Ken uses Timer2, so this would have to be timer1.
So, whenever there is a zerocross, there is no waiting in a delay, but it will be handled by timer1
An example is given in [Step 6 of my instructable][1]. There is no guarantee this will work but there is a good chance

Let me just point out that the basic program I supplied was just given as an example, It uses much computer time in waiting and therefore isn’t the best to combine with other actions of the processor.


HI, ttp://

this code to work fine =) but again trouble ((((this code is not a fan dimmer 220V, although the previous version Horchow deal with it, vchem could be the problem?

diy_bloke (author)  МихаилК1 month ago

i am not sure what you mean.
you mean the code woks with the IR receiver?
what does the fandimmer have todo with it

who is Horchow? what is vchem?

With this code can not control the fan on 220V, what could be the problem?

I have tried to do so, but unfortunately IR takes a lot of garbage in the end nothing works. ((((When I disable dimmeer from Arduino, debris present.

diy_bloke (author)  МихаилК1 month ago

Hmm as I haven't tried this myself it is hard to give a reply. The link you refer to gives some possible solutions/workarounds. Have you tried those?
The IR library uses the timer interrupt which in itself shldnt be a problem as I have combined that too with the interrupt in the dimmer program.
whether the slowness of the IR receiver is the culprit remains to be seen as that is what interrupts are for.
I wonder though how the problem presents itself to you: is it the receiving of the IR codes or the setting of the dimmer variable?
The 'debris' you talk about.. I presume that i sserial output you are looking at. What exactly is it you are sending to the serial monitor and that is 'debris'?

If you haven’t done already, try to send the following variables to the serial monitor:
-the received IR code
and let me know what is hapening
Then disable the ISR in the dimmer program and send the same to the serial monitor and let me know what's happening

guttih made it!2 months ago

Thanks diy_bloke

diy_bloke (author)  guttih2 months ago

takk fyrir athugasemdir. Það lítur vel út

rathodmanoj3 months ago


Many thanks for writing this article and explaining the functionality in simple steps yet providing all information.

I plan to use this in controlling the ceiling fan.

I plan to put the PCB in some kind of ABS plastic enclosure and fix it inside the switch board panel so that it is not visible to end user.

I have few queries.Does the TRIAC warm up and require ventilation or some kind of cooling? Is there a requirement of a Heat Sink?

Also if we do require a Heat Sink, can I connect multiple TRIACs in parallel (space constraints)?



diy_bloke (author)  rathodmanoj3 months ago

Thanks rathodmanoj
the heating up of the TRIAC is largely depend on the load it needs to drive. But if you tend to use it to regulate a fan of any considerable size I would add a heatsink
It is possible to mount various TRIAC's on one heatsink as long as you keep a few things in mind: With the TIC 206 the metal housing is connected to M2. If you therefore put several TIC206 TRIACs on one heatsink, they are all connected at M2.
That doesnt need to be a problem as long as the circuit allows for that.
In my circuit M2 is connected to the Mains, not to the load. That means that indeed, various TRIACS can be mounted on 1 plate.
However, if you use other TRIACS you have to make very sure that that is the case for them too.
Some airvents in the enclosure is a good idea.
If u use the TRIAC to drive a fan, it is best to add a snubber network as described in my article

diy_bloke (author)  diy_bloke3 months ago

Also, if you plan on mounting more than 1 Triac on 1 heatsink, make sure you dont make any mistakes in the wiring. Connect the wire from the mains to M2 only once.. they will be electrically connected throught the heatsink, or, if you have doubts on that.. connect them with a wire via the screws that mount them on the plate.

That way you avoid mixing up the 2 wires from the mains and get the best fireworks ever in yr ABS plastic case :-)

john2354 months ago

is this the same as pulse skipping modulation?

diy_bloke (author)  john2354 months ago

Let me add that PSM is in this case just a matter of software. The circuit here can be used for PSM. PSM however is not so suitable for incandescent lamps because of the inherent flickering.

Should you wish to use this circuit for PSM, then what you have to do is count the number of zerocrossings the cycle should be on and count the number of zerocrossings the cycle shld be off. So if you want to have a duty cycle of 50%, the software needs to switch on the triac at the first zerocrossing, kept open another after the 2nd zerocrossing, but switch off at the third zerocrossing, kept off at the 4th zerocrossing, until the 5th zerocrossing, when it should be switched on again.
The resulting output voltage is equal to:
Vrms x sqrt n
in which n is the duty cycle.
At a 50% duty cycle the output voltage thus is:
220 * sqrt 0.5 = 220 * 0.7 = 154 Volt
In determining the dutycycle, one should be careful to always send an even number of half cycles in order to avoid a dc component that could harm e.g. a motor.
a dutycycle of 50% therefure is done by conducting an entire cycle and stopping an entire cycle, not by conducting half a cycle and blocking the other half


I completed my TRIAC switching circuit and am back with few more queries for you. :)

Thanks for great and crystal clear explanation about PSM. I also understood your point about TRIAC firing angles. What I am really not sure about is the efficiency about this circuit in controlling fan speed (inductive load). I have read at several place that speed control using phase control method creates some harmonics in the power line which makes the motor turn hot and similar stuff. If that is the case what would you suggest ? PSM or Phase control ? Which one should be used say in case of controlling a ceiling fan ?

Just want to know that can I use this circuit to control an inductive load like I mentioned a ceiling fan. I certainly will incorporate my FAVORITE Snubber circuits :). And to control it properly what is that I need to keep in mind. Any suggestion would be highly appreciated.



diy_bloke (author)  egrabhishek4 months ago

I am not entirely shure abt the efficacy but I guess both methods may not differ that much in efficacy. I would guess though that the phase control would make for a better torque at low speeds.
You can use this circuit for a ceiling fan. I am surprised you havent tried it yet :-).
PSM or Pulse Skip Modulation, is sometimes also called cycle skip modulation. it does produce less rfi than phase cutting.
I am not sure if it has more harmonic interference.
You can always give bot methods a try and see what works best. The circuit can handle both as it is all in the software


I have a small idea. Just need your thoughts on the same.

I understand the importance of ZC detector and its use. However, I am a bit worried about putting 30K - 1/2 watt resistor with direct AC. I understand it will work and its already tested. However I have a small idea.

I am anyways using a 6v/12v AC step down transformer. I intend to take my A.C signal from that and fed it to 4n25/4n35 OC. Since transformer is an inductive load there will be issues with phase shifting and due to this the zero crossing will also shift a bit. It might happen earlier or a bit later which will result in appropriate trigerring.

What I plan to do is to get the first zero cross detection. See the deviation on my scope and then accordingly adjust the delay for first time and then create 20 ms delays from there.

To tune my circuit, assume my first time the zero crossing happens 2 ms after the actual time due to the presence of the transformer.

Now I will see this on scope and then adjust the next zero crossing event to happen after 18 ms and then subsequent will happen after every 20 ms (1/50 = 20 ms ). I wont be taking the zero crossing event from OC anymore it will happen just for the first time to get a hold of it.

Let me know your thoughts on it.

The idea is to make firing more accurate and use a bit more of isolation.



diy_bloke (author)  egrabhishek4 months ago

Abishek, as a matter of fact if you scroll through the replies to
someone called 'Peter'(about a year ago), you will see that I already
gave that as a possibility :-)
I actually have tried it myself and
didn’t get that many problems with a phase shift, but I didn't put a
scope to it. I am no expert on AC but I had the impression there is no phase shift between a HV and LV side of a transformer, depending of course how you would connect the secundary side, meaning that there is either a 0 or a 180 degree shift.
be interesting to see your results though.
I understand from your question that you want to sync only once with the zerocrossing signal and afterwards just use timing.
I would advise against that: the mains frequency may show slight variations and you would need to keep track of a lot of time.There is a problem though:
If there indeed is a phase delay (and I dont think so) then you would notice the zerocrossing a few micro or miliseconds late, i.e. AFTER the actual zerocrossing.
If you are on 50Hz you only have 10mSec to do all you need to do with the TRIAC. Obviously, if you would have a say 2 mSec delay in your phasing, you would not be able to ignite the TRIAC at the ZC anymore and thus would be unable to regulate to full power.
If you would say: "Yes, I know I am 2mS behind, I know that my next REAL ZC is actually 8mS AFTER I measured mine, So from that point on I will just use a timer to predict or guess my REAL ZC", you will run into some potential problems: There might be small variations in the grid frequency, that add up, and you would have to keep track of a lot of timing.

Again, I dont think there is a phase shift, but if there is I would advise to still have the measured ZC trigger a say 8mS timer (if the delay indeed would be 2mS) every cycle.

You talk about 20mS delays but remember that if you use a double phase rectification you will have a 100Hz signal=10mS

Still, I think there won't be a delay, but would be interested in your results

diy_bloke (author)  diy_bloke4 months ago

you also may want to read this article:

Hi thanks for your input.

I tried detecting zero cross with a 12 vac transformer.

In the attached images,

Red signal = ZC via transformer with the same circuit as in this post. (Slight change here. Instead of 30K resistor as you have suggested, I am using 33K + 33K). This gives the higher time period signal (2nd image).

First image with red signal with comparatively lower time period is after I removed one 33k resitor so now there exists only one of it.

Yellow Signal = ZC via circuit suggested in this post.

I m not able to make any sense out of this. Also why does the ZC singal time period reduced after removing one 33k resistor ?

Kindly let me your thoughts .

I am not sure whether ZC is happening before or after actual zero crossing.

Please suggest.

diy_bloke (author)  egrabhishek4 months ago

Those are very interesting pics Abishek.
regarding the first picture, I take it yr base is 25mSec? I presume that you have no capacitors on that secundary side of the transformer, just simply a bridge and an optocoupler.
The slight shift in time probably has all to do with the quality of your transformer. I am no expert on this, but have been reading up yesterday and this was one of the things that was suggested. Actually, if you look at the picture, there isn’t much difference between the start of the pulses, it is just that the secundary side has a wider peak that comes a bit later.
If your interrupt is set to be at the rising edge, this might well be possible to use.

regarding your second pic, that is actually not so surprising when you think of it. Now just to make sure I understand you correct: The 2nd pic is with 2x 33k and the first one is with 1x33k right?
That means that in the first picture the optocoupler will get all in all more current throughout the cycle and therefore is in saturation most of the time. Only when the wave comes very close to zero, the current wont be big enough anymore to open the transistor and the voltage on the collector will quickly rise till it peaks and quickly drop again when the wave is through its zero crossing because it soon will give enough voltage again to send the optocoupler in saturation, thanks to the smaller resistance.
In the 2nd picture where the resistance is much higher, relatively far before the actual zerocrossing the wave voltage is already low enough to prevent the optocoupler remain in saturation (coz of the higher resistance, and once it is through the zerocrossing, the voltage needs to rise higher (= further in the cycle) in order to saturate the optocoupler again.
What it teaches me is that maybe I should lower the resistance in my circuit.

It could well be that by tinkering a bit with the resistors on yr secundary side, you could move the rising flank a bit earlier.

Very very interesting graphs. I am very happy with them. Thanks

Hi Buddy,

Thanks for your wonderful feedback. You are absolutely right in all your understanding.

My base is 2.5 mSec (As you can see the ZC is ocurring after every 4 blocks / 10 mSec).

There is no smoothing capacitor and the one with smaller time period is 1 X 33k and the bigger time period is 2 X 33k.

One more thing, I do not think you need to decrease the resistance in your circuit. I decreased because I was working with 12VAC.

Also tell me one more thing. My resistances get a bit hot. Should I increase them to a bit more value say 100 K (1/2 watt). But I think that will make them dissipate more energy as heat. What do you say ?

Also I can make use of these ZC that I am getting but to make it more accurate I need to compare it against actual signal and see how much deviation is there from the waveform. I am not feeling confident although I know it will work. What do you say ?

I have a scope : OWON PDS5022T.

Here's the link to the manual:

Sorry for bothering you much but in case you have some time to spare, please let me know if I can see the AC waveform on it. Although I do not think so.

What I want to achieve is see the actual waveform and zero crossing and the ZC event that I am getting and sync them together.

I feel after adding some heavy resistances (100k x 4) I can add my probe to the stepped down AC voltage and that should give me the actual voltage waveform.

Please know your thoughts. I intend to test it now.

And I am based at India. (Frequency: 50Hz / 240 VAC)

1-40 of 346Next »