0
votes

I have written a code that detects a button press, first time the button is pressed a LED glows and when next time it is pressed , the LED should switch off, in the same way if third time it is pressed the LED should again glow.

The problem is , the controller is able to detect the button press but instead of switching on the LED for long time, it just momentarily switches it ON then it again switches OFF. And further button presses are not detected.

Below is the code:

#include <avr/io.h>
#include <avr/delay.h>

void glow();
void off();
void switchScan();

int main()
{
DDRA=0x02; // 0000 0010 --> BIT 0=connected to switch whose other pin is connected to   ground,, and BIT 1 is connected to LED with other pin of led connected to ground
PORTA=0x01; // 0000 0001---> Switch Input pulled up and LED output pulled down 

while(1)
{
switchScan();
}

return 0;
}


void glow()
{
PORTA=PORTA|(1<<1);
}

void off()
{
PORTA=PORTA&(~(1<<1));
}

void switchScan()
{
 static int counter=0;
if(~(PINA & 0x01))
{ 
 counter++;
if(counter < 2)
glow();
else
{
counter--;
off();
}
}
}
1
Maybe you need to introduce a delay when you change the counter, to eliminate contact bounce? You might get more help on E-Eng. - Brett Hale
Thanks for prompt reply.. But one more problem is that first press is detected always so in that case , glow() function is called so the LED should continuously glow.. but it just glows momentarily. - Virendra Kumar
What I mean is, if the switch 'bounces', the loop may record it as another 'press'. You won't see the bounce with the naked eye, but it's almost always present in any mechanical switch. - Brett Hale
ohh yes, right, thanks for your valuable comment .. i will try to fix the bouncing effect. - Virendra Kumar

1 Answers

2
votes

The logic in your switchScan() function is flawed. glow() will only be executed one single time. See code comments:

void switchScan() {
    static int counter=0;

    if (~(PINA & 0x01)) { 
        counter++;
        // 1st button press: counter will be 1
        // 2nd and all following button presses: counter will be 2
        if (counter < 2)
            // can only be called once!
            glow();
        else {
            // counter will always go from 2 to 1 at this point 
            counter--;
            off();
        }
    }
}

However, you should also consider the de-bouncing that Brett mentioned in the comments.