PDA

View Full Version : select case question



ronjodu
- 4th March 2006, 06:01
I'm using Darryl Taylor's Interrupt routine to increment a variable (display) once on every timer1 overflow. Thanks again Darryl for the cool includes files.
I then use a select case to display 3 different things on my LCD. All is well.



showonlcd:

select case display

Case 1

display = display + 1
gosub read_maintemp
INTCON.7 = 0
Serout2 thelcd,Baud, [I,clr]
Serout2 thelcd,Baud, [I,130,"MAIN TANK TEMP"]
Serout2 thelcd,Baud, [I,196,#(AD_Result/100),".",#(AD_Result//100),4," ","C"]
AD_Result = 0
INTCON.7 = 1
low buzzer
case 6

display = display + 1
gosub read_qttemp
INTCON.7 = 0
Serout2 thelcd,Baud, [I,clr]
Serout2 thelcd,Baud, [I,130,"Q/T TANK TEMP"]
Serout2 thelcd,Baud, [I,196,#(AD_Result/100),".",#(AD_Result//100),4," ","C"]
AD_Result = 0
INTCON.7 = 1
'display = 0
Case 11
display = display + 1
select case trouble
CASE 0
INTCON.7 = 0
Serout2 thelcd,Baud, [I,clr]
Serout2 thelcd,Baud, [I,128," SYSTEM"]
Serout2 thelcd,Baud, [I,196,"NORMAL"]
INTCON.7 = 1
end select
end select

if display = looplength then display = 0
RETURN
goto mainloop


What I would like to do is in the 3rd case (11), if there is anything "not normal" happening, I would like to display it at this step instead of "system normal". Sounds easy, I used another select case "trouble" within my original select case and I'll flag bits (elsewhere in the program) within the variable "trouble" to let me know what the problem is.
This should work well if I only have one problem at a time. If there are more than 1 problem is there an easier way to step thru the "trouble" bits (maybe some type of for..next loop)to display the problems or is the select case as I have it the best way?
The next select case would be


select case trouble
CASE 1,3,5,7,9,11,13,15,17,19........255
INTCON.7 = 0
Serout2 thelcd,Baud, [I,clr]
Serout2 thelcd,Baud, [I,128,"MAIN TANK TEMP"]
Serout2 thelcd,Baud, [I,196,"OVER LIMIT"]
INTCON.7 = 1
ETC...........
Or is there a better way to go about the whole thing!
Go easy on me I'm still a rookie. Any thoughts would be welcome.

16f876,4mhz, PBP2.45, labx2

sougata
- 4th March 2006, 09:49
Hi,

As far as code goes (it not the complete one), you are using the display variable to use a per second(x2,x3) update of your LCD to show multiple information. I think you can you the same Select Case loop to do more.

1. Since you are flagging bits in a variable under normal conditions the variable would be zero. So you an IF-Then_Else to display the normal when that byte is zero and use it to reset the display variable too. Next use more select case statement to do a bit by bit checking and displaying the error messages.

2. Now suppose you have the third bit set then your select case would waste 3 cycles to display that condition. So use another increment variable that acts as a pointer to your valid flags.

3. When all done reset the display variable.

I used this sort of code in one of my Annunciator Project. I will just have to check with my partner (the fat headed commercial guy) if I can share the same on this forum.

Good Luck

Regards

Sougata

ronjodu
- 5th March 2006, 00:30
Thanks sougata, yes I believe you have understood what it is I'm trying to do. I'll be away for most of the day today so I'll have time to absorb what you are suggesting. No need to sell the farm out from under ("the fat headed commercial guy") for now. A nudge in the right direction is all I was looking for.

Thank you for your help so far! Here is the whole code (although very much incomplete) if you think it will help.



'************************************************* ***************
'* Name : *
'* Author : *
'* Notice : *
'* : *
'* Date : 2/17/2006 *
'* Version : 1.0 *
'* Notes : Uses Darryl Taylor interrupt routines *
'* : *
'************************************************* ***************
DEFINE LOADER_USED 1 'Only required if bootloader used to program PIC
define OSC 4

INCLUDE "modedefs.bas"
INCLUDE "DT_INTS-14.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP.bas" ' Include if using PBP interrupts

' ** Setup the ADCIN Defines **

Define ADC_BITS 10 ' Set resolution of conversion
Define ADC_CLOCK 2 ' Set clock source (x/FOSC or FRC)
Define ADC_SAMPLEUS 50 ' Set sampling time (in uS)

' OPTION_REG.7 = 0
'ADCON1 = 7 ' PORTA digital

PORTA = %00000000 'Set all pins to 0
TRISA = %00111111 'Set PORTA RA0-RA5 to input
PORTB = %00000000 'Set all pins to 0 (off)
TRISB = %01110000 'Set PORTB inputs/output
PORTC = %00000000 'Set all outputs to 0 (off)
TRISC = %00000000 'Set PORTC to all output

'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::::::
' Alias pins
'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::::::


LED1 VAR PORTB.0 'LED1 simulating "alarm"
LED2 VAR PORTB.1 'LED2 simulating main heater on
LED3 VAR PORTB.2 'LED3 simulating Q/T heater on
thelcd var PORTB.3
button1 VAR PORTB.4
button2 VAR PORTB.5
button3 VAR PORTB.6
buzzer var PORTB.7 'sonalert alarm
heartbeat var PORTC.5
'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::::::
' Define Variables
'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::::::

display var byte
temp1 VAR byte
temp2 VAR byte
setpoint1 var byte
setpoint2 var byte
main_lowtmp var byte
main_hightmp var byte
qt_lowtmp var byte
qt_hightmp var byte
sample1 VAR byte
sample2 VAR byte
AD_Raw Var Word ' 16-bit result of A/D conversion
AD_Result Var Word ' Quantasized ADC result
Bit_Cnt Var Byte ' General purpose loop
Chr Var Byte ' Degrees sign build variable
Quanta Con 1250
Alarm var byte
looplength var byte
trouble var byte
'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::::::
' ** Define LCD Constants **
'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::::::

I Con 254 ' Control Byte
Clr Con 1 ' Clear the display
Line1 Con 128 ' Point to beginning of line 1
Line2 Con 194 ' Point to beginning of line 2
Line3 Con 148 ' Point to beginning of line 3
Line4 Con 212 ' Point to beginning of line 4
Baud con 84
Cgram Con 64 ' Point to Cgram in the LCD

'((((((((((((((((((((((((((((((((((((((()))))))))) )))))))))))))))))))))))))))))
' Clear LCD and pause to start
'((((((((((((((((((((((((((((((((((((((()))))))))) )))))))))))))))))))))))))))))

Pause 5000
Serout2 thelcd,Baud,[I,clr]
Pause 1000
Serout2 thelcd,Baud,[I,clr]
Pause 1000
Serout2 thelcd,Baud,[I,clr,I,128," START"]
Pause 1500

temp1 = 0
temp2 = 0
display = 0
setpoint1 = 79
setpoint2 = 79
main_lowtmp = setpoint1 - 2
main_hightmp = setpoint1 + 2
qt_lowtmp = setpoint2 - 2
qt_hightmp = setpoint2 + 2
looplength = 16
trouble = 0
'((((((((((((((((((((((((((((((((((((((()))))))))) )))))))))))))))))))))))))))))
' build the degree symbol
'((((((((((((((((((((((((((((((((((((((()))))))))) )))))))))))))))))))))))))))))

For Bit_Cnt =0 to 7 '
Lookup Bit_Cnt,[%00000110,%00001001,%00001001,%00000110,0,0,0,0],Chr
Serout2 thelcd,84,[$fe,96+Bit_Cnt,Chr,1]' Output the bit patterns to the LCD's CGRAM
Next
'((((((((((((((((((((((((((((((((((((((()))))))))) )))))))))))))))))))))))))))))
' set-up A/D channels
'((((((((((((((((((((((((((((((((((((((()))))))))) )))))))))))))))))))))))))))))

ADCON1= %10001110 ' Configure for AN0 and AN1 as analog input
' With right justified result
'((((((((((((((((((((((((((((((((((((((()))))))))) )))))))))))))))))))))))))))))
' Interrupt handler
'((((((((((((((((((((((((((((((((((((((()))))))))) )))))))))))))))))))))))))))))

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR1_INT, _ToggleLED1, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM

T1CON = $31 ; Prescaler = 8, TMR1ON
@ INT_ENABLE TMR1_INT ; enable Timer 1 interrupts

'((((((((((((((((((((((((((((((((((((((()))))))))) )))))))))))))))))))))))))))))
' Main program loop - updates the LCD and siteplayer with the time
'and status of temperatures and pumps
'((((((((((((((((((((((((((((((((((((((()))))))))) )))))))))))))))))))))))))))))

mainloop:

GoSub showonlcd
'GoSub read_switches
goto mainloop

'---[INT - interrupt handler]---------------------------------------------------
ToggleLED1:
TOGGLE heartbeat
display = display + 1
@ INT_RETURN
'''''''''''''''''''''''''''''''''''''''''''''''''' ''''''''''''''''''''''''''''''
'''''''''''''''''''''''''''''''''''''''''''''''''' ''''''''''''''''''''''''''''''
'read Temp sensors for high/low temp alarm and display on LCD
'''''''''''''''''''''''''''''''''''''''''''''''''' ''''''''''''''''''''''''''''''

showonlcd:

select case display

Case 1

display = display + 1
gosub read_maintemp
INTCON.7 = 0
Serout2 thelcd,Baud, [I,clr]
Serout2 thelcd,Baud, [I,130,"MAIN TANK TEMP"]
Serout2 thelcd,Baud, [I,196,#(AD_Result/100),".",#(AD_Result//100),4," ","C"]
AD_Result = 0
INTCON.7 = 1
low buzzer
case 6

display = display + 1
gosub read_qttemp
INTCON.7 = 0
Serout2 thelcd,Baud, [I,clr]
Serout2 thelcd,Baud, [I,130,"Q/T TANK TEMP"]
Serout2 thelcd,Baud, [I,196,#(AD_Result/100),".",#(AD_Result//100),4," ","C"]
AD_Result = 0
INTCON.7 = 1
'display = 0
Case 11
display = display + 1
select case trouble
CASE 0
'display = display + 1
INTCON.7 = 0
Serout2 thelcd,Baud, [I,clr]
Serout2 thelcd,Baud, [I,128," SYSTEM"]
Serout2 thelcd,Baud, [I,196,"NORMAL"]
INTCON.7 = 1
end select
end select

if display = looplength then display = 0
RETURN
goto mainloop
'''''''''''''''''''''''''''''''''''''''''''''''''' ''''''''''''''''''''''''''''''
'read CT sensors for pump motors
'''''''''''''''''''''''''''''''''''''''''''''''''' ''''''''''''''''''''''''''''''
read_switches:

RETURN
'''''''''''''''''''''''''''''''''''''''''''''''''' ''''''''''''''''''''''''''''''
'misc alarms and things
'''''''''''''''''''''''''''''''''''''''''''''''''' ''''''''''''''''''''''''''''''


sonalert:
high buzzer
goto mainloop

'''''''''''''''''''''''''''''''''''''''''''''''''' ''''''''''''''''''''''''''''''
'misc alarms and things ...LM335 temp sensors
'''''''''''''''''''''''''''''''''''''''''''''''''' ''''''''''''''''''''''''''''''

read_maintemp:
ADCIN 0,AD_Raw ' Place the conversion of channel0 into AD_RAW
AD_Result=((AD_Raw*10)-5594) */ Quanta 'Quantasize the result
return ' go back to where it came from

read_qttemp:
ADCIN 1,AD_Raw ' Place the conversion of channel1 into AD_RAW
AD_Result=((AD_Raw*10)-5594) */ Quanta 'Quantasize the result
return ' go back to where it came from


goto mainloop
Serout2 thelcd,Baud, [I,clr]
Serout2 thelcd,Baud, [I,128,"PROGRAM STOPPED"]
end

ronjodu
- 7th March 2006, 22:50
Thanks again Sougata, I pondered your suggestion for a while and what I came up with works exactly as I wanted it to. I'm not sure if I did it entirely as you were suggesting.
Here is the Select case code I ended up with. It works like a "leap frog" over the unflagged alarms and into the flagged ones. If you or anyone for that matter see a better way, I'm here to learn. I know I've seen a post by Darryl Taylor on sending strings to an LCD. I'm going to look for it to see if it could apply here.



showonlcd:

select case display

Case 1

display = display + 1
gosub read_maintemp
INTCON.7 = 0
Serout2 thelcd,Baud, [I,clr]
Serout2 thelcd,Baud, [I,130,"MAIN TANK TEMP"]
Serout2 thelcd,Baud, [I,196,#(AD_Result/100),".",#(AD_Result//100),4," ","C"]
AD_Result = 0
INTCON.7 = 1
low buzzer
case 6

display = display + 1
gosub read_qttemp
INTCON.7 = 0
Serout2 thelcd,Baud, [I,clr]
Serout2 thelcd,Baud, [I,130,"Q/T TANK TEMP"]
Serout2 thelcd,Baud, [I,196,#(AD_Result/100),".",#(AD_Result//100),4," ","C"]
AD_Result = 0
INTCON.7 = 1

Case 11
display = display + 1
if trouble = 0 then
INTCON.7 = 0
Serout2 thelcd,Baud, [I,clr]
Serout2 thelcd,Baud, [I,132," SYSTEM"]
Serout2 thelcd,Baud, [I,196,"NORMAL"]
INTCON.7 = 1
looplength = 15
else
display = 16
looplength = 21
ENDIF
Case 16
display = display + 1
holding = trouble.0
if holding = 1 then
INTCON.7 = 0
Serout2 thelcd,Baud, [I,clr]
Serout2 thelcd,Baud, [I,130,"MAIN TANK TEMP"]
Serout2 thelcd,Baud, [I,197,"ALARM"]
INTCON.7 = 1
trouble.0 = 0
looplength = 22
else
display = 21
looplength = 26
ENDIF
Case 21
display = display + 1
holding = trouble.1
if holding = 1 then
INTCON.7 = 0
Serout2 thelcd,Baud, [I,clr]
Serout2 thelcd,Baud, [I,130,"Q/T TANK TEMP"]
Serout2 thelcd,Baud, [I,194,"ALARM"]
INTCON.7 = 1
trouble.1 = 0
looplength = 27
else
display = 26
looplength = 31
ENDIF
Case 26
display = display + 1
holding = trouble.2
if holding = 1 then
INTCON.7 = 0
Serout2 thelcd,Baud, [I,clr]
Serout2 thelcd,Baud, [I,130,"MAIN TANK "]
Serout2 thelcd,Baud, [I,194,"SKIMMER ALARM"]
INTCON.7 = 1
trouble.2 = 0
looplength = 32
else
display = 31
looplength = 36
ENDIF
Case 31
display = display + 1
holding = trouble.3
if holding = 1 then
INTCON.7 = 0
Serout2 thelcd,Baud, [I,clr]
Serout2 thelcd,Baud, [I,130,"MAIN TANK RETURN"]
Serout2 thelcd,Baud, [I,196,"PUMP ALARM"]
INTCON.7 = 1
trouble.3 = 0
looplength = 37
else
display = 36
looplength = 41
ENDIF
Case 36
display = display + 1
holding = trouble.4
if holding = 1 then
INTCON.7 = 0
Serout2 thelcd,Baud, [I,clr]
Serout2 thelcd,Baud, [I,130,"WATER LEAK"]
Serout2 thelcd,Baud, [I,196,"ALARM"]
INTCON.7 = 1
trouble.4 = 0
looplength = 42
else
display = 41
looplength = 46
ENDIF
end select

if display = looplength then
display = 0
looplength = 16
ENDIF
RETURN
goto mainloop


Thanks all for the continued support.

sougata
- 8th March 2006, 02:46
Hi,

What I do is have a different subroutine to get the trouble flags which I call up every case. In that subroutine I use lookup table to change the case variable so an automatic leap occurs according to the trouble. It helps to prioritize your alarms. Another suggestion is that there can be momentary alarms which you may miss while in the loop. Why not keep an old variable of the trouble and reset after properly displayed.

Regards

Sougata

ronjodu
- 12th March 2006, 03:41
Thanks for the reply sougata. Sounds like it may be a cleaner way to get the job done. I'll spend some time on it over the next few days.

Thanks for the continued help.

Steve, if you're scanning the posts, Get Well Soon....I just read about your misfortune and ongoing recovery. Hope everything goes well for you.

mister_e
- 12th March 2006, 10:01
Thanks ronjodu. Yeah i'm OK. Just better and better every day... for now :)

As always i use the positive thinking attitude. Something we should all use IMHO.