CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Problems with bounce in code

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
danielpepo



Joined: 12 Apr 2010
Posts: 5

View user's profile Send private message

Problems with bounce in code
PostPosted: Fri Apr 30, 2010 2:09 pm     Reply with quote

I'm using this code to know if a wheel is turning right or left and to increment or decrement the times it turns and show it in a couple of 7segment displays.
When the wheel stops on one of the optical switches, after a few seconds it starts to increment or decrement even though I'm using a debounce code. Can anyone please help me? Thanks!
Code:

#include <16F88.H>
#fuses XT, NOWDT, PUT
#use delay(clock=4000000)
#byte port_b=6


int8 unid = 2;
int8 dece = 2;
int8 reta = 1;
int8 flag_b2 = 0;
int8 flag_b3 = 0;
int8 cont = 0;
// These are the "Bvar" variables.
int8 B2 = 0;   // For the button on pin b2
int8 B3 = 0;   // For the button on pin b3

#include <Button.c>

//  Function parameters:
//
//  button(pin, DownState, Delay, Rate, BVar, Action)
//
//  Returns:  The value of the Action variable (normally
//            set = 1) is returned when the button is
//            pressed.  When the button isn't pressed,
//            the opposite value is returned (normally 0).
//======================================

void main(void)
{
   delay_ms(10);
   while(1)
      { //check if button is pressed, if so, increment units or tens
      if(button(PIN_B2, 1, 0, 0, B2, 1))
         {
         cont++;
         if(cont==1&&flag_b2!=1)
            flag_b2=1;
         }
      
      //the LED with the low transistor lights
      output_high(pin_b7);
      output_high(pin_b6);   //units
      output_a(dece);
      output_low(pin_b6);    //tens on
      delay_us(reta);

      if(button(PIN_B3, 1, 0, 0, B3, 1))
         {
         cont++;
         if(cont==2)
            flag_b3=1;
         }


      if(flag_b2==1&&flag_b3==1)
         {
         cont=0;
         flag_b2=0;
         flag_b3=0;
         if(unid<10)
            {
            unid++;
            }
         if(unid==10)
            {
            dece++;
            unid=0;
            }
         if(dece==10)
            {
            dece=0;
            unid=0;
            }
         }
      
      if(cont==2)
         {cont=0;
         if(unid==0&&dece!=0)
            {unid=9;
            dece--;
            }
         else if(unid==0&&dece==0)
            unid=0;
         else
            unid--;
         }
      if(!input(pin_B4))      //second button to reset counter
         {
         dece=0;
         unid=0;
         cont=0;
         }
      
      //the LED with the low transistor lights
      output_high(pin_b7);
      output_high(pin_b6);   //units on
      output_a(unid);
      output_low(pin_b7);      //tens
      delay_us(reta);
   }
}


This is the debounce code:

Code:
// Description of function parameters:

// Pin:
// This must be a CCS-style pin number, such as PIN_B0.

// Downstate:
// This is the logic level of the button when it's pressed.
// For a circuit with a Normally-Open switch and a pull-up
// resistor, this parameter will be 0.

// Delay:
// This is the initial delay before auto-repeat begins.
// Example:  A Delay value of 50 means a 500 ms auto-repeat
// delay.

// Rate:
// This is the auto-repeat interval.
// Example:  A Rate value of 10 gives a 100 ms interval,
// which means an auto-repeat rate of 10 keys per second.     

// Bvar:
// This an 8-bit variable that must be declared in the main
// program, and it must be initialized to zero.  There must
// be a separate variable for each button that you use.
// Example: Declare the variable for pin B0 as int8 B0 = 0;
// See the demo program for more examples.   Note that Bvar
// is a "reference variable" (it has a "&" in front of it).
// This is intentional.  It's done so the button function
// can directly access the Bvar variable which is declared
// outside the function, without having to pass a pointer
// to it.  This keeps the function interface simple.
//====================================

// Action:
// This is the value that's returned when the button is
// pressed.  Normally you set this = 1.       

// Return value:
// When the button is pressed, the value of the Action
// parameter will be returned.  When the button is not
// pressed, the opposite value will be returned.
// Normally, you set the Action parameter = 1, and so
// if the button is pressed, the function will return 1.
// If it's not pressed, it will return 0.  So you just
// poll the function every 10 ms in a loop, and check the
// return value with an if() statement.  If it's non-zero
// then the button is pressed and you can take appropriate
// action.


//=====================================
// The following macro is used by the Button function.
#define read_bit_var(x)  bit_test(*(int8 *)(x >> 3), x & 7)


//=====================================
int8 button(int16 pin, int8 downstate, int8 delay,
            int8 rate, int8 &BVar, int8 action)
{
int8 pin_value;

// Read the button pin.
pin_value = read_bit_var(pin);

// Check if the button is pressed.  It's pressed if the
// pin value is the same as the "downstate".   If it's not
// pressed, then zero the Bvar and return "Not pressed".
if(pin_value != downstate)
  {
   Bvar = 0;
   return(!action);   
  }

// The button is pressed.  Check to see if it's a new
// keypress.  We can tell if it's a new keypress by
// checking if BVar = 0.   If so, load the counter with
// the initial auto-repeat delay and return "Pressed".
// (If the delay has been set to 0, then load a non-zero
// value to allow the function to operate properly).
if(Bvar == 0)       
  {
   if(delay == 0)
      Bvar = 255;     
   else   
      Bvar = delay;   

   return(action);
  }

// Decrement the auto-repeat counter.
Bvar--;       

// Check if we just counted down to 0.   If so, then load
// the counter with the auto-repeat interval and return
// "Pressed".  If the delay is set to 0 or 255, it means
// that auto-repeat is disabled, so fall through and
// return "Not Pressed".
if(BVar == 0)   
  {
   BVar = rate;
   
   if((delay != 0) && (delay != 255))
      return(action);   
  }

// If the counter is positive, then it means an auto-repeat
// is still pending, so return "Not Pressed".
return(!action);

}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Apr 30, 2010 2:15 pm     Reply with quote

Quote:
void main(void)
{
delay_ms(10);

while(1)
{ //check if button is pressed, if so, increment units or tens
.
.
.
}

The 10ms delay is supposed to be inside the button polling loop.
You have it above the loop.
danielpepo



Joined: 12 Apr 2010
Posts: 5

View user's profile Send private message

PostPosted: Sun May 02, 2010 1:59 pm     Reply with quote

There's another thing about the code, when I set the delay for 10ms, it takes about 4 seconds for the display to multiplex. Any ideas what's wrong?
Thank you
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group