ISC (aka Interlock Status Controller) commands sent by CONTROL: (Initialize commands) echo off sstatus istatus pstatus (sent once a minute) temp (sent when needed) calibrate sky calibrate hot (would send 8 channels of A/C converter values, but none are connected) analog These commands are sent to the ISC over a serial port and should be terminated with a \r character. The CONTROL program code declares a time out if no response is received within 5 seconds of issuing these commands. Since the CONTROL program can't be blocked waiting for the response, it's possible for several responses to be pending. The count of pending responses and the corresponding commands are stored in variables num_isc_pend and pending() (If this was done instead in a program dedicated to reading out the ISC, it could wait up to 5 seconds for the response and not issue any other commands until a response was received. This would simplify the code and make the pending() array unnecessary.) The routine that reads the input should accumulate characters as they come in, stripping off any leading \r and \n characters. When it sees a \r\n sequence it should call the intrepret function below with a string that is the characters received up to but not including the \r\n. Since the response may be several lines long, the result may not be stored completely until the explanation point character is seen. The array status_var() stores the character strings that are reported for the values of the various ISC variables. The names the ISC uses for the variables are stored in array name_stat(). The value strings that could be reported for the ISC variables are stored in array name_state(). Numerical values are also assigned to each of these value strings. The numerical state of the ISC variables is stored in the array isc_status(). The array elements of isc_status are each equivalenced to simple variables with suggestive names. For example the "calibrate" variable (which corresponds to the position of the calibration vane) might be reported to have the value, "at hot". This string would be stored in the corresponding status_var() array element. The corresponding isc_status() element (which is equivalenced to the variable, isc_vane) would be given the numerical value, AT_HOT. Thus some code that wanted to test the position of the vane could simply test if (isc_vane == AT HOT) The isc_status() array only corresponds to the first 10 ISC variables, which are the only ones that can have one of the name_state() values. The interpret function translates the status_var() strings into numerical values for these other ISC variables, too: Array shelter_status(4) holds the 4 shelter status bytes. Array vane_temp(6) holds the 6 vane temperatures reported. Array isc_volts(8) holds the 8 analog input values Array interlock(32) holds the status of the various interlocks (0 or 1). The istatus command's response is the names of those interlocks that are on. (The names are given at the end of the name_stat() array, beginning with "E STOP CONSOL".) The ones that are off are not mentioned. So the first thing the interpret function does is to set the interlock() array elements to -1. Then as it finds the names of the interlocks, it sets the corresponding array elements to 1. When the exclamation point that marks the end of the response is read, the array elements with the value -1 are set to 0. (So a routine interpreting the interlock() array in global memory should take 0 to mean Off, 1 to mean On, and -1 to be Undefined.) The following is the FORTRAN code for function interpret(). Following this is the code that interprets the building drive interlocks and puts the corresponding state on the Color Monitor display. subroutine interpret(text) C**** Interpret the ISC response, TEXT character*(*) text character*20 item,doing/' '/ integer i,n,ntext,num include 'tel$sources:isc_com.def' C --- DEC/CMS REPLACEMENT HISTORY, Element ISC_COM.DEF C --- *5 13-JUN-2001 13:42:25 PETERS "Define interlock() and isc_status() index parameters for vane, shelter, bldg drive" C --- *4 18-JAN-2000 15:14:21 PETERS "Define the PAUSED state and the KRUPP STOP interlock" C --- *3 7-JUL-1999 18:11:26 PETERS "Add BLD DRV ENAB status variables" C --- *2 8-SEP-1998 22:39:04 PETERS "Update status names" C --- *1 11-DEC-1997 15:31:44 PETERS "Include file for ISC parameters" C --- DEC/CMS REPLACEMENT HISTORY, Element ISC_COM.DEF integer TFLAG,ISC_FLAG,TMOFLAG,MASK_ISC,MASK_TT,MAX_STAT,MAX_ISC_PEND, 1 MAX_RESP,MAX_STATE,MASK_TMO,MAX_INTERLOCK, 2 FIRST_INTERLOCK,ISC_LEFT real*4 RESP_ISC_TMO parameter (TFLAG=1) ! Terminal input event flag parameter (ISC_FLAG=4) ! ISC event flag parameter (TMOFLAG=5) ! Time out event flag parameter (MASK_ISC = ishft(1,TFLAG) + ishft(1,ISC_FLAG) 1 + ishft(1,TMOFLAG)) ! Flag bits parameter (MASK_TT = ishft(1,TFLAG)) parameter (MASK_TMO = ishft(1,TMOFLAG)) parameter (MAX_STAT = 52) ! Number of status variables parameter (MAX_STATE = 14) ! Number of state names parameter (MAX_ISC_PEND = 9) ! Maximum number of responses pending parameter (MAX_RESP = 8) ! Number of responses parameter (RESP_ISC_TMO = 5.) ! Time limit for response wait (seconds) parameter (MAX_INTERLOCK=32) ! Number of interlocks TIMECOM.DEF has parameter (FIRST_INTERLOCK=26) ! Position of first IStatus interlock C**** Get a compilation error if there are more interlocks than MAX_INTERLOCK parameter (ISC_LEFT = MAX_INTERLOCK+1-(MAX_STAT-FIRST_INTERLOCK+1)) integer isc_dummy(ISC_LEFT) integer isc_chan integer*2 isc_iosb(4)/1,0,0,0/ character*20 status_var(MAX_STAT)/MAX_STAT*' '/ ! Status variables character*20 name_resp(MAX_RESP)/ ! Response names 1 'echo','pstatus','calibrate','button','sstatus','temp', 2 'analog','istatus'/ character*20 name_stat(MAX_STAT)/ ! Names of status variables 1 'echo','precipitation','vane','shelter','left roof', 2 'right roof','left door','right door','left pump','right pump', 3 'sa, sb, sc, sd','T6','T5','T4','T3','T2','Ta','a0', 4 'a1','a2','a3','a4','a5','a6','a7', 5 'faults','warnings','E STOP CONSOL','E STOP CAROUSL', 6 'FIRE ALARM','DRV BRAKES','DRV SHUTDOWN','JIB CRANE', 7 'L DOOR PLATFRM','R DOOR PLATFRM','L CHAMBR HATCH', 8 'R CHAMBR HATCH','CAROUSEL HATCH','CAS CAB DOOR', 9 'BLD DRV1 ENAB','BLD DRV2 ENAB','BLD DRV1 FAULT', 1 'BLD DRV2 FAULT','HYDR FLUID LOW','HYDR RETURN', 2 'HYDR SUPPLY R','HYDR SUPPLY L','HYDR OVER TEMP', 3 'HYDR FLTR R','HYDR FLTR L','HYDR FLTR RTN', 4 'KRUPP STOP'/ integer iii,first_stat(MAX_RESP),last_stat(MAX_RESP) ! NAME_STAT's data (first_stat(iii),last_stat(iii),iii=1,MAX_RESP)/ 1 1,1, ! Echo 2 2,2, ! PStatus 3 3,3, ! Calibrate 4 3,4, ! Button 5 4,11, ! SStatus 6 12,17, ! Temp 7 18,25, ! Ain 8 26,52/ ! IStatus integer lname_stat(MAX_STAT) ! (For lengths of the names) character*20 name_state(MAX_STATE)/'off','on','moving to hot', 1 'moving to sky','at hot','at sky','opened','closed','opening', 2 'closing','undefined','started','stopped','paused'/ C**** Positions of the above in NAME_STATE array integer ITS_OFF,ITS_ON,MOVING_HOT,MOVING_SKY,AT_HOT,AT_SKY, 1 OPENED,CLOSED,OPENING,CLOSING,UNDEFINED,STARTED,STOPPED, 2 FAULT,WARNING,PAUSED parameter (ITS_OFF = 1) parameter (ITS_ON = 2) parameter (MOVING_HOT = 3) parameter (MOVING_SKY = 4) parameter (AT_HOT = 5) parameter (AT_SKY = 6) parameter (OPENED = 7) parameter (CLOSED = 8) parameter (OPENING = 9) parameter (CLOSING = 10) parameter (UNDEFINED = 11) parameter (STARTED = 12) parameter (STOPPED = 13) parameter (PAUSED = 14) real*8 err_isc/0./ character*20 pending(MAX_ISC_PEND) integer num_isc_pend,resp_isc_time(2),last_timer/0/,next_timer/0/ common/isc_comm/isc_chan,isc_iosb,err_isc,status_var,num_isc_pend, 1 pending,resp_isc_time,last_timer,next_timer,lname_stat integer NRAIN,NVANE,NSHELTER,NB_BRAKE,NB_DRIVE,NB_POWER parameter (NRAIN = 2) ! Precip index in isc_status() parameter (NVANE = 3) ! Vane index in isc_status() parameter (NSHELTER = 4) ! Shelter index in isc_status() parameter (NB_BRAKE = 4) ! Building brake in interlock() parameter (NB_DRIVE = 13) ! 1st bldg drive state(4) in interlock() parameter (NB_POWER = 12) ! Building Control Power in interlock() include 'tel$sources:timecom.def' C --- DEC/CMS REPLACEMENT HISTORY, Element TIMECOM.DEF C --- *17 10-NOV-1999 09:23:45 PETERS "Define BE_ENABLE & FE_ENABLE" C --- *16 7-JUL-1999 18:12:45 PETERS "Add LOG_FSWITCH" C --- *15 8-SEP-1998 22:40:46 PETERS "Use MAX_INTERLOCK parameter not '32' for number of interlocks" C --- *14 11-DEC-1997 15:22:27 PETERS "Add ISC variables/status into Active Field" C --- *13 29-OCT-1997 00:25:37 PETERS "Define LOG_CALIB" C --- *12 17-APR-1997 13:03:39 PETERS "Adjust for including SATURATED in DRIVECOM.DEF" C --- *11 23-OCT-1996 11:35:13 PETERS "Adjust to keep global section an integral number of pages" C --- *10 18-JUN-1996 14:10:24 PETERS "Read out clock separately so can have either R&S or GPS" C --- *9 28-FEB-1996 00:02:14 PETERS "Implement SAM bus" C --- *8 12-MAY-1995 12:56:02 SMTSYS "Add CLOSE_TO_SUN variable for sun avoidance sensing in CONTROL" C --- *7 5-JUN-1994 09:20:04 JSCHRAML "Save the onposition vector in a global section for RADVEL" C --- *6 17-MAR-1994 14:29:45 PETERS "Added MTWRITE enable variable" C --- *5 7-MAR-1994 17:04:05 PETERS "Feb. 1994 Version" C --- *4 22-FEB-1994 13:06:46 PETERS "Add Focus variables" C --- *3 22-FEB-1994 08:36:59 PETERS "Corrected filler length so get whole number of pages" C --- *2 4-FEB-1994 10:54:28 PETERS "First SMT version" C --- *1 24-JUN-1993 17:30:31 PETERS "Imported July 1992" C --- DEC/CMS REPLACEMENT HISTORY, Element TIMECOM.DEF REAL*8 DV_ONPOS(16) LOGICAL*1 SYSFILL,IENDOFALL,REQUEST_RESET,ITOTALEND,MT_ENABLE logical*1 close_to_sun,log_wait,log_calib,log_fswitch, 1 be_enable,fe_enable byte shelter_status(4),interlock(MAX_INTERLOCK), 1 isc_status(10)/10*UNDEFINED/,isc_echo,isc_precip,isc_vane, 1 isc_shelter,isc_lroof,isc_rroof,isc_ldoor,isc_rdoor, 1 isc_lpump,isc_rpump real*4 vane_temp(6),isc_volts(8) equivalence (isc_status(1),isc_echo) COMMON/TIME000/I_YEAR,I_MONTH,I_DAY,I_WEEKDAY,I_JULDAY,I_ZONETIME 1,I_CLOCKCORRECTION,D_JULDAY 1,D_TIME,D_UTC,D_SIDFACTOR,d_sidmid 1,D_JULGREEN0,DSITMEAN,DSITAPP,I_DELTAT 1,DMICROREF,MICTRANS_TIME,REQUEST_RESET,DATE200 1,DV_ONPOS,I_CALCON 1,MT_ENABLE,close_to_sun,LOG_WAIT,LOG_CALIB,shelter_status,interlock, 1isc_echo,isc_precip,isc_vane,isc_shelter,isc_lroof,isc_rroof, 1isc_ldoor,isc_rdoor,isc_lpump,isc_rpump, 1vane_temp,isc_volts,log_fswitch,be_enable,fe_enable, 1sysfill(113),itotalend C save num if (text.eq.' ') return if (text.eq.'!') then if (name_resp(num).eq.'istatus') then C**** The last one. Set unmentioned interlocks to the off state. do i=first_stat(num)+2,last_stat(num) if (interlock(i-first_stat(num)-1).eq.-1) then interlock(i-first_stat(num)-1) = 0 status_var(i) = 'off' end if end do end if doing = ' ' return end if if (len(text).ge.4.and.text(1:4).eq.'cmd>') return if (doing.eq.' ') then ntext = len(text) n = index(text,':') - 1 if (n.le.0) n = index(text,' ') - 1 if (n.le.0) n = ntext doing = text(1:n) if (num_isc_pend.ne.0.and.(doing.eq.'unrecognized'.or. 1 doing(1:n).eq.pending(1)(1:n))) then last_timer = last_timer + 1 if (last_timer.ge.400) last_timer = 1 ! Expected this one call sys$cantim(%val(last_timer),) ! Cancel the timer do i=2,num_isc_pend pending(i-1) = pending(i) end do num_isc_pend = num_isc_pend - 1 Cd TYPE *,'CANCEL #',LAST_TIMER, Cd 1 ' FOR '//DOING,NUM_ISC_PEND,' PENDING' if (num_isc_pend.eq.0) then last_timer = next_timer end if end if C**** First look for matching responses num = 1 do while (num.le.MAX_RESP.and.name_resp(num)(1:n).ne.text(1:n)) num = num + 1 end do if (num.gt.MAX_RESP) then call send_error('CONTRL','I.S.C.','RESP',num,1,1) type *,'Could not interpret ISC message: '//text doing = ' ' return end if if (name_resp(num).eq.'istatus') then do i=first_stat(num)+2,last_stat(num) status_var(i) = ' ' ! First clear out all interlocks interlock(i-first_stat(num)-1) = -1 end do end if C**** Check the rest of the line (if any) for a status variable if (n+2.lt.ntext) call look_status(text(1:ntext),num) else if (len(text).ge.12.and.text(1:12).eq.'unrecognized') then call send_error('CONTRL','I.S.C.','RESP',num,1,1) type *,'Could not interpret ISC message: '//text doing = ' ' return end if C**** Multiple line response. Look for a status variable call look_status(text,num) end if if (index(text,'!').ne.0) then C**** The last one. Set unmentioned interlocks to the off state. if (name_resp(num).eq.'istatus') then do i=first_stat(num)+2,last_stat(num) if (interlock(i-first_stat(num)-1).eq.-1) then interlock(i-first_stat(num)-1) = 0 status_var(i) = 'off' end if end do end if doing = ' ' end if return end subroutine look_status(text,num) C**** Scan TEXT for a status variable and if found, store its state character*(*) text integer i,j,k,num,ntext include 'tel$sources:isc_com.def' include 'tel$sources:timecom.def' do i=first_stat(num),last_stat(num) j = index(text,name_stat(i)(1:lname_stat(i))) if (j.ne.0) then C**** Found the name of a status variable ntext = len(text) if (text(ntext:ntext).eq.'!') ntext = ntext - 1 C**** Advance j to its value j = j + lname_stat(i) if (j.le.ntext.and.text(j:j).eq.':') j = j + 1 do while (text(j:j).eq.' '.and.j.le.ntext) j = j + 1 end do if (j.le.ntext) then status_var(i) = text(j:ntext) else if (name_resp(num).eq.'istatus') then status_var(i) = 'on' else call send_error('CONTRL','I.S.C.','RESP',num,1,2) type *,'No value in: '//text return end if C**** Get numerical values if (name_resp(num).eq.'temp') then C**** Vane Temperatures read(text(j:ntext),*,err=10) vane_temp(last_stat(num)-i+1) else if (name_resp(num)(1:3).eq.'ain') then C**** Analog voltages read(text(j:ntext),*,err=10) isc_volts(i-first_stat(num)+1) else if (name_resp(num).eq.'istatus') then C**** Interlocks if (i.ge.first_stat(num)+2) 1 interlock(i-first_stat(num)-1) = 1 else if (name_stat(i).eq.'sa, sb, sc, sd') then C**** Shelter status bytes read(status_var(i),'(3(z3,1x),z3)') shelter_status else C**** Assign numerical value of state name to the rest do k=1,MAX_STATE if (status_var(i).eq.name_state(k)) then isc_status(i) = k return end if end do go to 10 end if return end if end do type *,'Unrecognized status for',num,': '//text call send_error('CONTRL','I.S.C.','RESP',num,1,3) return 10 type *,'Unrecogized value: '//text(j:ntext) call send_error('CONTRL','I.S.C.','RESP',num,1,4) return end Color Monitor Code: subroutine show_isc include 'tel$sources:isc_com.def' include 'tel$sources:timecom.def' common/cmon/ns_cmon,nc_cmon character text*21,dtime*23,bg*1,fg*1 byte old_status(10)/10*-99/, 1 old_interlock(MAX_INTERLOCK)/MAX_INTERLOCK*-99/ character*7 sh_name(6)/'L ROOF','R ROOF','L DOOR','R DOOR','L PUMP', 1 'R PUMP'/ parameter (NCOL_SHEL = 34, NROW_SHEL = 22) ! Pos of shelter msgs parameter (NCOL_BLDG = 13, NROW_BLDG = 27) ! Pos of building msgs parameter (NCOL_RAIN = 48, NROW_RAIN = 28) ! Pos of rain message parameter (NCOL_VANE = 40, NROW_VANE = 29) ! Pos of vane message parameter (INTER_SKIP = 13) ! Skip CAB DOOR to FLTR RTN parameter (INTER_UNUSED = 7) ! Undefined interlocks character*16 inter_name(MAX_INTERLOCK)/' CONTROL-RM',' CAROUSEL', 1 ' FIRE',' ',' ',' JIB-CRANE',' L-PLATFORM',' R-PLATFORM', 2 ' L-CHAMBER',' R-CHAMBER',' CAROUSEL', INTER_SKIP*' ', 3 ' KRUPP STOP',INTER_UNUSED*' '/ integer inter_row(MAX_INTERLOCK),inter_col(MAX_INTERLOCK) data (inter_col(i),inter_row(i),i=1,MAX_INTERLOCK)/25,12, 37,12, 1 57,12, 0,0, 0,0, 2,10, 43,11, 55,11, 11,11, 22,11, 2 33,11, INTER_SKIP*0, INTER_SKIP*0, 24,13, 3 INTER_UNUSED*0, INTER_UNUSED*0/ logical changing/.false./ integer last_drive/-1/,last_old,last_shelter/0/ real*4 now,rain_time/-1.e6/ data old_status(NRAIN)/STOPPED/,long/0/ C**** Check for shelter status changed if (isc_status(NSHELTER).ne.old_status(NSHELTER)) then last_old = old_status(NSHELTER) old_status(NSHELTER) = isc_status(NSHELTER) if (isc_status(NSHELTER).eq.CLOSED.or. 1 isc_status(NSHELTER).eq.OPENED) then if (isc_lpump.eq.ITS_ON.or.isc_rpump.eq.ITS_ON) then C**** Not really open/closed if the pumps are on old_status(NSHELTER) = last_old else C**** Blank out individual roof, door, & pump entries text = ' ' do i=1,6 if (i.ne.3) then call cmon_line (NROW_SHEL+i-1,NCOL_SHEL,'L','L', 1 .FALSE.,text(1:16),nc_cmon,ns_cmon,iret) else if (isc_status(NSHELTER).eq.CLOSED) then text = ' SHELTER CLOSED' bg = 'R' fg = 'L' if (changing) call send_error('SHELTR','CLOSED', 1 'NOW ',0,2,0) changing = .false. else text = ' SHELTER OPEN' bg = 'L' fg = 'D' if (changing) call send_error('SHELTR','OPENED', 1 'NOW ',0,2,0) changing = .false. end if call cmon_line(NROW_SHEL+i-1,NCOL_SHEL,fg,bg, 1 .FALSE.,text(1:16),nc_cmon,ns_cmon,iret) text = ' ' end if end do end if ! isc_lpump.eq.ITS_ON.or.isc_rpump.eq.ITS_ON else C**** Shelter state changed to other than OPENED or CLOSED C**** Display individual Roof, Door, & Pump status if (isc_shelter.ne.last_shelter) then last_shelter = isc_shelter if (isc_shelter.eq.OPENING) then call send_error('SHELTR','OPENIN','NOW ',0,2,0) else if (isc_shelter.eq.CLOSING) then call send_error('SHELTR','CLOSIN','NOW ',0,2,0) else if (isc_shelter.eq.PAUSED) then call send_error('SHELTR','PAUSED','NOW ',0,2,0) else if (isc_shelter.eq.STOPPED) then call send_error('SHELTR','STOPPD','NOW ',0,2,0) else i = isc_shelter ! isc_shelter is a byte call send_error('SHELTR','UNKNWN','NOW ',0,2,i) end if end if changing = .true. do i=1,6 call str$upcase(text, 1 ' '//sh_name(i)//name_state(isc_status(i+NSHELTER))) call cmon_line (NROW_SHEL+i-1,NCOL_SHEL,'D','L', 1 .FALSE.,text(1:16),nc_cmon,ns_cmon,iret) old_status(i+NSHELTER) = isc_status(i+NSHELTER) end do end if else if (isc_status(NSHELTER).ne.CLOSED.and. 1 isc_status(NSHELTER).ne.OPENED) then C**** Shelter the same, but neither CLOSED nor OPENED C**** Display individual Roof, Door, & Pump status that have changed do i=1,6 if (isc_status(NSHELTER+i).ne.old_status(NSHELTER+i)) then old_status(NSHELTER+i) = isc_status(NSHELTER+i) call str$upcase(text, 1 ' '//sh_name(i)//name_state(isc_status(i+NSHELTER))) call cmon_line (NROW_SHEL+i-1,NCOL_SHEL,'D','L', 1 .FALSE.,text(1:16),nc_cmon,ns_cmon,iret) old_status(i+NSHELTER) = isc_status(i+NSHELTER) end if end do end if if (isc_status(NVANE).ne.old_status(NVANE)) then old_status(NVANE) = isc_status(NVANE) call str$upcase(text,' '//name_state(isc_status(NVANE))) call cmon_line(NROW_VANE,NCOL_VANE,'D','L',.FALSE., 1 text(1:7),nc_cmon,ns_cmon,iret) end if now = secnds(0.) if (now.lt.rain_time) now = now + 86400. if (isc_status(NRAIN).ne.old_status(NRAIN).or. 1 rain_time+6*3600..lt.now) then if (isc_status(NRAIN).eq.old_status(NRAIN)) then C**** It's been 6 hours since anything happened. if (isc_status(NRAIN).eq.STOPPED) then text = ' ' ! Time to blank it out call cmon_line(NROW_RAIN,NCOL_RAIN,'L','L',.FALSE., 1 text(1:16),nc_cmon,ns_cmon,iret) rain_time = 1.e6 ! Only needed once else C**** It's still raining after 6 hours!? long = long + 6 call send_error(' It''s ','a long','rain',long,2,0) rain_time = rain_time + 6.*3600. ! Another 6 hours if (rain_time.gt.86400.) rain_time = rain_time - 86400. end if else C**** Rain has just stopped or started call lib$date_time(dtime) if (isc_status(NRAIN).eq.STARTED) then text = ' RAINING @ '//dtime(13:17) bg = 'R' fg = 'L' call send_error(' It''s ','Rainin','Now!',0,2,0) long = 0 else text = ' NO RAIN @ '//dtime(13:17) bg = 'L' fg = 'D' call send_error('Rain''s','Stoppd','.5 h',0,2,0) end if call cmon_line(NROW_RAIN,NCOL_RAIN,fg,bg,.FALSE., 1 text(1:16),nc_cmon,ns_cmon,iret) if (isc_status(NRAIN).ne.old_status(NRAIN)) 1 rain_time = secnds(0.) end if old_status(NRAIN) = isc_status(NRAIN) end if C**** Check Drive Brakes and power interlocks if (interlock(NB_BRAKE).ne.0) then text = ' BRAKE' else text = ' ' end if if (interlock(NB_POWER).ne.old_interlock(NB_POWER)) then if (interlock(NB_POWER).ne.0) text = ' POWER OFF'//text old_interlock(NB_POWER) = interlock(NB_POWER) call cmon_line(NROW_BLDG,NCOL_BLDG,'L','R',.FALSE., 1 ' '//text(1:20),nc_cmon,ns_cmon,iret) end if if (interlock(NB_POWER).ne.0) then C**** Building Drive Control power is off. last_drive = -1 ! Check drive state when it's back on else C**** Building Drive Control power is on. Check state of drives idrive = interlock(NB_BRAKE) do i=NB_DRIVE,NB_DRIVE+3 idrive = 2*idrive + interlock(i) old_interlock(i) = interlock(i) end do if (idrive.ne.last_drive) then last_drive = idrive if (idrive.eq.0) then C**** Drive is on text = ' ON'//text call cmon_line(NROW_BLDG,NCOL_BLDG,'D','L',.FALSE., 1 text,nc_cmon,ns_cmon,iret) else C**** Drive is not on. Choose between Off and Standby i1 = (idrive/2).and.5 i2 = idrive.and.5 if (i1.eq.5) then if (i2.eq.5) then text = 'S 1 & 2 OFF'//text else if (i2.eq.4) then text = ' 1 OFF, 2 STANDBY'//text else text = ' 1 OFF, 2 ON'//text end if else if (i1.eq.4) then if (i2.eq.4) then text = 'S 1 & 2 STANDBY'//text else if (i2.eq.5) then text = ' 1 STANDBY, 2 OFF'//text else text = ' 1 STANDBY, 2 ON'//text end if else if (i2.eq.5) then text = ' 1 ON, 2 OFF'//text else text = ' 1 ON, 2 STANDBY'//text end if end if if (text(1:1).ne.' ') then C**** Text starts with 2 normal characters call colorline(NROW_BLDG,NCOL_BLDG,'D','L',.FALSE., 1 ' '//text(1:2),nc_cmon,ns_cmon,iret) call cmon_line(NROW_BLDG,NCOL_BLDG+2,'L','R',.FALSE., 1 ' '//text(3:20),nc_cmon,ns_cmon,iret) else C**** Text is all red call cmon_line(NROW_BLDG,NCOL_BLDG,'L','R',.FALSE., 1 ' '//text(1:20),nc_cmon,ns_cmon,iret) endif end if end if end if do i=1,MAX_INTERLOCK if (interlock(i).ne.old_interlock(i)) then old_interlock(i) = interlock(i) if (inter_row(i).ne.0) then n = index(inter_name(i),' ') - 1 if (interlock(i).eq.0) then text = ' ' call cmon_line(inter_row(i),inter_col(i),'L','L', 1 '.FALSE',text(1:n),nc_cmon,ns_cmon,iret) else call cmon_line(inter_row(i),inter_col(i),'L','R', 1 '.FALSE',inter_name(i)(1:n),nc_cmon, 2 ns_cmon,iret) end if end if end if end do return end