I am making use of the code below to control the speed of an AC fan and the intensity of an AC Lamp with an Uno.

The problem I am having is that, when I set the lamp intensity to low or medium, the fan turns on at a very low speed as well, and I cannot turn it off even when setting the fan to off.

Also if I turn the lamp on and then off, the fan (which is still set as off), will spin slowly for a second or two in random intervals.

For troubleshooting purposes, I did separate this program into two programs, controlling each device and its circuit separately, and it works perfectly, but when I combine them, I get the above problem.

Any assistance in troubleshooting or ideas to solve this would be appreciated. Haven't attempted AC control before.

int PWM = 3;
int FAN = 4;
int dimming;

void setup()
  Serial.println("Serial connection started, waiting for instructions…n0 =     Offn1 = 25%n2 =50%n3 = 75%n4 = 100%");
  pinMode(PWM, OUTPUT);
  pinMode(FAN, OUTPUT);

  attachInterrupt(0, zero_crosss_int, RISING);

void zero_crosss_int()
// function to be fired at the zero crossing to dim the light
  int dimtime = (75 * dimming);  // For 60Hz =>65
  delayMicroseconds(dimtime);    // Off cycle
  digitalWrite(FAN, HIGH);   // triac firing
  delayMicroseconds(10);         // triac On propogation delay
  //(for 60Hz use 8.33)
  digitalWrite(FAN, LOW);    // triac Off

void loop ()
  if (Serial.available()) {
    char ser = Serial.read(); //read serial as a character

    switch (ser)

  /* Lamp Control  */

  case '0':
    analogWrite(PWM, 0);  //lamp Off
  case '1':
    analogWrite(PWM, 50);  //lamp low

  case '2':
    analogWrite(PWM, 130); //lamp medium

  case '3':
    analogWrite(PWM, 255); //lamp high

  /* Fan Control  */

  case '4':
    dimming = 128;  //fan off

  case '5':
    dimming = 90; //fan low

  case '6':
    dimming = 65; //fan medium

  case '7':
    dimming = 35; //fan high

    Serial.println("Invalid entry");


The circuits it controls is based on these :

Lamp PWM AC Lamp

Fan Dimmer AC Fan

Also, these circuits and code are based on these post, if it may interest you:

Lamp PWM AC Lamp

Fan Dimmer AC Fan

  • 1
    dimming should be volatile. – Majenko Nov 3 '17 at 18:48
  • I was advised that. Tried it and it didn't make a difference. – Imraan Nov 3 '17 at 19:18
  • Suppose you have conditions under which the problem manifests itself. Please tell me what will happen if you disconnect the lamp manually. – AltAir Nov 4 '17 at 10:07
  • If the lamp is disconnected, I still get the same issue . In fact, disconnecting the lamp circuit completely from the Arduino, I still get the fan randomly spinning for a short burst if I set the lamp to turn on at low or medium with the code. It's almost as if the PWM signal is controlling the fan or interfering – Imraan Nov 4 '17 at 13:02
  • By the end of interrupt processing, all others are blocked. The function zero_crosss_int() takes too much time. This can cause problems with the built-in function and the base code. Try to move the part that specifies the time interval outside the interrupt handler.Or schedule a timer for these purposes. Also, I wonder why you use two different circuit-based principles for similar tasks in one design? – AltAir Nov 5 '17 at 14:22

The design of the zero_crosss_int() ISR is unreliable. After each interrupt it unconditionally turns on the triac, even in the OFF position. Since the dimming value in that case is close to the AC cycle duration, it may miss the current cycle and turn on early in the next cycle. This may happen e.g. due to noise in zero crossing input.

75 us * 128 = 9.6 ms. Assuming 50 Hz AC, cycle duration is 1000 ms / 100 = 10 ms. You only have 4% margin.

You need to avoid turning on the triac close to the end of the AC cycle. Limit the maximum value of dimming variable to, say, 75% of the AC cycle. This will impose a lower limit on the output power. However, you want to do this anyway because motors need a minimum power to start rotating. Adjust the ISR so that in the OFF position it does not send a positive pulse at all.

ADDED: so you just need to add an if statement to you ISR code:

void zero_crosss_int()
// function to be fired at the zero crossing to dim the light
  if (dimming > 96) // choose this value experimentally, adding some margin
  ... everything else goes here ...

ADDED2: Blocking for extended duration in the ISR is not a good idea in general. If you happen to need to do anything else in addition to 'dimming' a fan, you will almost certainly need to get rid of this. You could start a timer in the ISR and send the output pulse in the timer ISR, making sure that the timer ISR does not get executed after the next zero-crossing ISR...

  • I added the if (dimming > 96) condition, and that fixed the problem! The Fan is no longer turning on if I switch the lamp on at low intensity. However, the IFR830 Mosfet used in the circuit to control the lamp is now heating up, just noticed it melting a jumper cable. Did not experience this before. – Imraan Nov 4 '17 at 18:34
  • Well, what wattage is on the lamp? – A.K. Nov 4 '17 at 18:46
  • It is a 70w bulb. And just to correct a typo, it is IRF830 Mosfet. – Imraan Nov 4 '17 at 19:09
  • Yes it is quite strange. It seems like the Drain pin was the one heating up (breadboard melted around it). I really thought I found a solution with the if statement so this is disappointing. Could you explain what is meant by underdriven. Sort of learning all of this along the way. – Imraan Nov 5 '17 at 1:14
  • @Imraan: are you doing 220V on a breadboard? I cannot advise on a circuit that works on the line voltage. – A.K. Nov 5 '17 at 1:31

Imraan, you have most definitely NOT build your circuit safely as to do so is impossible on a 'breadboard' when using 220 VAC. The contacts on these boards are extremely poor not to mention that the separation between the metal contacts is inadequate. Please read up on track separation for mains voltages on PCB's to get an idea of what is required. The commonly used 0.1" pitch strip board is also unsuitable for mains voltages.

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.