IR controlled light dimmer not working

I am doing a project on IR controlled light dimmer using an Arduino. I am using 4N35 for zero crossing detection and I am giving that zero crossing as interrupt. Also when I am combining the IR receiver and the interrupt the ground of the receiver is floating and it starts receiving garbage value. So I need to know what is the problem with this?
I have used standard schematics for zero cross detection (4N25 + bridge rectifier), MOC 3021 + BT136 traic, and standard IR receiver.

The source code is as follows:

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

IRrecv irrecv(RECEIVE_PIN);
decode_results results;

void setup() 
{
    Serial.begin(9600);
    irrecv.enableIRIn();   
    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)) 
    {
        Serial.print("0x");
        Serial.println(
        results.value, HEX);
        delay(50);

        if(results.value==0xE13DDA28)
         dimming = 120;

        if(results.value==0xAD586662)
         dimming = 80;

       if(results.value==0x273009C4)
          dimming = 20;

       irrecv.resume();
    }
}

Also, if I remove the zero cross interrupt from the code than it works fine. Please help :frowning:

Also, I am using Uno R3.

Also when I am combining the IR receiver and the interrupt the ground of the receiver is floating

Why would you leave ground for the receiver disconnected? Why would you then expect the receiver to work?

This isn't a programming issue. This is a PEBKAC issue.

I have connected the receiver ground. Still it is not working. If you try this code with all the wiring done properly, you surely will get the issue

It sounds like you have somehow got the ground of your IR receiver entangled with pin3. I'd suggest you triple check your wiring.

Like I said, when I comment following line of code, I get correct codes from the IR.

attachInterrupt(0, zero_crosss_int, RISING);

Problem is with this only. I have got 220v 50Hz AC mains. I think IR decoding gets interrupted by above interrupt.

amitgaur06:
I think IR decoding gets interrupted by above interrupt.

You may be onto something there. You have some delays going on in there. This could totally destroy the timing of incoming bytes.

So what happens if you cut your interrupt routine down to the bare minimum, like this.

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

IRrecv irrecv(RECEIVE_PIN);
decode_results results;

void setup() 
{
    Serial.begin(9600);
    irrecv.enableIRIn();   
    pinMode(AC_LOAD, OUTPUT);         
    attachInterrupt(0, zero_crosss_int, RISING);  
}

bool fireNOW=false;

void zero_crosss_int()  
{
fireNOW=true;  
}


void loop() 
{
    if (irrecv.decode(&results)) 
    {
        Serial.print("0x");
        Serial.println(
        results.value, HEX);
        delay(50);

        if(results.value==0xE13DDA28)
         dimming = 120;

        if(results.value==0xAD586662)
         dimming = 80;

       if(results.value==0x273009C4)
          dimming = 20;

       irrecv.resume();
    }

if(fireNOW)
  { 
  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
  fireNOW=false;
  }

}

So what happens if you cut your interrupt routine down to the bare minimum, like this.

It won't work. The triac needs to be fired on a very tight schedule - inside the ISR.

OP - Frankly, you are pushing the limits of the Arduino - probably past the breaking point. You might be able to get two Arduinos to talk to each other. One would deal with the dimming. The other would deal with the the IR.

PaulS:
It won't work. The triac needs to be fired on a very tight schedule - inside the ISR.

OP - Frankly, you are pushing the limits of the Arduino - probably past the breaking point. You might be able to get two Arduinos to talk to each other. One would deal with the dimming. The other would deal with the the IR.

VERY tight? Aren't we talking about 50hz mains? I'm sure a few microseconds won't do any harm.

Thanks KenF and PaulS for your replies. I have modified the code so that now I don't use interrupts.
I have modified the IRRemote library to access the decodeNEC as public method in my code (Remote I used sends NEC encoded codes), as the decode method is a bit slow. I had to modify the decodeNEC method as decode method do some inits before calling decodeNEC. Now it is working
Following is the modified code

#include <IRremote.h>

int RECV_PIN = 11;
decode_results results;
int ZERO_CROSS_PIN = 10;
IRrecv irrecv(RECV_PIN);

int AC_LOAD = 13;    
volatile int dimming = 67;  
int isOn = 1;
int dimInc = -4;


void setup() 
{
   //Serial.begin(9600);
    irrecv.enableIRIn();   
    pinMode(AC_LOAD, OUTPUT);
    pinMode(ZERO_CROSS_PIN, INPUT);
}

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

long prevMills = 0;

void loop() 
{
    if(digitalRead(ZERO_CROSS_PIN) && isOn){
      zero_crosss_int();
    }
    
    if(millis() - prevMills > 10000){
      prevMills = millis();
      dimming += dimInc;
     // Serial.println(dimming);
      if(dimming >= 67){
        dimInc = -4;
      }else if(dimming <= 50){
        dimInc = 4;
     }
   }
   
    
    if (irrecv.decodeNEC(&results)) {
      
      long currentMicros = micros()-lastMicros;
//        Serial.println(currentMicros);
        
//      Serial.print("0x");
//      Serial.println(results.value, HEX);
        switch(results.value){
          case 0xFFEA15:
            dimming = 71;
            break;
          case 0xFFDA25:
            dimming = 67;
            break;
          case 0xFFFA05:
            dimming = 63;
            break;
          case 0xFF6A95:
            dimming = 59;
            break;
          case 0xFF5AA5:
            dimming = 55;
            break;
          case 0xFFE21D:
            isOn = !isOn;
        } 
        irrecv.resume();
              
        
    }
   
   
}

This code also contains 5 step testing of the dimmer in every 10 secs.

I think this would help anyone who have/had faced this issue.

jito79:
How to store dimmer value into EEPROM?

Depends on the board that you conveniently forgot to mention. For Arduinos, look at EEPROM.put() and EEPROM.get(). This will probably not work for ESPs and STMs (but I have no experience with them).

For everybody that wants to reply, please note that this thread is about 6 years old.