unit StartupTest;

{$mode ObjFPC}{$H+}

interface

uses
  Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls
  , ExtCtrls, ComCtrls, Spin, BCFluentProgressRing
  , header_utils
  , StrUtils
  , DateUtils
  ;

type

  { TStartupTestForm }

  TStartupTestForm = class(TForm)
    PeriodLabel: TLabel;
    TemperatureLabel: TLabel;
    rxLabel1: TLabel;
    rxTemperatureProgressBar: TProgressBar;
    rxTemperatureText: TStaticText;
    rxuxProgressRing: TBCFluentProgressRing;
    rxuxScaleLabel: TLabel;
    rxText: TStaticText;
    rxuxscaleTrackBar: TTrackBar;
    uxLabel1: TLabel;
    uxTemperatureProgressBar: TProgressBar;
    uxText: TStaticText;
    uxLabel: TLabel;
    uxPeriodProgressBar: TProgressBar;
    rxLabel: TLabel;
    rxPeriodProgressBar: TProgressBar;
    rxuxStopButton: TButton;
    rxuxStartButton: TButton;
    CancelButton: TButton;
    CurrentTestLabeledEdit: TLabeledEdit;
    rxuxGroupBox: TGroupBox;
    ResultsLabel: TLabel;
    ResultsMemo: TMemo;
    StatusLabel: TLabel;
    SleepTimeLabel: TLabel;
    SleepTimeSpinEdit: TSpinEdit;
    uxTemperatureText: TStaticText;
    ValidResponseTimeLabeledEdit: TLabeledEdit;
    StartTimeLabeledEdit: TLabeledEdit;
    StatusMemo: TMemo;
    TestResponseButton: TButton;
    procedure CancelButtonClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure ResultsMemoChange(Sender: TObject);
    procedure rxuxStartButtonClick(Sender: TObject);
    procedure rxuxStopButtonClick(Sender: TObject);
    procedure StatusMemoChange(Sender: TObject);
    procedure TestResponseButtonClick(Sender: TObject);
  private

  public

  end;

var
  StartupTestForm: TStartupTestForm;

implementation

{ TStartupTestForm }
var
  BreakFlag: Boolean = False;
  BreakFlagrxux: Boolean = False;

//Send reset then multiple rx to test the response time of getting a reading after power up.
procedure TStartupTestForm.TestResponseButtonClick(Sender: TObject);
var
 pieces:TStringList;
 i: integer = 0; //Counter
 j: integer = 0; //Extra counter
 Result: String = '';
 StartTime: TDateTime;
 ValidResponseTime: Double;
 GotValid: Boolean;
 ReadingString:String;
 Reading: Double;
 FrequencyString: String;
 Frequency: Double;
 CountsString: String;
 Counts: Double;
 PeriodString: String;
 Period: Double;
 SleepTime: Integer;
begin
     GotValid:=False;
     TestResponseButton.Enabled:=False;
     pieces := TStringList.Create;
     pieces.Delimiter := ',';
     pieces.StrictDelimiter := True; //Do not parse spaces

     BreakFlag:=False;
     SleepTime:=SleepTimeSpinEdit.value;
     ValidResponseTimeLabeledEdit.Text:='';

     StartTime:=Now();
     StartTimeLabeledEdit.Caption:=FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz',StartTime);

     StatusMemo.Append(FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz',StartTime) +
        ' : Reset device, and running test, ' +
        IntToStr(SleepTime) + 'ms sleep time.'
        );

     StatusMessage('Sending reset to meter.');
     sendget(chr($19),False,1,False);

     sleep(1); //Pause 1ms while unit is resetting

     //gather readings
     while true do begin
         if BreakFlag then Break;

         Inc(i);
         CurrentTestLabeledEdit.Caption:=IntToStr(i); //Update cycle counter

         Dec(j); //Take care of extra readings counter

         pieces.DelimitedText:=SendGet('U1x',false,4000);   //GetReading

         //Check for a response
         if pieces.Count>0 then begin

           if not GotValid then begin
             if  AnsiContainsStr(pieces.strings[9],'V') then begin //Check for a valid response
               GotValid:=True; //Indicate that a valid reading was gathered.
               j:=3; //Allow to log a few more readings to check that reading does not change.

               ValidResponseTime:=MilliSecondsBetween(Now(),StartTime)/1000.0;
               ValidResponseTimeLabeledEdit.Text:= Format('%0.3f',[ValidResponseTime])+'s';
               StatusMemo.Append('Done, valid response time: '+ FloatToStr(ValidResponseTime) + ' : ' +
                  Result +
                  ' Finished test. in ' + IntToStr(i) + ' cycles.' );

               ReadingString:=pieces.Strings[6];
               SetLength(ReadingString, Length(ReadingString) - 1);
               Reading:=strtofloat(ReadingString);

               FrequencyString:=pieces.Strings[2];
               SetLength(FrequencyString, Length(FrequencyString) - 2);;
               Frequency:=strtofloat(FrequencyString);

               CountsString:=pieces.Strings[3];
               SetLength(CountsString, Length(CountsString) - 1);;
               Counts:=strtofloat(CountsString);

               PeriodString:=pieces.Strings[4];
               SetLength(PeriodString, Length(PeriodString) - 1);;
               Period:=strtofloat(PeriodString);

               ResultsMemo.Append(
                  Format('%0.2f',[Reading]) +
                  ', ' + Format('%0.3f',[ValidResponseTime]) +
                  ', ' + Format('%0.0f',[Frequency]) +
                  ', ' + Format('%0.0f',[Counts]) +
                  ', ' + Format('%0.3f',[Period])
                  );
             end; //End of valid response
           end; //End of got valid check

           if (j=0) then  //Final
             Break;

         end; //End of any reponse
         CurrentTestLabeledEdit.Text:=IntToStr(i);
         sleep(SleepTime); //Sleep between readings to allow interrupt handler to keep up.
     end;
     TestResponseButton.Enabled:=True;
end;

procedure TStartupTestForm.FormCreate(Sender: TObject);
begin
  //Default values
  SleepTimeSpinEdit.Value:=16; //Sleep time between sending commands

  //Clear displays
  CurrentTestLabeledEdit.Text:='';//Current test cycle counter
  ResultsMemo.Clear;              //Results
  ResultsMemo.Append('Reading (mpsas), Time (s), Frequency (Hz), Counts, Period (s)');
  rxuxProgressRing.Indeterminate:=False;

end;

procedure TStartupTestForm.ResultsMemoChange(Sender: TObject);
begin
  ResultsMemo.SelStart := MaxInt;
end;


procedure TStartupTestForm.rxuxStartButtonClick(Sender: TObject);
var
 piecesrx:TStringList;
 piecesux:TStringList;
 i:  integer = 0;
 Result: String = '';
 rxPeriodString: String;
 rxPeriod: Double;
 uxPeriodString: String;
 uxPeriod: Double;
 rxTemperatureString: String;
 rxTemperature: Double;
 uxTemperatureString: String;
 uxTemperature: Double;
 SleepTime: Integer;
begin
     rxuxStartButton.Enabled:=False;
     rxuxProgressRing.Indeterminate:=True;
     piecesrx := TStringList.Create;
     piecesrx.Delimiter := ',';
     piecesrx.StrictDelimiter := True; //Do not parse spaces

     piecesux := TStringList.Create;
     piecesux.Delimiter := ',';
     piecesux.StrictDelimiter := True; //Do not parse spaces

     BreakFlagrxux:=False;
     SleepTime:=SleepTimeSpinEdit.value;

     //gather a few readings
     while not BreakFlagrxux do begin

         //Get results at ~ same time.
         piecesrx.DelimitedText:=SendGet('rx',false,4000);
         piecesux.DelimitedText:=SendGet('ux',false,4000);

         rxPeriodString:=piecesrx.Strings[4];
         SetLength(rxPeriodString, Length(rxPeriodString) - 1);;
         rxPeriod:=strtofloat(rxPeriodString);
         rxText.Caption:=Format('%0.3fs',[rxPeriod]);
         rxPeriodProgressBar.Position:=Round(rxPeriod*rxuxscaleTrackBar.Position);

         uxPeriodString:=piecesux.Strings[4];
         SetLength(uxPeriodString, Length(uxPeriodString) - 1);;
         uxPeriod:=strtofloat(uxPeriodString);
         uxText.Caption:=Format('%0.3fs',[uxPeriod]);
         uxPeriodProgressBar.Position:=Round(uxPeriod*rxuxscaleTrackBar.Position);

         rxTemperatureString:=piecesrx.Strings[5];
         SetLength(rxTemperatureString, Length(rxTemperatureString) - 1);;
         rxTemperature:=strtofloat(rxTemperatureString);
         rxTemperatureText.Caption:=Format('%0.1fC',[rxTemperature]);
         rxTemperatureProgressBar.Position:=Round(rxTemperature);

         uxTemperatureString:=piecesux.Strings[5];
         SetLength(uxTemperatureString, Length(uxTemperatureString) - 1);;
         uxTemperature:=strtofloat(uxTemperatureString);
         uxTemperatureText.Caption:=Format('%0.1fC',[uxTemperature]);
         uxTemperatureProgressBar.Position:=Round(uxTemperature);

         sleep(10); //Sleep in ms between readings to allow interrupt handler to keep up, and properly update display.
     end;
     rxuxStartButton.Enabled:=True;
     rxuxProgressRing.Indeterminate:=False;

end;

procedure TStartupTestForm.rxuxStopButtonClick(Sender: TObject);
begin
  BreakFlagrxux:=True;   //Set break flag to for loop
end;

procedure TStartupTestForm.StatusMemoChange(Sender: TObject);
begin
  StatusMemo.SelStart := MaxInt;
end;

procedure TStartupTestForm.CancelButtonClick(Sender: TObject);
begin
  BreakFlag:=True;   //Set break flag to for loop
end;

initialization
  {$I startuptest.lrs}

end.

