I'm trying to write a elevator control panel simulator and have been having quite a bit of difficulty processing the input trigger button. The program tends to stick in one state. I've tried the runway.src code and it runs great. I've also hard coded each state and they seem to work individually. I just can't move between states using the trigger. Any suggestions would be appreciated.
Thanks,
Duane Ball
' =========================================================================
'
' File....... ELEVATOR.SXB
' Purpose.... Linear strobe of six outputs
' Author..... EFX-TEK (www.efx-tek.com)
' Modified by..D Ball
' E-mail..... teamefx@efx-tek.com
' Started....
' Updated.... 29 SEPT 2011
'
' =========================================================================
' -------------------------------------------------------------------------
' Program Description' -------------------------------------------------------------------------
'
' Elevator control panel simulator derived from runway.SRC from EFX-TEK
' Manages six lamps/LEDs on P8..P13 which represent elevator floor buttons
' Initially (STATE_0) Lamp 3 is illuminated indicating ground floor.
' When button on P14 is first pressed the illuminated buttons change to indicate ascent (STATE_1).
' A second press of the button causes the illuminated buttons to randomly flash (STATE_2).
' A third press of the button turns all the buttons off (STATE_3)
' A fourth press of the button illuminates Lamp 1 (STATE_4)
' A fifth press of the button resets the program variables (STATE_5)
' can be adjusted with pot circuit on P15.
'
' Replace the ULN2803A on P8..P15 with a ULN2003A to allow the pot circuit
' on P15 to operate correctly.
' -------------------------------------------------------------------------
' Conditional Compilation Symbols
' -------------------------------------------------------------------------
' -------------------------------------------------------------------------
' Device Settings
' -------------------------------------------------------------------------
DEVICE SX28, OSC4MHZ, TURBO, STACKX, OPTIONX, BOR42
FREQ 4_000_000
ID "Lights"
' -------------------------------------------------------------------------
' I/O Pins
' -------------------------------------------------------------------------
Speed PIN RC.7 ' SETUP = DN; remove ULN
Trigger PIN RC.6 ' SETUP = DN
Lamps PIN RC
Lamp6 PIN RC.5 OUTPUT
Lamp5 PIN RC.4 OUTPUT
Lamp4 PIN RC.3 OUTPUT
Lamp3 PIN RC.2 OUTPUT
Lamp2 PIN RC.1 OUTPUT
Lamp1 PIN RC.0 OUTPUT
UnusedRB PIN RB INPUT PULLUP
' -------------------------------------------------------------------------
' Constants
' -------------------------------------------------------------------------
IsOn CON 1
IsOff CON 0
' -------------------------------------------------------------------------
' Variables
' -------------------------------------------------------------------------
idx VAR Byte ' loop index
holdTm VAR Word ' for timing
tmpW1 VAR Word ' for subs & funcs
state VAR Byte
seed VAR Byte
first VAR Byte
' =========================================================================
PROGRAM Start
' =========================================================================
' -------------------------------------------------------------------------
' Subroutine / Function Declarations
' -------------------------------------------------------------------------
DELAY_MS SUB 1, 2 ' delay in milliseconds
GET_SPEED FUNC 2, 0 ' read speed pot
' -------------------------------------------------------------------------
' Program Code
' -------------------------------------------------------------------------
Start:
Lamps = %000000 ' clear all
state=0 'Initial State
holdTm = GET_SPEED ' read speed setting
idx=2 'index to LED illuminated
Main:
first=1
DO WHILE Trigger = IsOn ' run when button pressed
IF first=1 THEN ' only advance state once per keypress
first=0
state=state+1
ENDIF
LOOP
BRANCH state,STATE_0,STATE_1,STATE_2,STATE_3,STATE_4,STATE_5
STATE_0:
Lamps = %000100 ' LED #2 On
DELAY_MS holdTm
GOTO Main
STATE_1:
Lamps = 1 << idx ' Strobe LEDs #2 to #5 and stop on #5
DELAY_MS holdTm
idx = idx + 1
idx = idx MAX 5
GOTO Main
STATE_2:
RANDOM seed
idx = seed // 6
Lamps = 1 << idx 'Randomly flash LEDs
DELAY_MS holdTm
GOTO Main
STATE_3:
Lamps = %000000 'All LEDs off
DELAY_MS holdTm
GOTO Main
STATE_4:
Lamps = %000001 'LED #0 On
DELAY_MS holdTm
GOTO Main
STATE_5:
GOTO Start 'Reset Program Variables
' -------------------------------------------------------------------------
' Subroutine / Function Code
' -------------------------------------------------------------------------
' Use: DELAY_MS mSecs
' -- 'mSecs' is delay in milliseconds, 1 - 65535
SUB DELAY_MS
IF __PARAMCNT = 1 THEN
tmpW1 = __PARAM1 ' save byte value
ELSE
tmpW1 = __WPARAM12 ' save word value
ENDIF
PAUSE tmpW1
ENDSUB
' -------------------------------------------------------------------------
' Use: result = GET_SPEED
' -- scales Prop-1 Trainer pot to 50 to 150
FUNC GET_SPEED
HIGH Speed ' charge cap
DELAY_MS 1
RCTIME Speed, 1, tmpW1 ' measure RC circuit
tmpW1 = tmpW1 ** $71C7 ' x 0.44 (max = 100)
tmpW1 = tmpW1 + 50 ' set min to 50
RETURN tmpW1
ENDFUNC
Can you please attach your code. When I copy-and-paste from forum window hidden characters get injected which cause compilation errors.
Hi,
Here is the source file.
Thanks,
Duane Ball
Have a look at this version -- I added some debouncing to the trigger input section. Note that you may want to add a routine that forces the button to be release, otherwise you may zip through the states very quickly.
Updated and tested: 01 OCT 2011
' -------------------------------------------------------------------------
' Device Settings
' -------------------------------------------------------------------------
ID "Elevator"
DEVICE SX28, OSC4MHZ, TURBO, STACKX, OPTIONX, BOR42
FREQ 4_000_000
' -------------------------------------------------------------------------
' I/O Pins
' -------------------------------------------------------------------------
Speed PIN RC.7 ' SETUP = DN; remove ULN
Trigger PIN RC.6 ' SETUP = DN
Lamps PIN RC
Lamp6 PIN RC.5 OUTPUT
Lamp5 PIN RC.4 OUTPUT
Lamp4 PIN RC.3 OUTPUT
Lamp3 PIN RC.2 OUTPUT
Lamp2 PIN RC.1 OUTPUT
Lamp1 PIN RC.0 OUTPUT
UnusedRB PIN RB INPUT PULLUP
' -------------------------------------------------------------------------
' Constants
' -------------------------------------------------------------------------
IsOn CON 1
IsOff CON 0
' -------------------------------------------------------------------------
' Variables
' -------------------------------------------------------------------------
idx VAR Byte ' loop index
state VAR Byte
seed VAR Byte
trTimer VAR Byte
holdTm VAR Word ' for timing
tmpW1 VAR Word ' for subs & funcs
' -------------------------------------------------------------------------
' Subroutine / Function Declarations
' -------------------------------------------------------------------------
DELAY_MS SUB 1, 2 ' delay in milliseconds
GET_SPEED FUNC 2, 0 ' read speed pot
' =========================================================================
PROGRAM Start
' =========================================================================
Start:
state = 0
Main:
RANDOM seed ' restir random #
Check_Trigger:
trTimer = 0 ' restart debounce timer
DO WHILE Trigger = IsOn ' button pressed?
DELAY_MS 1
INC trTimer ' update timer
LOOP
IF trTimer > 50 THEN ' valid press?
INC state ' update state
IF state = 5 THEN
state = 0
ENDIF
ENDIF
BRANCH state, STATE_0, STATE_1, STATE_2, STATE_3, STATE_4
GOTO Start
STATE_0:
Lamps = %000100 ' LED #2 On
GOTO Main
STATE_1:
FOR idx = 2 TO 5
IF Trigger = IsOn THEN Main ' early abort
Lamps = 1 << idx
holdTm = GET_SPEED ' rescan speed pot
DELAY_MS holdTm
NEXT
GOTO Main
STATE_2:
IF Trigger = IsOn THEN Main ' early abort
idx = seed // 6 ' select one light
Lamps = 1 << idx ' light it
holdTm = GET_SPEED ' rescan speed pot
DELAY_MS holdTm
GOTO Main
STATE_3:
Lamps = %000000 ' All LEDs off
GOTO Main
STATE_4:
Lamps = %000001 ' LED #0 On
GOTO Main
' -------------------------------------------------------------------------
' Subroutine / Function Code
' -------------------------------------------------------------------------
' Use: DELAY_MS mSecs
' -- 'mSecs' is delay in milliseconds, 1 - 65535
SUB DELAY_MS
mSecs VAR __WPARAM12
\ SB __PARAMCNT.1 ' skip if word passed
\ CLR mSecs_MSB ' clear MSB if byte
PAUSE mSecs
ENDSUB
' -------------------------------------------------------------------------
' Use: result = GET_SPEED
' -- scales Prop-1 Trainer pot to 50 to 150
FUNC GET_SPEED
HIGH Speed ' charge cap
DELAY_MS 1
RCTIME Speed, 1, tmpW1 ' measure RC circuit
tmpW1 = tmpW1 ** $71C7 ' x 0.44 (max = 100)
tmpW1 = tmpW1 + 50 ' set min to 50
RETURN tmpW1
ENDFUNC
I tried again and got similar results. I must be something to do with timing of the button. I'm using a PROP-1 trainer to test this routine.
I started again with the control loop from the runway program and wrote the following control loop which works fine. I have no idea why this worked and the other programs didn't.
I did notice (and was at fault for not mentioning) my use of the Prop-1 trainer. Looking at the board, it appears the capacitor is probably doing the debounce for me.
' -------------------------------------------------------------------------
' Program Code
' -------------------------------------------------------------------------
Start:
state = 0
Lamps = %000100 ' start at ground
idx=2
holdTm = GET_SPEED ' read speed setting
Main:
Lamps = %000000 ' clear all
DO WHILE Trigger = IsOff ' run when button pressed
RANDOM seed ' stir random #
BRANCH state,STATE_0,STATE_1,STATE_2,STATE_3,STATE_4,STATE_5
LOOP
DO WHILE Trigger = IsOn ' wait while button pressed
PAUSE 1
LOOP
state=state+1
IF state = 6 THEN
state = 0
ENDIF
GOTO Main
I cleared my desk and dusted off a Prop-SX. The update (posted above) seems to work the way you want it and has some refinements. I had to connect LEDs to the RB port to monitor the state to get the button press work; it works well now, giving you debouncing so that you know you're getting an actual button press.
Note that I also moved the reading of the pot to the states that have LED movement; this lets you tune the speed while in that state. Those states also have an early exit if the button is pressed. Finally, for states with static LED output I removed the delay as it serves no purpose with the code now forcing a button release to change states.
Thank you very much! The code works fine now. Your responsiveness is amazing! ;D