home *** CD-ROM | disk | FTP | other *** search
- { Unit: Tags
-
- Utilization notes:
-
- 1. If no file name is supplied on the command line, the
- program will print output to the screen. If a file
- name is supplied, the output will be directed to the
- file.
-
- 2. The object 'Quiet' controls program output
- (including the opening and closing of output files.)
- The procedure Quiet.On will turn output off and close
- the output file, if one is specified. Subsequent calls
- to the procedure Quiet.Off will turn output back on and
- append it to f. The default status of Quiet is ON.
-
- 3. Users wanting to write to a file must first
- make sure Quiet is Off, and direct output to
- the file f, as in the following example.
-
- if Quiet.IsOff then
- writeln( f, 'Put your string here' );
-
- 4. Programs using this unit should, at the end of the progam,
- either explicitly make a call to Quiet.On or include the
- line
-
- Close( f );
- }
-
- { Specification for Tags class ***************************
-
- Variables:
- TagNumber : String12;
- Stores a tag number of up to 12 characters.
-
- Procedures:
- .Init(( ATag : String12 );
- ATag is stored in TagNumber.
-
- Descendant object types:
- Digital
- Analog }
-
- { Specification for Digital class ************************
-
- Variables:
- Status : boolean;
- Indicates whether digital object is ON or OFF.
- ON denotes TRUE; OFF, FALSE.
-
- Procedures:
- .Init( ATag : String12; AStatus : boolean );
- ATag is stored in TagNumber; AStatus is stored
- in Status.
-
- .PutStatus( AStatus : boolean );
- Sets Status to AStatus.
-
- Functions:
- .GetStatus : boolean;
- Returns ON or OFF status of object.
- If variable 'Quiet' (boolean) is ON, then
- Status is not printed to screen; otherwise
- the Status and TagNumber are printed to
- the screen.
-
- Descendant object types:
- DInput
- DOutput }
-
- { Specification for Analog class *************************
- Variables:
- Value : Resolution;
- Value must have a value between 0 and 4095.
-
- ZeroVal : real;
- Engineering unit value corresponding to a Value
- of 0.
-
- MaxVal : real;
- Engineering unit value corresponding to a Value
- of 4095.
-
- Slope : real;
- A number calculated from the equation:
- (MaxVal-ZeroVal)/(4095-0).
-
- Procedures:
- .Init(( ATag : String12; AValue : Resolution;
- Min, Max : real );
- Storage as follows:
- ATag -> TagNumber
- AValue -> Value
- Min -> ZeroVal
- Max -> MaxVal
-
- .PutValue( AValue : real );
- Converts AValue engineering units into counts
- (between 0 and 4095) and stores in Value.
-
- Functions:
- .GetValue : real;
- Converts and returns the counts in Value to
- engineering units.
-
- Descendant types:
- None. }
-
- { Specification for DInput class *************************
-
- Variables:
- Setpoint : real;
- Contains a value at which something happens.
-
- Reading : real;
- Contains an number that is compared to the
- setpoint.
-
- Procedures:
- .PutSetpoint( NewSetpoint : real );
- Sets Setpoint to NewSetpoint.
-
- NOTE: .Init procedure is packaged with
- descendant classes.
-
- Descendant object types:
- HiSwitch
- LoSwitch }
-
- { Specification for DOutput class ************************
-
- NO VARIABLES, NO PROCEDURES, NO FUNCTIONS
- (see descendant object type)
-
- Descendant object types:
- Pump }
-
- { Specification for HiSwitch class ************************
-
- Procedures:
- .Init(( ATag : string;
- ASetpoint : real;
- AReading : real);
- Storage as follows:
- ATag -> TagNumber
- ASetpoint -> Setpoint
- The value of AReading is stored in Reading
- using the .PutReading method.
-
- .PutReading( NewReading : real);
- Store NewReading in Reading. Set Status to
- ON if Reading >= Setpoint.
-
- Descendant object types:
- None. }
-
- { Specification for LoSwitch class ************************
-
- Procedures:
- .Init(( ATag : string;
- ASetpoint : real;
- AReading : real);
- Storage as follows:
- ATag -> TagNumber
- ASetpoint -> Setpoint
- The value of AReading is stored in Reading
- using the .PutReading method.
-
- .PutReading( NewReading : real);
- Store NewReading in Reading. Set Status to
- ON if Reading <= Setpoint.
-
- Descendant object types:
- None. }
-
- { Specification for Pump class **************************
-
- Variables:
- FlowRate : real;
- A number representing gpm flow when pump is
- ON. NOTE: THIS IS A *VERY* ROUGH APPROXIMATION
- OF PUMP BEHAVIOR!
-
- Procedures:
- .Init( ATag : String12; AStatus : boolean;
- AFlow : real );
- Storage as follows:
- ATag -> TagNumber
- AStatus -> Status
- AFlow -> FlowRate
-
- Functions:
- .Flow : real;
- Returns the value stored in FlowRate.
-
- Descendant object types:
- None. }
-
- unit Tags;
-
- interface
-
- uses Crt; { for KeyPressed }
-
- const
-
- ON = true;
- OFF = false;
- MinR = 0; { Minimum number of counts in an analog
- input }
- MaxR = 4095; { Maximum number of counts in an analog
- input }
-
- var
- f : text; {predefined file type}
-
- type
-
- Resolution = 0..4095; { Range for analog input }
- String12 = string[12];
-
-
- Tag = object
- TagNumber : String12;
- procedure Init( ATag : String12 );
- end;
-
- Digital = object(Tag)
- Status : boolean;
- procedure Init( ATag : String12; AStatus :
- boolean );
- procedure PutStatus( AStatus : boolean );
- function GetStatus : boolean;
- end;
-
- Analog = object(Tag)
- Value : Resolution;
- ZeroVal : real;
- MaxVal : real;
- Slope : real;
- procedure Init( ATag : String12; AValue :
- Resolution;
- Min, Max : real );
- procedure PutValue( AValue : real );
- function GetValue : real;
- end;
-
- DOutput = object(Digital)
- end;
-
- Pump = object(DOutput)
- FlowRate : real;
- procedure Init( ATag : String12; AStatus : boolean;
- AFlow : real );
- function Flow : real;
- end;
-
-
- DInput = object(Digital)
- Setpoint : real;
- Reading : real;
- procedure PutSetpoint( NewSetpoint : real );
- end;
-
- HiSwitch = object(DInput)
- procedure Init( ATag : string;
- ASetpoint : real;
- AReading : real);
- procedure PutReading( NewReading : real );
- end;
-
- LoSwitch = object(DInput)
- procedure Init( ATag : string;
- ASetpoint : real;
- AReading : real);
- procedure PutReading( NewReading : real );
- end;
-
- FSwitch = object
- State : boolean;
- procedure Init( InitState : boolean );
- procedure On;
- procedure Off;
- function IsOn : boolean;
- function IsOff : boolean;
- end;
-
-
- function HtToPSI( Height : real ) : real;
-
- function FlowToDeltaHt( Flow : real ) : real;
-
- var
- Quiet : FSwitch;
-
- implementation
-
- procedure Tag.Init( ATag : String12 );
- begin
- TagNumber := ATag;
- end;
-
- procedure Digital.Init( ATag : String12; AStatus : boolean
- );
- begin
- Tag.Init( ATag );
- Status := AStatus;
- end;
-
- procedure Digital.PutStatus( AStatus : boolean );
- begin
- Status := AStatus;
- end;
-
- function Digital.GetStatus : boolean;
- begin
- if (Status = ON) and (Quiet.IsOff) then
- writeln( f, TagNumber, ' is ON.' )
- else
- if (Quiet.IsOff) then
- writeln( f, TagNumber, ' is OFF.' );
- GetStatus := Status;
- end;
-
- procedure Pump.Init( ATag : String12; AStatus : boolean;
- AFlow : real );
- begin
- Digital.Init( ATag, AStatus );
- FlowRate := AFlow;
- end;
-
- function Pump.Flow : real;
- begin
- Flow := FlowRate;
- end;
-
- procedure Analog.Init( ATag : String12;
- AValue : Resolution;
- Min, Max : real );
- begin
- Tag.Init( ATag );
- Value := AValue;
- MaxVal := Max;
- ZeroVal := Min;
- Slope := (Max-Min)/(MaxR-MinR);
- end;
-
- procedure Analog.PutValue( AValue : real );
- begin
- if AValue > MaxVal then
- AVAlue := MaxVal
- else
- if AValue < ZeroVal then
- AValue := ZeroVal;
- Value := Round((AValue - ZeroVal)/Slope);
- end;
-
- function Analog.GetValue : real;
- begin
- GetValue := Slope*Value + ZeroVal;
- end;
-
- procedure DInput.PutSetpoint( NewSetpoint : real );
- begin
- Setpoint := NewSetpoint;
- end;
-
- procedure LoSwitch.Init( ATag : string;
- ASetpoint : real;
- AReading : real);
- begin
- Tag.Init( ATag );
- DInput.PutSetpoint( ASetpoint );
- PutReading( AReading );
- end;
-
- procedure LoSwitch.PutReading( NewReading : real );
- begin
- Reading := NewReading;
- if Reading <= Setpoint then
- Status := true
- else
- Status := false;
- end;
-
- procedure HiSwitch.Init( ATag : string;
- ASetpoint : real;
- AReading : real);
- begin
- Tag.Init( ATag );
- DInput.PutSetpoint( ASetpoint );
- PutReading( AReading );
- end;
-
- procedure HiSwitch.PutReading( NewReading : real );
- begin
- Reading := NewReading;
- if Reading >= Setpoint then
- Status := true
- else
- Status := false;
- end;
-
- procedure FSwitch.Init( InitState : boolean );
- begin
- State := InitState;
- if State = false then { If we want output}
- Rewrite( f ) { Open file f }
- else
- begin
- Rewrite( f ); { Open file f }
- Close( f ); { and close it }
- end;
- end;
-
- procedure FSwitch.On;
- begin
- if State = false then
- begin
- State := true;
- Close( f );
- end;
- end;
-
- procedure FSwitch.Off;
- begin
- if State = true then
- begin
- State := false;
- Append( f );
- end;
- end;
-
- function FSwitch.IsOn : boolean;
- begin
- if State = true then
- IsOn := true
- else
- IsOn := false;
- end;
-
- function FSwitch.Isoff : boolean;
- begin
- IsOff := not IsOn;
- end;
-
- { HtToPSI converts a height (of a column of water) into a
- pressure.
- The math is pretty simple: A column of water 2.31 feet
- high exerts
- a force of one pound per square inch at the bottom. }
-
- function HtToPSI( Height : real ) : real;
- begin
- HtToPSI := Height/2.31;
- end;
-
- { FlowToDeltaHt converts a flow into (or out of) our system
- into a
- change in height in the tank.
- The math is as follows: Divide the flow, in gpm, by 7.48
- gal/cu.ft.
- to get the number of cubic feet pumped per minute.
- Divide this
- number by the volume of 1 vertical foot of the tank,
- which is
- the radius squared times 'pi' (15*15*3.1416). }
-
- function FlowToDeltaHt( Flow : real ) : real;
- begin
- FlowToDeltaHt := Flow/(7.48 * 706) ;
- end;
-
- { initialization code }
- begin
-
- Assign( f, ParamStr(1) );
-
- Quiet.Init(OFF);
-
- end.
-
- { Listing 3-1 }