Help with programming uC toggle LED using one switch

Discussion in 'Embedded Systems and Microcontrollers' started by eagle32, Mar 18, 2011.

  1. eagle32

    Thread Starter Member

    Feb 18, 2011
    30
    0
    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;

    }
     
  2. MMcLaren

    Well-Known Member

    Feb 14, 2010
    759
    116
    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

    Code ( (Unknown Language)):
    1.  
    2.     unsigned char swnew = 0;        //
    3.     unsigned char swold = 0;        // switch state latch
    4.  
    5.  
    6.    /*
    7.     *  swnew  ___---___---___---___    sample active hi switches
    8.     *  swold  ____---___---___---__    switch state latch
    9.     *  delta  ___-__-__-__-__-__-__    changes, press or release
    10.     *  swnew  ___-_____-_____-_____    filter out 'release' bits
    11.     *
    12.     *  b3led  ____------______-----    toggle LED on B3
    13.     */
    14.  
    15.     void main()
    16.     {
    17.       delay_ms(20);                 // 20-msec debounce interval
    18.       swnew = PORTA;                // sample active hi switches
    19.       swnew ^= swold;               // changes, press or release
    20.       swold ^= swnew;               // update switch state latch
    21.       swnew &= swold;               // filter out 'release' bits
    22.  
    23.       if(swnew & 2);                // if A1 "new press"
    24.         PORTC ^= 8;                 // toggle LED on B3
    25.     }
    26.  
     
    Last edited: Mar 18, 2011
  3. eagle32

    Thread Starter Member

    Feb 18, 2011
    30
    0
    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.
     
  4. t06afre

    AAC Fanatic!

    May 11, 2009
    5,939
    1,222
    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.
     
  5. eagle32

    Thread Starter Member

    Feb 18, 2011
    30
    0
    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.
     
  6. t06afre

    AAC Fanatic!

    May 11, 2009
    5,939
    1,222
    Code ( (Unknown Language)):
    1. #define _XTAL_FREQ 4000000
    2. #include <htc.h>
    3. #define bitset(var, bitno) ((var) |= 1 << (bitno))
    4. #define bitclr(var, bitno) ((var) &= ~(1 << (bitno)))
    5. #define toggle_bit(var,bitno) (var ^= (1 << bitno))
    6. #define test_bit(var,bitno) (var & (1 << bitno))
    7. #define  DISP_EN 0
    8. #define  DISP_RS 1
    9. #define  DISP_RW 2
    10. char test_var;
    11. char LCD;
    12. void main(void)
    13. {
    14.  volatile char LCD;
    15.  volatile char test_var;
    16.  TRISC=0;
    17.  while(1)
    18.   {
    19.    LCD=240;
    20.    test_var=240;
    21.    bitset(LCD, DISP_EN);
    22.    bitset(LCD, DISP_RW);
    23.    bitset(LCD,DISP_RS);
    24.    bitclr(LCD, DISP_EN);
    25.     if (test_bit(LCD,DISP_RS))
    26.      {(bitclr(LCD, DISP_EN);}
    27.    PORTC=test_var;
    28.    PORTC=LCD;
    29.    toggle_bit(LCD,7);//flip bit
    30.             LCD=LCD & 0x0;
    31.             LCD=LCD^0x80;
    32.   }
    33. }
    34.  
    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)
    from The C Programming Language (sometimes referred to as K&R)
     
  7. mbxs3

    Active Member

    Oct 14, 2009
    141
    3
    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?
     
  8. eagle32

    Thread Starter Member

    Feb 18, 2011
    30
    0
    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 .
     
  9. t06afre

    AAC Fanatic!

    May 11, 2009
    5,939
    1,222
    Can you post a simple schematics (drawing) on how you connect your switch to the MCU
     
  10. mbxs3

    Active Member

    Oct 14, 2009
    141
    3
    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.
     
  11. HallMark

    Member

    Apr 3, 2011
    89
    5
    This is the Basic Schematic for the code i have written.
    [​IMG]

    Here is the Basic Code.

     
  12. t06afre

    AAC Fanatic!

    May 11, 2009
    5,939
    1,222
    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: Apr 4, 2011
  13. HallMark

    Member

    Apr 3, 2011
    89
    5
    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.
     
  14. t06afre

    AAC Fanatic!

    May 11, 2009
    5,939
    1,222
    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
     
  15. HallMark

    Member

    Apr 3, 2011
    89
    5
    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. :)
     
  16. t06afre

    AAC Fanatic!

    May 11, 2009
    5,939
    1,222
    No my circuit are wrong. It should not be used:eek:
     
  17. HallMark

    Member

    Apr 3, 2011
    89
    5
    What happened Sir?:confused:
     
  18. eagle32

    Thread Starter Member

    Feb 18, 2011
    30
    0
    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.
     
  19. eagle32

    Thread Starter Member

    Feb 18, 2011
    30
    0
    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: Apr 4, 2011
  20. eagle32

    Thread Starter Member

    Feb 18, 2011
    30
    0
    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.
     
Loading...