PIC16F877A PUSHBUTTON

Discussion in 'Embedded Systems and Microcontrollers' started by namratha_r, Jan 27, 2015.

  1. namratha_r

    Thread Starter New Member

    Jan 27, 2015
    23
    0
    I am working on pic16f877a and using XC8 complier. Have interfaced pushbutton if I press the button value should increment by 1.. its working fine but one more condition - If I keep press and hold down for long time fastely value should increment how to do this I dont no am trying but not achieved. Below is my button code

    void main()
    {
    int oldstate;
    oldstate = 0;

    while(1)
    {
    if(RA4 == 1) // switch

    {

    oldstate = 1; // update flag

    }

    if(oldstate &&(RA4 == 0))

    {

    val++;

    if(val > 10)

    {

    val = 1;

    }

    oldstate = 0; // update flag

    }
    }
     
  2. sevenfold4

    Member

    Jan 12, 2015
    80
    7
    Please make your code more readable


    Code (Text):
    1.  
    2. void main()
    3. {
    4.     int oldstate;
    5.     oldstate = 0;
    6.     while(1)
    7.     {
    8.         if(RA4 == 1) // switch
    9.         {
    10.             oldstate = 1; // update flag
    11.         }
    12.         if(oldstate &&(RA4 == 0))
    13.         {
    14.             val++;
    15.             if(val > 10)
    16.             {
    17.                 val = 1;
    18.             }
    19.  
    20.             oldstate = 0; // update flag
    21.         }
    22.     }
    23. }
    24.  
    I would personally recommend using an interrupt for the button instead. If more code is added it will simplify and make everything faster.

    I can not really understand your question, but this should increment variable v for as long as the button is held down.


    Code (Text):
    1. void main()
    2. {
    3.     int v = 0;
    4.     while(1)
    5.     {
    6.         if(RA4 == 1) // switch
    7.         {
    8.             v++;
    9.         }
    10.     }
    11. }
    For simplicity sake you can add a delay to take care of bouncing and if you want to increment it slower, while held down
     
    Last edited: Jan 27, 2015
  3. namratha_r

    Thread Starter New Member

    Jan 27, 2015
    23
    0
    Code (Text):
    1.  
    2. void main()
    3. {
    4. int oldstate;                                              // old state flag
    5. oldstate = 0;
    6.  
    7. while(1)
    8. {
    9. if(RA4 == 1)                                           // [I]Detect logical one (switch)[/I]
    10.  
    11. {
    12.  
    13. oldstate = 1;                                          // update flag
    14.  
    15. }
    16.  
    17. if(oldstate &&(RA4 == 0))                   // [I]Detect one-to-zero transition[/I]
    18.  
    19. {
    20.  
    21. val++;                                                  // increment value by 1
    22.  
    23. if(val > 10)                                        
    24.  
    25. {
    26.  
    27. val = 1;                                              // counts upto 10 values
    28.  
    29. }
    30.  
    31. oldstate = 0;                                     // update flag
    32.  
    33. }
    34. }
    35.  
    Moderators note: Please use code tags to preserve the spaces
     
    Last edited by a moderator: Jan 27, 2015
  4. namratha_r

    Thread Starter New Member

    Jan 27, 2015
    23
    0
    if i press the button value will be incremented by 1 . And in my code if i press down and hold button for long time value will be same here i have to change the logic . If i press down the button for long time value should fastely increment ...
     
  5. sevenfold4

    Member

    Jan 12, 2015
    80
    7
    Please use tabs...

    Code (Text):
    1. void main()
    2. {
    3.     int oldstate; // old state flag
    4.     oldstate = 0;
    5.     while(1)
    6.     {
    7.         if(RA4 == 1) // Detect logical one (switch)
    8.         {
    9.             oldstate = 1; // update flag
    10.         }
    11.         if(oldstate &&(RA4 == 0)) // Detect one-to-zero transition
    12.         {
    13.             val++; // increment value by 1
    14.             if(val > 10)
    15.             {
    16.                 val = 1; // counts upto 10 values
    17.             }
    18.             oldstate = 0; // update flag
    19.         }
    20.     }
    21. }    
    Of course the value will remain the same, because of the variable oldstate, it can not increment until you have released the button and the variable resets. You can have the variable increment once when pressed, or you can use my code and have it increment for as long as the button is pressed...
     
  6. namratha_r

    Thread Starter New Member

    Jan 27, 2015
    23
    0
    Thanks .., will try it out
     
  7. sevenfold4

    Member

    Jan 12, 2015
    80
    7
    If it increments too fast, add a delay.
    If my answer is not what you hoped for please be clearer with your question.
     
  8. namratha_r

    Thread Starter New Member

    Jan 27, 2015
    23
    0
    Hi..,
    Here is my complete code . What am trying to do actually is AC dimming. Have used TRIAC and zerocrossing detector in my hardware connected to ac bulb and interfaced 2 pushbuttons. Variable (val) is incremented/decremented when switch is pressed and later used in delay so dimming is happening . Code is working fine for - > If i press the button once val will inc/dec one time so dimming will happen step by step. But, > If i press the button down for longer time val should fastely inc/dec and dimming should happen smoothly without flickering. But here in my code it will be in same state as perilously discussed.

    Code (Text):
    1.  
    2.  
    3. void interrupt RB0_int(void)
    4. {
    5.     if (INTF)
    6.     {
    7.         RB0 = 1;
    8.         INTF = 0;
    9.     }
    10. }
    11.  
    12. void main(void)
    13. {
    14.     int val;
    15.     int oldstate;
    16.     int oldstate1;
    17.  
    18.     PORTB = 0;
    19.     TRISB = 0xFF; //RB0 input for interrupt
    20.     TRISD = 0;
    21.     PORTA = 0;
    22.     TRISA = 0xFF;
    23.     OPTION_REG = 1;
    24.  
    25.      val = 1;
    26.      oldstate = 0;
    27.      oldstate1 =0;
    28.    
    29.     while(1)
    30.     {
    31.         if (RB0)                       // interrupt
    32.         {
    33.             if(RA4 == 1)           // sw1
    34.             {
    35.                 oldstate = 1;
    36.             }
    37.                 if(oldstate &&(RA4 == 0))
    38.                 {
    39.                     val++;              
    40.                     if(val > 10)
    41.                     {
    42.                         val = 1;
    43.                     }
    44.  
    45.                     oldstate = 0;
    46.  
    47.                }
    48.  
    49.             if(RB4 == 1)                   // sw2
    50.             {
    51.                 oldstate1 = 1;
    52.             }
    53.             if(oldstate1 &&(RB4 == 0))
    54.             {
    55.                 val--;
    56.                 if(val < 1)
    57.                 {
    58.                     val = 10;
    59.                 }
    60.                 oldstate1 = 0;
    61.  
    62.             }
    63.                     DelayMs(val);                  
    64.                     RD1 = 0;                                     //light on                          
    65.                     DelayMs(1);
    66.                     RD1 = 1;                                    //light off
    67.  
    68.                     while (RB0)
    69.                     {
    70.  
    71.                     }
    72.             }
    73.  
    74.     }
    75.     return;
    76. }
    77. }
     
  9. sevenfold4

    Member

    Jan 12, 2015
    80
    7
    And what was your question? It does not dim smoothly?
    The val will increment/decrement once each time you press the button, because of the variable oldstate0 and 1.
     
  10. namratha_r

    Thread Starter New Member

    Jan 27, 2015
    23
    0
    if i remove oldstate also same issue ...
     
  11. sevenfold4

    Member

    Jan 12, 2015
    80
    7

    Code (Text):
    1.  
    2. if(RA4 == 1)           // sw1
    3.             {
    4.          
    5.                 if((RA4 == 0))
    6.                 {
    7.                     val++;      
    8. //Insert some kind of delay.      
    9.                     if(val > 10)
    10.                     {
    11.                         val = 1;
    12.                     }
    13.                 }
    14.             }
    15.  
    16.                }
    You probably will want to make val a bigger value, to ensure more smoothness.
     
  12. namratha_r

    Thread Starter New Member

    Jan 27, 2015
    23
    0
    Sorry for disturbing :( ... If button pressed down its flickering . I changed delay as well as changed val value

    Code (Text):
    1.  
    2. if(RA4 == 0)
    3.             {
    4.                 DelayMs(100);
    5.                 if((RA4 == 0))
    6.                 {
    7.                     val++;
    8.                     DelayMs(50);
    9.                     if(val > 10)
    10.                     {
    11.                         val = 1;
    12.                     }
    13.                 }
    14.             }
     
  13. sevenfold4

    Member

    Jan 12, 2015
    80
    7
    Well of course it will be flickering, You are not using a Digital to Analog to power the LED. You are simply turning it on and off at different time periods.
    Code (Text):
    1.    DelayMs(val);                
    2.                     RD1 = 0;                                     //light on                        
    3.                     DelayMs(1);
    4.                     RD1 = 1;                                    //light off
     
  14. namratha_r

    Thread Starter New Member

    Jan 27, 2015
    23
    0
    Right ... Can I use PWM ?
     
  15. sevenfold4

    Member

    Jan 12, 2015
    80
    7
    You can use PWM to control a motor, but a LED?
    I suspect that you will need a driver or something, but when connected straight, i doubt.
    You can of course google it. I have never tried something like this, so i do not really know.
    EDIT:
    This is what i found from my first google
    http://www.eetimes.com/document.asp?doc_id=1281013
    It seems you do need a driver to do this.
     
  16. namratha_r

    Thread Starter New Member

    Jan 27, 2015
    23
    0
    Am not using led .. have connected AC Incandescent bulb .
     
  17. jpanhalt

    AAC Fanatic!

    Jan 18, 2008
    5,671
    899
    If you want to smooth out the flicker, you can use a low-pass filter like this:

    upload_2015-1-29_5-24-54.png

    John
     
  18. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,386
    1,605
    When you use "TRIAC and zerocrossing detector in my hardware connected to ac bulb" you control the brightness by delaying the TRIAC turn on from each and every zero crossing. Do not think PWM (though this is a close cousin to that) as there is no linear relationship between delay and brightness.

    Do not compute the delay but use a look up table as this is much faster: when you have 100% brightness you have zero time to calculate that delay!

    However, a clever coder could calculate the delay for the next half cycle, and have almost the full half cycle of time to compute that delay.

    (I would ask to see your schematic but that might open an unneccessary TOS (Terms of Service) discission: just be careful working on this!)
     
Loading...