Hi all-
I'm currently trying to debounce some buttons in an AVR project with Kenneth Kuhn's debounce algorithm. The problem is that I can't seem to get "IF buttonpressed, do something" to work. This is likely a simple problem, here's what I'm doing.
20 times a second a timer interrupt calls the debounce algorithm. Since there's 4 buttons (I'm only testing 1 currently), I've created array variables (buttonInput[4], integrator[4], etc.)to store the data required by the debounce function. If the debounceOutput variable is a 0, i set buttonPressed to 1 and buttonReleased to 0 (and vice versa). Both are global variables.
Then in main, I check to see if the button was pressed. Since I'm learning, I keep it simple and just toggle an LED. But I can't get it to work.
The funny thing is, if I move the "if statement" to the debounce function, it works. I have another function I wrote to check for errors that will simply blink the same LED any number of times based on the integer passed into the function. If I pass buttonPressed[0] into errorBlink from main, it blinks once. So in other words there is a 1 stored into buttonPressed[0] when the button is pressed.
The statement " if(buttonPressed[0] == 1), PORTA ^= 1<<PINA0;" does not work in main, but again, it works in the debounce function.
Any clue what I'm doing wrong?
Here's my code (minus the initialization functions to make the code smaller):
I'm currently trying to debounce some buttons in an AVR project with Kenneth Kuhn's debounce algorithm. The problem is that I can't seem to get "IF buttonpressed, do something" to work. This is likely a simple problem, here's what I'm doing.
20 times a second a timer interrupt calls the debounce algorithm. Since there's 4 buttons (I'm only testing 1 currently), I've created array variables (buttonInput[4], integrator[4], etc.)to store the data required by the debounce function. If the debounceOutput variable is a 0, i set buttonPressed to 1 and buttonReleased to 0 (and vice versa). Both are global variables.
Then in main, I check to see if the button was pressed. Since I'm learning, I keep it simple and just toggle an LED. But I can't get it to work.
The funny thing is, if I move the "if statement" to the debounce function, it works. I have another function I wrote to check for errors that will simply blink the same LED any number of times based on the integer passed into the function. If I pass buttonPressed[0] into errorBlink from main, it blinks once. So in other words there is a 1 stored into buttonPressed[0] when the button is pressed.
The statement " if(buttonPressed[0] == 1), PORTA ^= 1<<PINA0;" does not work in main, but again, it works in the debounce function.
Any clue what I'm doing wrong?
Here's my code (minus the initialization functions to make the code smaller):
Rich (BB code):
//Debounce
#define DEBOUNCE_TIME 0.2
#define SAMPLE_RATE 20
#define MAXIMUM (DEBOUNCE_TIME * SAMPLE_RATE)
// Prototypes
//****************************************************************************************
void mgpInit(void);
void ioInit(void);
void errorBlink(unsigned char);
void debounce(uint8_t);
// Global Variables
//****************************************************************************************
//Debounce Variables
uint8_t refNum = 0;
uint8_t interruptInput[4];
uint8_t integrator[4];
uint8_t debounceOutput[4];
uint8_t buttonPressed[4];
uint8_t buttonReleased[4];
/*****************************************************************************************
* This function blinks the Warm LED a set number of times defined by parameter
* PARAM: number of times the LED will Blink
******************************************************************************************/
void errorBlink (unsigned char numOfBlinks)
{
unsigned char temp = 0;
for(temp = 0; temp < numOfBlinks; temp++)
{
PORTA ^= 1<<PINA0;
_delay_ms(500);
PORTA ^= 1<<PINA0;
_delay_ms(500);
}
}
/*****************************************************************************************
* This function debounces the switches
* PARAM: Pin to debounce
* RETURN: none
*******************************************************************************************/
void debounce (uint8_t refNum)
{
interruptInput[0]= bit_is_set(PINC,7); //reads the input of PINC7 and stores it into interruptInput
//called "interruptInput" since we are actually reading the interrupt
//output from an IO Expander
//Here we start by reading the input. Since we know a bounce will be a random set of 1's and 0's, we will use
//the variable "integrator" which will constantly be pulled up or down between 0 and 4 (MAXIMUM). MAXIMUM is
//determined by multiplying the sample rate by the debounce time (see #defines above).
if (interruptInput[refNum] == 0)
{
if (integrator[refNum] > 0)
{
integrator[refNum]--;
}
}
else if (integrator[refNum] < MAXIMUM)
{
integrator[refNum] ++;
}
//Here we test to see if we've reached either threshold.
if (integrator[refNum] == 0) //indicates we have had a string of zeros
{
debounceOutput[refNum] = 0; //sets debounced output to 0 (may not need this)
buttonPressed[refNum] = 1; //Used to tells main a button has been pressed
buttonReleased[refNum] = 0; //Can't be pressed and released
}
else if (integrator[refNum] >= MAXIMUM) //indicates the button hasn't been pressed or is bouncing
{
debounceOutput[refNum] = 1; //sets debounced output to 1 (may not need this)
integrator[refNum] = MAXIMUM; //defensive code
buttonPressed[refNum] = 0; //Can't be released and pressed
buttonReleased[refNum] = 1; //Used to tell main a button has been released
}
//if statement will work if placed here
/* if(buttonPressed[0] == 1)
{
PORTA ^= 1<<PINA0;
}*/
}
/*****************************************************************************************
* MAIN
******************************************************************************************/
int main(void)
{
// Main Variables
//**********************************************************************************
// Initializations
//**********************************************************************************
mgpInit(); //Initializes all uC ports and timers.
i2c_init(); //Initializes the TWI
ioInit(); //Initializes the IO Expanders
sei(); //Enables Global Interrupts
//Here is where we would load the previous settings from flash
//Next step is to turn on all of the LEDs
i2c_start_wait(EQ_IO_ADDR+I2C_WRITE); //Loads the address of CLN IO into the first byte of the message buffer.
i2c_write(PCA9535_OUT_PORT_CB); //Loads the Code to access the output port0 (2) into the command byte of the message buffer.
i2c_write(0b00000000); //Loads the code to turn the port0 pins to be 0V
i2c_write(0b00000011); //Tells the output port1 pins to be 0V (except pin7 which is not used).
i2c_stop(); //sends prepared messageBuf on the TWI bus
//Should have lights on.
//errorBlink(2);
while(1)
{
//This will blink the LED
//errorBlink(buttonPressed[0]);
//this code does not toggle LED
if(buttonPressed[0] == 1)
{
PORTA ^= 1<<PINA0;
}
}
}
/*****************************************************************************************
* Interrupt Service Routine to debounce switches
* PARAM: Timer 0 Compare Vector
******************************************************************************************/
ISR(TIMER0_COMPA_vect)
{
debounce(refNum);
}
Last edited: