User Tools

Site Tools


en:pfw:switchledwithbutton

Switch LED with button

Idea

The LED in a button is to be switched on and off safely.

Implementation

The challenge is to give the user a sure feeling when switching. Nothing should flicker and there must be no doubt about the state of the switch.

In order to achieve this, bounce in the switch must be removed by software.

Pseudo code for togglgeLED implementation

What Pseudo code is.

Function: init ( -- )
    set all ports, values, variables ...
     
Function: toggleLED ( -- )  \ Demo
    LOOP:
      IF: button was pressed, toggle LED
          halt testing button
      IF: button has been released stabel H
          enable testing again
    ENDLOOP if any key is pressed

Forth implementation of toggleLED

\ Switch LED with button
\ TI MSP430G2553 Launchpad with noForth mv 2553 240101 
 
(* 
History
20250620 toggle LED in button
20250609 P1.7 digital input, some bounce tests
 
addr acronym registername
020  P1IN    Input
021  P1OUT   Output 
022  P1DIR   Direction
023  P1IFG   Interupt Flag
024  P1IES   Interrupt Edge Select
025  P1IE    Interrupt Enable
026  P1SEL   Port Select
041  P1SEL2  Port Select2
027  P1REN   Resistor Enable 
 
     Pin1.7--<---R---Button---GND
     Pin1.0-->---R-----Led----GND
	 R=47K
*)
 
\ tools\ ( include if it is your latest shield )  
 
 
 
\ --- input ---    
hex
80 constant pin7 \ mask for pin7 of port
 
: PININ ( mask -- ) \  make pin to input 
  ( 020 )    \ P1IN    Input, read only
dup 021 *bis \ P1OUT   Output, pullup resistor set
dup 022 *bic \ P1DIR   Direction to IN
dup 023 *bic \ P1IFG   Interupt Flag, cleared
dup 024 *bic \ P1IES   Interrupt Edge Select, falling  \_ 
dup 025 *bic \ P1IE    Interrupt Enable, off
dup 026 *bic \ P1SEL   Port Select,  I/O
dup 041 *bic \ P1SEL2  Port Select2, I/O
    027 *bis \ P1REN   Resistor Enable, set
  ;
 
: CLAVIS? ( mask -- f )  \ Query button.
  >r
  r@ 023 bit*      \ test for edge
  r@  = ( true )    \ button has been pressed 
  r> 023 *bic        \ clear edge detection flag.
  ;
 
: TASTO? ( mask -- f )  \ Query button. debounced
  >r
  r@ 020 bit* 3 ms 
  r@ 020 bit* 3 ms
  and
  r@ 020 bit* 3 ms
  and  
  r@ 020 bit* 3 ms
  and
  r@ 020 bit* 3 ms
  and  
  r> =
  ;
 
 
 
\ --- output ---
hex
01 constant pin0
 
: PINOUT ( mask -- )  \ Switch pin P1.0 as output
  dup 027 *bic \ ren off
  dup 025 *bic \ ie  disable interrupt
  dup 026 *bic \ SEL I/0
  dup 041 *bic \ SEL2 I/0 
      022 *bis \ set out for P1.0
  ;
 
: p1H     pin0 021 *bis ; \ set P1.0 to H
: p1L     pin0 021 *bic ; \ set P1.0 to L
 
 
 
\ --- Demo Application ---
 
variable ILED  \  LED integrated in button
value sem      \  semaphor: allows testing
 
: +sem   true  to sem ;  \ some syntactic sugar
: -sem   false to sem ;
 
: init ( -- )  \ make the various settings at once.
  pin0 pinout
  pin7 pinin
  0 iled !  
  +sem
  p1L
;
 
: setled ( -- ) \ even number is led off
  iled @ 1 and 0=     
  if p1L else p1H then
  ;
 
: incled ( -- ) 1 iled +! ;
 
 
 
: toggleLED ( -- )  \ toggle LED in button
  init
  begin
    sem if
	  pin7 clavis? if    \ if button pressed
	    incled setled     \ toggle LED
	    100 ms             \ do some debouncing
	    -sem                \ don't test again 
	    then
	then
    pin7 tasto? if   \ if button is released stabel
	 pin7 023 *bic    \ clear edgedetection bit to debounce loop
     +sem              \ now allow retesting
	 then           
   \ when the routine gets too fast...
   10 ms                
  key? until
  ;
 
shield nn\
freeze
( finis)

You can use it as follows:

toggleled <ret>

Glossary

clavis? and tasto? are different methods for querying the button.

Clavis? checks whether there has been a falling edge on the pin. The port pin remembers this in its interrupt flag bit, requiring no additional wiring on the MCU.

Tasto?, on the other hand, monitors the logic level on the port pin several times in succession. Only when all queries have returned an H level is it assumed that the bouncing is over, i.e., the button has been released.

With these two routines, the state of the LED can be toggled back and forth. Only when the button has been safely released does clavis? fire on the next keypress.

The “smaller” Forth words in between are simply factored-out parts of the toggleLED routine. These are useful during the interactive testing phase.

Background information

See clavis? and tasto? for more background information.

Here, clavis? has been configured to immediately clear its interrupt flag after the query. This isn't really necessary, since it can only be queried again after tasto? allows it and has cleared the flag.

Possible Pitfalls

None so far.

Contributions

You have another approach?

Please add it at the end of this document.

en/pfw/switchledwithbutton.txt · Last modified: 2025-06-22 00:26 by mka