home *** CD-ROM | disk | FTP | other *** search
- program Listing2_3;
-
- 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;
-
- 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 then
- writeln( f, TagNumber, ' is ON.' )
- else
- 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;
-
- { 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;
-
- var
- LT100,
- FT100 : Analog;
- PSL100 : LoSwitch;
- PSH100 : HiSwitch;
- EY100 : Pump;
- time : integer;
-
- begin
-
- { If no file name is passed to the program, then ParamStr(1)
- will be the null string, which will cause Assign to output
- to the standard output (the screen). If a file name is
- passed, the output will be saved in the file for later
- reference. }
-
- Assign( f, ParamStr(1) );
- Rewrite( f );
-
- LT100.Init( 'LT100', 512, 50, 250 );
- FT100.Init( 'FT100', 2048, 0, 10000 );
- PSL100.Init( 'PSL100', 60, HtToPSI(LT100.GetValue) );
- PSH100.Init( 'PSH100', 75, HtToPSI(LT100.GetValue) );
- EY100.Init( 'EY100', off, 8000);
- time := 0;
-
- repeat
-
- Inc( time ); { increment the time }
- { First, adjust the reading in LT-100 by reducing the level in
- LT100.Value by an amount corresponding to the flow out of the
- system. We do this by fetching the value of FT100, converting
- it to a height in the tank, and subtracting from the actual
- height... }
- LT100.PutValue( LT100.GetValue - FlowToDeltaHt(FT100.GetValue) );
-
- { We take the result and update the switches }
- PSL100.PutReading( HtToPSI(LT100.GetValue) );
- PSH100.PutReading( HtToPSI(LT100.GetValue) );
-
- {Let's publish the level in the tank...}
- writeln( f, 'Level in tank is ', LT100.GetValue:2:2, ' feet at minute ', time );
-
- { If the pressure is too low, turn on the pump }
- if PSL100.GetStatus = on then
- EY100.PutStatus( ON );
- { If the pressure is too high, turn off the pump }
- if PSH100.GetStatus = on then
- EY100.PutStatus( OFF );
-
- LT100.PutValue( LT100.GetValue + FlowToDeltaHt( EY100.Flow ));
-
- until KeyPressed;
- Close ( f );
- end.
-
-
-
-
-
-
-
-
-
-
-