'{$STAMP BS2} ' Flasher4.bs2 - a program to Flash 3 LEDs WITH an FSM ' Each LED can have on times and off times separately programmable in ' 200 ms increments. ' Subsumption Architecture is also used for the warning lights LED1 CON 0 ' LED 1 is on port 0 LED2 CON 1 ' LED 2 is on port 1 LED3 CON 5 ' LED 3 is on port 5 Control1 VAR BIT ' IF set, causes LED 1 to flash Control2 VAR BIT ' IF set, causes LED 2 to flash Control3 VAR BIT ' IF set, causes LED 3 to flash State1 VAR NIB ' Contains the state of the LED1 State machine State2 VAR NIB ' Contains the state of the LED2 State machine State3 VAR NIB ' Contains the state of the LED3 State machine ' StateX = 0 means the LEDX is off and not timing. ' StateX = 1 means the LEDX is on and timing. ' StateX = 2 means the LEDX is off and timing. Cntr1 VAR NIB ' Contains a counter to allow timing between ' states for the LED1 State machine Cntr2 VAR NIB Cntr3 VAR NIB On_cnt1 CON 5 ' the number of 200ms time slices LED1 stays on. Off_cnt1 CON 5 ' the number of 200ms time slices LED1 stays off. On_cnt2 CON 3 Off_cnt2 CON 3 On_cnt3 CON 2 Off_cnt3 CON 2 ' If the following errors are set, the operator needs to see the ' appropriate LED flash Error1 VAR BIT ' IF set, causes LED 1 to flash ' Error1 input is pin P7 ' Error1 could be unit needs routine maintenance Error2 VAR BIT ' IF set, causes LED 2 to flash ' Error2 input is pin P8 could be overtemp Error3 VAR BIT ' IF set, causes LED 3 to flash ' Error3 input is pin P9 ' could be dangerous vibration ' While it is important to know about needing routine maintenance, ' it is much more important to be warned about overtemp and ' vibration. ' ----------------------------------------------------------- ' Initialization ' ----------------------------------------------------------- Control1 = 1 ' Make it flash Control2 = 1 ' Make it flash Control3 = 1 ' Make it flash State1 = 0 ' start in idle mode State2 = 0 ' start in idle mode State3 = 0 ' start in idle mode Cntr1 = 0 ' start with timer expired Cntr2 = 0 ' start with timer expired Cntr3 = 0 ' start with timer expired Error1 = 0 ' Don't have that error Error2 = 0 ' Don't have that error Error3 = 0 ' Don't have that error ' ----------------------------------------------------------- ' Main Program ' ----------------------------------------------------------- main: GOSUB ChkErrors ' check in the real world for errors GOSUB Behavior1 ' lowest priority behavior done first GOSUB Behavior2 ' highest priority behavior done last GOSUB FSM1 ' Do FSM for LED1 flashing GOSUB FSM2 ' Do FSM for LED2 flashing GOSUB FSM3 ' Do FSM for LED3 flashing PAUSE 200 ' Wait for 1/5 second = time modularity GOTO main ' ----------------------------------------------------------- ' Behaviors and State Machine Subroutines ' ----------------------------------------------------------- ' ------ ChkErrors ------------------------------------------ ChkErrors: ' check in the real world for errors Error1 = IN7 ' Error1 input is pin P7 Error2 = IN8 ' Error2 input is pin P8 Error3 = IN9 ' Error3 input is pin P9 RETURN ' ------ Behavior1 ------------------------------------------ Behavior1: ' This is the lowest priority behavior Control1 = Error1 ' enable the LED if we have that error RETURN ' ------ Behavior2 ------------------------------------------ Behavior2: ' This is the highest priority behavior Control2 = Error2 ' enable the LED if we have that error Control3 = Error3 ' enable the LED if we have that error IF Error3 = 0 THEN done2 ' no conflict Control1 = 0 ' When Error3, we can't have LED1 on. ' We have a serious problem, Don't ' confuse operator with non-critical ' warnings - Note Behavior2 "subsumed" ' Behavior1 done2: RETURN ' ------- FSM1 ----------------------------------------------- FSM1: ' Here is the state machine for LED1 IF (Control1 = 0) THEN LED1_Off ' If not enabled force state 0 Cntr1 = Cntr1 - 1 ' decrement counter - saves code doing it here BRANCH State1,[ST1_0,ST1_1,ST1_2] ' Go to behaviors for each state ' will fall through if invalid index ST1_0: ' State machine1 state = 0 IF (Control1 = 1) THEN LED1_On ' See if it should move to state 1 LED1_Off: LOW LED1 ' Turn off LED State1 = 0 ' set up next state GOTO FSM1_done ' Still to stay off ST1_1: ' State machine1 state = 1 IF Cntr1 > 0 THEN FSM1_done ' wait for counter to expire LOW LED1 ' Need to turn off LED State1 = 2 ' set up next state Cntr1 = Off_cnt1 ' set up timer GOTO FSM1_done ST1_2: ' State machine1 state = 2 IF Cntr1 > 0 THEN FSM1_done ' wait for counter to expire LED1_On: HIGH LED1 ' Need to turn on LED State1 = 1 ' set up next state Cntr1 = On_cnt1 ' set up timer FSM1_done: RETURN ' ------- FSM2 ----------------------------------------------- FSM2: ' Here is the state machine for LED2 IF (Control2 = 0) THEN LED2_Off ' If not enabled force state 0 Cntr2 = Cntr2 - 1 ' decrement counter - saves code doing it here BRANCH State2,[ST2_0,ST2_1,ST2_2] ' Go to behaviors for each state ' will fall through if invalid index ST2_0: ' State machine1 state = 0 IF (Control2 = 1) THEN LED2_On ' See if it should move to state 1 LED2_Off: LOW LED2 ' Turn off LED State2 = 0 ' set up next state GOTO FSM2_done ' Still to stay off ST2_1: ' State machine1 state = 1 IF Cntr2 > 0 THEN FSM2_done ' wait for counter to expire LOW LED2 ' Need to turn off LED State2 = 2 ' set up next state Cntr2 = Off_cnt2 ' set up timer GOTO FSM2_done ST2_2: ' State machine1 state = 2 IF Cntr2 > 0 THEN FSM2_done ' wait for counter to expire LED2_On: HIGH LED2 ' Need to turn on LED State2 = 1 ' set up next state Cntr2 = On_cnt2 ' set up timer FSM2_done: RETURN ' ------- FSM1 ----------------------------------------------- FSM3: ' Here is the state machine for LED3 IF (Control3 = 0) THEN LED3_Off ' If not enabled force state 0 Cntr3 = Cntr3 - 1 ' decrement counter - saves code doing it here BRANCH State3,[ST3_0,ST3_1,ST3_2] ' Go to behaviors for each state ' will fall through if invalid index ST3_0: ' State machine1 state = 0 IF (Control3 = 1) THEN LED3_On ' See if it should move to state 1 LED3_Off: LOW LED3 ' Turn off LED State3 = 0 ' set up next state GOTO FSM3_done ' Still to stay off ST3_1: ' State machine1 state = 1 IF Cntr3 > 0 THEN FSM3_done ' wait for counter to expire LOW LED3 ' Need to turn off LED State3 = 2 ' set up next state Cntr3 = Off_cnt3 ' set up timer GOTO FSM3_done ST3_2: ' State machine1 state = 2 IF Cntr3 > 0 THEN FSM3_done ' wait for counter to expire LED3_On: HIGH LED3 ' Need to turn on LED State3 = 1 ' set up next state Cntr3 = On_cnt3 ' set up timer FSM3_done: RETURN