+ Post New Thread
Results 1 to 9 of 9
  1. #1
    Member level 3
    Points: 469, Level: 4

    Join Date
    Aug 2018
    Posts
    59
    Helped
    0 / 0
    Points
    469
    Level
    4

    AutokeyReset function

    Dear all.
    I am looking for code where i could achieve below functionality.
    function requirement: Once Test button pressed in timer interrupt timing should start after 1 min automatically RUN_RESET() should be called.
    in below code unless keyreset is pressed RUN_RESET() function wont be called. Can some one suggest how can implement logic

    i have used PIC16F886
    Code:
    #include 
    #include 
    #include 
    #include "delay.h"
    
    __CONFIG(WDTE_OFF & PWRTE_ON & CP_OFF & BOREN_ON & LVP_OFF & CPD_OFF & FCMEN_ON & IESO_OFF & CP_OFF & MCLRE_ON);
    #define TEST RA5
    #define RESET RC0
    #define ACK RC1
    #define MUTE RC2
    #define AUTO_RST RA4 
    unsigned char Auto_Counter=0;
    
    void interrupt isr(void) {
    
     asm("clrwdt"); //ANN
    
     if (TMR1IF) {
      TMR1IF = 0;
      /// TMR1H = 0xD8; //
      // TMR1L = 0xFC; //
      TMR1H = 0xAF;
      TMR1L = 0xC8;
    
     }
    
     INTF = 0;
    
    
    }
    
    void InitController() {
    
     OSCCON = 0b01110010; //changes 8Mhz
     WREN = 0;
     WDTCON = 0b00010111; //2sec Watch Dog Reset //STP //ANN
     PORTA = 0b00000000;
     TRISA = 0b00111000;
    
     TRISB = 0b11001000;
     PORTB = 0b00000000;
    
     WPUB = 0b00000000;
     ANSEL = 0b00000000;
     ADCON0 = 0b00000000;
    
     // TRISC = 0b10000111;
     TRISC = 0b11001111;
     PORTC = 0b00000000;
     ANSELH = 0b00000000;
    
     ADDEN = 0;
     T1OSCEN = 0;
     INTEDG = 0; //falling edge
     INTF = 0;
     INTE = 1;
     PIE1 = 0b00000001;
     PIR1 = 0x01;
     INTCON = 0; //ANN
     T1CON = 0b00000101; //Timer Settings //ANN
     TMR1H = 0xF0; //ANN
     TMR1L = 0x61; //ANN
     TMR1IE = 1;
    
     PEIE = 1; //ANN
     GIE = 1; // Global interrupt enabled.
    
    }
    
    
    //********************************************************************************************
    //// CHECK IF TEST IS PRESSED
    //********************************************************************************************
    
    void Key_CHK_TEST() {
    
     if (!TEST && !bits.KeyLock_TEST1) {
      Debounce++;
      if (Debounce > 30) {
       Debounce = 0;
       bits.KeyLock_TEST1 = 1;
       RUN_TEST();
    
      }
     } else if (TEST && bits.KeyLock_TEST1) {
      bits.KeyLock_TEST1 = 0;
      Debounce = 0;
     }
    
    }
    
    //**********************************************************************************************
    //// CHECK MUTE KEY pressed
    //**********************************************************************************************
    
    void Key_CHK_MUTE() {
    
     if (!MUTE && !bits.KeyLock_MUTE1) {
      Debounce++;
      if (Debounce > 30) {
       Debounce = 0;
       bits.KeyLock_MUTE1 = 1;
       RUN_MUTE();
      }
     } else if (MUTE && bits.KeyLock_MUTE1) {
      bits.KeyLock_MUTE1 = 0;
      Debounce = 0;
     }
    
    }
    
    //**********************************************************************************************
    //// CHECK ACK KEY PRESS IN RUN MODE
    //**********************************************************************************************
    void Key_CHK_ACK() {
     if (!ACK && !bits.KeyLock_ACK1) { // CHECK IF ack IS PRESSED
      Debounce++;
      if (Debounce > 30) {
       Debounce = 0;
       bits.KeyLock_ACK1 = 1;
       RUN_ACK();
      }
     } else if (ACK && bits.KeyLock_ACK1) {
      bits.KeyLock_ACK1 = 0;
      Debounce = 0;
     }
    }
    
    //**********************************************************************************************
    //// CHECK RESET KEY PRESS IN RUN MODE
    //**********************************************************************************************
    
    void Key_CHK_RESET() {
    
     if (!RESET && !bits.KeyLock_RESET1) { // CHECK IF SELECT IS PRESSED
      Debounce++;
      if (Debounce > 30) {
       Debounce = 0;
       bits.KeyLock_RESET1 = 1;
       RUN_RESET();
      }
     } else if (RESET && bits.KeyLock_RESET1) {
      bits.KeyLock_RESET1 = 0;
      Debounce = 0;
     }
    }
    
    
    
    
    
    
    void CHECK_SEQ(void) {
     if (AUTO_RST == 1) { 
      bits.MANUAL_RESET = 1;
      bits.AUTO_RESET = 0;
    
     }
    
     if (AUTO_RST == 0) {
      bits.MANUAL_RESET = 0;
      bits.AUTO_RESET = 1;
    
     }
    
    }
    
    
    
    
    
    void main() {
     InitController();
     CHECK_SEQ();
     while(1) {
      Key_CHK_TEST();
      Key_CHK_MUTE();
      Key_CHK_ACK();
      if (bits.MANUAL_RESET == 1)
       Key_CHK_RESET();
    
      if (bits.AUTO_RESET == 1) {
       Auto_Counter++;
       if (Auto_Counter >= 100) {
        Auto_Counter = 0;
        RUN_RESET();
       }
    
      }
     }
    
    
    
    }

    •   AltAdvertisement

        
       

  2. #2
    Super Moderator
    Points: 81,302, Level: 69
    Achievements:
    7 years registered
    Awards:
    2nd Helpful Member
    betwixt's Avatar
    Join Date
    Jul 2009
    Location
    Aberdyfi, West Wales, UK
    Posts
    13,328
    Helped
    4453 / 4453
    Points
    81,302
    Level
    69

    Re: AutokeyReset function

    More information is needed to answer exactly but the easiest way to achieve it is to follow this principle:

    Accept that unless you have a very low clock frequency you will not be able to make delays as long as one minute using a timer alone.

    inside the ISR:
    1. remove the "clrwdt" line. It is useful elsewhere but not inside an ISR because an interrupt routine can continue to run if the rest of the program crashes.
    2. Set the values in TMR1H and TMR1L so it overflows and interrupts say every 100mS. Your code is good but I can't tell if the values are correct without knowing the clock frequency.
    3. You need to count the interrupts, maybe this is what your "Auto_Counter" is supposed to do but bear in mind that for 1 minute you need to count 60 seconds of 1/10 S (60 * 10) = 600 so a char size variable is too small. Use a volatile int instead.
    4. Add the line "if(Auto_Counter > 0) Auto_Counter--;" so if it contains more than zero it counts down at each interrupt. If it reaches zero it stops counting.

    in your main() code:
    1. Check for the test button being pressed.
    2. When pressed, load the value (600 in my example) into Auto_Counter;
    3. If "Auto_Counter" holds zero, run your RUN_RESET() routine.
    4. If Auto Counter is not yet zero you are still waiting so do a "clrwdt" and go back to step 3.

    Note that if you use this method, you can create any delay from 100mS to 327.68 seconds (~5 minutes 45 seconds) by simply loading different numbers into Auto_Counter.
    If you want to use the watchdog timer you first have to enable it in the config settings!

    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.



  3. #3
    Member level 3
    Points: 469, Level: 4

    Join Date
    Aug 2018
    Posts
    59
    Helped
    0 / 0
    Points
    469
    Level
    4

    Re: AutokeyReset function

    i dint find any sample code in your thread.



    •   AltAdvertisement

        
       

  4. #4
    Member level 3
    Points: 469, Level: 4

    Join Date
    Aug 2018
    Posts
    59
    Helped
    0 / 0
    Points
    469
    Level
    4

    Re: AutokeyReset function

    I have tried but it didn't worked.

    Currently its doing like this.

    Manually: When Test button pressed RUN_TEST() called;

    When MUTE button pressed RUN_Mute() called;
    When ACK button pressed RUN_ACK() called;
    When RESET button pressed RUN_RST() called;
    Auto Mode:

    When Test button pressed RUN_TEST() called;

    When MUTE button pressed RUN_Mute() called;

    When ACK button pressed RUN_ACK() called;

    Here RunReset function automatically called.



    Now I am looking for feature.Where once Test Button pressed RUN_Test() should be called. Wait for 1 min

    within 1 min if any of key is not pressed automatically RUN_RST() should be called.else wait for other key to presses and other operation should be perform.







    Code:
    void int Test_Button_Counter=0;
    void interrupt isr(void) {
    
    if (TMR1IF) {
    TMR1IF = 0;
    TMR1H = 0xAF;
    TMR1L = 0xC8;
    if(bits.KeyLock_TEST1==1) {
    Test_Button_Counter++;
    if(Test_Button_Counter>200) {
    Test_Button_Counter=0;
    bits.AUTO_RESET =1;
    }
    }
    }
    
    INTF = 0;
    
    
    }
    
    void main() {
    
    while(1) {
    Key_CHK_TEST();
    Key_CHK_MUTE();
    Key_CHK_ACK();
    if (bits.MANUAL_RESET == 1)
    Key_CHK_RESET();
    
    if (bits.AUTO_RESET == 1) {
    
    RUN_RESET();
    }
    
     
    
    }
    
    }



    •   AltAdvertisement

        
       

  5. #5
    Super Moderator
    Points: 81,302, Level: 69
    Achievements:
    7 years registered
    Awards:
    2nd Helpful Member
    betwixt's Avatar
    Join Date
    Jul 2009
    Location
    Aberdyfi, West Wales, UK
    Posts
    13,328
    Helped
    4453 / 4453
    Points
    81,302
    Level
    69

    Re: AutokeyReset function

    I have no idea what your schematic and setup is but that isn't what you originally asked for and you didn't do as I suggested.
    Firstly, please comment your code and indent the functions, it makes it far easier to read. I've reformatted your original code below:
    Code:
    void int Test_Button_Counter=0;
    void interrupt isr(void)
    {
        if (TMR1IF) 
        {
            TMR1IF = 0;
            TMR1H = 0xAF;
            TMR1L = 0xC8;
            if(bits.KeyLock_TEST1==1) 
            {
                Test_Button_Counter++;
                if(Test_Button_Counter>200) 
                {
                    Test_Button_Counter=0;
                    bits.AUTO_RESET =1;
                }
            }
        }
    
        INTF = 0;
    }
    
    
    void main() 
    {
        while(1) 
        {
            Key_CHK_TEST();
            Key_CHK_MUTE();
            Key_CHK_ACK();
            if (bits.MANUAL_RESET == 1) Key_CHK_RESET();
            if (bits.AUTO_RESET == 1) 
            {
                RUN_RESET();
            }
        }
    }
    What I suggested was to use to interrupt routine to maintain a count-down timer. It is far easier and quicker to see if a value is zero or not than to compare it to another number.
    More like this:
    Code:
    #define TIMEOUT_PERIOD 100
    
    volatile int Test_Button_Counter=0;
    
    void interrupt isr(void)
    {
        if (TMR1IF) 
        {
            TMR1IF = 0;
            TMR1H = 0xAF;       // without knowing your clock and prescaler I can't confirm these values
            TMR1L = 0xC8;
     
            if(Test_Button_Counter > 0) Test_Button_Counter--; // count down to zero then stop
         }
    
        INTF = 0;
    }
    
    
    void main() 
    {
        while(1) 
        {
            Key_CHK_TEST();
            Key_CHK_MUTE();
            Key_CHK_ACK();
            
            if (Test button pressed)
            {
                RUN_TEST();
                Test_Button_Counter = TIMEOUT_PERIOD; // start the countdown period for 1 min.
            }
             
            if (Test_Button_Counter == 0)
            {
                RUN_RST();
            }
        }
    }
    You need to set the value in the #define according to how fast your clock runs, it will decide how long it take before RUN_RST() is automatically called. Bigger number = longer wait.
    Also note two other 'bugs' you might encounter:
    1. the main() has a while(1) loop that continues after RUN_RST() has been called, check this is what you want to happen.
    2. the timer values are only initialized inside the ISR so the first time it is run after a reset will take 0xFFFF counts instead of 0xAFC8. If you want the timing ot be accurate on the first run, you need to put the values in the timer registers BEFORE the ISR is called as well as inside it.

    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.



  6. #6
    Member level 3
    Points: 469, Level: 4

    Join Date
    Aug 2018
    Posts
    59
    Helped
    0 / 0
    Points
    469
    Level
    4

    Re: AutokeyReset function

    i have tested code . All above mentioned condition are working as per mentioned but it is not resetting .i have checked in debug when key pressed It load the value and some iteration it became zero. But it wont Reset at all.

    Old Program:
    Code:
    void Key_CHK_TEST() {
    
     if (!TEST && !bits.KeyLock_TEST1) {
      Debounce++;
      if (Debounce > 30) {
       Debounce = 0;
       bits.KeyLock_TEST1 = 1;
       RUN_TEST();
    
      }
     } else if (TEST && bits.KeyLock_TEST1) {
      bits.KeyLock_TEST1 = 0;
      Debounce = 0;
     }
    
    }
    
    void Key_CHK_RESET() {
    
     if (!RESET && !bits.KeyLock_RESET1) { // CHECK IF SELECT IS PRESSED
      Debounce++;
      if (Debounce > 30) {
       Debounce = 0;
       bits.KeyLock_RESET1 = 1;
       RUN_RESET();
      }
     } else if (RESET && bits.KeyLock_RESET1) {
      bits.KeyLock_RESET1 = 0;
      Debounce = 0;
     }
    }

    Changes:
    Code:
    void Key_CHK_TEST() {
    
    	if (!TEST && !bits.KeyLock_TEST1) {
    		Debounce++;
    		if (Debounce > 30) {
    			Debounce = 0;
    			bits.KeyLock_TEST1 = 1;
    			RUN_TEST();
    			TCounter=TIMEOUT_PERIOD;
    
    		}
    	} else if (TEST && bits.KeyLock_TEST1) {
    		bits.KeyLock_TEST1 = 0;
    		Debounce = 0;
    	}
    
    }
    
    
    void RUN_TEST() {
    
    	bits.KeyTEST_PRESS=1;
    
    		if(TCounter==0)
    	{
    		bits.KeyLock_TEST1 = 0;
    		bits.KeyLock_RESET1 = 1;
    		bits.KeyTEST_PRESS = 1;
         	RUN_RESET();
    	}
    
    }
    
    
    void RUN_RESET() {
    
    	if (bits.KeyTEST_PRESS == 1)
    		bits.KeyTEST_PRESS = 0;
    		
    		// Other Function related to REset fun But not any flags realted to Key
    		
    	}



  7. #7
    Member level 3
    Points: 469, Level: 4

    Join Date
    Aug 2018
    Posts
    59
    Helped
    0 / 0
    Points
    469
    Level
    4

    Re: AutokeyReset function

    This what changes i made.When i debug TestFlag became 1 and after define time became zero but it wont call reset funs(). for testing i kept Test period very low instead of 200 kept 5.

    Code:
    #define AUTO_RST		RA4
    #define RESET			RC0
    #define	ACK				RC1
    #define MUTE			RC2
    
    volatile int TCounter=0;
    unsigned char TestFlag=0;
    unsigned char Debounce =0;
    #define TIMEOUT_PERIOD 5
    unsigned char TestFlag=0;
    
    void Key_CHK_TEST() {
    
    	if (!TEST && !bits.KeyLock_TEST1) {
    		Debounce++;
    		if (Debounce > 30) {
    			Debounce = 0;
    			bits.KeyLock_TEST1 = 1;
    			RUN_TEST();
    			TCounter=TIMEOUT_PERIOD;
    			TestFlag=1;
    
    		}
    	} else if (TEST && bits.KeyLock_TEST1) {
    		bits.KeyLock_TEST1 = 0;
    		Debounce = 0;
    
    	}
    
    }
    
    
    void RUN_TEST() {
    	bits.KeyTEST_PRESS=1;
    	// funs realted to Test
    }
    
    void Key_CHK_MUTE() {
    
    	if(!MUTE && !bits.KeyLock_MUTE1) {
    		Debounce++;
    		if(Debounce >30) {
    			Debounce = 0;
    			bits.KeyLock_MUTE1 = 1;
    			RUN_MUTE();
    		}
    	} else if(MUTE && bits.KeyLock_MUTE1) {
    		bits.KeyLock_MUTE1 = 0;
    		Debounce = 0;
    	}
    
    }
    
    
    void RUN_MUTE() {
    
    // funs related to Run_Mute
    
    }
    
    
    void Key_CHK_ACK() {
    	if(!ACK && !bits.KeyLock_ACK1 ) {	// CHECK IF ack IS PRESSED
    		Debounce++;
    		if(Debounce >30) {
    			Debounce = 0;
    			bits.KeyLock_ACK1 = 1;
    			RUN_ACK();
    		}
    	} else if(ACK && bits.KeyLock_ACK1) {
    		bits.KeyLock_ACK1 = 0;
    		Debounce = 0;
    	}
    }
    
    
    void RUN_ACK() {
    	// funs related to RunACk
    
    }
    
    void Key_CHK_RESET() {
    
    	if(!RESET && !bits.KeyLock_RESET1) {		// CHECK IF SELECT IS PRESSED
    		Debounce++;
    		if(Debounce > 30) {
    			Debounce = 0;
    			bits.KeyLock_RESET1 = 1;
    			RUN_RESET();
    		}
    	} else if(RESET && bits.KeyLock_RESET1) {
    		bits.KeyLock_RESET1 = 0;
    		Debounce = 0;
    	}
    }
    
    void RUN_RESET() {
    
    	if (bits.KeyTEST_PRESS == 1)
    		bits.KeyTEST_PRESS = 0;
    	// fUNC ASSOCIATED WITH RESET
    }
    
    void ISR() {
    	if (TMR1IF) {
    		TMR1IF = 0;
    		TMR1H = 0xAF;
    		TMR1L = 0xC8;
    
    		if(TCounter>0) {
    			TCounter--;
    		}
    
    	}
    
    	INTF = 0;
    	if (PRG_RUN == 1) {
    		if (bits.KeyTEST_PRESS == 0) {
    		}
    	}
    
    }
    
    
    void CHECK_SEQ(void) { //STP
    
    	if (AUTO_RST==1) { // CHECK IF HIGH - MANUAL
    		bits.MANUAL_RESET = 1;
    		bits.AUTO_RESET = 0;
    
    	}
    
    	if (AUTO_RST==0) { // CHECK IF LOW - AUTO
    		bits.MANUAL_RESET = 0;
    		bits.AUTO_RESET = 1;
    
    	}
    
    }
    void main() {
    	InitController();
    	CHECK_SEQ();
    	while(1) {
    		Key_CHK_TEST() ;
    		Key_CHK_MUTE();
    		Key_CHK_ACK();
    
    		if(TestFlag==1) {
    			if(TCounter==0) {
    				bits.KeyTEST_PRESS=0;
    				RUN_RESET();
    				TestFlag=0;
    			}
    
    		}
    
    
    		if (bits.MANUAL_RESET == 1)
    			Key_CHK_RESET();
    
    		if (bits.AUTO_RESET == 1) {
    
    			RUN_RESET();
    		}
    	}
    
    }



  8. #8
    Advanced Member level 2
    Points: 3,128, Level: 13
    baileychic's Avatar
    Join Date
    Aug 2017
    Posts
    622
    Helped
    49 / 49
    Points
    3,128
    Level
    13

    Re: AutokeyReset function

    I can provide you a working code but only mikroC PRO PIC code if you are interested and if you can port it to your XC8 code because I don't use XC8 Compiler much.



    •   AltAdvertisement

        
       

  9. #9
    Member level 3
    Points: 469, Level: 4

    Join Date
    Aug 2018
    Posts
    59
    Helped
    0 / 0
    Points
    469
    Level
    4

    Re: AutokeyReset function

    The problem is solved.



--[[ ]]--