AC dimming using zero crossing

Hello everyone,

I have a rather curios problem.
Using this guide I build the circuit for the AC dimming with my own parts. Since nothing was happening I bought the finished PCB of the internet and tried again.
I have an Arduino Nano where I used (230V@50Hz)

  • D2 for zero crossing (pin number 2)
  • D3 to switch the Triac (pin number 3)

I connected the Nano first and then switched on the Mains for the bulb. The loop counted to level=128 and nothing happened. I set a “Print” function in the interrupt and noticed, that it was not fired. Then I tried measuring the mains if 230V are present. I only touched the N (blue) side of the circuit and the light turned on. It counted to ~90 (low dimm) and then the counter was not able to print the level every 250ms (apparently the interrupt kept firing). After it reached 128 a short bright flash turned the bulb off and the counting started again. Now the bulbs keeps turned off until I touch the N side again with my multimeter.

This is the code I used

#include<Arduino.h>

int AC_LOAD = 3;    // Output to Opto Triac pin
int dimming = 128;  // Dimming level (0-128)  0 = ON, 128 = OFF

//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
  //Serial.println("Fire");
  int dimtime = (75*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) Some Triacs need a longer period
  digitalWrite(AC_LOAD, LOW);    // No longer trigger the TRIAC (the next zero crossing will swith it off) TRIAC
}

void setup() {
  Serial.begin(9600);
  pinMode(AC_LOAD, OUTPUT);// Set AC Load pin as output
  attachInterrupt(digitalPinToInterrupt(2), zero_crosss_int, RISING);  // Choose the zero cross interrupt # from the table above
  Serial.println("--Setup--");
}

void loop1() {
  dimming = 10;
  delay(100);
}

void loop()  {
  for (int i=5; i <= 90; i++){
    dimming=i;
    delay(250);
    Serial.print("level = "); Serial.println(dimming);
}

   
}

I do not understand why the interrupt stops after one rotation (5-128) and the needs a ‘manual’ reset using an open connection against my multimeter?

Please post a schematic, I cannot tell from your description how you have everything wired up.

Thank you.

Classic mistake.

For my selfbuild circuit I followed

but it did nothing. Then I bought a module from here and some dimming behavior can be produced (between 'level=5-90').

At higher levels (nearing my set limit of 128) the counter slows down (probably due to continuing firing of the interrupt), the light flashes once and the loop starts over without lighting the bulb. Only when touched with the multimeter the bulb starts dimming again (until the loop is finished).

I am always amused at the use of a resistor in each leg of the bridge rectifier. It suggests there is some attempt at "isolation" from the mains which is quite meaningless. There is a good reason to put two resistors in series, to add the voltage rating of the two as the voltage is equally shared. The RobotDyn circuit actually has the resistors in parallel, and mounted rather close!

The use of interrupts in this manner is very crude and makes it difficult to control more than one channel, or perform any other tasks. It would be easier not to use interrupts.

The triac is not being driven correctly.
Get a good circuit.
Why do you think you need zero crossing?
The triac will switch off at each zero crossing
by it self.

herbschwarz:
The triac is not being driven correctly.

And just what do you mean by that?

In the circuits I've seen, there is
an impedance between the gate
and it's related terminal. The classic
circuit uses a diac and a resistor to
control the current into the gate.

herbschwarz:
In the circuits I've seen, there is an impedance between the gate and it's related terminal.

Earlier triacs may have required a resistor between gate and MT1 if they were unduly sensitive to dv/dt triggering.

herbschwarz:
The classic circuit uses a diac and a resistor to control the current into the gate.

The circuit shown includes a series resistor with the MOC3021 which is in effect, an opto-DIAC (more commonly called an opto-TRIAC). Perfectly standard and universal circuit. :roll_eyes:

v3xX:
Hello everyone,

I have a rather curios problem.
Using this guide I build the circuit for the AC dimming with my own parts. Since nothing was happening I bought the finished PCB of the internet and tried again.

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?
Touching the N is very dangerous and and wonder if you know the danger of a circuit like this.
What Arduino controller are you using?
Can you please post a picture of your project so we can see your component layout?

Tom.... :slight_smile:

@herbschwarz: The zerocrossing is the starting point for the time delay. How would the Triac know when to fire?

@Tom: I did not really touch it. I wanted to measure the voltage drop of the load and the voltage from the mains.

I will post a clear picture when I am at the lab. There I also have a good oscilloscope to measure the Triacs behavior.

NY73o.gif

The variable dimming is used inside and outside of the ISR and therefore should be declared as volatile.

You should also turn off the interrupts when changing its value from the main code because you have used an int and that is two bytes and so you can get an interrupt in the middle of changing it. But why is in not a byte?

@grumpy: Good point with the interrupts. I will also have a closer look at the code. In a first attempt I will do everything in the main_loop (read out the digital input from the zero crossing) and then set the dimming level.

My main concern is, that when I add functionality to my loop the time delay between the firing of my Triac may not be the same for each iteration. Interrupts would have priority over the functions in the main loop.

Sideproblem: I am trying to hunt down a ac-ac transformer to measure the triacs output.

I am trying to hunt down a ac-ac transformer to measure the triacs output.

Are there any other sorts of transformer?

My main concern is, that when I add functionality to my loop the time delay between the firing of my Triac may not be the same for each iteration. Interrupts would have priority over the functions in the main loop.

If interrupts take priority like they do then any added functionally in the main loop is not going to slow your interrupts down it is going to slow down your loop.

The correct way to do this job is to use the interrupt from the zero crossing to set a timer to time out after your dimming delay time. Then use that timer’s ISR to fire the triac. You don’t want to be hanging about doing a delay in an ISR.

Paul__B:
I am always amused at the use of a resistor in each leg of the bridge rectifier. It suggests there is some attempt at "isolation" from the mains which is quite meaningless. There is a good reason to put two resistors in series, to add the voltage rating of the two as the voltage is equally shared.

Why do you think it is meaningless? Sure it cannot be considered safe but 30k provides at least some protection. IMO it makes much more sense to place one resistor to each leg than 2 resistors to one and none to the other.

Sorry. I had trouble logging in.

I setup the circuit (picture below).

The power for the circuit comes from an external power supply (5V max 3A). The load is supplied via a Wavegenerator and the load is a standard 20k resistor.

I measured the Zero cross signal and noticed that the optocoupler is never triggered fully. This might be because circuit is designed for 120-240V, but at least I see that the opto has its minimum at the zero crossing.

This suggests, that the timing of the code is the problem. Next step will be measuring the TRIAC and the Zerocrossing simultaneously in a live circuit (I will get a 12V transformer late in the evening). Also I will change the code to continously read out the digital state of the Z-C and fire the Triac in the "main-loop".

Are there any other sorts of transformer?

Yeah, yeah. I meant that we only have AC-DC "power supplyies" laying around not real trafos

Hi,

I measured the Zero cross signal and noticed that the optocoupler is never triggered fully. This might be because circuit is designed for 120-240V, but at least I see that the opto has its minimum at the zero crossing.

It is not the minimum that shows zero crossing, it is the change in output state of the opto that shows the zero crossing.
In this case with very little current into the zero crossing opto, you will not have the zero crossing trigger at the actual AC zero crossing.

A 20,000 Ohm load with 5V is nowhere near representative of a 120V AC supply and load.
5/20,000 = ‭0.00025‬ A or 250uA.

Can you tell us your electronics, programming, arduino, hardware experience?

Tom..... :o :o :o :o :o :o

Sorry. I had trouble logging in.

Yes we all did, they might have been doing some maintenance at the site.

I measured the Zero cross signal and noticed that the optocoupler is never triggered fully

Where did you measure this? On the transistor's collector?

@Tom: 5V is power supply. The signal generated was a sine 10V@50Hz (I did not plot the scale of my signal, sorry).
Experience: Medium (mostly I learned from projects when I studied). Currently a senior scientist building/ testing new experiments at a university (a lot of makeshift hardware and software solutions). Arduino: Good-Very good. Dependent on the chips/ hardware I want to drive

@Grumpy: On the "output" pin of the circuit (Z-C pin of the module). This should be collector of the 4N25.

I've used this zero-cross (double) detector for years without problems with an Arduino Uno:

So what are the 1N4007s for?