View Full Version : select case question
  
ronjodu
- 4th March 2006, 07: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, 10: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, 01: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, 23: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, 03: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, 04: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, 11: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.
 
Powered by vBulletin® Version 4.1.7 Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.