Ir light dimmer using PIC18F

Thread Starter

naresh5555

Joined Mar 3, 2017
11
Hi every one , I am doing IR based lamp dimmer .My circuit working fine but only issue with IR interrupt and zero crossing interrupt .
What i done is

1) For detecting the zero crossing from the Mains i used the RB1 pin for interrup ( Zero crossing detection).every 10ms it will give the interrupt to MC.
2) For Ir decoding i used RB2 INT2 ( Interrupt pin )

Now I am facing problem with both the interrupt
a) when ever I am pressing the Ir ,light are flickering.

I am guessing bcz both in ISR may be this reason I am getting this type of problem ..

suggest me a solution.
 

Sensacell

Joined Jun 19, 2012
2,544
Cannot say anything definitive without seeing your code.

But here is a hint:

Write your interrupts so that they do the absolute minimum, even to the point of having a main-line piece of code that does everything else but the critical, time-sensitive tasks.
 

Thread Starter

naresh5555

Joined Mar 3, 2017
11
Cannot say anything definitive without seeing your code.

But here is a hint:

Write your interrupts so that they do the absolute minimum, even to the point of having a main-line piece of code that does everything else but the critical, time-sensitive tasks.
Thank you for your reply ...i dint get u what u r saying ....
 

Robin66

Joined Jan 5, 2016
252
Cannot say anything definitive without seeing your code.

But here is a hint:

Write your interrupts so that they do the absolute minimum, even to the point of having a main-line piece of code that does everything else but the critical, time-sensitive tasks.
Could you expand on this point please? I started off developing a motor controller with this in mind but I have ended up with some rather large ISRs which effectively include all the business logic ie. calc'ing a zero-crossing point and computing the motor trim required to keep the crossing point centered. It's a lot of logic but it's important that it's done in a timely manner. I defo what to prioritise this over driving the LCD. The only stuff I have outside of the ISRs are for user input/output eg. monitoring buttons, LCD etc.
 

ErnieM

Joined Apr 24, 2011
8,011
Keeping the ISR short and sweet is just a standard good practice, not written in stone and very application dependent. I did have one job, a simple timing circuit, where just about all of the timing and switching was done directly inside the ISR itself. I could do that because the main app code was simple and quite interruptible as all it did was make a calculation that would finish long before it was needed.

In the TS project there is obviously a timing issue when slow IR data is coming in bogging down the fast zero crossing code. That may need some refactoring to fix it.

Without seeing the code I do find strange there is no timer interrupt in the mix. If I coded this I would have the zero cross fire the interrupt to start a timer and exit. The timer ISR would control the dimmer switch and exit. These two functions should be damn fast, just a few lines each.

My main code, without any interrupt, would monitor or poll the IR signal and process that as needed and present the next dimming time code to the ISR functions to use as is with no timing computation in the ISR. It should present the next timing interval for the ISR to use.
 

Sensacell

Joined Jun 19, 2012
2,544
What I often do is write the ISR to do only the stuff that absolutely-positively-has-to-happen at that instant.
At the end of the ISR, a flag is set that tells another mainline chunk of code that the ISR has occurred, this code then performs all the housekeeping for the next ISR event. Spend the absolute minimum of time in the ISR, this minimizes timing jitter when the events happen at the same time.

This technique is good when multiple asynchronous inputs occur, at a predicable rate, but not so good when the ISR repetition rate is high, as you must be sure the mainline code executes before the next interrupt.
 

Thread Starter

naresh5555

Joined Mar 3, 2017
11
Keeping the ISR short and sweet is just a standard good practice, not written in stone and very application dependent. I did have one job, a simple timing circuit, where just about all of the timing and switching was done directly inside the ISR itself. I could do that because the main app code was simple and quite interruptible as all it did was make a calculation that would finish long before it was needed.

In the TS project there is obviously a timing issue when slow IR data is coming in bogging down the fast zero crossing code. That may need some refactoring to fix it.

Without seeing the code I do find strange there is no timer interrupt in the mix. If I coded this I would have the zero cross fire the interrupt to start a timer and exit. The timer ISR would control the dimmer switch and exit. These two functions should be damn fast, just a few lines each.

My main code, without any interrupt, would monitor or poll the IR signal and process that as needed and present the next dimming time code to the ISR functions to use as is with no timing computation in the ISR. It should present the next timing interval for the ISR to use.
Hi ! Thank you for your replay I am firing the traic after getting the Zc in ISR only so in my section it will stay 10 msecs in ISR only ...
Give me some suggestion and if possible any example code
 

ErnieM

Joined Apr 24, 2011
8,011
For a 50Hz line frequency you get 100 zero crosses a sec. If you spend 10 mS per cross in the ISR then you spend 100 * .01= 1 sec or 100% of your time in the ISR.

It gets even worse for a 60Hz line.

My code suggestion to you was back in post #5.
 

Thread Starter

naresh5555

Joined Mar 3, 2017
11
For a 50Hz line frequency you get 100 zero crosses a sec. If you spend 10 mS per cross in the ISR then you spend 100 * .01= 1 sec or 100% of your time in the ISR.

It gets even worse for a 60Hz line.

My code suggestion to you was back in post #5.
Hi , I changed my code and i tested still same issue . After zc I am going to the 300usec timer interrupt loop within that TRAIC will be Fire.

C:
void interrupt ISR(void)
{
INTCONbits.GIEH = 0;
if(INTCON3bits.INT1IF ==1)
   {
zc=1;
    INTCON3bits.INT1IF = 0;
}

if (PIR1bits.TMR1IF)//50ms interrupt
    {
    
    
    
    PIR1bits.TMR1IF= 0;
    TMR1H    =0xFA; //0xFE;
    TMR1L    = 0x24;//0x0C;
   // PORTBbits.RB3=~ PORTBbits.RB3;

    if(zc==1)
    {
     count3=count3+1;
    }
        if(count3>22)
        {
            count3=0;
        }
  
  
         if(count3==20)
       {
         zc=0;
                

        
         PORTCbits.RC1=1;
         #asm

nop;nop;nop;nop;nop;nop;
nop;nop;nop;nop;nop;nop;
nop;nop;nop;nop;nop;nop;
nop;nop;nop;nop;nop;nop;
nop;nop;nop;nop;nop;nop;
nop;nop;nop;nop;nop;nop;
nop;nop;nop;nop;nop;nop;
nop;nop;nop;nop;nop;nop;
nop;nop;nop;nop;nop;nop;
nop;nop;nop;nop;nop;nop;
nop;nop;nop;nop;nop;nop;
nop;nop;nop;nop;nop;nop;
nop;nop;nop;nop;nop;nop;
nop;nop;nop;nop;nop;nop;
nop;nop;nop;nop;nop;nop;
#endasm
        
         //__delay_us(250);
         PORTCbits.RC1=0;
         count3=0;
      
          //INTCON3bits.INT1IF = 0;
       }
  
INTCONbits.GIEH = 1;
}
}

void InitExternal_INT(void)
{
  /* INTCON2bits.INTEDG2 = 0; //INTEDG2_bit = 0;          // Set interrupt on rising edge
   INTCON3bits.INT2IF = 0; //INT2IF_bit  = 0;          // Clear INT2 flag
   INTCON3bits.INT2IE = 1;//INT2IE_bit  = 1;          // Enable INT2 interrupts
   INTCONbits.GIEH = 1; //GIEH_bit     = 1;          // Enable GLOBAL interrupts
   INTCON3bits.INT2IP = 1;//INT2IP_bit  = 1;          // Enable INT2 interrupts*/
  
   INTCON2bits.INTEDG1 = 0; //INTEDG2_bit = 0;          // Set interrupt on rising edge
   INTCON3bits.INT1IF = 0; //INT2IF_bit  = 0;          // Clear INT2 flag
   INTCON3bits.INT1IE = 1;//INT2IE_bit  = 1;          // Enable INT2 interrupts
   INTCONbits.GIEH = 1; //GIEH_bit     = 1;          // Enable GLOBAL interrupts
   INTCON3bits.INT1IP = 0;//INT2IP_bit  = 1;          // Enable INT2 interrupts
}





void InitTimer1()//
{
  T1CON    = 0x01;
  PIR1bits.TMR1IF     = 0;
  TMR1H    = 0xFA; //0xFE;
  TMR1L    = 0x24;//0x0C;
  PIE1bits.TMR1IE     = 1;
  INTCON    = 0xC0;
}
Moderators note : used code tags
 
Last edited by a moderator:

ErnieM

Joined Apr 24, 2011
8,011
Verifying uncomment code for an unknown processor running on unknown hardware is not possible.

Please provide a schematic, processor type, and some comments for what the code is trying to achieve.

Seeing what you have I do notice you reset and set what seems to be the global interrupt bit. The ISR function should be doing this for you (it's what that "interrupt" keyword means) and can lead to the ISR running multiple times before it ever exits.
 

Thread Starter

naresh5555

Joined Mar 3, 2017
11
Verifying uncomment code for an unknown processor running on unknown hardware is not possible.

Please provide a schematic, processor type, and some comments for what the code is trying to achieve.

Seeing what you have I do notice you reset and set what seems to be the global interrupt bit. The ISR function should be doing this for you (it's what that "interrupt" keyword means) and can lead to the ISR running multiple times before it ever exits.
Hi thank you for your reply . I tried and now working without flickering . And I am firing the triac after the zero crossing with some timer delay ( Based on required brightness). Now the new issue is while running the ZC and Timer2 .My IR not functioning properly .
1) After the Zc I am clearing the external interrupt flag and after the Timer 2 overflow i am Clearing the timer2 flag bit .
2) And I am using the sony based remote .
 
Top