1
\$\begingroup\$

I am trying to interface switch and led. I want to write a program in which if I press and release the switch led should glow and if I again press the switch led should turn off. I am not able to write logic for it as I am newbie to embedded system. Can anyone just help me writing the logic for it.? Thanks.

This is my code of turning on and off led using switch CODE

int main(void)
 {
    DDRC |= (1<<PC0); //Makes first pin of PORTC as Output
    DDRD &= ~(1<<PD0);//Makes firs pin of PORTD as Input

    while(1) //infinite loop
    {
        if(PIND & (1<<PD0) == 1) //If switch is pressed
        {
            PORTC |= (1<<PC0); //Turns ON LED
            _delay_ms(3000); //3 second delay
            PORTC &= ~(1<<PC0); //Turns OFF LED
        }
    }
}
\$\endgroup\$
5
  • \$\begingroup\$ What have you tried so far? We're not going to sit down and do your project for you - if we did that, you wouldn't learn anything at all. \$\endgroup\$ Jun 28, 2015 at 10:41
  • \$\begingroup\$ @NickJohnson I have included the code of switch and led but in this code led turns off when releasing switch \$\endgroup\$ Jun 28, 2015 at 10:54
  • \$\begingroup\$ A good start - do you understand why it acts the way it does presently? What specifically do you need to know in order to modify it to work the way you want? \$\endgroup\$ Jun 28, 2015 at 10:56
  • \$\begingroup\$ I dont know how to modify it \$\endgroup\$ Jun 28, 2015 at 11:08
  • \$\begingroup\$ What happens when you run this code? \$\endgroup\$ Jun 30, 2015 at 9:04

5 Answers 5

1
\$\begingroup\$

I am not a programmer but after reading your question on solution came in to my mind which I am going to explain below.

For the below logic your LED and Switch both should be controlled with a controller's different I/O pin. First controller should sense the switch pressed logic and based on the switch logic controller has to first sense the LED I/O Pin Logic for previous condition of LOW or HIGH Logic. If LED Pin logic is HIGH make it LOW and vice versa. Note LED's pin I/O has to be reversed only after the switch is pressed.

Below logic can be followed

Switched pressed (Y/N)
{

If Y
    {
      changed the logic of LED port pin // If HIGH, change it to LOW if LOW, change it to HIGH

        else N
              { Do nothing}
        }
}
\$\endgroup\$
1
\$\begingroup\$

The only change to be done might be from this to

if(PIND & (1<<PD0) == 1) //If switch is pressed
        {
            PORTC |= (1<<PC0); //Turns ON LED
            _delay_ms(3000); //3 second delay
            PORTC &= ~(1<<PC0); //Turns OFF LED
        }

this:

if(PIND & (1<<PD0) == 1) //If switch is pressed
        {
            //Toggle PC0
            // a few 10s of mili-second delay
        }

You may consider using Switch as interrupt, PD0 can be configured as interrupt, so that you can do some useful job until user presses the switch. LED toggling code can be a part of ISR (Interrupt Service Routine). Also, look for Switch De-bouncing...

\$\endgroup\$
1
\$\begingroup\$

Suggestion #1) Perform an Internet search using c program operator precedence and then study your if() statement's logical expression. Specifically, consider the order of evaluation of the subexpressions in an expression whose form is

a & b == c

Suggestion #2) The if() statement's logical expression should be rewritten to test for a zero (=false) or non-zero (=true) result, rather than testing for a result value of exactly '1' (one). Why is a zero/non-zero test a preferable practice when testing bit values like this?

\$\endgroup\$
0
\$\begingroup\$

the problem with the posted code is with this line:

if(PIND & (1<<PD0) == 1)

Given: if PIND bit 0 were being tested, then the result would be either 0 or 1

However, if 'PD0' is not defined as 0 then

then the resulting value of 'PIND & (1<

Suggest:

if( (PIND & (1<<PD0)) == 1<<PD0 )

Note use parens so do not have to be concerned about order of evaluation and operator precedence.

By using the suggested code statement, both sides of the '==' are checking against the same value.

Also, the question did not mention which chip is being programmed.

Some chips require more than one instruction to change the state of a GPIO pin.

Suggest adding a statement giving the target chip.

\$\endgroup\$
0
\$\begingroup\$

The problem with your code is that you are turning the LED off after a delay. Which is not the requirement. Instead you should toggle the LED whenever button is pressed. Check the following code:

int main(void)
 {
    int flag=0;
    DDRC |= (1<<PC0); //Makes first pin of PORTC as Output
    DDRD &= ~(1<<PD0);//Makes firs pin of PORTD as Input

    while(1) //infinite loop
    {
        if(PIND & (1<<PD0) == 1) //If switch is pressed
        {
            flag=~flag;
        }
        PORTC = (1<<PC0) | flag  ; //Toggle the LED
    }
}
\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.