'**************************************************************** '* Name : Timed Model Rocket Launcher '* Author : Cy Brown '* Notice : Copyright (c) 2006 '* : All Rights Reserved '* Date : 9/7/2006 '* Version : 1.0 '* Notes :Timed Model Rocket Launcher Device '* :Device will count down from a user set time and trip '* :a relay that energizes the model rocket engine igniter '* :Min of 10 secs for selected time, if user specifies less '* :the code will set time to 10 before beginning countdown '* :Piezo speaker on the device will give a beep every second '* :for the last 10 seconds, and a steady tone for the last '* :2 seconds. '* :User will set time with 4 buttons, Mins up/down and '* :Secs up/down. '* :User will start/stop the clock with a start/stop button '* :If at any time the clock is started with less than 10 secs '* :the clock will be set to 10 secs before counting down '* :Time is displayed on a HC4LED Display, which is 4 7segment led's '* :on a module that uses data shifted in via SPI '* :Current Device is a PIC 16F628A '**************************************************************** DEFINE OSC 4 'Use internal 4Mhz Osc CMCON = $07 'This sets the PIC's comparators OFF so the pins can be used for I/O '-------[Constants]----------------------------------------------------- FireTime con 750 'Time to hold the fire Pin active, value in ms BtnRelease con 100 'button release timer value for debounce, value in ms BtnRepeat con 200 'button repeat timer value in ms BeepTime con 30 'Time to beep during last 10 secs of countdown, in 10ms '-------[I/O Definitions]----------------------------------------------- LEDPin VAR portb.0 'Output pin for SPI Data for LED Display ClkPin var portb.1 'Output pin for SPI Clk for LED Display MupPin var portb.7 'Input pin for Min up button MdnPin var portb.6 'Input pin for Min down button SupPin var portb.5 'Input pin for Sec up button SdnPin var portb.4 'Input pin for Sec down button StSpPin var portb.2 'Input pin for the Start/Stop button FirePin Var porta.1 'Output pin to activate the firing relay FirePin = 0 AlarmPin VAR portb.3 'Output pin to activate the piezo alarm AlarmPin = 0 AlarmLED VAR porta.0 'Ouput pin for the power good/Alarm LED (Active LOW) AlarmLED = 0 'set AlarmLED to on (Active LOW) '--------[Variables]----------------------------------------------------- Mins Var Byte 'Variable to store Mins value Secs Var Byte 'Variable to store Secs value i var byte 'Variable for counter increments Secs1s var byte 'These variables hold the digits for the LED display Secs10s var byte Mins1s var byte Mins10s var byte '********************************************************************* '--------[Pre-Main Loop Startup routine]------------------------------ '********************************************************************* 'set appropriate input/output states for the tris registers trisA = %00000000 trisB = %11110100 'snazzy startup display routine... for Secs1s = 50 to 0 step - 5 secs = 255 for mins = 0 to 10 shiftout LEDPin, ClkPin, 4, [~secs] secs = secs/2 pause Secs1s next mins next Secs1s pause 1000 Mins = 0 'init mins to 0 Secs = 10 'init secs to 10 gosub Display 'init display '********************************************************************* '-------[Setup Loop]--------------------------------------------------- 'This loops polls all the buttons. 'If the Start/Stop button is pressed, the code checks for a min time of 10 secs 'Sets the time to 10 if it was below ten, then goes to the CoundDown Loop 'The 4 time ajustment buttons are polled and time is ajusted accordingly. '********************************************************************* Setup: AlarmLED = 0 'turn on the powergood/alarm LED 'check for start/stop button If StSpPin = 0 Then 'if the start/stop button is pressed then... AlarmPin = 1 'start warning buzzer while StSpPin = 0 'debounce loop waiting for button release pause BtnRelease wend If (Mins = 0)and (secs<10) then 'check for time of less than 10 secs secs = 10 'set to time minimum time of 10 secs endif AlarmPin = 0 'stop warning buzzer Goto countdown 'goto countdown loop endif 'check for Mins/Secs increment/decrement buttons while MupPin = 0 if mins = 59 then 'wraparound from 59 to 0 mins = 0 gosub display 'update display else Mins = mins +1 'increment mins by one gosub display 'refresh display to show change endif pause BtnRepeat 'pause before repeating action wend while MdnPin = 0 if mins = 0 then 'wraparound from 0 to 59 mins = 59 gosub display 'update display else Mins = mins -1 'decrement mins gosub display 'update display endif pause BtnRepeat 'pause before repeating action wend while SupPin = 0 if Secs = 59 then Secs = 0 gosub display else Secs = Secs +1 gosub display endif pause BtnRepeat wend while SdnPin = 0 if Secs = 0 then Secs = 59 gosub display else Secs = Secs -1 gosub display endif pause BtnRepeat wend Goto Setup '********************************************************************* '-------[CountDown Loop]---------------------------------------------- 'This loop counts down the time while polling the Start/Stop button. 'If the StartStop button is pressed the loop stops counting down and checks the 'time and if it is below the 10 second min, it sets time to 10 secs. It then 'jumps to the Setup Loop. 'For the last 10 seconds speaker pin goes high for a fraction of a second at the 'start of each second. 'For the last 2 seconds the speaker pin goes high for the whole 2 seconds. 'When the countdown gets to 0 the fire pin is set high to activate the fire 'relay. The time is then set to 10 seconds and the program jumps to the setup 'loop. '********************************************************************* CountDown: 'This is a 1 second loop broken into 100 10ms sections so that the 'start/stop button is polled every 10ms 'The loop also checks and controls the buzzer for the final 10 and 2 sec 'alarm scheme 'decrement the mins and secs counter or fire as needed if (Mins = 0) then if secs = 0 then gosub Display 'update display before firing goto Fire 'goto to the fire routine else secs = secs - 1 endif else if secs = 0 then mins = mins -1 secs = 59 else Secs = secs - 1 'if secs are > 0 then decrement secs endif endif GoSub Display 'Update the display 'this for loop polls the stop button and beeps when needed for i = 1 to 100 if StSpPin = 0 then 'poll start/stop button AlarmPin = 1 'start buzzer While StSpPin = 0 'wait for button release pause BtnRelease wend if (mins = 0) and (secs < 10) then 'check for min time secs = 10 'set min time if needed gosub Display endif Alarmpin = 0 'stop buzzer goto setup 'goto setup loop endif if (mins = 0) and (secs < 11) And (i < BeepTime)then AlarmPin = 1 'buzz for first BeepTime iterations of the count 'and last 10 seconds of time else if (mins = 0) and (Secs < 3) then AlarmPin = 1 'buzz for the last 3 seconds else Alarmpin = 0 'kill buzzer otherwise endif endif pause 10 AlarmLED = i.2 'this sets the AlarmLED on/off state to the third bit of the i counter for this loop 'since each increment of i is 10ms, each increment of the third bit of i should be 40ms 'this gives the AlarmLED for a flashing effect next i Goto CountDown '-------[Goto Labels]------------------------------------------------- '***************************************************** '*********************!!!Fire!!!********************** '***************************************************** 'This label fires the relay, resets the time to 10 seconds, updates the display, 'then goes back to the setup loop Fire: alarmpin = 0 'turn off the alarm buzzer alarmLED = 1 'turn off the alarm LED Firepin = 1 'put firepin high to activate relay pause fireTime 'pause FireTime ms firepin = 0 'put firepin back low mins = 0 'reset time secs = 10 Gosub Display 'update display Goto Setup 'return to setup '------[Subroutines]----------------------------------------------------- Display: 'These are the lookup tables for the decimbal numbers that will light the correct 'segments on the 7 seg displays. lookup (secs // 10),[126,24,182,188,216,236,238,56,254,248],Secs1s lookup (secs / 10),[126,24,182,188,216,236,238,56,254,248],secs10s lookup (Mins // 10),[126,24,182,188,216,236,238,56,254,248],Mins1s lookup (Mins / 10),[126,24,182,188,216,236,238,56,254,248],Mins10s 'This shifts the data out to the LED display, the left most byte of data 'ends up on the right most digit of the display. It shifts from left to right. shiftout LEDPin, ClkPin, 4, [secs1s,secs10s,mins1s,mins10s] Return