DECLARE SUB SetHCODE (HouseCode$, HCODE$) DECLARE SUB bang (Message$, Header$, HCODE$, GPN$, Action$, FOOTER$, PokePlace, speed!, PortNumber!) DECLARE SUB CyclSave (OutFile$, NumSegments, InitTemp, SegmentType$(), FinalTemp(), Rate(), SegTime()) DECLARE SUB DisplayCycle (NumSegments, InitTemp, SegmentType$(), FinalTemp(), Rate(), SegTime()) DECLARE SUB GetKey (a$) DECLARE SUB GetMv (MV, PortNumber!) DECLARE SUB Instructions () DECLARE SUB LoadCycle (InFile$, NumSegments!, InitTemp!, SegmentType$(), FinalTemp!(), Rate(), SegTime!()) DECLARE SUB MakeBox () DECLARE SUB MV2DG (MV, MTemp) DECLARE SUB NewCycle (NumSegments, InitTemp, SegmentType$(), FinalTemp(), Rate(), SegTime()) DECLARE SUB NoRead (MV) DECLARE SUB NoBath (MV, RoomT) DECLARE SUB OpenPort (PortNumber!, PokePlace, speed!) DECLARE SUB SaveName (OutFile$, NumSegments!, InitTemp!, SegmentType$(), FinalTemp!(), Rate!(), SegTime!()) DECLARE SUB SelCyc (InFile$) DECLARE SUB SendFCMessage (Message$, PortNumber!, PokePlace, speed!) DECLARE SUB SetHardware (PortNumber!, speed!, HouseCode$, AlarmTemp) DECLARE SUB ShowHardware (PortNumber!, speed!, HouseCode$, AlarmTemp) DECLARE SUB SmallBox (Y%, X%, text1$, text2$) DECLARE SUB Target (TargetTemp, Cycletime, InitTemp, SegmentType$(), FinalTemp(), Rate(), SegTime(), Done%, Segment%) DECLARE SUB TCPAutoLoad DECLARE SUB TestExist (FileName$, a%) DECLARE SUB TimeWait () DECLARE SUB Title () DECLARE SUB TurnOff (HCODE$, PortNumber!, PokePlace, speed!) DECLARE SUB TurnOn (HCODE$, PortNumber!, PokePlace, speed!) DECLARE SUB YesNo (a$) DIM DEST1, DEST2, DEST3, DEST4 AS INTEGER DIM SegmentType$(12), FinalTemp(12), SegTime(12), Rate(12) REM ============================ SIMP-CON.BAS ======================= REM == Basic ON-OFF controller for 120 volt kiln on COM1 or COM2 == REM == using Metex ME-11 Digital Multimeter for thermocouple input == REM == W. Venable - 3 April 2001 == REM == Program SIMP-CON.BAS is copyright 2001 by Wallace Venable == REM ============ Variables for Control Operations =================== REM ================================================================= REM ================ .TCP Temperature Profiles ====================== REM = Files are stored with the following format: REM = NumSegments!, InitTemp! REM = then NumSegments! lines of the form REM = SegmentType$(i), FinalTemp!(i), Rate(i), SegTime!(i) REM ================================================================= REM = This program uses the TIME$ function which returns system clock REM = time in the form hh:mm:ss REM = Files are saved in the form REM = N = number of segments (maximum = 12), Starting temperature REM = R, A or S, End temperature, Rate in Fø/hr, Duration in minutes REM = from this information a run time matrix is generated in the form REM = InitTemp, FinalTemp, Duration, Slope REM = where temperatures are øF, time in minutes, slope in Fø/hour REM =================================================================== REM = Data is logged in .TXT files REM = REM =================================================================== REM For FIRECRACKER Header$ = "1101010110101010" FOOTER$ = "10101101" GPN$ = "0000" 'UNIT! <9 I've divided Units into High and Low groups REM GPN$ = "0100" for UNIT! => 9 REM Action Codes for FIRECRACKER REM 1 ON = 0000 0000 ' used for kiln power REM 1 OFF = 0010 0000 ' used for kiln power REM BRIGHT = 1000 1000 '5% power change REM DIM = 1001 1000 '5% power change REM 2 ON = 0001 0000 ' used for ALARM REM 2 OFF = 0011 0000 ' used for ALARM REM 5 ON = 0100 0000 ' used for CROWBAR shutdown REM 5 OFF = 0110 0000 ' used for CROWBAR shutdown REM COMMAND = Header$(16) + HCODE$(4) + GPN$(4) + ACTION$(8) + FOOTER$(8) REM PortTestStuff: REM COM 1 03F8 to 03FF INT 4 REM COM 2 02F8 to 02FF INT 3 REM COM 3 03E8 to 03EF INT 4 REM COM 4 02E8 to 02EF INT 3 REM LPT1 0378 to 037B INT 7 'Base addresses for the COM ports can be read from the BIOS Data Area. 'COM1's Base Address 0000:0400 HEX 'COM2's Base Address 0000:0402 'COM3's Base Address 0000:0404 'COM4's Base Address 0000:0406 REM TEST COM 1 PORT ADDRESS REM Message to FireCracker is sent to Base Address + 4 REM "Ready" = 3 REM "Reset" = 0 REM Logical "1" = 2 REM Logical "0" = 1 REM ====================== Working Program ========================== CALL MakeBox CALL Title text1$ = "CAUTION - This program makes hardware calls which may" text2$ = "lock up your computer and require a reset." CALL SmallBox(15, 10, text1$, text2$) CALL GetKey(a$) REM ======== Automatically load AUTOLOAD.TCH hardware file ========== FileName$ = "AUTOLOAD.TCH" a% = 0 CALL TestExist(FileName$, a%) IF a% = 1 THEN InFile$ = FileName$ OPEN InFile$ FOR INPUT AS #1 INPUT #1, PortNumber! INPUT #1, speed! INPUT #1, HouseCode$ INPUT #1, AlarmTemp CLOSE #1 END IF IF a% <> 1 THEN CALL SetHardware(PortNumber!, speed!, HouseCode$, AlarmTemp) END IF REM ========== Done loading AUTOLOAD.TCH ================================ REM ======== Automatically load AUTOLOAD.TCP temperature profile ========== REM ======== if an AUTOLOAD has been saved by user choice ================= FileName$ = "AUTOLOAD.TCP" a% = 0 CALL TestExist(FileName$, a%) IF a% = 1 THEN InFile$ = FileName$ CALL LoadCycle(InFile$, NumSegments!, InitTemp!, SegmentType$(), FinalTemp!(), Rate(), SegTime!()) END IF REM ========== Done loading AUTOLOAD.TCP ================================ REM ================ START of ACTION ============================= REM IF PortNumber! = 1 THEN PokePlace = &H3FC REM IF PortNumber! = 2 THEN PokePlace = &H2FC CALL SetHCODE(HouseCode$, HCODE$) REM PokePlace = &H3FC REM IF PortNumber! = 1 THEN OPEN "COM1:600,N,7,2,RS,CS,DS,CD" FOR RANDOM AS #2 REM IF PortNumber! = 2 THEN OPEN "COM2:600,N,7,2,RS,CS,DS,CD" FOR RANDOM AS #2 REM ======================= Main Menu ============================== SCMainMenu: CALL MakeBox a$ = "" LOCATE 3, 32 PRINT "MAIN MENU" LOCATE 5, 6 PRINT "Please select from the following menu." LOCATE 6, 10 PRINT " to run" LOCATE 7, 10 PRINT "

to view, load, or create a temperature profile." LOCATE 8, 10 PRINT " to view, load, or create a hardware file." LOCATE 9, 10 PRINT " to close program" DO UNTIL (a$) = "P" OR a$ = "R" OR a$ = "Q" OR a$ = "H" CALL GetKey(a$) a$ = UCASE$(a$) LOOP IF a$ = "R" THEN GOTO RunMenu IF a$ = "P" THEN GOTO NewCycleMenu IF a$ = "Q" THEN CLS END END IF IF a$ = "H" THEN GOTO HardwareMenu REM =================== End Main Menu ============================== REM ================== Run Preparation ============================= RunMenu: CALL MakeBox LOCATE 3, 33 PRINT "RUN PREPARATION" LOCATE 5, 6 RoomT = 32 REM ========= Allow for room temperature cold junction ============= PRINT "Are you using an ice-bath for the cold junction? Press or ."; CALL YesNo(a$) IF a$ = "Y" THEN Bath = 1 IF a$ = "N" THEN Bath = 0 LOCATE 6, 6 PRINT "Enter the room temperature "; INPUT RoomT END IF LOCATE 8, 6 PRINT "Enter identifying text for LOG file. (i.e. kiln contents)" LOCATE 9, 6 COLOR 0, 7 PRINT " " LOCATE 9, 7 LINE INPUT Comment$ COLOR 7, 0 LOCATE 11, 6 PRINT "By default, data is logged at 5 minute intervals. To change log" LOCATE 12, 6 PRINT "interval, enter a time in minutes, otherwise press . "; INPUT "", LogInterval IF LogInterval = 0 THEN LogInterval = 5 LOCATE 21, 30 PRINT "Press any key to continue." CALL GetKey(a$) REM ====================== Actual Run Menu Starts Here ===================== RunMenu2: CALL MakeBox LOCATE 3, 33 PRINT "RUN MENU" LOCATE 5, 6 PRINT "Please select from the following:" LOCATE 6, 10 PRINT " Begin kiln run. (Time = 0) " LOCATE 7, 10 PRINT " Adjust room temperature setting." LOCATE 8, 10 PRINT "

Pause kiln run." LOCATE 9, 10 PRINT " Continue kiln run." LOCATE 10, 10 PRINT " Shut down kiln, end run cycle." LOCATE 5, 72 RunKey: CALL GetKey(a$) a$ = UCASE$(a$) IF a$ <> "B" AND a$ <> "S" AND a$ <> "P" AND a$ <> "A" AND a$ <> "C" THEN GOTO RunKey: IF a$ = "B" THEN GOTO StartRun IF a$ = "C" THEN GOTO ContinueRun IF a$ = "S" THEN REM SEND OFF MESSAGE Action$ = "00100000" Message$ = Header$ + HCODE$ + GPN$ + Action$ + FOOTER$ CALL SendFCMessage(Message$, PortNumber!, PokePlace, speed!) GOTO SCMainMenu END IF IF a$ = "A" THEN CALL MakeBox LOCATE 3, 25 PRINT "ROOM TEMPERATURE ADJUSTMENT" LOCATE 5, 6 PRINT "Enter the room temperature "; INPUT "", RoomT END IF StartRun: StartTime$ = TIME$ StartDate$ = DATE$ CurrentDate$ = DATE$ StartHours = VAL(LEFT$(TIME$, 2)) StartMinutes = VAL(MID$(TIME$, 4, 2)) StartSeconds = VAL(MID$(TIME$, 7, 2)) REM LogTime = StartHours * 60 + StartMinutes + StartSeconds / 60 LogTime = 0 StartTime = StartHours * 60 + StartMinutes + StartSeconds / 60 REM =============== Setup LOGFILE$ file ======================== LogFile$ = (LEFT$(DATE$, 2)) + (MID$(DATE$, 4, 2)) + (LEFT$(TIME$, 2)) + (MID$(TIME$, 4, 2)) + ".TXT" REM PRINT "LogFile$ = "; LogFile$ 'DEBUG REM CALL GetKey(a$) 'DEBUG REM Test LogTime = LogTime + LogInterval against CurrentTime OPEN LogFile$ FOR APPEND AS #5 PRINT #5, "Kiln run log created by SIMP-CON PC-X10 Kiln Controller" PRINT #5, "Run Date "; StartDate$ PRINT #5, "Start Time "; StartTime$ PRINT #5, Comment$ PRINT #5, "The temperature profile is:" REM ==================== Print profile to log ============================= FOR i = 1 TO NumSegments IF SegmentType$(i) = "R" THEN ST$ = "Ramp - " IF SegmentType$(i) = "S" THEN ST$ = "Soak - " IF SegmentType$(i) = "A" THEN ST$ = "Alarm - " SegTimeHours = INT(SegTime(i) / 60) SegTimeMin = INT(SegTime(i)) - SegTimeHours * 60 SegTimeSec = INT((SegTime(i) - SegTimeHours * 60 - SegTimeMin) * 60) IF SegmentType$(i) = "A" THEN IF FinalTemp(i) = 2500 THEN AA$ = "Kiln set ON" IF FinalTemp(i) = 0 THEN AA$ = "Kiln set OFF" PRINT #5, i; ST$; AA$; " - Duration = "; SegTimeHours; " h "; SegTimeMin; "m "; SegTimeSec; "s" ELSE PRINT #5, i; ST$; "Final Temperature ="; FinalTemp(i); "F - Rate ="; Rate(i); "Duration ="; SegTimeHours; " h"; SegTimeMin; " m" END IF NEXT i REM ==================== End print profile to log ============================= PRINT #5, "Elapsed Time"; CHR$(44); CHR$(44); "Total"; CHR$(44); "Temperature"; CHR$(44); CHR$(44); "Kiln" PRINT #5, "Hrs."; CHR$(44); "Min."; CHR$(44); "Minutes"; CHR$(44); "Target"; CHR$(44); "Measured"; CHR$(44); "Status" CLOSE #5 Log0 = 0 REM == Calculate duration === TotalTime = 0 FOR i = 1 TO NumSegments TotalTime = TotalTime + SegTime(i) NEXT i REM == End duration calculation ContinueRun: CALL MakeBox LOCATE 3, 25 PRINT "SIMP-CON is running your kiln" LOCATE 21, 22 PRINT "Press to return to Run Menu." DO UNTIL INKEY$ = CHR$(27) LOCATE 5, 6 PRINT "Run started at", StartTime$; " on "; StartDate$ LOCATE 6, 6 CurrentHours = VAL(LEFT$(TIME$, 2)) CurrentMinutes = VAL(MID$(TIME$, 4, 2)) CurrentSeconds = VAL(MID$(TIME$, 7, 2)) REM =================== Test for midnight ========================== IF DATE$ > CurrentDate$ THEN StartHours = StartHours - 23 StartMinutes = StartMinutes - 59 StartSeconds = StartSeconds - 60 CurrentDate$ = DATE$ END IF REM ====================== End rollover ============================ PRINT "Current system time is", TIME$; " on "; DATE$ REM ======= CycleTime$ = TIME$ - StartTime$ ====================== LOCATE 7, 6 CycleHours = CurrentHours - StartHours CycleMinutes = CurrentMinutes - StartMinutes CycleSeconds = CurrentSeconds - StartSeconds Cycletime = CycleHours * 60 + CycleMinutes + CycleSeconds / 60 PRINT "Cycle time is ", PRINT USING "#####.##"; Cycletime; PRINT " minutes" LOCATE 8, 6 PRINT "Cycle length is ", PRINT USING "#####.##"; TotalTime; PRINT " minutes" LOCATE 9, 6 REM CycleHours = CurrentHours - StartHours REM CycleMinutes = CurrentMinutes - StartMinutes REM CycleSeconds = CurrentSeconds - StartSeconds Time2Go = TotalTime - Cycletime PRINT "Time remaining is", PRINT USING "#####.##"; Time2Go; PRINT " minutes" CALL GetMv(MV, PortNumber!) CALL NoBath(MV, RoomT) CALL MV2DG(MV, MTemp) REM === Warm kiln to allow for "Temp = 0" shut down to guard ==== REM === against thermocouple failure IF Bath = 0 AND Cycletime < 5 THEN Status$ = "ON " CALL TurnOn(HCODE$, PortNumber!, PokePlace, speed!) GOTO Skip END IF REM ====== Shut down if no valid thermocouple reading ======= IF MTemp = 40 THEN CALL MakeBox LOCATE 10, 6 PRINT "Low thermocouple reading suggests failure." LOCATE 11, 6 PRINT "Executing shut-down." REM =================== Shut Down ============================== Action$ = "00100000" Message$ = Header$ + HCODE$ + GPN$ + Action$ + FOOTER$ CALL SendFCMessage(Message$, PortNumber!, PokePlace, speed!) REM =================== Trigger Alarm ========================== Action$ = "00010000" Message$ = Header$ + HCODE$ + GPN$ + Action$ + FOOTER$ CALL SendFCMessage(Message$, PortNumber!, PokePlace, speed!) END ' End of thermocouple shutdown END IF Skip: REM ======================= End warm-up ============================ REM ================== Test Temperature ============================= REM LOCATE 11, 6 DisplayTemp = INT(MTemp) REM PRINT "Temperature is " LOCATE 11, 6 PRINT "Temperature is ", PRINT USING "########"; DisplayTemp; PRINT " øF" CALL Target(TargetTemp, Cycletime, InitTemp, SegmentType$(), FinalTemp(), Rate(), SegTime(), Done%, Segment%) LOCATE 12, 6 PRINT "Target Temperature is", PRINT USING "########"; TargetTemp; PRINT " øF" LOCATE 13, 16 REM ==================== High Temperature =========================== REM IF MTEMP > TargetTemp THEN IF (MTemp - TargetTemp) > 7.5 THEN PRINT "Too Hot " 'DEBUG Status$ = "OFF" CALL TurnOff(HCODE$, PortNumber!, PokePlace, speed!) END IF REM ==================== Over Temperature Shutdown =========================== IF MTemp > AlarmTemp THEN CALL MakeBox LOCATE 6, 24 PRINT "OVER HEAT SITUATION DETECTED" LOCATE 8, 20 Mtemp2 = INT(MTemp) PRINT "Last temperature measured is"; Mtemp2; "øF" LOCATE 12, 24 PRINT "Executing EMERGENCY SHUTDOWN" Status$ = "OFF" REM =================== Shut Down ============================== Action$ = "00100000" Message$ = Header$ + HCODE$ + GPN$ + Action$ + FOOTER$ CALL SendFCMessage(Message$, PortNumber!, PokePlace, speed!) REM =================== Trigger Alarm ========================== Action$ = "00010000" Message$ = Header$ + HCODE$ + GPN$ + Action$ + FOOTER$ CALL SendFCMessage(Message$, PortNumber!, PokePlace, speed!) END IF IF MTemp > AlarmTemp + 100 THEN Status$ = "OFF" REM =================== CROWBAR Shut Down ============================== Action$ = "01000000" ' trip CROWBAR Message$ = Header$ + HCODE$ + GPN$ + Action$ + FOOTER$ CALL SendFCMessage(Message$, PortNumber!, PokePlace, speed!) REM ==== Maintain state for at least 5 s ======== REM T1# = TIMER REM DO UNTIL T2# > T1# + 5 REM T2# = TIMER REM IF T2# < T1# THEN T1# = TIMER REM Midnight passed REM LOOP REM Action$ = "01100000" ' turn CROWBAR off Message$ = Header$ + HCODE$ + GPN$ + Action$ + FOOTER$ CALL SendFCMessage(Message$, PortNumber!, PokePlace, speed!) END 'REM end of EMERGENCY SHUTDOWN END IF REM ==================== End Overtemp Shutdown ===================== REM ==================== Low Temperature =========================== REM IF MTEMP < TargetTemp THEN IF (TargetTemp - MTemp) > 7.5 THEN PRINT "Too Cold " 'DEBUG Status$ = "ON " CALL TurnOn(HCODE$, PortNumber!, PokePlace, speed!) END IF REM ===================== LOG DATA =================================== REM Test LogTime = LogTime + LogInterval against CycleTime REM PRINT "Log Time = "; LogTime REM PRINT "Log Interval = "; LogInterval IF Log0 = 0 THEN 'Write start data CycleSecondsSav = CycleSeconds CycleMinutesSav = CycleMinutes CycleHoursSav = CycleHours IF CycleSecondsSav < 0 THEN CycleSecondsSav = 60 - CycleSecondsSav CycleMinutesSav = CycleMinutesSav - 1 END IF IF CycleMinutesSav < 0 THEN CycleMinutesSav = 60 - CycleMinutesSav CycleHoursSav = CycleHoursSav - 1 END IF REM ======================================== Log0 = 1 OPEN LogFile$ FOR APPEND AS #5 REM WRITE #5, CycleHoursSav, CycleMinutesSav, CycleSecondsSav, Cycletime, TargetTemp, MTEMP, Status$ WRITE #5, CycleHoursSav, CycleMinutesSav, Cycletime, TargetTemp, MTemp, Status$ CLOSE #5 END IF IF Cycletime > LogTime + LogInterval THEN CycleSecondsSav = CycleSeconds CycleMinutesSav = CycleMinutes CycleHoursSav = CycleHours IF CycleSecondsSav < 0 THEN CycleSecondsSav = 60 - CycleSecondsSav CycleMinutesSav = CycleMinutesSav - 1 END IF IF CycleMinutesSav < 0 THEN CycleMinutesSav = 60 - CycleMinutesSav CycleHoursSav = CycleHoursSav - 1 END IF REM ======================================== LogTime = Cycletime OPEN LogFile$ FOR APPEND AS #5 WRITE #5, CycleHoursSav, CycleMinutesSav, CycleSecondsSav, Cycletime, TargetTemp, MTemp, Status$ CLOSE #5 END IF REM ======================== END LOG ================================= FOR i = 1 TO 6000 NEXT i IF Cycletime > (TotalTime - .1) THEN Status$ = "OFF" CALL TurnOff(HCODE$, PortNumber!, PokePlace, speed!) REM ===================== LOG DATA =================================== CycleSecondsSav = CycleSeconds CycleMinutesSav = CycleMinutes CycleHoursSav = CycleHours IF CycleSecondsSav < 0 THEN CycleSecondsSav = 60 - CycleSecondsSav CycleMinutesSav = CycleMinutesSav - 1 END IF IF CycleMinutesSav < 0 THEN CycleMinutesSav = 60 - CycleMinutesSav CycleHoursSav = CycleHoursSav - 1 END IF REM ======================================== OPEN LogFile$ FOR APPEND AS #5 WRITE #5, CycleHoursSav, CycleMinutesSav, Cycletime, TargetTemp, MTemp, Status$ CLOSE #5 REM ======================== END LOG ================================= OPEN LogFile$ FOR APPEND AS #5 PRINT #5, "Run terminated normally after full cycle." CLOSE #5 LOCATE 21, 16 PRINT " RUN HAS FINISHED - Kiln has been turned off. " LOCATE 22, 16 PRINT " Press any key to continue. " CALL GetKey(a$) GOTO SCMainMenu END IF LOOP GOTO RunMenu2 REM ===================== End of Run Menu ======================== NewCycleMenu: REM ============== Cycle Menu ==================================== CALL MakeBox LOCATE 3, 27 PRINT "TEMPERATURE PROFILE MENU" LOCATE 5, 6 PRINT "Please select one of the following options:" LOCATE 6, 10 PRINT " Display the current temperature profile." LOCATE 7, 10 PRINT " Load an existing temperature profile." LOCATE 8, 10 PRINT " Create a new temperature profile." LOCATE 9, 10 PRINT " Save the current temperature profile." LOCATE 10, 10 PRINT " Return to main menu." CycleMenu: DO UNTIL a$ = "N" OR a$ = "L" OR a$ = "R" OR a$ = "D" OR a$ = "S" CALL GetKey(a$) a$ = UCASE$(a$) LOOP REM ================ IF a$ = "L" THEN CALL SelCyc(InFile$) CALL LoadCycle(InFile$, NumSegments, InitTemp, SegmentType$(), FinalTemp(), Rate(), SegTime()) END IF IF a$ = "N" THEN CALL NewCycle(NumSegments, InitTemp, SegmentType$(), FinalTemp(), Rate(), SegTime()) IF a$ = "D" THEN CALL DisplayCycle(NumSegments, InitTemp, SegmentType$(), FinalTemp(), Rate(), SegTime()) IF a$ = "S" THEN CALL SaveName(OutFile$, NumSegments!, InitTemp!, SegmentType$(), FinalTemp!(), Rate!(), SegTime!()) CALL CyclSave(OutFile$, NumSegments, InitTemp, SegmentType$(), FinalTemp(), Rate(), SegTime()) END IF IF a$ = "R" THEN GOTO SCMainMenu ' RETURN TO MAIN PROGRAM a$ = "" GOTO NewCycleMenu REM ========================== HARDWARE ===================== HardwareMenu: CALL MakeBox LOCATE 3, 30 PRINT "HARDWARE MENU" LOCATE 5, 6 PRINT "Please select one of the following options:" LOCATE 6, 10 PRINT " Display the current hardware file." LOCATE 7, 10 PRINT " Create a hardware file." LOCATE 8, 10 PRINT " Return to main menu." REM HardwareMenu: DO UNTIL a$ = "N" OR a$ = "R" OR a$ = "D" CALL GetKey(a$) a$ = UCASE$(a$) LOOP REM ================ IF a$ = "N" THEN CALL SetHardware(PortNumber!, speed!, HouseCode$, AlarmTemp) IF a$ = "D" THEN CALL ShowHardware(PortNumber!, speed!, HouseCode$, AlarmTemp) IF a$ = "R" THEN CALL SetHCODE(HouseCode$, HCODE$) GOTO SCMainMenu ' RETURN TO MAIN PROGRAM END IF a$ = "" GOTO HardwareMenu SUB CyclSave (OutFile$, NumSegments, InitTemp, SegmentType$(), FinalTemp(), Rate(), SegTime()) REM ========== Saves a kiln run temperature profile ===================== OPEN OutFile$ FOR OUTPUT AS #1 PRINT #1, NumSegments; InitTemp FOR i = 1 TO NumSegments PRINT #1, SegmentType$(i); CHR$(44); FinalTemp(i); CHR$(44); Rate(i); CHR$(44); SegTime(i) NEXT i CLOSE #1 END SUB SUB DisplayCycle (NumSegments, InitTemp, SegmentType$(), FinalTemp(), Rate(), SegTime()) REM === Displays current kiln run temperature profile ===================== CALL MakeBox LOCATE 3, 16 PRINT "There are "; NumSegments; " segments - Starting Temperature = "; InitTemp TotalTime = 0 FOR i = 1 TO NumSegments LOCATE i + 4, 3 IF SegmentType$(i) = "R" THEN ST$ = "Ramp - " IF SegmentType$(i) = "S" THEN ST$ = "Soak - " IF SegmentType$(i) = "A" THEN ST$ = "Alarm - " SegTimeHours = INT(SegTime(i) / 60) SegTimeMin = INT(SegTime(i)) - SegTimeHours * 60 SegTimeSec = INT((SegTime(i) - SegTimeHours * 60 - SegTimeMin) * 60) IF SegmentType$(i) = "A" THEN IF FinalTemp(i) = 2500 THEN AA$ = "Kiln FULL ON" IF FinalTemp(i) > 0 AND FinalTemp(i) < 2500 THEN AA$ = "Final Temperature = " + STR$(FinalTemp(i)) IF FinalTemp(i) = 0 THEN AA$ = "Kiln set OFF" PRINT i; ST$; AA$; " - Duration = "; SegTimeHours; " h "; SegTimeMin; "m "; SegTimeSec; "s" ELSE PRINT i; ST$; "Final Temperature ="; FinalTemp(i); "øF - Rate ="; Rate(i); "Duration ="; SegTimeHours; " h"; SegTimeMin; " m" END IF TotalTime = TotalTime + SegTime(i) NEXT i LOCATE i + 5, 16 TimeHours = INT(TotalTime / 60) REM TimeMin = INT(TotalTime) - TimeHours * 60 TimeMin = (TotalTime) - TimeHours * 60 PRINT "Total Time ="; TimeHours; " hours "; PRINT USING "##.##"; TimeMin; PRINT " minutes" LOCATE 21, 35 PRINT "Press any key to continue." CALL GetKey(a$) END SUB SUB GetKey (a$) REM ======================== SUB GetKey ================================== REM ========== Waits for and returns a character from keyboard =============== NotYet: a$ = INKEY$ IF a$ = "" THEN GOTO NotYet END SUB SUB GetMv (MV, PortNumber!) REM ============================ SUB GetMv ============================== REM =================== Reads the multimeter ============================ REM ===== From Radio Shack 22-805 and Metex ME-11 instructions ========== REM CLOSE #2 IF PortNumber! = 1 THEN OPEN "COM1:600,N,7,2,RS,CS,DS,CD" FOR RANDOM AS #2 IF PortNumber! = 2 THEN OPEN "COM2:600,N,7,2,RS,CS,DS,CD" FOR RANDOM AS #2 a$ = "D" ' "D" activates data transmission PRINT #2, a$ IN$ = INPUT$(14, #2) LOCATE 4, 8 Set$ = LEFT$(IN$, 3) LOCATE 6, 8 UNIT$ = MID$(IN$, 10, 4) LOCATE 7, 8 MV = VAL(MID$(IN$, 4, 6)) LOCATE 8, 8 CLOSE #2 END SUB SUB LoadCycle (InFile$, NumSegments!, InitTemp!, SegmentType$(), FinalTemp!(), Rate(), SegTime!()) REM =========== Loads a kiln run temperature profile ===================== OPEN InFile$ FOR INPUT AS #1 INPUT #1, NumSegments, InitTemp FOR i = 1 TO NumSegments INPUT #1, SegmentType$(i), FinalTemp(i), Rate(i), SegTime(i) NEXT i CLOSE #1 END SUB SUB MakeBox REM ============================= SUB MakeBox ============================= CLS LOCATE 1, 1 PRINT "ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»" PRINT "º º" PRINT "º º" PRINT "º º" PRINT "º º" PRINT "º º" PRINT "º º" PRINT "º º" PRINT "º º" PRINT "º º" PRINT "º º" PRINT "º º" PRINT "º º" PRINT "º º" PRINT "º º" PRINT "º º" PRINT "º º" PRINT "º º" PRINT "º º" PRINT "º º" PRINT "º º" PRINT "º º" PRINT "ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ SIMP-CON ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ v 1.0 ÍÍÍͼ" END SUB SUB MV2DG (MV, MTemp) REM ============================= SUB MV2DG ============================= REM Conversion of thermocouple reading from millivolts to Farenheit degrees. REM Based on reference junction at 32 degrees Farenheit and ISA C96.1-1969 table IF MV < .18 THEN MTemp = 40 IF MV >= .18 AND MV < 1.52 THEN MTemp = 40 + (MV - .18) * 60 / (1.52 - .18) IF MV >= 1.52 AND MV < 3.82 THEN MTemp = 100 + (MV - 1.52) * 100 / (3.82 - 1.52) IF MV >= 3.82 AND MV < 6.09 THEN MTemp = 200 + (MV - 3.82) * 100 / (6.09 - 3.82) IF MV >= 6.09 AND MV < 8.31 THEN MTemp = 300 + (MV - 6.09) * 100 / (8.31 - 6.09) IF MV >= 8.31 AND MV < 10.57 THEN MTemp = 400 + (MV - 8.31) * 100 / (10.57 - 8.31) IF MV >= 10.57 AND MV < 12.86 THEN MTemp = 500 + (MV - 10.57) * 100 / (12.86 - 10.57) IF MV >= 12.86 AND MV < 15.18 THEN MTemp = 600 + (MV - 12.86) * 100 / (15.18 - 12.86) IF MV >= 15.18 AND MV < 17.53 THEN MTemp = 700 + (MV - 15.18) * 100 / (17.53 - 15.18) IF MV >= 17.53 AND MV < 19.89 THEN MTemp = 800 + (MV - 17.53) * 100 / (19.89 - 17.53) IF MV >= 19.89 AND MV < 22.26 THEN MTemp = 900 + (MV - 19.89) * 100 / (22.26 - 19.89) IF MV >= 22.26 AND MV < 24.63 THEN MTemp = 1000 + (MV - 22.26) * 100 / (24.63 - 22.26) IF MV >= 24.63 AND MV < 26.98 THEN MTemp = 1100 + (MV - 24.63) * 100 / (26.98 - 24.63) IF MV >= 26.98 AND MV < 29.32 THEN MTemp = 1200 + (MV - 26.98) * 100 / (29.32 - 26.98) IF MV >= 29.32 AND MV < 31.65 THEN MTemp = 1300 + (MV - 29.32) * 100 / (31.65 - 29.32) IF MV >= 31.65 AND MV < 33.93 THEN MTemp = 1400 + (MV - 31.65) * 100 / (33.93 - 31.65) IF MV >= 33.93 AND MV < 36.19 THEN MTemp = 1500 + (MV - 33.93) * 100 / (36.19 - 33.93) IF MV >= 36.19 AND MV < 38.43 THEN MTemp = 1600 + (MV - 36.19) * 100 / (38.43 - 36.19) IF MV >= 38.43 AND MV < 40.62 THEN MTemp = 1700 + (MV - 38.43) * 100 / (40.62 - 38.43) IF MV >= 40.62 AND MV < 42.78 THEN MTemp = 1800 + (MV - 40.62) * 100 / (42.78 - 40.62) IF MV >= 42.78 AND MV < 44.91 THEN MTemp = 1900 + (MV - 42.78) * 100 / (44.91 - 42.78) IF MV >= 44.91 AND MV < 47! THEN MTemp = 2000 + (MV - 44.91) * 100 / (47! - 44.91) IF MV >= 47! AND MV < 49.05 THEN MTemp = 2100 + (MV - 47!) * 100 / (49.05 - 47!) IF MV >= 49.05 AND MV < 51.05 THEN MTemp = 2200 + (MV - 49.05) * 100 / (51.05 - 49.05) IF MV >= 51.05 AND MV < 53! THEN MTemp = 2300 + (MV - 51.05) * 100 / (53! - 51.05) IF MV > 53 THEN MTemp = 2500 REM IF MV >= 53 THEN CALL NoRead REM DisplayTemp = INT(MTEMP) REM LOCATE 10, 8 REM PRINT "Temperature is " REM LOCATE 10, 8 REM PRINT "Temperature is "; DisplayTemp END SUB SUB NewCycle (NumSegments, InitTemp, SegmentType$(), FinalTemp(), Rate(), SegTime()) REM ======== Creates a kiln run temperature profile ===================== CALL MakeBox LOCATE 3, 6 INPUT "What is your starting temperature in øF? ", InitTemp i = 1 StepCycle: CALL MakeBox LOCATE 3, 6 PRINT "Data entry for Segment "; i LOCATE 4, 6 PRINT "Is this segmant a Ramp, a Soak, or an Alarm? Press , or ." StepType: LOCATE 4, 72 CALL GetKey(a$) IF UCASE$(a$) <> "R" AND UCASE$(a$) <> "S" AND UCASE$(a$) <> "A" THEN GOTO StepType SegmentType$(i) = UCASE$(a$) IF SegmentType$(i) = "R" OR SegmentType$(i) = "S" THEN LOCATE 5, 6 PRINT "What is the final temperature of this segment in øF"; INPUT FinalTemp(i) END IF IF SegmentType$(i) = "A" THEN LOCATE 5, 6 PRINT "Do you want the kiln On or Off during the alarm? Press or ."; AlarmTemp: CALL GetKey(a$) IF UCASE$(a$) <> "O" AND UCASE$(a$) <> "F" THEN GOTO AlarmTemp IF UCASE$(a$) = "O" AND i = 1 THEN FinalTemp(i) = 2500 IF UCASE$(a$) = "O" AND i > 1 THEN FinalTemp(i) = FinalTemp(i - 1) IF UCASE$(a$) = "F" THEN FinalTemp(i) = 0 Rate(i) = 0 LOCATE 7, 6 PRINT "How long (in seconds) do you want the alarm to sound"; LOCATE 6, 6 IF UCASE$(a$) = "F" THEN PRINT "(An alarm with kiln OFF should usually be followed by a soak.)"; LOCATE 7, 58 INPUT SegTime(i) SegTime(i) = SegTime(i) / 60 END IF IF SegmentType$(i) = "R" THEN LOCATE 6, 6 PRINT "What is the rate in Fø/hour"; REM LOCATE 6, 72 INPUT Rate(i) Rate(i) = ABS(Rate(i)) IF i > 1 THEN IT = FinalTemp(i - 1) ELSE IT = InitTemp SegTime(i) = ABS(60 * (FinalTemp(i) - IT) / Rate(i)) END IF IF SegmentType$(i) = "S" THEN Rate(i) = 0 LOCATE 6, 6 PRINT "What is the soak time in minutes"; REM LOCATE 7, 72 INPUT SegTime(i) END IF LOCATE 8, 8 PRINT "Press to end entry, any other key to continue." CALL GetKey(a$) IF a$ = CHR$(27) THEN GOTO DoneEntry i = i + 1 GOTO StepCycle DoneEntry: NumSegments = i CALL DisplayCycle(NumSegments, InitTemp, SegmentType$(), FinalTemp(), Rate(), SegTime()) END SUB SUB NoBath (MV, RoomT) REM ======================= SUB NoBath ======================= REM Between 32 and 100 degrees Farenheit, correction is +0.11 mv per 10 degrees REM from ISA C96.1-1969 table MV = MV + .011 * (RoomT - 32) END SUB SUB SaveName (OutFile$, NumSegments!, InitTemp!, SegmentType$(), FinalTemp!(), Rate!(), SegTime!()) REM == This routine gets OutFile$ then calls save routine ======= REM =================== Establish OutFile$ ====================== GetOutFile: CALL MakeBox LOCATE 7, 10 PRINT "What do you wish to call the output file?" LOCATE 8, 10 PRINT "(Enter 1 to 8 characters." LOCATE 9, 10 PRINT "The extension "; CHR$(34); ".TCP"; CHR$(34); " will be added automatically.)" LOCATE 8, 55 COLOR 0, 7 PRINT " " LOCATE 8, 56 LINE INPUT OutFile$ j = 1 DO UNTIL j = 9 OR MID$(OutFile$, j, 1) = " " Test$ = Test$ + MID$(OutFile$, j, 1) j = j + 1 LOOP OutFile$ = UCASE$(Test$) COLOR 7, 0 LOCATE 11, 15, 0 PRINT "Please wait a moment." SHELL "DIR *.TCP > DIRFILE.IN" OPEN "DIRFILE.IN" FOR INPUT AS #1 DO LINE INPUT #1, InLine$ InLine$ = LEFT$(InLine$, 12) IF INSTR(InLine$, "TCP") > 0 THEN j = 1: Test$ = "" DO UNTIL j = 9 OR MID$(InLine$, j, 1) = " " Test$ = Test$ + MID$(InLine$, j, 1) j = j + 1 LOOP InLine$ = Test$: Test$ = "": a% = 0 IF INSTR(InLine$, OutFile$) > 0 THEN IF LEN(InLine$) = LEN(OutFile$) THEN a% = 1: EXIT DO END IF END IF LOOP UNTIL EOF(1) CLOSE #1 IF a% = 1 THEN LOCATE 11, 15 PRINT " " COLOR 0, 7 LOCATE 12, 20 PRINT " " LOCATE 12, 23 PRINT InLine$; ".TCP already exists." LOCATE 13, 20 PRINT " Do you wish to replace it? (Y or N) " 'LOCATE 13, 20 'PRINT " " COLOR 7, 0 CALL YesNo(Y$) IF Y$ <> "Y" THEN GOTO GetOutFile END IF OutFile$ = OutFile$ + ".TCP" SHELL "DEL DIRFILE.IN" CALL CyclSave(OutFile$, NumSegments, InitTemp, SegmentType$(), FinalTemp(), Rate(), SegTime()) REM - saving routine END SUB SUB SelCyc (InFile$) REM ======================== SUB SelCyc ====================== REM ======= Make sure DEFAULT.TCP exists to avoid "not found" ==== OPEN "DEFAULT.TCP" FOR OUTPUT AS #1 PRINT #1, 3; CHR$(44); 70 PRINT #1, "R"; CHR$(44); 970; CHR$(44); 100; CHR$(44); 540 PRINT #1, "S"; CHR$(44); 970; CHR$(44); 0; CHR$(44); 55 PRINT #1, "R"; CHR$(44); 70; CHR$(44); 100; CHR$(44); 540 CLOSE #1 REM === This routine gets InFile$ =================== CALL MakeBox InDir: COLOR 7, 0 LOCATE 5, 8 PRINT " Please wait while files are identified." SHELL "DIR *.TCP > DIRFILE.IN" OPEN "DIRFILE.IN" FOR INPUT AS #1 DIM InName(1 TO 40) AS STRING * 12 j = 1 DO LINE INPUT #1, InLine$ InLine$ = LEFT$(InLine$, 12) IF INSTR(InLine$, "TCP") > 0 THEN InName(j) = InLine$ j = j + 1 END IF LOOP UNTIL EOF(1) Last% = j - 1 CLOSE #1 SHELL "DEL DIRFILE.IN" LOCATE 5, 8 PRINT " " COLOR 7, 0 LOCATE 6, 10 PRINT "Available CYCLE FILES:" FOR j = 1 TO Last% + 1 Y = 1 + INT((j - 1) / 3) X = 1 + (j - 1) MOD 3 XLine% = INT(16 + 18 * (X - 1)) YLine% = INT(8 + (Y - 1)) LOCATE YLine%, XLine%, 0 PRINT InName(j) NEXT j REM ========== Print Instructions ================================ LOCATE 20, 10 PRINT "Move HIGHLIGHT with cursor keys, use RETURN to SELECT" X = 1 Y = 1 HiLiteFile: REM ==== create highlight ========================================== DO REM === remove highlight =========================================== OldYLine% = YLine% OldXLine% = XLine% OldName$ = InName(j) LOCATE OldYLine%, OldXLine%, 0 COLOR 7, 0 PRINT OldName$ COLOR 0, 7 j = INT(3 * (Y - 1) + X) XLine% = INT(16 + 18 * (X - 1)) YLine% = INT(8 + (Y - 1)) LOCATE YLine%, XLine%, 0 PRINT InName(j) REM ====== Wait for keypress ====================================== GetMov: a$ = INKEY$ IF a$ = "" THEN GOTO GetMov IF a$ = CHR$(13) THEN EXIT DO REM ======= Process input ========================================= Rit$ = CHR$(0) + CHR$(77) Lef$ = CHR$(0) + CHR$(75) Up$ = CHR$(0) + CHR$(72) Dn$ = CHR$(0) + CHR$(80) F10$ = CHR$(0) + CHR$(68) IF a$ = Rit$ THEN X = X + 1 IF X = 4 THEN Y = Y + 1: X = 1 J2 = INT(3 * (Y - 1) + X) IF J2 > Last% THEN X = 1: Y = 1 END IF IF a$ = Lef$ THEN X = X - 1 IF X = 0 THEN Y = Y - 1: X = 3 J2 = INT(3 * (Y - 1) + X) IF J2 < 1 THEN X = 1: Y = 1: BEEP END IF IF a$ = Dn$ THEN Y = Y + 1 J2 = INT(3 * (Y - 1) + X) IF J2 > Last% THEN X = 1: Y = 1 END IF IF a$ = Up$ THEN Y = Y - 1 J2 = INT(3 * (Y - 1) + X) IF J2 < 1 THEN X = 1: Y = 1: BEEP END IF a$ = "" LOOP FileFound: REM ================= End of Selection Process ==================== InFile$ = InName(j) REM ================ Write InFile$ in conventional way ================= j = 1: Test$ = "" DO UNTIL j = 9 OR MID$(InFile$, j, 1) = " " Test$ = Test$ + MID$(InFile$, j, 1) j = j + 1 LOOP InFile$ = Test$ + ".TCP": Test$ = "" COLOR 7, 0 END SUB SUB SendFCMessage (Message$, PortNumber!, PokePlace, speed!) IF PortNumber! = 1 THEN OPEN "COM1:600,N,7,2,CS,DS" FOR RANDOM AS #2 IF PortNumber! = 2 THEN OPEN "COM2:600,N,7,2,CS,DS" FOR RANDOM AS #2 IF PortNumber! = 1 THEN PokePlace = &H3FC IF PortNumber! = 2 THEN PokePlace = &H2FC REM ====== Actual hardware message transmission for FireCracker ========= FOR j = 1 TO LEN(Message$) c$ = MID$(Message$, j, 1) IF c$ = "0" THEN OUT PokePlace, 1 IF speed! = 1 THEN CALL TimeWait OUT PokePlace, 3 IF speed! = 1 THEN CALL TimeWait END IF IF c$ = "1" THEN OUT PokePlace, 2 IF speed! = 1 THEN CALL TimeWait OUT PokePlace, 3 IF speed! = 1 THEN CALL TimeWait END IF NEXT j T1# = TIMER DO UNTIL T2# > T1# + .4 T2# = TIMER IF T2# < T1# THEN T1# = TIMER REM Midnight passed LOOP CLOSE #2 END SUB SUB SetHardware (PortNumber!, speed!, HouseCode$, AlarmTemp) REM ============== Input data for hardware setup ======================= REM ============ Data automatically saved in "AUTOLOAD.TCH" =========== REM ==================== Choose Serial Port =========================== SetPort: CALL MakeBox LOCATE 3, 20 PRINT "Hardware Setup" a$ = "" Delay$ = "" LOCATE 5, 6 PRINT "Which Serial Port do you wish to use? Press <1> or <2>" DO UNTIL a$ = "1" OR a$ = "2" a$ = INKEY$ REM ================================== PortNumber! = VAL(a$) ' PRINT "Choice = "; a$; "" ' PRINT "PortNumber! = "; PortNumber! LOOP a$ = "" LOCATE 7, 6 PRINT "Do you want a time delay?" LOCATE 8, 8 PRINT " No - probably not needed for old PCs" LOCATE 9, 8 PRINT " Yes - might be needed for Pentiums" DO UNTIL Delay$ = "N" OR Delay$ = "Y" Delay$ = UCASE$(INKEY$) IF Delay$ = "N" THEN speed! = 0 IF Delay$ = "Y" THEN speed! = 1 LOOP REM ======================= Select House Code =================== LOCATE 11, 6 PRINT "Which House Code do you wish to use? ( through

) " CALL GetKey(a$) HouseCode$ = UCASE$(a$) REM ==================== Set Alarm Temperature ================== LOCATE 13, 6 PRINT "What overheat alarm temperature setting do you want?" LOCATE 14, 8 PRINT "(Should be about 100 to 200ø above maximum expected during run.)" LOCATE 13, 57 INPUT AlarmTemp REM =================== End Setup - Save Info ==================== REM OPEN OutFile$ FOR OUTPUT AS #1 OPEN "AUTOLOAD.TCH" FOR OUTPUT AS #1 PRINT #1, PortNumber! PRINT #1, speed! PRINT #1, HouseCode$ PRINT #1, AlarmTemp CLOSE #1 END SUB SUB SetHCODE (HouseCode$, HCODE$) REM ==== House Code look-up for FireCracker Interface ============= IF HouseCode$ = "A" THEN HCODE$ = "0110" IF HouseCode$ = "B" THEN HCODE$ = "0111" IF HouseCode$ = "C" THEN HCODE$ = "0100" IF HouseCode$ = "D" THEN HCODE$ = "0101" IF HouseCode$ = "E" THEN HCODE$ = "1000" IF HouseCode$ = "F" THEN HCODE$ = "1001" IF HouseCode$ = "G" THEN HCODE$ = "1010" IF HouseCode$ = "H" THEN HCODE$ = "1011" IF HouseCode$ = "I" THEN HCODE$ = "1110" IF HouseCode$ = "J" THEN HCODE$ = "1111" IF HouseCode$ = "K" THEN HCODE$ = "1100" IF HouseCode$ = "L" THEN HCODE$ = "1101" IF HouseCode$ = "M" THEN HCODE$ = "0000" IF HouseCode$ = "N" THEN HCODE$ = "0001" IF HouseCode$ = "O" THEN HCODE$ = "0010" IF HouseCode$ = "P" THEN HCODE$ = "0011" END SUB SUB ShowHardware (PortNumber!, speed!, HouseCode$, AlarmTemp) REM ============ Displays current hardware settings =============== CALL MakeBox LOCATE 3, 27 PRINT "Current Hardware Settings" LOCATE 5, 6 IF PortNumber! = 1 THEN port$ = "COM1" IF PortNumber! = 2 THEN port$ = "COM2" IF speed! = 0 THEN speed$ = " with NO delay." IF speed! = 1 THEN speed$ = " with a delay." PRINT "Output is to "; port$; speed$ LOCATE 6, 6 PRINT "House Code is set to "; HouseCode$ LOCATE 7, 6 PRINT "Over heat alarm is set to go off at "; AlarmTemp; " øF" LOCATE 21, 35 PRINT "Press any key to continue." CALL GetKey(a$) END SUB SUB SmallBox (Y%, X%, text1$, text2$) REM === Puts a small box for warnings, etc on the screen ===== REM =========== Displays 2 lines of text in box ============== LOCATE Y%, X% PRINT "ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿" LOCATE Y% + 1, X% PRINT "³ ³" LOCATE Y% + 2, X% PRINT "³ ³" LOCATE Y% + 3, X% PRINT "ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ" LOCATE Y% + 1, X% + 2 PRINT text1$ LOCATE Y% + 2, X% + 2 PRINT text2$ END SUB SUB Target (TargetTemp, Cycletime, InitTemp, SegmentType$(), FinalTemp(), Rate(), SegTime(), Done%, Segment%) REM === Determines target temperature as a function of time since start === SegTimeEnd = 0 i = 1 DO UNTIL SegTimeEnd >= Cycletime StartSegTime = SegTimeEnd SegTimeEnd = SegTimeEnd + SegTime(i) Segment% = i i = i + 1 LOOP i = i - 1 IF Segment% <= 1 THEN TargetTemp = InitTemp ELSE TargetTemp = FinalTemp(Segment% - 1) END IF IF SegmentType$(Segment%) = "R" THEN IF FinalTemp(Segment%) < FinalTemp(Segment% - 1) THEN Rate = -Rate(Segment%) TargetTemp = TargetTemp + (Rate / 60) * (Cycletime - StartSegTime) ELSE Rate = Rate(Segment%) TargetTemp = TargetTemp + (Rate / 60) * (Cycletime - StartSegTime) END IF END IF IF SegmentType$(Segment%) = "S" THEN TargetTemp = FinalTemp(Segment%) IF SegmentType$(Segment%) = "A" THEN REM ========= SEND ALARM MESSAGE - hold temperature ================= REM 2 ON = 0001 0000 ' used for ALARM Action$ = "00010000" Message$ = Header$ + HCODE$ + GPN$ + Action$ + FOOTER$ CALL SendFCMessage(Message$, PortNumber!, PokePlace, speed!) TargetTemp = FinalTemp(Segment%) LOCATE 15, 6 PRINT "ALARM IS ON " END IF IF SegmentType$(Segment%) <> "A" THEN REM ========= Cancel ALARM ================= REM 2 OFF = 0011 0000 ' used for ALARM Action$ = "00110000" Message$ = Header$ + HCODE$ + GPN$ + Action$ + FOOTER$ CALL SendFCMessage(Message$, PortNumber!, PokePlace, speed!) LOCATE 15, 6 PRINT "Alarm is off " END IF END SUB SUB TestExist (FileName$, a%) REM ==== This routine tests the default subdirectory for the existance REM ==== of a file. If the file exists, flag a% = 1, else a% = 0 REM == Make sure some xx.EXT exists to avoid "File not found" DOS message == FileName$ = UCASE$(FileName$) IF INSTR(FileName$, ".") > 0 THEN BaseName$ = LEFT$(FileName$, (INSTR(FileName$, ".") - 1)) EXT$ = "" j = INSTR(FileName$, ".") + 1 DO UNTIL j = LEN(FileName$) + 1 EXT$ = EXT$ + MID$(FileName$, j, 1) j = j + 1 LOOP END IF SHELL "DIR *." + EXT$ + " > DIRFILE.IN" OPEN "DIRFILE.IN" FOR INPUT AS #1 a% = 0 DO LINE INPUT #1, InLine$ InLine$ = LEFT$(InLine$, 12) IF INSTR(InLine$, EXT$) > 0 THEN IF INSTR(InLine$, BaseName$) > 0 THEN a% = 1 END IF LOOP UNTIL EOF(1) CLOSE #1 SHELL "DEL DIRFILE.IN" END SUB SUB TimeWait REM ==== Maintain state for at least .5 ms ======== T1# = TIMER DO UNTIL T2# > T1# + .00055 T2# = TIMER IF T2# < T1# THEN T1# = TIMER REM Midnight passed LOOP END SUB SUB Title REM ============== Puts OPENING MESSAGE on screen ==================== LOCATE 4, 10 PRINT "Program SIMP-CON sends signals to an X10 FireCracker interface" LOCATE 5, 6 PRINT "based on input from a thermocouple attached to a Metex ME-11 digital" LOCATE 6, 6 PRINT "multimeter, both on the same serial port, either COM1 or COM2." LOCATE 9, 10 PRINT "The program sends simple ON-OFF output to the FireCracker." LOCATE 10, 6 PRINT "" LOCATE 10, 10 PRINT "Set the X-10 Receiver and Modules to the same House Code." LOCATE 11, 10 PRINT "Set the Kiln Control Module to Unit 1." LOCATE 12, 10 PRINT "Set the Alarm Module to Unit 2." LOCATE 13, 10 PRINT "Set the Over-Temp Module to Unit 5." LOCATE 19, 28 PRINT "Press any key to continue." LOCATE 21, 14 PRINT "Program SIMP-CON is copyright 2001 by Wallace Venable" END SUB SUB TurnOff (HCODE$, PortNumber!, PokePlace, speed!) REM ============= Turns the kiln off ================ LOCATE 14, 6 PRINT "Kiln elements are OFF" REM CALL OpenPort(PortNumber!, PokePlace, speed!) REM For FIRECRACKER Header$ = "1101010110101010" FOOTER$ = "10101101" REM HCODE$ = "0110" 'House Code A GPN$ = "0000" Action$ = "00100000" Message$ = Header$ + HCODE$ + GPN$ + Action$ + FOOTER$ CALL SendFCMessage(Message$, PortNumber!, PokePlace, speed!) END SUB SUB TurnOn (HCODE$, PortNumber!, PokePlace, speed!) REM ============= Turns the kiln on ================ LOCATE 14, 6 PRINT "Kiln elements are ON " REM For FIRECRACKER Header$ = "1101010110101010" FOOTER$ = "10101101" GPN$ = "0000" Action$ = "00000000" Message$ = Header$ + HCODE$ + GPN$ + Action$ + FOOTER$ CALL SendFCMessage(Message$, PortNumber!, PokePlace, speed!) END SUB SUB YesNo (a$) REM ======== This routine waits for a Y or N key press ================= KeyIn: a$ = INKEY$ IF a$ = "" THEN GOTO KeyIn a$ = UCASE$(a$) IF a$ <> "Y" AND a$ <> "N" THEN GOTO KeyIn END SUB