I am doing a project on Arduino controlled light dimmer circuit...

I have a separate circuit for zero crossing detector and IR receiver but when I am combining both of them in arduino then my IR receiver stops working and zero crossing interrupt is not detected...

Here is my code:

#include <IRremote.h>
int RECEIVE_PIN = 8;
int AC_LOAD = 3;    
int dimming;  

IRrecv irrecv(RECEIVE_PIN);
decode_results results;

void setup() 
    pinMode(AC_LOAD, OUTPUT);         
    attachInterrupt(0, zero_crosss_int, RISING);  

void zero_crosss_int()  
    int dimtime = 75*dimming;      
    delayMicroseconds(dimtime);    // Off cycle
    digitalWrite(AC_LOAD, HIGH);   // triac firing
    delayMicroseconds(10);         // triac On propogation delay
    digitalWrite(AC_LOAD, LOW);    // triac Off

void loop() 
    if (irrecv.decode(&results)) 
        results.value, HEX);

            dimming = 120;

            dimming = 80;

            dimming = 20;


Can anyone help me with this????

  • 3
    Need to provide some code, libraries and description of the IO used. It is likely that is a conflict. – mpflaga May 2 '14 at 8:05
  • 3
    Add links to the circuit diagram and spec sheet of both zero crossing detector and IR-receiver. – jippie May 2 '14 at 10:19
  • Without looking at the code, it seems like you have a loop somewhere and the code can't get pass that loop at the right time so an event isn't registered by the code and it's "missed." – Anonymous Penguin May 2 '14 at 19:16
  • Can you clarify the sentence "my IR receiver stops working and zero crossing interrupt is not detected": how do you know that concretely, did you add some traces to show what happens? – jfpoilpret May 7 '14 at 5:49
  • www.instructables.com/id/Arduino-controlled-light-dimmer-The-circuit..study this instructable, I successfully implement IR remote and Light dimming by following his second option which doesn't use interrupt.. – demy Mar 6 '18 at 10:27

What you've described (without source code and/or a circuit diagram) sounds like you'll probably be using interrupts at least for the zero crossing detection. And probably the IR receiver too. The IR receiver is going to be your problem since the zero crossing is a very quick flag set and you're out of the interrupt.

On the other hand, the IR detection is going to take time, and if you're doing THAT in an interrupt you're going to be missing dozens of crossings.

To mix the two you can leave the zero crossing in it's own interrupt, but you're probably better off handling the IR in the loop via a state machine.

Since you say that neither are working, I'm going to hazard a guess and you're using the same interrupt or badly implemented them (possibly a timer and interrupt clash) and until you post some code people here aren't going to be able to help you any more than that.


One important problem in your code is concurrent access to dimming variable. That may not be the only problem you have though.

Indeed, deeming is accessed for writing in your loop(), but it can be simultaneously read by zero_crosss_int() function which is executed in interruption mode because it was registered as such with attachInterrupt().

Since deeeming is an int (2 bytes on AVR MCU), it cannot be read or written in just one clock-cycle (AVR is an 8-bit technology). Hence it is perfectly possible that loop() gets interrupted by zero_crosss_int() just in the middle of writing dimming, eg in:

dimming = 120;

Note that, in theory, concurrent acces in your case should not be an issue as long as dimming is never greater than 255.

How do you protect access to dimming variable?

You can do the following:

int dimming() {
    int temp = dimming;

void dimming(int value) {
    dimming = value;

And replace any direct access to the dimming variable in your code with a call to one of these functions above.

Will that fix your problem?

Maybe not unfortunately, as it is probable that mixing IRremote.h with your code brings other conflicts.

But at least, this will solve a dormant bug in your code, a complex bug that may catch you some day.


It seems that the jaydeep might have been building my circuit and used the provided code: http://www.instructables.com/id/Arduino-controlled-light-dimmer-The-circuit/step4/Arduino-controlled-light-dimmer-The-software/ 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).

Solution? 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. 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.

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.