Shop OBEX P1 Docs P2 Docs Learn Events
Initializing state change logic — Parallax Forums

Initializing state change logic

FalconFalcon Posts: 191
edited 2012-02-08 16:24 in BASIC Stamp
Hello all,
The following code is used to report the state of an Active Low switch input on Pin 0. The only circuit is the switch and two resistors.

I'm having a problem getting this code to show the initial state of the switch if it is CLOSED. When I RUN the code, and the switch is OPEN, it displays correctly. If the switch is CLOSED when the code is RUN it doesn't show anything. Only after I OPEN the switch does it then show the state of the switch, and works every time thereafter...until I RUN the code again with the switch CLOSED.
switch          PIN     0

temp  VAR Bit
Saved VAR Bit
Flag  VAR Bit

main:
  temp = switch             'load temp with current door state
  IF Saved = temp THEN      'if door saved = door current = no change set To false
    Flag = 0                'no change ensure flag is cleared
  ELSE
    Flag = 1                 'door changed states , set flag to true
    Saved = temp             'save current state for compare next time through
ENDIF

IF Flag = 1 THEN
  IF Saved = 1 THEN

    DEBUG "NOT CLOSED"
  ELSE
    DEBUG "CLOSED    "

  ENDIF
      Flag = 0
ENDIF

GOTO main

This code represents just a snippet of a much bigger project that I'm working cleaning up. The same logic is used to check 16 inputs via a 74HC165 pair.

I've read about the Finite State Machine code on Tracy Allen's website at http://www.emesystems.com/BS2fsm.htm but I do not have enough variable space left for it. I would need 5 WORDs of space (5bits x 16 inputs) and I don't have it.

I tried adding the following lines (individually) before the Main label, but none helped. They only changed which state of the switch did or didn't work at initial code RUN.
Saved = 0
Saved = 1
Flag = 0
Flag = 1

Is there something I can do to have the initial state of the switch reported before I activate the switch?


falcon

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2012-02-07 20:18
    I'm not quite sure what you're trying to do, but I usually keep two variables, one for the previous state of the switch and one for the current state. When you have previous <> current, then there's been a change and you can use the new state of the switch to do something like:
    switch pin 0
    previous var bit
    current var bit
    
    previous = switch   ' initialize to current switch setting
    current = previous
    if current = 0
       debug "initially open",cr
    else
       debug "initially closed",cr
    endif
    do
       previous = current
       current = switch
       if previous <> current then
          if current = 0 then
             debug "switch opened",cr
          else
             debug "switch closed",cr
          endif
       endif
    loop
    
  • Tracy AllenTracy Allen Posts: 6,662
    edited 2012-02-08 09:08
    Falcon,
    The state machine on my web site is implementing what is called a "vertical counter" in order to scan an x-y keypad and to debounce 16 keys at once. If you don't have to debounce, and you don't need to scan a keyboard, the program only takes three state variables. As Mike pointed out, one is for the present state of the keys, one is for the past state, and I have a third one that flags changes of state, which is then decoded to decide what actions to take. The past-state variable has to be unique, but the current and changes variables can be aliased and used for multiple purposes.

    I don't know how to answer your specific question about initialization. Explain more what you want to do. The routines detect changes in state of the keys, so it is not unusual to initialize the past-state variable to the actual current state of the switches. Then it detects subsequent changes. If the program needs to take immediate action when the program starts if a switch happens to be in its active state, then the past-state variable would have to be initialized to the not-active state.
    [INDENT]   
    keys var word ' present state of keys, bit low for key pressed
    keyz var word ' state variable, previous state of keys
    keyx var word ' transition output, bit high one iteration for each press
    keyz = $FFFF ' initialize past state to "not-active"
    scanloop:
     gosub whatkeys   ' this reads 16 key inputs
     keyx=keys^keyz & keyz ' detect change 1->0 (active low keypress)
     keyz=keys
     ' optional debug to visualize operation of the state machine
     debug CR,bin16 keys,32,bin16 keyx 
     if keyx then decode ' decode decides what to do
    goto scanloop
    [/INDENT]
    
  • RiJoRiRiJoRi Posts: 157
    edited 2012-02-08 13:04
    Maybe it's my age, but I've learned to use constants. Makes for easier reading...
    'I'm having a problem getting this code 
    '  to show the initial state of the switch 
    '  if it is CLOSED.
    
    switch	PIN	0
    CLOSED	CON	0
    OPEN	CON	1
    NO_CHANGE CON	0
    CHANGE	CON	1
    
    [b]'In BASIC, all variables default to 0:[/b]
    temp  VAR Bit ' Default = CLOSED
    Saved VAR Bit ' Default = CLOSED
    Flag  VAR Bit ' Default = NO_CHANGE
    
    main:
    	temp = switch			'load temp with current door state
    
    	IF Saved = temp THEN		'if door saved = door current = no change set To false
    		Flag = NO_CHANGE	'no change ensure flag is cleared
    	ELSE
    		Flag = CHANGE		'door changed states , set flag to true
    		Saved = temp		'save current state for compare next time through
    	ENDIF
    
    	IF Flag = CHANGE THEN
    		IF Saved = OPEN THEN
    			DEBUG "NOT CLOSED"
    		ELSE
    			DEBUG "CLOSED    "
    		ENDIF
    		Flag = NO_CHANGE
    	ENDIF
    
    GOTO main
    

    So your code is starting out with "Saved" set to Closed. And if the door is closed, then the software sees no change!

    I would "prime the pump" by reading the switch and loading Saved with the inverse of the switch value. Something like
    temp = switch
     Saved = ~temp
    
    before the Main loop.

    HTH,
    --Rich
  • FalconFalcon Posts: 191
    edited 2012-02-08 16:24
    Mike,
    That code worked. It provided the initial state of the switch whether OPEN or CLOSED, which was what I was missing.

    As I said, this was part of a much bigger program. I had to minimize it to the essentials to eliminate any other code causing the problem so it probably looks cluncky. I actually use a SERIN to receive 2 BYTES instead of a switch and the first line of code is really temp = Current1.BIT1. I substituted the switch to simplify it.

    I don't know where that second reply went, but I didn't understand it anyway.

    Tracy,
    I didn't realize that code was to read the x-y keypad. I think you hit the nail on the head re: "...initialize the past-state variable to the actual current state of the switches". I'm going to work with your code too and see what I can come up with.

    RiJoRi,
    Your suggestion certainly did work (with the pump priming). I'm going to try that first since it is based on my existing code.

    Thank you all for your help. One good reply would have been great but these three gives me more to study and try to understand different approaches to solving the same problem. That's priceless.

    Not that I might not be back soon with another question...

    falcon
Sign In or Register to comment.