'****************************************************************
'* Name : UV PCB Exposure System Timer *
'* Author : Stijn Coenen [Stynus] *
'* Notice : Licensed under Creative Commons *
'* : Attribution-Noncommercial 2.0 Belgium Licence *
'* : http://creativecommons.org/licenses/by-nc/2.0/be/ *
'* Date : 28/08/2011 *
'* Version : 2.11 *
'* Url : English: en.elektronicastynus.be/projects/81/ *
'* : Dutch: www.elektronicastynus.be/Projecten/81/ *
'****************************************************************
Device 16F628A
Config INTRC_OSC_NOCLKOUT, WDT_off, PWRTE_ON, LVP_off, MCLRE_OFF
All_Digital TRUE
Xtal = 4
'Set the default data in the eeprom at programming
EData 0,0,10, 107 'Singe Sided, Exposure Time minutes, Exposure Time Seconds, Interrupt preload
'****************************************************************
'In and outputs
'Tris registers
'76543210
TRISA = %01100000
TRISB = %00001111
Symbol Relay1 = PORTA.2
Symbol Relay2 = PORTA.3
Symbol Buzzer = PORTA.7
High Buzzer 'Buzzer is connected to the 5V, so pin must be high to disable
Symbol Btn_1 = PORTB.2 '3 input buttons
Symbol Btn_2 = PORTB.1
Symbol Btn_3 = PORTB.0
'Lcd screen
Declare LCD_ENPin PORTA.1
Declare LCD_RSPin PORTA.0
Declare LCD_DTPin PORTB.4
Declare LCD_Interface 4
Declare LCD_Lines 2
Symbol LcdTime = 200 'Time for each step at the startup message and hidden menu
'On-chip pull-up resistors active
PortB_Pullups On
'Settings:
Dim SingleDouble As Bit
Dim Time_Min As Byte
Dim Time_Sec As Byte
Dim Count_Min As Byte
Dim Count_Sec As Byte
'Interupt
On_Hardware_Interrupt GoTo Int_Routine
Symbol T0IE = INTCON.5 'TMR0 Overflow Interrupt Enable
Symbol T0IF = INTCON.2 'TMR0 Overflow Interrupt Flag
Symbol GIE = INTCON.7 'Global Interrupt Enable
Symbol PS0 = OPTION_REG.0 'Prescaler bit-0
Symbol PS1 = OPTION_REG.1 'Prescaler bit-1
Symbol PS2 = OPTION_REG.2 'Prescaler bit-2
Symbol PSA = OPTION_REG.3 'Prescaler Assignment
Symbol T0CS = OPTION_REG.5 'Timer0 Clock Source Select
Dim Timer_Go As Bit
Dim Int_Counter As Byte
Dim Int_Preload As Byte
PSA = 0
PS0 = 1
PS1 = 1
PS2 = 1
T0CS = 0
TMR0 = 0
T0IF = 0
T0IE = 1
GIE = 1
'Eeprom adresses
Symbol Ee_SS_DS = 0 'Singe Sided / Double Sided
Symbol Ee_Ti_Mi = 1 'Exposure Time minutes
Symbol Ee_Ti_Se = 2 'Exposure Time Seconds
Symbol Ee_Inter = 3 'Interrupt preload value (for fine tuning the timing)
Symbol Ee_Skip = 4 'Skip startup message?
Symbol Ee_TopBot = 5 'Is single sided top or bottom?
Symbol Ee_En_DS = 6 'Is double sided enabled?
'Div.:
'Custom LCD characters
Print $FE,$40,$04,$04,$04,$07,$00,$00,$00,$00
Dim Temp As Byte 'Byte for temporary storage
'****************************************************************
StartUp:
Clear 'Clear ram
Cls 'Clear lcd
DelayMS 300
'Enter hidden menu?
If Btn_1 = 0 Then
GoSub Hidden
EndIf
'Read Eeprom data
Temp = ERead Ee_SS_DS
SingleDouble = Temp.0
Time_Min = ERead Ee_Ti_Mi
Time_Sec = ERead Ee_Ti_Se
Int_Preload = ERead Ee_Inter
'Skip startup message?
Temp = ERead Ee_Skip
If Temp <> 1 Then
'Startup message
'1234567890123456
Print At 1,1, "UV Exposure Syst"
Print At 2,1, "V2.1 Stynus 2011"
DelayMS LcdTime
DelayMS LcdTime
Print At 1,1, "V Exposure Syste"
DelayMS LcdTime
Print At 1,1, " Exposure System"
DelayMS LcdTime
Print At 1,1, "Exposure System "
DelayMS LcdTime
Print At 1,1, "xposure System T"
DelayMS LcdTime
Print At 1,1, "posure System Ti"
DelayMS LcdTime
Print At 1,1, "osure System Tim"
DelayMS LcdTime
Print At 1,1, "sure System Time"
DelayMS LcdTime
Print At 1,1, "ure System Timer"
DelayMS 700
Cls
EndIf
'****************************************************************
StartScreen:
While 1 = 1 '1234567890123456
Print At 1, 1, "Time:"
Print At 1, 7, Dec2 Time_Min, ":", Dec2 Time_Sec 'Display the exposure time
Print At 2, 1, "Start"
'If double sided is not enabled we don't need this setting
Temp = ERead Ee_En_DS
If Temp > 0 Then
If SingleDouble = 0 Then
Print At 2, 6, "|S.S.|"
Else
Print At 2, 6, "|D.S.|"
EndIf
EndIf
Print At 2,12, "SetT"
While 1 = 1 'Button read loop
If Btn_1 = 0 Then
'Start the timer
GoSub Timer
Break
EndIf
If Btn_2 = 0 Then
Temp = ERead Ee_En_DS
'If double sided is possible then toggle between double and single sided
If Temp > 0 Then
GoSub Debounce_BTN_2
SingleDouble = ~ SingleDouble 'Toggle the value of SingleDouble (bit)
EWrite Ee_SS_DS, [SingleDouble] 'Write the setting to the eeprom
Break
EndIf
EndIf
If Btn_3 = 0 Then
'Enter the menu to change the exposure time
GoSub Debounce_BTN_3
GoSub TimeMenu
Break
EndIf
Wend
Wend
'****************************************************************
Timer:
'This sub contains the exposure timer
Cls 'Clear the display
'Load timer
Count_Min = Time_Min
Count_Sec = Time_Sec
Timer_Go = 1
Restart:
'Put the relays on
If SingleDouble = 0 Then
'For single sided check if top or bottom is used.
Temp = ERead Ee_TopBot
If Temp = 0 Then
High Relay1
Else
High Relay2
EndIf
Temp = ERead Ee_En_DS
If Temp > 0 Then
Print At 1, 11, "(S.S.)"
EndIf
Else
High Relay1
High Relay2
Print At 1, 11, "(D.S.)"
EndIf
Print At 1,1, "Status:On"
Print At 2,12, "|Stop"
'Timer check loop
While 1 = 1
'Print timer value
Print At 2, 1, Dec2 Count_Min, ":", Dec2 Count_Sec
DelayMS 300
'Check if time is done
'The timer counts down in the interrupt routine)
If Timer_Go = 0 Then
Break
EndIf
'If the right button is pressed the timer stops
If Btn_3 = 0 Then
GoSub Debounce_BTN_3
Timer_Go = 0
Break
EndIf
Wend
Print At 1,1, "Status:Off "
'Turn relays back off
Low Relay1
Low Relay2
'Is the time over, or is the stop button pressed?
If Count_Min > 0 Or Count_Sec > 0 Then
'Stop button 1234567890123456
Print At 1,1, "Stopped at "
Print At 2,6, " Start|Exit"
'(Time is still on the second line from above)
'Check the buttons
While 1 = 1
'If the middle button is pressed then the timer is restarted to do the remaining time
If Btn_2 = 0 Then
GoSub Debounce_BTN_2
Timer_Go = 1
GoTo Restart
EndIf
'If the right button is pressed then the timer is cancelled and the program returs from this sub
If Btn_3 = 0 Then
GoSub Debounce_BTN_3
Cls
Return
EndIf
Wend
Else
'Exposure time over
Cls '1234567890123456
Print At 1,1, " DONE "
'Beep
Buzzer = 0
DelayMS 200
Buzzer = 1
DelayMS 250
Buzzer = 0
DelayMS 200
Buzzer = 1
Print At 2,1, " Press Any Key. "
While 1 = 1
'Stay on this screen until a button is pressed
If Btn_1 = 0 Then
GoSub Debounce_BTN_1
Break
EndIf
If Btn_2 = 0 Then
GoSub Debounce_BTN_2
Break
EndIf
If Btn_3 = 0 Then
GoSub Debounce_BTN_3
Break
EndIf
Wend
EndIf
'Wait for button press
Cls
Return
'****************************************************************
TimeMenu:
'This subroutine contains the menu to change the exposure time
Cls 'Clear the display
Temp = 1
Print At 1, 1, "Set Time:"
Print At 1, 11, Dec2 Time_Min, ":", Dec2 Time_Sec
Print At 2, 1, " + | - | ", 0, "-> "
Cursor 1, 11
Print $FE, $0E ' Underline cursor on
Print $FE, $0F ' Blinking cursor on
'Minutes first digit
While 1 = 1
If Btn_1 = 0 Then
If Time_Min < 89 Then
Time_Min = Time_Min + 10
Print At 1, 11, Dec2 Time_Min
Cursor 1, 11
EndIf
GoSub Debounce_BTN_1
EndIf
If Btn_2 = 0 Then
If Time_Min > 9 Then
Time_Min = Time_Min - 10
Print At 1, 11, Dec2 Time_Min
Cursor 1, 11
EndIf
GoSub Debounce_BTN_2
EndIf
If Btn_3 = 0 Then
GoSub Debounce_BTN_3
Break
EndIf
Wend
'Minutes second digit
Cursor 1, 12
While 1 = 1
If Btn_1 = 0 Then
If Time_Min < 98 Then
Time_Min = Time_Min + 1
Print At 1, 11, Dec2 Time_Min
Cursor 1, 12
EndIf
GoSub Debounce_BTN_1
EndIf
If Btn_2 = 0 Then
If Time_Min > 0 Then
Time_Min = Time_Min - 1
Print At 1, 11, Dec2 Time_Min
Cursor 1, 12
EndIf
GoSub Debounce_BTN_2
EndIf
If Btn_3 = 0 Then
GoSub Debounce_BTN_3
Break
EndIf
Wend
EWrite Ee_Ti_Mi, [Time_Min]
'Seconds first digit
Cursor 1, 14
While 1 = 1
If Btn_1 = 0 Then
If Time_Sec < 49 Then
Time_Sec = Time_Sec + 10
Print At 1, 14, Dec2 Time_Sec
Cursor 1, 14
EndIf
GoSub Debounce_BTN_1
EndIf
If Btn_2 = 0 Then
If Time_Sec > 9 Then
Time_Sec = Time_Sec - 10
Print At 1, 14, Dec2 Time_Sec
Cursor 1, 14
EndIf
GoSub Debounce_BTN_2
EndIf
If Btn_3 = 0 Then
GoSub Debounce_BTN_3
Break
EndIf
Wend
'Seconds second digit
Cursor 1, 15
While 1 = 1
If Btn_1 = 0 Then
If Time_Sec < 58 Then
Time_Sec = Time_Sec + 1
Print At 1, 14, Dec2 Time_Sec
Cursor 1, 15
EndIf
GoSub Debounce_BTN_1
EndIf
If Btn_2 = 0 Then
If Time_Sec > 0 Then
Time_Sec = Time_Sec - 1
Print At 1, 14, Dec2 Time_Sec
Cursor 1, 15
EndIf
GoSub Debounce_BTN_2
EndIf
If Btn_3 = 0 Then
GoSub Debounce_BTN_3
Break
EndIf
Wend
EWrite Ee_Ti_Se, [Time_Sec]
Cls 'Clear display
Print $FE, $0C 'Cursor off
Return
'****************************************************************
Debounce_BTN_1:
DelayMS 300
While Btn_1 = 0
DelayMS 300
Wend
Return
'****************************************************************
Debounce_BTN_2:
DelayMS 300
While Btn_2 = 0
DelayMS 300
Wend
Return
'****************************************************************
Debounce_BTN_3:
DelayMS 300
While Btn_3 = 0
DelayMS 300
Wend
Return
'****************************************************************
Hidden: 'Menu
'Adjust the timing
'1234567890123456
Print At 1,1, " - Hidden Menu -"
DelayMS 1000 '1234567890123456
Print At 1,1, "Check manual for"
Print At 2,1, " instructions"
DelayMS 1000 '1234567890123456
Print At 1,1, "Timing adjustmen"
Print At 2,1, "Value: "
Int_Preload = ERead Ee_Inter
Print At 2, 7, Dec3 Int_Preload
While 1 = 1
If Btn_1 = 0 Then
If Int_Preload < 255 Then
Int_Preload = Int_Preload + 1
Print At 2, 7, Dec3 Int_Preload
EndIf
GoSub Debounce_BTN_1
EndIf
If Btn_2 = 0 Then
If Int_Preload > 0 Then
Int_Preload = Int_Preload - 1
Print At 2, 7, Dec3 Int_Preload
EndIf
GoSub Debounce_BTN_2
EndIf
If Btn_3 = 0 Then
GoSub Debounce_BTN_3
Break
EndIf
Wend
EWrite Ee_Inter, [Int_Preload]
Cls
'Enable double sided exposure?
'1234567890123456
Print At 1,1, "Enable double "
Print At 2,1, "sided? Yes|No"
While 1 = 1
If Btn_2 = 0 Then
GoSub Debounce_BTN_2
EWrite Ee_En_DS, [1]
Break
EndIf
If Btn_3 = 0 Then
GoSub Debounce_BTN_3
EWrite Ee_En_DS, [0]
Break
EndIf
Wend
'Skip start up message?
'1234567890123456
Print At 1,1, "Skip start up "
Print At 2,1, "message? Yes|No"
While 1 = 1
If Btn_2 = 0 Then
GoSub Debounce_BTN_2
EWrite Ee_Skip, [1]
Break
EndIf
If Btn_3 = 0 Then
GoSub Debounce_BTN_3
EWrite Ee_Skip, [0]
Break
EndIf
Wend
'Single side top or bottom?
'1234567890123456
Print At 1,1, "Single side top/"
Print At 2,1, "bottom? Top|bot"
While 1 = 1
If Btn_2 = 0 Then
GoSub Debounce_BTN_2
EWrite Ee_TopBot, [1]
Break
EndIf
If Btn_3 = 0 Then
GoSub Debounce_BTN_3
EWrite Ee_TopBot, [0]
Break
EndIf
Wend
Cls
Return
'****************************************************************
Int_Routine: 'Interrupt routine to time the exposure time
Context Save
If T0IF = 1 Then 'Check if the interrupt does come from timer 0
T0IF = 0 'Reset timer overflow flag
TMR0 = Int_Preload 'Preload the timer with the Int_Preload value
'This value can be set in the hidden menu
Inc Int_Counter ''Increment the timer
If Int_Counter = 26 Then '26 times the interrupt routine = 1sec
Int_Counter = 0
If Timer_Go = 1 Then 'If the timer is enabled then decrease
If Count_Sec > 0 Then 'enough seconds left to dec?
Dec Count_Sec
Else
If Count_Min > 0 Then 'enough minutes left to dec?
Dec Count_Min
Count_Sec = 59
Else
Timer_Go = 0 'Time finished, disable timer
EndIf
EndIf
EndIf
EndIf
EndIf
Context Restore
'****************************************************************
End