+ Post New Thread
Results 1 to 17 of 17
  1. #1
    Newbie level 5
    Points: 47, Level: 1

    Join Date
    Jun 2019
    Posts
    8
    Helped
    0 / 0
    Points
    47
    Level
    1

    PIC 16f877A interrupt

    Hi.
    I have been working on a project of Over current relay using PIC 16f877A controller in which I have used interrupt signal to generate a exact time delay (trip signal) . For which I have used timer 1 configuration.
    It is working all fine when I run its simulation on Protues, it gives accurate result there.
    But On hardware sometime it does not gives an interrupt signal, sonetimes it gives on very accuarte time. On tbe otherhand it malfunctions as well.

    What could be the reason of this malfunctioning ? Why it does not give an interrupt signal ? Please help.

  2. #2
    Super Moderator
    Points: 29,561, Level: 41
    andre_teprom's Avatar
    Join Date
    Nov 2006
    Location
    Brazil
    Posts
    8,824
    Helped
    1114 / 1114
    Points
    29,561
    Level
    41
    Blog Entries
    9

    Re: PIC 16f877A interrupt

    What kind of oscillator are you using, internal RC, external crystal, etc... ?
    Anyway, how much inaccurate it is being ?
    --------------------------------------------------------------------------------------------------
    Part of the world that you live in, You are the part that you're giving ( Renaissance )



  3. #3
    Newbie level 5
    Points: 47, Level: 1

    Join Date
    Jun 2019
    Posts
    8
    Helped
    0 / 0
    Points
    47
    Level
    1

    Re: PIC 16f877A interrupt

    I am using an external oscillator of 20Mhz.
    When its inaccurate it never gives an interrupt signal until I reset the circuit 2 or 3 times.
    And sometime it gives so accurate result in a single attempt.



    •   AltAdvertisement

        
       

  4. #4
    Super Moderator
    Points: 80,602, Level: 69
    Achievements:
    7 years registered
    Awards:
    2nd Helpful Member
    betwixt's Avatar
    Join Date
    Jul 2009
    Location
    Aberdyfi, West Wales, UK
    Posts
    13,211
    Helped
    4411 / 4411
    Points
    80,602
    Level
    69

    Re: PIC 16f877A interrupt

    Please post your schematic and code, we can't advise without seeing what you have done.

    Brian.
    PLEASE - no friends requests or private emails, I simply don't have time to reply to them all.
    It's better to share your questions and answers on Edaboard so we can all benefit from each others experiences.



  5. #5
    Advanced Member level 4
    Points: 7,740, Level: 20

    Join Date
    Jan 2015
    Posts
    1,086
    Helped
    345 / 345
    Points
    7,740
    Level
    20

    Re: PIC 16f877A interrupt

    You seem to be talking about 2 interrupts - one from the outside world to detect the over-current situation, and the other from the internal timer.
    I find it hard to see how the internal timer can be 'unreliable' without bad programming. Therefore I assume that you are saying that the signal from the outside world is not always being detected - correct?
    Check that you have all of the bypass capacitors correctly installed, that the circuit around the \MCLR\ is not triggering a reset.
    Also what is actually generating the external interrupt signal? Could it be noisy/suffering contact bounce/etc.?
    Susan



  6. #6
    Super Moderator
    Points: 29,561, Level: 41
    andre_teprom's Avatar
    Join Date
    Nov 2006
    Location
    Brazil
    Posts
    8,824
    Helped
    1114 / 1114
    Points
    29,561
    Level
    41
    Blog Entries
    9

    Re: PIC 16f877A interrupt

    When its inaccurate it never gives an interrupt signal until I reset the circuit
    In this case there is a misuse of the term inaccuracy, which would imply an operation of timer interruption with incorrect cadence, whereas in the above case it simply stopped to work, and I agree with Susan's remark about the possibility of dealing with bad programming issues. Anyway, just to add, you migh be aware that PIC16F877 has only one interrupt vector for all peripherals, therefore proper care have to be taken to handle all events, which means that once happening an interrupt, all individual interrupt flags should be checked.
    --------------------------------------------------------------------------------------------------
    Part of the world that you live in, You are the part that you're giving ( Renaissance )



  7. #7
    Newbie level 5
    Points: 47, Level: 1

    Join Date
    Jun 2019
    Posts
    8
    Helped
    0 / 0
    Points
    47
    Level
    1

    Re: PIC 16f877A interrupt

    No, signal from the sensor is correctly read by the controller as I am using LCD as well which shows the value of current. But again the problem is with the interrupt signal it sometimes give and sometimes it does not, quite possible it is due to the bad programming.



    •   AltAdvertisement

        
       

  8. #8
    Newbie level 5
    Points: 47, Level: 1

    Join Date
    Jun 2019
    Posts
    8
    Helped
    0 / 0
    Points
    47
    Level
    1

    Re: PIC 16f877A interrupt

    Thank you for again and agian responding me.
    If I share my code with you, would it be possible that you would tell me my mistake in timer 1 configuration ?



    •   AltAdvertisement

        
       

  9. #9
    Advanced Member level 2
    Points: 3,043, Level: 12
    baileychic's Avatar
    Join Date
    Aug 2017
    Posts
    612
    Helped
    49 / 49
    Points
    3,043
    Level
    12

    Re: PIC 16f877A interrupt

    Yes, zip and post your complete project so that we can tell you what is wrong with it if any and how to fix it.



  10. #10
    Advanced Member level 4
    Points: 7,740, Level: 20

    Join Date
    Jan 2015
    Posts
    1,086
    Helped
    345 / 345
    Points
    7,740
    Level
    20

    Re: PIC 16f877A interrupt

    Quote Originally Posted by Junaid1996 View Post
    No, signal from the sensor is correctly read by the controller as I am using LCD as well which shows the value of current. But again the problem is with the interrupt signal it sometimes give and sometimes it does not....
    How is the interrupt derived from the sensor?
    I take it from your descriptor that you are continuously monitoring the sensor output with the MCU (and so displaying the value the LCD). Is there a separate signal from the sensor to the MCU that is acting as the interrupt?
    Or are you comparing the value with some threshold value in your code and triggering your 'interrupt' (I would not call it that in this case) that way?
    Perhaps a schematic diagram would help.
    Susan



  11. #11
    Newbie level 5
    Points: 47, Level: 1

    Join Date
    Jun 2019
    Posts
    8
    Helped
    0 / 0
    Points
    47
    Level
    1

    Re: PIC 16f877A interrupt

    Quote Originally Posted by Aussie Susan View Post
    How is the interrupt derived from the sensor?
    I take it from your descriptor that you are continuously monitoring the sensor output with the MCU (and so displaying the value the LCD). Is there a separate signal from the sensor to the MCU that is acting as the interrupt?
    Or are you comparing the value with some threshold value in your code and triggering your 'interrupt' (I would not call it that in this case) that way?
    Perhaps a schematic diagram would help.
    Susan
    Exactly, a threshold value has been defined in the code, as the sensor's value reach the threshold value a particular time delay is calculated after which interrupt signal should be generated and the LED must glow at that time.
    I am also attaching the zip file of my MP lab Project and the simulation as well.



  12. #12
    Advanced Member level 2
    Points: 3,043, Level: 12
    baileychic's Avatar
    Join Date
    Aug 2017
    Posts
    612
    Helped
    49 / 49
    Points
    3,043
    Level
    12

    Re: PIC 16f877A interrupt

    It is better to use Timer1 interrupt for the delay generation as it gives accurate delays.
    What is your required delay range based on your Amps range?



  13. #13
    Newbie level 5
    Points: 47, Level: 1

    Join Date
    Jun 2019
    Posts
    8
    Helped
    0 / 0
    Points
    47
    Level
    1

    Re: PIC 16f877A interrupt

    Quote Originally Posted by baileychic View Post
    It is better to use Timer1 interrupt for the delay generation as it gives accurate delays.
    What is your required delay range based on your Amps range?
    I am already using timer 1 configuration as I have mentioned above.
    It might varies from 1 second to 1 minute no particular range is defined.



    •   AltAdvertisement

        
       

  14. #14
    Advanced Member level 2
    Points: 3,043, Level: 12
    baileychic's Avatar
    Join Date
    Aug 2017
    Posts
    612
    Helped
    49 / 49
    Points
    3,043
    Level
    12

    Re: PIC 16f877A interrupt

    Explain these so that I can understand the code fully and then debug the code.

    What is Ip, PSM, TMS, top, tactual?

    Code:
    Amps = 0.007;
            float Ip = 0.005 * 1 ;
           
            if(Amps>Ip)
            {
             float   PSM;
             float   top ;
             float   TMS = 1.0 ;   
             float  tactual =0.0 ;
             PSM = Amps/Ip ; // 1.4
             top = TMS * (0.14 / (pow(PSM,0.02)-1))  ; // 20.73
    
             //tactual = top * TMS ;
             delayy(top);
    Are you sure XC8 compiler's __delay_ms() function accepts float values are arguments?



  15. #15
    Newbie level 5
    Points: 47, Level: 1

    Join Date
    Jun 2019
    Posts
    8
    Helped
    0 / 0
    Points
    47
    Level
    1

    Re: PIC 16f877A interrupt

    Quote Originally Posted by baileychic View Post
    Explain these so that I can understand the code fully and then debug the code.

    What is Ip, PSM, TMS, top, tactual?

    Code:
    Amps = 0.007;
            float Ip = 0.005 * 1 ;
           
            if(Amps>Ip)
            {
             float   PSM;
             float   top ;
             float   TMS = 1.0 ;   
             float  tactual =0.0 ;
             PSM = Amps/Ip ; // 1.4
             top = TMS * (0.14 / (pow(PSM,0.02)-1))  ; // 20.73
    
             //tactual = top * TMS ;
             delayy(top);
    Are you sure XC8 compiler's __delay_ms() function accepts float values are arguments?
    No, __delay_ms() does not accept float value that is the only reason why I chose interrupt function.



  16. #16
    Advanced Member level 2
    Points: 3,043, Level: 12
    baileychic's Avatar
    Join Date
    Aug 2017
    Posts
    612
    Helped
    49 / 49
    Points
    3,043
    Level
    12

    Re: PIC 16f877A interrupt

    Code:
    #include 
    #include "LCD.h"
    #include 
    #define _XTAL_FREQ 20000000
    // CONFIG
    // CONFIG1H
     
    #pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator)
    #pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
    #pragma config PWRTE = ON       // Power-up Timer Enable bit (PWRT enabled)
    #pragma config BOREN = ON       // Brown-out Reset Enable bit (BOR enabled)
    #pragma config LVP = OFF        // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
    #pragma config CPD = OFF        // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
    #pragma config WRT = OFF        // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
    #pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)
    int count;
    int k;
    
    //**ADC FUnctions***//
    void ADC_Initialize()
    {
      ADCON0 = 0b01000001; //ADC ON and Fosc/16 is selected
      ADCON1 = 0b11000000; // Internal reference voltage is selecte
    }
     
    unsigned int ADC_Read(unsigned char channel)
    {
      ADCON0 &= 0x11000101; //Clearing the Channel Selection Bits
      ADCON0 |= channel<<3; //Setting the required Bits
      __delay_ms(2); //Acquisition time to charge hold capacitor
      GO_nDONE = 1; //Initializes A/D Conversion
      while(GO_nDONE); //Wait for A/D Conversion to complete
      return ((ADRESH<<8)+ADRESL); //Returns Result
    }
    //***End of ADC Functions***//
     
    void main(void) 
    {
        int adc=0; //Variable to read ADC value
        float Voltage1; //Variable to store voltage
        float Amps; //Variable to store Amps value
        int Am1,Am2,Am3; //Variable to split Amps value into char
        float top;
        float PSM;
        TRISA4 =1; //AN4 declared as input
        TRISB = 0x00;
        TRISD0 = 0;
        TRISD1 = 0;
        char bool = 1;
        TRISC0 =1;
        TRISC1 =1;
        TRISC2 =1;
        
        ADC_Initialize();
    	InitLCD();
        RD0=0;
        RD1=0;
        
    while(1)
    {   
        /***Current Calculation*****/
            for (int i=0; i<20;i++) //Read value for 20 Times
        {       
            adc=0;// Initialize the LCD
            adc=ADC_Read(4); //Read ADC
            Voltage1 = (adc*4.8828); //Calculate the Voltage
            if( Voltage1>=2500)
            {
            //If the current is positive
              Amps += ((Voltage1-2500)/18.5);
            }
            else if (Voltage1<=2500) //If the current is negative
            {
                Amps += ((2500-Voltage1)/18.5);
            }
        }
            Amps/=20;  //Average the value that was read for 20 times
             if (bool) //during the normal operating condition
             {
            RD0 = 1;  // LED ON
            RD1 = 0;  // LED ON   
            }
    
            GotoYXPositionOnLCD(LCD_LINE1, 0);
            Am1 = fmod((Amps/100) , 10) ;
            Am2 = fmod((Amps/10 ) ,10) ;
            Am3 = fmod(Amps,10);
            //Am4 = fmod(Amps *10,10);
            WriteStringToLCD("CURRENT ="); // displaying the value of current sensed by the ACS 712
            WriteDataToLCD(Am1+'0');
            WriteDataToLCD(Am2+'0');
            WriteDataToLCD('.');
            WriteDataToLCD(Am3+'0');
            //WriteDataToLCD(Am4+'0');
            WriteDataToLCD('A'); 
            
            float Ip = 30.0; // giving a threshold value for tripping
            float Is = 80.0; // giving a threshold value for instantaneous tripping
                if(Amps > Is )
                {
                  RD0 = 0;  // LED ON
                  RD1 = 1;
                  while (1){
                  GotoYXPositionOnLCD(LCD_LINE1, 0);
                  WriteStringToLCD(" SHORT CIRCUIT"); 
                  GotoYXPositionOnLCD(LCD_LINE2, 0);
                  WriteStringToLCD("     ALERT"); 
                }
                }
            else if( Amps> Ip)
            {
                // timer 1 config starting
            TMR1=0;
            TMR1CS=0;
            T1CKPS0=0;
            T1CKPS1=0;
            TMR1ON=1;
            TMR1IE=1;
            TMR1IF=0;
            GIE=1;
            PEIE=1;
            // timer 1 config ending
            PSM = Amps/Ip ;
            top = (13.5 / (PSM-1))  ; // time delay calculation after which the interrupt signal should be generated 
            k = (top * 20000000)/(4*65536); // overflow counter calculation
            bool= 0 ;
            }
            }    
    }
    __interrupt() void timer_isr()
    {
        if  (TMR1IF)
        {
            count++;
            if (count == k)
            {
            RD0 = 0;  // LED ON
            RD1 = 1; 
            count=0;
            }
            TMR1IF=0;
        }//interrupt service routine 
    }
    Your Ip = 30 Amps and Is = 80 Amps but your sensor is 5 Amps type.
    Did you change the ACS712 sensor to 100A or 200A type?
    I see you use 20 MHz Oscillator but with 20 MHz you can't get 1 sec timer interrupt. Even if you use 4 MHz Crystal then you can get around 500ms timer interrupt max.
    Why not create a 1ms timer interrupt and then find out value for k and test if ++count >= k in ISR?



  17. #17
    Full Member level 4
    Points: 963, Level: 7

    Join Date
    May 2019
    Location
    Roskilde, Denmark
    Posts
    219
    Helped
    9 / 9
    Points
    963
    Level
    7

    Re: PIC 16f877A interrupt

    Quote Originally Posted by Junaid1996 View Post
    kindly help me.
    Hi Junaid1996!

    For what it's worth, I had the same issue not long ago on an 16F device i.e. external interrupt + TIMER1 interrupt. In the end I dropped the external interrupt and did some polling in main loop in stead. The main reason for this was that regardless of IOCBP/IOCBN settings the external interrupt triggered on both edges.



--[[ ]]--