PIC LED Push Button Counter issue

Thread Starter

rkrutz

Joined Dec 2, 2009
29
Hello,
I am working on a PIC project that is counting the number of push button presses and when it hits a predetermined value it will change states. However when the number of button presses equals the value nothing happens. I have even tried setting it up so that as long as the counter is greater than the set value the state would change to see if there was a debouncing issue and that too did not make a difference. I was wondering if anyone could point me in the right direction? I am assuming there is an issue in my code. I am using the 16f88 with XC8 compiler and MPLABX

Rich (BB code):
 #include <stdio.h>
#include <stdlib.h>

#define _XTAL_FREQ 800000//Declare internal OSC Freq as 8MHz
#include <xc.h>
#include<pic.h>

__CONFIG(FOSC_INTOSCIO & WDTE_OFF & PWRTE_OFF & MCLRE_ON & BOREN_OFF & LVP_OFF & CPD_OFF & WRT_OFF & CCPMX_RB0 & CP_OFF);
__CONFIG(FCMEN_ON & IESO_ON);

unsigned int count=0;

main()
{
    TRISA=0;//Sets all ports on A to be outputs
    TRISB=1;//Sets all ports on B to be inputs

    for(;;){
        if(PORTBbits.RB0==1){//When the button is  pressed the LED is off
            PORTAbits.RA1 =0;
            count=count+1;
        }
            else  {
                PORTAbits.RA1=1;
                count = count +1;
                        
            }
        if (count > 20){//if count =20 aka 20 button presses the LED turns on
            PORTAbits.RA0=1;
        }
        else{
            PORTAbits.RA0=0;
        }
        
    }

}
 

tshuck

Joined Oct 18, 2012
3,534
First, you are only making RB0 an input, but that shouldn't matter in this case, just something for you to remember...

Second, you increment count regardless of the state of RB0, so RA1 will be changing pretty fast.

Third, you are not resetting count, this may, or may not, be desired operation. As it is, count will continue to increment on each iteration, and overflow to 0 after 65535(assuming 16 bit int, which I think XC8 does...)

Is it safe to assume you are trying to view the operation with LEDs? Using am oscilloscope should show you the behavior your eyes can't see...
 

Thread Starter

rkrutz

Joined Dec 2, 2009
29
Thanks for the help. I only have RB0 as an input because that is where I have a NC switched hooked up. Is there a better way of doing that?

As for the counter when I changed it to just work on the if statement now it will go on after only 1 press not 20. Is this due to the debouncing in the switch and therefor should go away when I either do a hardware or software fix? I am still not understanding the software fix after reading a few different versions online(if anyone could recommend a good debouncing guide online that would be great).

As for not resetting the counter that was on purpose for this test, I am just removing my pull-up resistor on MCLR or modifying and re-uploading the code to reset the program.

Yes it is safe to assume that I am using LEDs, I do have access to a scope at work, but not at home.
 

tshuck

Joined Oct 18, 2012
3,534
Thanks for the help. I only have RB0 as an input because that is where I have a NC switched hooked up. Is there a better way of doing that?
No, there's nothing wrong with that, just that your comments indicate that you are attempting to set all of PORTB to be inputs.

As for the counter when I changed it to just work on the if statement now it will go on after only 1 press not 20. Is this due to the debouncing in the switch and therefor should go away when I either do a hardware or software fix? I am still not understanding the software fix after reading a few different versions online(if anyone could recommend a good debouncing guide online that would be great).
If you don't have a method of debouncing your input, there is no way to determine if the device is operating properly(you could always simulate it, though)...

Here is a pretty good reference for switch debounce, page 1 discusses the need and characteristics for switch debouncing, page two discusses ways to mitigate switch bounce.

As for not resetting the counter that was on purpose for this test, I am just removing my pull-up resistor on MCLR or modifying and re-uploading the code to reset the program.
You needn't remove the resistor to program it, just connect Vpp directly to pin 1(or whatever it is for your device) and use a pull-up from there... 10kΩ is usually what I use...

Yes it is safe to assume that I am using LEDs, I do have access to a scope at work, but not at home.
You also need to be aware that you cannot see the high frequency(relative to human sight) flashes of the LED. You may want to slow things down to work out the kinks, but If you design properly, shouldn't be necessary...
 

Thread Starter

rkrutz

Joined Dec 2, 2009
29
Thanks I will try that after work tomorrow and see. Yes I am not removing the resistor for programming, I am either removing the resistor to cycle the MCLR pin to reset the PIC or reprogramming with a modified code.
 

Thread Starter

rkrutz

Joined Dec 2, 2009
29
Thanks for the help! I added the following statement
Rich (BB code):
if(PORTBbits.RB0==1){//When the button is  pressed the LED is off
            __delay_ms(5);
            if(PORTBbits.RB0==1){
            PORTAbits.RA1 =0;
                count=count+1;
            }
        }
The one thing I keep noticing is that it is not always reliable. Even when I keep the press duration consistent the count can fluctuate a little and it also will turn on if I just keep the button pressed once for a long time. However after reading up on debouncing it seems like a simple case like this should work because I would want to have the input change states then have a brief pause and recheck the same pin to make sure the input is the same, which would insure that it was actually pressed and not just an internal bounce. Is there something else I am missing?

EDIT:
It looks like if I add a condition to check for the switch to be released it before it counts a press the issue of the long press, but it still is not repeatable every time just better then the first code.
 
Last edited:

tshuck

Joined Oct 18, 2012
3,534
....Sounds like abounce issue... 5Ms is probably not enough time to wait for settling... increase that wait before checking. Also now that it may determine false button presses when released if the switch bounces high at the right times...
 

Thread Starter

rkrutz

Joined Dec 2, 2009
29
After playing around with delay times and how I press the button I think I have it working right. I also noticed when using the delay_ms function that the delay is longer then when it should be. For example a 50ms delay actually acts like a 1sec delay, would that suggest there is something wrong with the internal oscillator on the chip I am using?
 

tshuck

Joined Oct 18, 2012
3,534
It would suggest the oscillator you have defined (#define Foc, or whatever the #define is) is not the same that your PIC is running off of...

Actually, it looks like that's the case.... you have 800,000 for _XTAL_FREQUENCY...
 

tshuck

Joined Oct 18, 2012
3,534
It looks like you are assuming that #define sets the crystal frequency... this its not the case, all the #define does is tell the pre compiler to replace any instance of _XTAL_FREQUENCY with the number specified.


You need to configure the PIC to run first in your CONFIG(), which you have, then OSCCON bits to determine a finer control over the oscillator...
 

tshuck

Joined Oct 18, 2012
3,534
Okay, now that I've taken a look at the datasheet, look at page 42, this is the OSCCON register. By default, the bits that select the frequency of the internal oscillator are cleared, meaning the oscillator is running at 31.25kHz.

The delay routine used the #defined _XTAL_FREQUENCY to determine the delay. Having a #defined _XTAL_FREQUENCY of 800000, means the delay is
(800000/31250)*50ms =1.28 seconds, about what you mentioned the delay was...
 

Thread Starter

rkrutz

Joined Dec 2, 2009
29
Thanks for all your help! Everything seems to be working okay, I just need to keep playing around with the code to figure out the right delay time since now when I press the button the LED will come on but not latch so that is just a code issue I can work on. At least I believe I have the debounce part working right. Thanks again!
 

Thread Starter

rkrutz

Joined Dec 2, 2009
29
Never mind I had a loose wire that was causing a short which is why the LED was not working right. Now everything works great, I just need to figure out the best delays for my switch but that is all trial and error. Thanks again this was a huge help.
 
Top