Help with programming uC toggle LED using one switch

Thread Starter

eagle32

Joined Feb 18, 2011
30
Hi everyone,

Im trying to get an LED to light on when i press a switch but im having trouble with it to make it turn off when i press the switch again. I got the LED works when i press the sw but i want to turn it off but pressing that switch again

Could some one help me with this code to get it working please. My C programming is pretty bad so im abit strugling to get it going. So please tell me where i have done wrong and correct me .

Here are the codes i've done:


/* Pressing the sw will toggle led on and off. That is:
i, press once- led on
ii, press again- led off
iii, press again- led on(and so on)
*/

#define F_CPU 16E6 //16mhz
#include <avr/io.h>

void main(void)

{
DDRA = 0x00;//port a :i/p


DDRC = 0xFF ;// port c as output
PORTC = 0xff ;//port c set to high state

for (;;)

if ((PINA & 0x02 )==0x02) // INPUT if switch2 is press led on


{ PORTC ^= 0x08 ; }//bit 3 change to low state, led2 light on

//else //led2 extinguish

// { PORTC |= 0x00; }//led2 off


return 0;

}
 

MMcLaren

Joined Feb 14, 2010
853
Lots of different ways to do it. If you use a switch state latch or switch state memory bit for each switch it becomes relatively easy to filter out all but the "new press" state.

Cheerful regards, Mike

Rich (BB code):
    unsigned char swnew = 0;        //
    unsigned char swold = 0;        // switch state latch


   /*
    *  swnew  ___---___---___---___    sample active hi switches
    *  swold  ____---___---___---__    switch state latch
    *  delta  ___-__-__-__-__-__-__    changes, press or release
    *  swnew  ___-_____-_____-_____    filter out 'release' bits
    *
    *  b3led  ____------______-----    toggle LED on B3
    */

    void main()
    {
      delay_ms(20);                 // 20-msec debounce interval
      swnew = PORTA;                // sample active hi switches
      swnew ^= swold;               // changes, press or release
      swold ^= swnew;               // update switch state latch
      swnew &= swold;               // filter out 'release' bits

      if(swnew & 2);                // if A1 "new press" 
        PORTC ^= 8;                 // toggle LED on B3
    }
 
Last edited:

Thread Starter

eagle32

Joined Feb 18, 2011
30
hi Mike, sorry for reply late, i didnt receive any email from this forum so i though no one would reply to my quest. Im still couldnt get the toggle switch working. I've used your code and run it on the uC and the led on bit 3 it keep flashing on and off. What i would like the led to do is if i press the switch( spring type) the led stay on, if i pressed the switch again, the led would turn off.
I've also tried the different ways but it still wont work. These code i've changed, the led is still blinking.


#define F_CPU 16E6 //16mhz
#include <avr/io.h>
#include <util/delay.h>
unsigned char swnew ; //= 0; //
unsigned char swold ; //= 0; // switch state latch
/*
* swnew ___---___---___---___ sample active hi switches
* swold ____---___---___---__ switch state latch
* delta ___-__-__-__-__-__-__ changes, press or release
* swnew ___-_____-_____-_____ filter out 'release' bits
*
* b3led ____------______----- toggle LED on B3
*/
void main(void)

{

DDRA = 0x00;
DDRC = 0xff;
PORTC = 0xff;

for(;;)
{
_delay_ms(50); // 20-msec debounce interval
swnew = PORTA; // sample active hi switches
swold = PORTC;
swnew ^= swold; // changes, press or release
swold ^= swnew; // update switch state latch
swnew &= swold; // filter out 'release' bits

if((swnew & 0x01)==0x01) //if sw on bit 1 is pressed, go in the loop to turn led on bit bit 3 on
{ PORTC ^= 0x08; } // toggle LED on B3

}
return 0;
}


Please help.
 

t06afre

Joined May 11, 2009
5,934
Try these macros.
#define bitset(var, bitno) ((var) |= 1UL << (bitno))
#define bitclr(var, bitno) ((var) &= ~(1UL << (bitno)))
#define toggle_bit(var,bitno) (var ^= (1UL << bitno))
#define test_bit(var,bitno) (var & (1UL << bitno))
I use those in the Hi-Tech C compiler. But I am sure your compiler will recognize the syntax and produce compact code.
 

Thread Starter

eagle32

Joined Feb 18, 2011
30
Try these macros.
#define bitset(var, bitno) ((var) |= 1UL << (bitno))
#define bitclr(var, bitno) ((var) &= ~(1UL << (bitno)))
#define toggle_bit(var,bitno) (var ^= (1UL << bitno))
#define test_bit(var,bitno) (var & (1UL << bitno))
I use those in the Hi-Tech C compiler. But I am sure your compiler will recognize the syntax and produce compact code.
sorry, i am still new to uC so i dont really recognize those statements and i dont know where to start with your codes after those, could you point me to the rest of your code pls.
 

t06afre

Joined May 11, 2009
5,934
Rich (BB code):
#define _XTAL_FREQ 4000000
#include <htc.h>
#define bitset(var, bitno) ((var) |= 1 << (bitno))
#define bitclr(var, bitno) ((var) &= ~(1 << (bitno)))
#define toggle_bit(var,bitno) (var ^= (1 << bitno))
#define test_bit(var,bitno) (var & (1 << bitno)) 
#define  DISP_EN 0
#define  DISP_RS 1
#define  DISP_RW 2
char test_var; 
char LCD;
void main(void)
{
 volatile char LCD;
 volatile char test_var;
 TRISC=0;
 while(1)
  {
   LCD=240;
   test_var=240;
   bitset(LCD, DISP_EN);
   bitset(LCD, DISP_RW);
   bitset(LCD,DISP_RS);
   bitclr(LCD, DISP_EN);
    if (test_bit(LCD,DISP_RS)) 
     {(bitclr(LCD, DISP_EN);}
   PORTC=test_var;
   PORTC=LCD;
   toggle_bit(LCD,7);//flip bit
            LCD=LCD & 0x0;
            LCD=LCD^0x80; 
  }
}
This is an example on how do it on Hi-Tech C for a PIC MCU. I guess perhaps you use a ATMEL CPU. But my code follow ansi C. I have never used ATMEL or AVR studio. So I am in somewhat unknow water here.
But the code from MMcLaren look good.
I think you need a book about C. I can recommend some good ones if you want. Also then programming the art of knowing how to debug is important. If you can not debug. You will have a hard time creating programs.
By the way this code look very dodgy.
if((swnew & 0x01)==0x01)
try if(swnew & 0x01)
The if-else statement is used to express decisions. Formally the syntax is
if (expression)
statement1
else
statement2​
where the else part is optional. The expression is evaluated; if it is true (that is, if expression has a non-zero value), statement1 is executed. If it is false (expression is zero) and if there is an else part, statement2 is executed instead.
Since an if tests the numeric value of an expression, certain coding shortcuts are possible. The most obvious is writing
if (expression)
instead of
if (expression != 0)​
Sometimes this is natural and clear;
from The C Programming Language (sometimes referred to as K&R)
 

mbxs3

Joined Oct 14, 2009
170
I am curious as to the technical specs of the switch you are using. Is it a normally closed switch that opens when it is depressed and returns to a closed position when depressed? Or is it of another make up?
 

Thread Starter

eagle32

Joined Feb 18, 2011
30
t06afre if you know any C programming book that have the sample codes that you would recommend me, that would be great.

mbxs3, the switch i am using is the normally open type .
 

mbxs3

Joined Oct 14, 2009
170
So is it a momentary closed switch when you depress the button or do the contacts stay closed until the button is actuated a second time.
 

HallMark

Joined Apr 3, 2011
89
This is the Basic Schematic for the code i have written.


Here is the Basic Code.

#define LED <your pin> // Set this pin as output
#define SW <your pin> // Set this pin as Input

void main()
{
Init_MCU(); // Initialize your MCU
LED = 1; //LED OFF
for(;;)
{
if(!SW)
{
unsigned int i; // you can set this delay by trial and error its for Key_debounce
for(i=0;i<1000;i++); // Wait for sometime
if(!SW) LED = ~ LED; // Toggle LED
}
}
}
 

t06afre

Joined May 11, 2009
5,934
This is the Basic Schematic for the code i have written.
That approach is kind of dodgy. An input should not/never be floated like this. Some MCU may let you enable internal weak pull-ups. But this must be set in code.
 
Last edited:

HallMark

Joined Apr 3, 2011
89
That approach is kind of dodgy. An input should not/never be floated like this. Some MCU may let you enableint internal weak pull-ups. But this must be set in code.
Oh sorry for this but the Controller i am using it provides internal Pull up and its Freescale so i forgot to put external Pull up.

Freescale Controller not required External Pull Up. they are providing Internal Register to unable disable PULL UP.
 

t06afre

Joined May 11, 2009
5,934
This mistake is quite common for beginners. With this setup you will most (very) likely not see any changes on the input port. If the MCU has internal pull-ups. You will never see any changes on the port
 

Attachments

HallMark

Joined Apr 3, 2011
89
This mistake is quite common for beginners. With this setup you will most (very) likely not see any changes on the input port. If the MCU has internal pull-ups. You will never see any changes on the port
There is nothing wrong if we are using Freescale microcontroller but if you are using other than that then you must have to follow the circuit given by t06afre Sir.

Thanks t06afre for correction. :)
 

Thread Starter

eagle32

Joined Feb 18, 2011
30
mbxs3 the switch i am using is the type that when i push it, the contact stay close, when i let go of the switch, the contact stay open.
 

Thread Starter

eagle32

Joined Feb 18, 2011
30
t06afre, the pix you have shown me that is the type of diagram that i am using. I had to use the external switch from outside out the uC development board, the one that is available on the board is the one same as shown in the pix HallMark have shown me and i dont know how to set up for the input pins to work.
 
Last edited:

Thread Starter

eagle32

Joined Feb 18, 2011
30
Hi HallMark, the schematic diagram of your micro controller has the same switch configuration as on my uC board, by the way can you show me how to set the code up for it to work on those type on switch on PORT B, and the LEDs on PORT C , say if i press a switch bit1, led bit1 on.
Here's some pix of my uC board schematic diagram and how the switchs look like.
 

Attachments

Top