unit mainunit; //{$mode objfpc}{$H+} {$mode delphi} {$H+} //{$define evalue} interface uses Classes, SysUtils, Forms, Controls, Graphics, Dialogs, CustomDrawnControls,Dos, Spin, StdCtrls, CustomDrawn_Common, ExtCtrls, TAGraph, TASeries, TATools, TAChartUtils, Types, Process, TADrawUtils, LCLType, TAChartAxisUtils, TACustomSource, TATypes, TAFuncSeries, math,utypes,umulfit,unlfit,ufft; type { Tmain } Tmain = class(TForm) ChartConstantLine1: TConstantLine; ChartConstantLine2: TConstantLine; FitButton2: TCDButton; FresnelButton: TCDButton; FitescButton: TCDButton; FitescButton2: TCDButton; FresnelescButton: TCDButton; FitIChartLineSeries: TLineSeries; FitIChartLineSeries1: TLineSeries; FresnelChartLineSeries: TLineSeries; ChartConstantLine3: TConstantLine; SelectDirectoryDialog: TSelectDirectoryDialog; FitButton: TCDButton; StepsizeButton: TCDButton; StepsizeEdit: TFloatSpinEdit; Timer1: TTimer; FresnelEdit: TFloatSpinEdit; xposLabel: TLabel; MarkerConstantLine: TConstantLine; OpenDialog: TOpenDialog; RedrawButton: TCDButton; IEdit: TEdit; IChartLineSeries: TLineSeries; IChart: TChart; ChartToolset: TChartToolset; ChartToolsetDataPointDragTool: TDataPointDragTool; ImaxEdit: TFloatSpinEdit; IminEdit: TFloatSpinEdit; getposButton: TCDButton; XzeroButton: TCDButton; SelectXButton: TCDButton; StartButton: TCDButton; SaveButton: TCDButton; XmaxEdit: TFloatSpinEdit; MoveEdit: TFloatSpinEdit; RateButton: TCDButton; RateEdit: TFloatSpinEdit; XminEdit: TFloatSpinEdit; XOut: TEdit; QuitButton: TCDButton; SaveDialog: TSaveDialog; SaveimageButton: TCDButton; Timer: TTimer; Status: TEdit; MoveButton: TCDButton; InitposButton: TCDButton; procedure ChartToolsetDataPointDragToolAfterMouseUp(ATool: TChartTool; APoint: TPoint); procedure ChartToolsetDataPointDragToolDrag(ASender: TDataPointDragTool; var AGraphPoint: TDoublePoint); procedure FresnelButtonClick(Sender: TObject); procedure FitButton2Click(Sender: TObject); procedure FitButtonClick(Sender: TObject); procedure FitescButton2Click(Sender: TObject); procedure FitescButtonClick(Sender: TObject); procedure FresnelEditKeyPress(Sender: TObject; var Key: char); procedure FresnelEditMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure FresnelescButtonClick(Sender: TObject); procedure getposButtonClick(Sender: TObject); procedure IChartAfterDraw(ASender: TChart; ADrawer: IChartDrawer); procedure MoveEditChange(Sender: TObject); procedure RateButtonClick(Sender: TObject); procedure RedrawButtonClick(Sender: TObject); procedure SelectXButtonClick(Sender: TObject); procedure StepsizeButtonClick(Sender: TObject); procedure StepsizeEditKeyPress(Sender: TObject; var Key: char); procedure StepsizeEditMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure Timer1Timer(Sender: TObject); procedure XmaxEditKeyPress(Sender: TObject; var Key: char); procedure XmaxEditMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure RateEditKeyPress(Sender: TObject; var Key: char); procedure RateEditMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure ImaxEditKeyPress(Sender: TObject; var Key: char); procedure ImaxEditMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure StartButtonClick(Sender: TObject); procedure IminEditKeyPress(Sender: TObject; var Key: char); procedure IminEditMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure SaveButtonClick(Sender: TObject); procedure FormClose(Sender: TObject; var CloseAction: TCloseAction); procedure FormCreate(Sender: TObject); procedure MoveEditKeyPress(Sender: TObject; var Key: char); procedure MoveEditMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure InitposButtonClick(Sender: TObject); procedure QuitButtonClick(Sender: TObject); procedure SaveimageButtonClick(Sender: TObject); procedure TimerTimer(Sender: TObject); procedure MoveButtonClick(Sender: TObject); procedure XminEditKeyPress(Sender: TObject; var Key: char); procedure XminEditMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure XzeroButtonClick(Sender: TObject); private public end; var main: Tmain; version:longint=1; mainpath:string; paramsavefile:string='version'; implementation uses comUSB, connect; {$R *.lfm} type data_t=record X:double; I:double; rate:double; status:double; mtime:double; end; { Tmain } const DATASIZE=20000; var savefile:String; {$ifdef LINUX} imagedirectory:string='measures/'; savedirectory:string='measures/'; bbs:string='/'; {$else} imagedirectory:string='measures\'; savedirectory:string='measures\'; bbs:string='\'; {$endif} curdata:data_t; timepointer:longint=0; hours: word; minutes: word; seconds: word; milliseconds: word; connected:boolean=false; running:boolean=false; datanum:longint=0; data_list:array[0..DATASIZE] of data_t; saverequest:boolean=false; imagenum:longint=0; n0,n1:longint; xmax,xmin:double; resetb:boolean=false; resetb2:boolean=false; notconnected:boolean=false; nn0,nn1:longint; fitxmax,fitImax,fitxmin,fitxmin2:double; XX : TMatrix; YY : TVector; XXn : TVector; B : TVector; V : TMatrix; fit1b,fit2b,fresnelb:boolean; fresnel_x,fresnel_y:array[0..1500] of double; fresnelnum:longint; fresnelmax:double; fresnelzero,fresnelI,fresnelscale,fresnelshift:double; fresnelhalf:double=0; fresnelx1,fresnelx2,fresnely1,fresnely2:double; fmaxx1:double=1.2200000000000000E+000; fmaxy1:double=1.3704219780253974E+000; fmaxx2:double=2.3399999999999999E+000; fmaxy2:double=1.1991665987199460E+000; {$ifdef evalue} evalueb:boolean=true; {$else} evalueb:boolean=false; {$endif} {$include edge.dat} procedure loadfresnel; var i:longint; r1,r2:double; f:text; begin {$I+} fresnelnum:=1000; fresnelmax:=0; for i:=1 to fresnelnum do begin fresnel_x[i]:=fresnelx[i]; fresnel_y[i]:=fresnely[i]; if fresnel_y[i]>fresnelmax then fresnelmax:=fresnel_y[i]; end; exit; i:=ioresult; assign(f, mainpath+bbs+'src/fresnel.dat'); reset(f); i:=0; repeat inc(i); read(f,fresnel_x[i]); read(f,r1); readln(f,r2); fresnel_y[i]:=((r1+0.5)*(r1+0.5)+(r2+0.5)*(r2+0.5))/2; until eof(f); fresnelnum:=i; i:=ioresult; close(f); //exit; writeln(mainpath+bbs+'src/edge.dat'); assign(f, mainpath+bbs+'src/edge.dat'); rewrite(f); writeln(f,'fresnelx:array[1..',fresnelnum,'] of double =('); for i:=1 to fresnelnum do begin write(f,fresnel_x[i]); if i<> fresnelnum then writeln(f,','); end; writeln(f,');'); writeln(f,'fresnely:array[1..',fresnelnum,'] of double =('); for i:=1 to fresnelnum do begin write(f,fresnel_y[i]); if i<> fresnelnum then writeln(f,','); end; writeln(f,');'); close(f); {$I-} end; function RegFunc(X : Float; B : TVector) : Float; var xx,xx1:double; yy:double; begin xx:=B[2]*(X-B[3]); xx1:=B[5]*(X-B[3]); if abs(xx)<1e-6 then xx:=1e-6; yy:=B[1]*sin(xx)*sin(xx)/xx/xx; if fit2b then yy:=yy*cos(xx1)*cos(xx1); result:=yy+B[4]; end; function RegFunc2(X : Float; B : TVector) : Float; var xx,xx1:double; yy:double; begin xx:=B[2]*(X-B[3]); xx1:=B[5]*(X-B[3]); if abs(xx)<1e-6 then xx:=1e-6; yy:=B[1]*sin(xx)*sin(xx)/xx/xx; result:=yy+B[4]; end; procedure DerivProc(X, Y : Float; B, D : TVector); var z:double; xx:double; begin if y<-1e-10 then exit; xx:=B[2]*(X-B[3]); if abs(xx)<1e-6 then xx:=1e-6; D[1]:=sin(xx)*sin(xx)/xx/xx; z:=2*B[1]*sin(xx)*cos(xx)/xx/xx-2*B[1]*sin(xx)*sin(xx)/xx/xx/xx; D[2]:=(X-B[3])*z; D[3]:=-B[2]*z; D[4]:=1; end; procedure DerivProc2(X, Y : Float; B, D : TVector); var z:double; xx,xx1,y1,y2,dy1,dy2:double; begin if y<-1e-10 then exit; xx:=B[2]*(X-B[3]); if abs(xx)<1e-6 then xx:=1e-6; xx1:=B[5]*(X-B[3]); y1:=sin(xx)*sin(xx)/xx/xx; y2:=cos(xx1)*cos(xx1); dy1:=2*sin(xx)*cos(xx)/xx/xx-2*sin(xx)*sin(xx)/xx/xx/xx; dy2:=-2*sin(xx1)*cos(xx1); D[1]:=y1*y2; D[2]:=(X-B[3])*dy1*y2; D[5]:=(X-B[3])*dy2*y1; D[3]:=-B[2]*(dy1*y2+y1*dy2); D[4]:=1; end; function get_instdir:string; var ss:string; begin ss:=paramstr(0); {$IFDEF LINUX} get_instdir:=copy(ss,1,pos('interference',ss)-1)+'interference/'; mainpath:=getuserdir; //+'interference/'; {$ELSE} mainpath:=copy(ss,1,pos('interference.exe',ss)-1); get_instdir:= mainpath; {$ENDIF} end; procedure initvalues; var s:string; res:longint; begin s:=get_instdir; savedirectory:=mainpath+savedirectory; Main.SaveDialog.InitialDir:=savedirectory; res:=readparam(mainpath+paramsavefile); main.FitButton.Caption:='Fit 1'; main.FitButton2.Caption:='Fit 2'; DimMatrix(XX, DATASIZE, 5); DimVector(YY, DATASIZE); DimVector(XXn, DATASIZE); DimVector(B, 5); DimMatrix(V, 5, 5); loadfresnel; end; procedure savefilep; var f:Text; i:longint; begin if not Main.SaveDialog.Execute then exit; savefile:=Main.SaveDialog.FileName; {$I-} ioresult; assign(f,savefile); rewrite(f); writeln(f,'Time X I Rate'); for i:=1 to datanum-1 do begin write(f,data_list[i].mtime:14:6); write(f,data_list[i].X:14:6); write(f,data_list[i].I:14:6); writeln(f,data_list[i].rate:14:6); end; close(f); saverequest:=false; end; procedure savequestion; begin if saverequest then begin if Application.MessageBox('Measurement is not saved! Save?', 'Save', MB_ICONQUESTION + MB_YESNO)=IDYES then savefilep; end; saverequest:=false; end; procedure Tmain.QuitButtonClick(Sender: TObject); begin savequestion; if evalueb then halt; sendUSB('START 0'); sendUSB('GETDATA 0'); sendUSB('HLD 0'); sendUSB('HRESET'); halt; end; procedure Tmain.SaveimageButtonClick(Sender: TObject); var year,month,day,dayw:word; hour,minute,second,sec100: word; Times,imagefile:String; begin {$I-} ioresult; getdate(year,month,day,dayw); gettime(hour,minute,second,sec100); times:=IntToStr(year)+'_'+IntToStr(month)+ '_'+IntToStr(day)+':'+IntToStr(hour)+'_'+IntToStr(minute)+'_'; imagefile:=imagedirectory+times+IntToStr(imagenum+1)+'_image.jpg'; inc(imagenum); ioresult; Main.IChart.SaveToFile(TJPEGImage,imagefile); {$I+} end; procedure Add_draw(x:data_t); begin if (x.X>=main.IChart.AxisList[1].Range.Min) and (x.X<=main.IChart.AxisList[1].Range.Max) and (x.I>=main.IChart.AxisList[0].Range.Min) and (x.I<=main.IChart.AxisList[0].Range.Max) then Main.IChartLineseries.AddXY(x.X,x.I); end; function gauss(x:double):double; begin gauss:=exp(-fresnelhalf*x*x); end; procedure redraw; var i:longint; x,y:double; begin main.IChartLineSeries.Pointer.Style:=psRectangle; if Main.FitIChartLineSeries.active then begin Main.FitIChartLineSeries.clear; main.IChartLineSeries.Pointer.Style:=psPoint; //main.IChartLineSeries.Pointer.VertSize:=2; for i:=nn0 to nn1 do begin x:=data_list[i].x; y:=RegFunc(x,B); if (x>=main.IChart.AxisList[1].Range.Min) and (x<=main.IChart.AxisList[1].Range.Max) and (y>=main.IChart.AxisList[0].Range.Min) and (y<=main.IChart.AxisList[0].Range.Max) then begin Main.FitIChartLineseries.AddXY(x,y); end; end; end; if Main.FitIChartLineSeries1.active then begin Main.FitIChartLineSeries1.clear; main.IChartLineSeries.Pointer.Style:=psPoint; for i:=nn0 to nn1 do begin x:=data_list[i].x; y:=RegFunc2(x,B); if (x>=main.IChart.AxisList[1].Range.Min) and (x<=main.IChart.AxisList[1].Range.Max) and (y>=main.IChart.AxisList[0].Range.Min) and (y<=main.IChart.AxisList[0].Range.Max) then begin Main.FitIChartLineseries1.AddXY(x,y); end; end; end; if Main.FresnelChartLineSeries.active then begin Main.FresnelChartLineseries.Clear; //main.IChartLineSeries.Pointer.Style:=psPoint; for i:=1 to fresnelnum-1 do begin x:=fresnelscale*fresnel_x[i]-fresnelshift; y:=fresnelI*fresnel_y[i]*gauss(x+fresnelshift); y:=y+fresnelzero; if (x>=main.IChart.AxisList[1].Range.Min) and (x<=main.IChart.AxisList[1].Range.Max) and (y>=main.IChart.AxisList[0].Range.Min) and (y<=main.IChart.AxisList[0].Range.Max) then begin Main.FresnelChartLineseries.AddXY(x,y); end; end; end; Main.IChartLineseries.clear; for i:=1 to datanum-1 do Add_draw(data_list[i]); end; procedure readUSB; var s:string; code:longint; i,j:longint; s1,s2,s3:string; d:double; integral:double; n:longint; nn:double; begin if evalueb then exit; if notconnected then exit; s:=getUSB(0); if s='nodata' then exit; if s<>'Data' then repeat s:=getUSB(500); //writeln(s); until s='End'; if s='End' then Begin exit; end; s:=getUSB(1000); val(s,d,code); if code=0 then curdata.X:=d; s:=getUSB(1000); val(s,d,code); if code=0 then curdata.I:=d; s:=getUSB(1000); val(s,d,code); if code=0 then curdata.rate:=d; s:=getUSB(1000); val(s,d,code); if code=0 then curdata.status:=d; //writeln(curdata.status); s:=getUSB(1000); val(s,d,code); if code=0 then curdata.mtime:=d; if running and (curdata.mtime>0) then begin inc(datanum); if datanum>=DATASIZE then datanum:=DATASIZE-1; data_list[datanum]:=curdata; Add_draw(data_list[datanum]); end; s:=getUSB(1000); main.Xout.caption:='X='+floatTostrF(curdata.X,ffFixed,10,3)+'mm'; main.Iedit.caption:='I='+floatTostrF(curdata.I,ffFixed,10,3)+'mV'; if curdata.status=0 then main.Status.caption:='Status off'; if curdata.status=1 then main.Status.caption:='Status on'; if curdata.status=2 then main.Status.caption:='Status -out'; if curdata.status=3 then main.Status.caption:='Status out'; end; procedure StartClock; begin GetTime(hours, minutes, seconds, milliseconds); end; function StopClock:word; var seconds_count : longint; c_hours: word; c_minutes: word; c_seconds: word; c_milliseconds: word; begin GetTime(c_hours, c_minutes, c_seconds, c_milliseconds); seconds_count := c_seconds - seconds + (c_minutes - minutes) * 60 + (c_hours - hours) * 3600; stopclock:=seconds_count; end; procedure initpos; begin if main.InitposButton.Color=clSilver then begin sendUSB('VEL 1'); sendUSB('SETZERO'); main.InitposButton.Color:=clRed; resetb:=true; end else begin main.InitposButton.Color:=clSilver; resetb:=false; sendUSB('HLD 1'); end; end; procedure Tmain.TimerTimer(Sender: TObject); begin if notconnected then exit; if not connected then begin Showmessage('Cannot connect to USB'); notconnected:=true; //halt; end; if connectform.visible then connectform.visible:=false; readUSB; if not running and (curdata.Status=0) then main.MoveButton.caption:='Stop'; if curdata.Status<>0 then main.MoveButton.caption:='Move [mm]'; if running and (abs(curdata.X-main.Moveedit.Value)<3.0*main.stepsizeedit.Value) then begin running:=false; main.Startbutton.caption:='Start'; sendUSB('START 0'); sendUSB('HLD 0'); end; if resetb then begin if curdata.Status=2 then begin resetb:=false; resetb2:=true; //main.InitposButton.Color:=clSilver; sendUSB('HLD 0'); sendUSB('MOV -85'); main.MoveButton.caption:='Stop'; end; end; if resetb2 then begin if curdata.X=-85.0 then begin main.MoveButton.caption:='Move [mm]'; sendUSB('HLD 0'); resetb2:=false; main.InitposButton.Color:=clSilver; end; end; end; procedure Tmain.MoveButtonClick(Sender: TObject); begin if running then exit; if resetb then exit; if curdata.status>0 then begin sendUSB('VEL '+floatTostrF(main.Rateedit.Value,ffFixed,10,3)); sendUSB('MOV '+floatTostrF(main.moveedit.Value,ffFixed,10,3)); main.MoveButton.caption:='Stop'; end else begin sendUSB('HLD 1'); main.MoveButton.caption:='Move [mm]'; resetb2:=false; end; end; procedure Tmain.FormCreate(Sender: TObject); begin initvalues; if evalueb then exit; if startUSB<0 then begin connected:=false; main.Timer.Enabled:=true; exit; end; connected:=true; main.Timer.Enabled:=true; sendUSB('START 0'); sendUSB('VEL 2'); sendUSB('GETDATA 1'); end; procedure Tmain.RateEditKeyPress(Sender: TObject; var Key: char); begin if running then exit; if resetb then exit; if byte(key) =13 then begin sendUSB('VEL '+floatTostrF(main.Rateedit.Value,ffFixed,10,3)); end; end; procedure Tmain.RateEditMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if running then exit; if resetb then exit; sendUSB('VEL '+floatTostrF(main.Rateedit.Value,ffFixed,10,3)); end; procedure Tmain.RateButtonClick(Sender: TObject); begin if resetb then exit; if running then exit; sendUSB('VEL '+floatTostrF(main.Rateedit.Value,ffFixed,10,3)); end; procedure Tmain.ChartToolsetDataPointDragToolDrag(ASender: TDataPointDragTool; var AGraphPoint: TDoublePoint); var y:double; begin y:= AGraphPoint.y; AGraphPoint.y:=y; if ASender <> ChartToolsetDataPointDragTool then exit; if not main.MarkerConstantLine.Active then exit; main.xposLabel.Caption:='(' +floattostrf(main.MarkerConstantLine.position,ffGeneral,5,0)+')'; end; procedure getfitinterval; var i:longint; begin if data_list[1].X < data_list[datanum-1].X then begin nn0:=1; while (data_list[nn0].X1) do begin dec(nn0); end; nn1:=datanum; while (data_list[nn1].X1) do begin dec(nn1); end; end; if nn0>nn1 then begin i:=nn0; nn0:=nn1; nn1:=i; end; end; function getpos:longint; var n:longint; begin if data_list[1].X < data_list[datanum-1].X then begin n:=1; while (data_list[n].X1) do begin dec(n); end; result:=n; //writeln(n); //writeln(datanum); end; end; Procedure fitp; var i,N,NF,nmax:longint; Maxiter:longint=1000; Tol:Float=1e-8; r:double; begin N:=nn1-nn0; //writeln(nn1); //writeln(nn0); nmax:=0; i:=1; if fit1b then repeat inc(nmax); until data_list[nmax+nn0].I>(fitImax+B[4]); //writeln(nmax); if fit1b then begin r:=Regfunc(data_list[nmax+nn0].X,B)-B[4]; //writeln(r); B[1]:=B[1]/r*fitImax; end; NF:=0; if data_list[1].X1e-6 then B[2]:=pi/abs(fitxmax-fitxmin) else B[2]:=1e6; B[1]:=fitImax; B[5]:=B[2]; fitp; redraw; end; end; procedure Tmain.FitButton2Click(Sender: TObject); var i:longint; d:double; begin if datanum=0 then exit; if running then exit; if fit1b then exit; if fresnelb then exit; if main.FitButton2.Caption='Fit 2' then begin redraw; main.FitButton.Caption:='Fit 1'; main.FitButton2.Color:=clsilver; main.FitescButton2.Visible:=false; fit1b:=false; fresnelb:=false; fit2b:=true; main.FitIChartLineSeries.clear; main.FitIChartLineSeries1.clear; main.FresnelChartLineSeries.clear; main.FitButton2.Caption:='Select interval'; main.ChartConstantLine1.Active:=false; main.ChartConstantLine2.Active:=false; main.ChartConstantLine3.Active:=false; main.FitIChartLineSeries.active:=false; main.FitIChartLineSeries1.active:=false; main.FresnelChartLineSeries.Active:=false; redraw; main.ChartConstantLine1.Active:=true; main.ChartConstantLine2.Active:=true; main.FitButton2.Color:=clRed; main.FitescButton2.Visible:=true; main.getposButton.Visible:=false; d:=main.IChart.AxisList[1].Range.Max-main.IChart.AxisList[1].Range.Min; main.ChartConstantLine1.Position:=main.IChart.AxisList[1].Range.Min+0.1*d; main.ChartConstantLine2.Position:=main.IChart.AxisList[1].Range.Max-0.1*d; exit; end; if main.FitButton2.Caption='Select interval' then begin getfitinterval; main.FitButton2.Caption:='Select maxpos'; main.ChartConstantLine1.Active:=true; main.ChartConstantLine2.Active:=false; main.ChartConstantLine3.Active:=false; main.ChartConstantLine1.Position:= 0.5*(main.IChart.AxisList[1].Range.Max+main.IChart.AxisList[1].Range.Min); exit; end; if main.FitButton2.Caption='Select maxpos' then begin fitxmax:=main.ChartConstantLine1.Position; i:=getpos; fitImax:=data_list[i].I; //writeln(fitImax); main.FitButton2.Caption:='Select min1'; main.ChartConstantLine1.Active:=true; main.ChartConstantLine2.Active:=false; main.ChartConstantLine3.Active:=false; main.ChartConstantLine1.Position:=main.ChartConstantLine1.Position+ 0.1*(main.IChart.AxisList[1].Range.Max+main.IChart.AxisList[1].Range.Min); exit; end; if main.FitButton2.Caption='Select min1' then begin fitxmin:=main.ChartConstantLine1.Position; B[4]:=data_list[nn0].I; Main.ChartConstantLine1.Position:=Main.ChartConstantLine1.Position+10; main.FitButton2.Caption:='Select min2'; exit; end; if main.FitButton2.Caption='Select min2' then begin fitxmin2:=main.ChartConstantLine1.Position; main.FitButton2.Caption:='Fit 2'; main.FitButton2.Color:=clsilver; main.ChartConstantLine1.Active:=false; main.ChartConstantLine2.Active:=false; main.ChartConstantLine3.Active:=false; B[3]:=fitxmax; if abs(fitxmax-fitxmin)>1e-6 then B[5]:=pi/abs(fitxmax-fitxmin)/2.0 else B[5]:=1e6; if abs(fitxmax-fitxmin2)>1e-6 then B[2]:=pi/abs(fitxmax-fitxmin2) else B[2]:=1e6; //writeln(B[4]); B[1]:=fitImax-B[4]; //writeln(B[1]); fitp; redraw; end; end; procedure Tmain.FresnelButtonClick(Sender: TObject); var d:double; i:longint; begin if datanum=0 then exit; if running then exit; if fit2b then exit; if fit1b then exit; if main.FresnelButton.Caption='Fresnel' then begin fresnelb:=true; main.FitIChartLineSeries.clear; main.FitIChartLineSeries1.clear; Main.FresnelChartLineSeries.clear; main.FresnelButton.Caption:='Select maxp1'; main.ChartConstantLine1.Active:=false; main.ChartConstantLine2.Active:=false; main.ChartConstantLine3.Active:=false; main.FitIChartLineSeries.active:=false; main.FitIChartLineSeries1.active:=false; main.FresnelChartLineSeries.Active:=false; redraw; main.ChartConstantLine1.Active:=true; main.FresnelButton.Color:=clRed; main.FresnelescButton.Visible:=true; main.getposButton.Visible:=false; d:=main.IChart.AxisList[1].Range.Max-main.IChart.AxisList[1].Range.Min; main.ChartConstantLine1.Position:=main.IChart.AxisList[1].Range.Min+0.5*d; main.ChartConstantLine2.Position:=main.IChart.AxisList[1].Range.Max-0.1*d; Main.FresnelChartLineSeries.active:=true; exit; end; if main.FresnelButton.Caption='Select maxp1' then begin fresnelx1:=main.ChartConstantLine1.Position; i:=getpos; fresnely1:=data_list[i].I; main.FresnelButton.Caption:='Select maxp2'; main.ChartConstantLine1.Active:=true; main.ChartConstantLine2.Active:=false; main.ChartConstantLine3.Active:=false; main.ChartConstantLine1.Position:=main.ChartConstantLine1.Position+ 0.1*(main.IChart.AxisList[1].Range.Max-main.IChart.AxisList[1].Range.Min); exit; end; if main.FresnelButton.Caption='Select maxp2' then begin fresnelx2:=main.ChartConstantLine1.Position; i:=getpos; fresnely2:=data_list[i].I; main.FresnelButton.Caption:='Select bg.'; main.ChartConstantLine1.Active:=true; main.ChartConstantLine2.Active:=false; main.ChartConstantLine3.Active:=false; main.ChartConstantLine1.Position:=main.ChartConstantLine1.Position- 0.2*(main.IChart.AxisList[1].Range.Max-main.IChart.AxisList[1].Range.Min); exit; end; if main.FresnelButton.Caption='Select bg.' then begin i:=getpos; fresnelzero:=data_list[i].I; main.FresnelButton.Caption:='Fresnel'; main.FresnelButton.Color:=clsilver; main.ChartConstantLine1.Active:=false; main.ChartConstantLine2.Active:=false; main.ChartConstantLine3.Active:=false; fresnelscale:=(fresnelx1-fresnelx2)/(fmaxx1-fmaxx2); fresnelI:=(fresnely1-fresnelzero)/fmaxy1; fresnelI:=(fresnelI+(fresnely2-fresnelzero)/fmaxy2)/2; fresnelshift:=fresnelscale*fmaxx1-fresnelx1; main.FresnelEdit.Visible:=true; redraw; exit; end; if main.FresnelButton.Caption='Select hw.' then begin main.FresnelButton.Caption:='Fresnel'; main.FresnelButton.Color:=clsilver; main.FresnelEdit.Visible:=false; redraw; end; end; procedure Tmain.FitescButton2Click(Sender: TObject); begin main.ChartConstantLine1.Active:=false; main.ChartConstantLine2.Active:=false; main.ChartConstantLine3.Active:=false; main.MarkerConstantLine.Active:=false; main.FitIChartLineSeries.active:=false; main.FitIChartLineSeries1.active:=false; main.FresnelChartLineSeries.active:=false; main.FitescButton2.Visible:=false; main.getposButton.Visible:=true; main.FitButton2.Caption:='Fit 2'; main.FitButton2.Color:=clsilver; fit2b:=false; redraw; end; procedure Tmain.FitescButtonClick(Sender: TObject); begin main.ChartConstantLine1.Active:=false; main.ChartConstantLine2.Active:=false; main.ChartConstantLine3.Active:=false; main.MarkerConstantLine.Active:=false; main.FitIChartLineSeries.active:=false; main.FitIChartLineSeries1.active:=false; main.FresnelChartLineSeries.active:=false; main.FitescButton.Visible:=false; main.getposButton.Visible:=true; main.FitButton.Caption:='Fit 1'; main.FitButton.Color:=clsilver; fit1b:=false; redraw; end; procedure Tmain.FresnelEditKeyPress(Sender: TObject; var Key: char); begin if running then exit; if resetb then exit; if byte(key) =13 then begin fresnelhalf:=main.FresnelEdit.value; redraw; end; end; procedure Tmain.FresnelEditMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin fresnelhalf:=main.FresnelEdit.value; redraw; end; procedure Tmain.FresnelescButtonClick(Sender: TObject); begin main.ChartConstantLine1.Active:=false; main.ChartConstantLine2.Active:=false; main.ChartConstantLine3.Active:=false; main.MarkerConstantLine.Active:=false; main.FitIChartLineSeries.active:=false; main.FitIChartLineSeries1.active:=false; main.FresnelChartLineSeries.active:=false; main.FresnelescButton.Visible:=false; main.getposButton.Visible:=true; main.FresnelButton.Caption:='Fresnel'; main.FresnelButton.Color:=clsilver; main.FresnelEdit.Visible:=false; fit1b:=false; redraw; end; procedure Tmain.getposButtonClick(Sender: TObject); begin main.MarkerConstantLine.Active:=not main.MarkerConstantLine.Active; if main.MarkerConstantLine.Active then begin main.xposLabel.Visible:=true; main.MarkerConstantLine.Active:=true; end else begin main.xposLabel.Visible:=false; main.MarkerConstantLine.Active:=false; end; end; procedure Tmain.IChartAfterDraw(ASender: TChart; ADrawer: IChartDrawer); var x0,y0,dy,x,y:longint; scale:longint=1; s,sk1,sk2,s1,s2:string; I0,k1,k2,L1,L2:double; dk1,dk2,dL1,dL2:double; begin if not Main.FitIChartLineSeries.Active then exit; //fit2b:=true; if B[2]>1e-6 then begin dk1:=sqrt(abs(V[2,2])); if dk1=0 then dk1:=0.01*B[2]; L1:=pi/B[2]; dL1:=pi/B[2]/B[2]*dk1; end else begin L1:=1.0; dL1:=0; end; if B[5]>1e-6 then begin dk2:=sqrt(abs(V[5,5])); if dk2=0 then dk2:=0.01*B[5]; L2:=pi/B[5]; dL2:=pi/B[5]/B[5]*dk2; end else begin L2:=1.0; dL2:=0; end; I0:=B[1]; x0:=scale*70;y0:=scale*5+10; x:=x0;y:=y0; dy:=round(1.5*ADrawer.TextExtent('A',tfhtml).y); ADrawer.SetFont(IChart.Title.Font); sk1:='k1(x-x0)'; sk2:='k2(x-x0)'; s1:='I(x)=I0sin 2 ('+sk1+')/('+sk1+')2'; if fit2b then s1:=s1+'cos 2 ('+sk2+')'; s:=s1; ADrawer.TextOut.Pos(x,y).TextFormat(tfhtml).Text(s).Done; x:=x+ADrawer.TextExtent(s,tfhtml).x; x:=x0; y:=y+dy; s:='I0='+floattostrf(I0,ffGeneral,3,0); s:=s+', k1='+floattostrf(B[2],ffGeneral,3,0); ADrawer.TextOut.Pos(x,y).TextFormat(tfhtml).Text(s).Done; x:=x+ADrawer.TextExtent(s,tfhtml).x; s:='±'; ADrawer.TextOut.Pos(x,y).TextFormat(tfhtml).Text(s).Done; x:=x+ADrawer.TextExtent(s,tfhtml).x; s:=floattostrf(dk1,ffGeneral,2,0)+' mm-1, '; ADrawer.TextOut.Pos(x,y).TextFormat(tfhtml).Text(s).Done; x:=x+ADrawer.TextExtent(s,tfhtml).x; s:=' L1='+floattostrf(L1,ffGeneral,3,0); ADrawer.TextOut.Pos(x,y).TextFormat(tfhtml).Text(s).Done; x:=x+ADrawer.TextExtent(s,tfhtml).x; s:='±'; ADrawer.TextOut.Pos(x,y).TextFormat(tfhtml).Text(s).Done; x:=x+ADrawer.TextExtent(s,tfhtml).x; s:=floattostrf(dL1,ffGeneral,2,0)+' mm'; ADrawer.TextOut.Pos(x,y).TextFormat(tfhtml).Text(s).Done; if fit2b then begin x:=x0; y:=y+dy; s:='k2='+floattostrf(B[5],ffGeneral,3,0); ADrawer.TextOut.Pos(x,y).TextFormat(tfhtml).Text(s).Done; x:=x+ADrawer.TextExtent(s,tfhtml).x; s:='±'; ADrawer.TextOut.Pos(x,y).TextFormat(tfhtml).Text(s).Done; x:=x+ADrawer.TextExtent(s,tfhtml).x; s:=floattostrf(dk2,ffGeneral,2,0)+' mm-1, '; ADrawer.TextOut.Pos(x,y).TextFormat(tfhtml).Text(s).Done; x:=x+ADrawer.TextExtent(s,tfhtml).x; s:=' L2='+floattostrf(L2,ffGeneral,3,0); ADrawer.TextOut.Pos(x,y).TextFormat(tfhtml).Text(s).Done; x:=x+ADrawer.TextExtent(s,tfhtml).x; s:='±'; ADrawer.TextOut.Pos(x,y).TextFormat(tfhtml).Text(s).Done; x:=x+ADrawer.TextExtent(s,tfhtml).x; s:=floattostrf(dL2,ffGeneral,2,0)+' mm'; ADrawer.TextOut.Pos(x,y).TextFormat(tfhtml).Text(s).Done; end; x:=x0; y:=y+dy; s:='x0='+floattostrf(B[3],ffGeneral,3,0); ADrawer.TextOut.Pos(x,y).TextFormat(tfhtml).Text(s).Done; x:=x+ADrawer.TextExtent(s,tfhtml).x; s:='±'; ADrawer.TextOut.Pos(x,y).TextFormat(tfhtml).Text(s).Done; x:=x+ADrawer.TextExtent(s,tfhtml).x; x:=x+ADrawer.TextExtent(s,tfhtml).x; s:=floattostrf(sqrt(abs(V[3,3])),ffGeneral,2,0)+' mm'; ADrawer.TextOut.Pos(x,y).TextFormat(tfhtml).Text(s).Done; end; procedure Tmain.MoveEditChange(Sender: TObject); begin end; procedure getinterval; var i:longint; begin n0:=1; while (data_list[n0].Xn1 then begin i:=n0; n0:=n1; n1:=i; end; end; procedure loaddraw; var p:text; i:longint; ymax:double=-1e6; d:double; var s:string; begin {$I-} ioresult; assign(p,Main.OpenDialog.FileName); reset(p); readln(p,s); i:=0; repeat inc(i); read(p,data_list[i].mtime); read(p,data_list[i].X); readln(p,data_list[i].I); readln(p,data_list[i].rate); if ymaxxmax then begin d:=xmin; xmin:=xmax; xmax:=d; end; main.IChart.AxisList[1].Range.Max:=xmax; main.IChart.AxisList[1].Range.Min:=xmin; main.IChartLineSeries.Clear; main.XmaxEdit.Value:=xmax; main.XminEdit.Value:=xmin; main.ImaxEdit.Value:=ymax; main.IminEdit.Value:=0; for i:=1 to datanum-1 do main.IChartLineSeries.AddXY(data_list[i].X,data_list[i].I); if evalueb then begin curdata:=data_list[datanum-1]; //main.Tempheater.caption:='T heater='+floatTostrF(curdata.Tc,ffFixed,10,3)+' °C'; end; {$I+} end; procedure Tmain.RedrawButtonClick(Sender: TObject); begin if running then exit; savequestion; Main.OpenDialog.InitialDir:=savedirectory; Main.OpenDialog.Execute; if Main.OpenDialog.Filename = '' then exit; main.ChartConstantLine1.Active:=false; main.ChartConstantLine2.Active:=false; main.ChartConstantLine3.Active:=false; main.MarkerConstantLine.Active:=false; main.FitIChartLineSeries.active:=false; main.FitIChartLineSeries1.active:=false; main.FresnelChartLineSeries.Active:=false; main.FitescButton.Visible:=false;; main.FitButton.Caption:='Fit 1'; main.FitButton.Color:=clsilver; main.FitescButton.Visible:=false; main.FitButton2.Caption:='Fit 2'; main.FitButton2.Color:=clsilver; main.FitescButton2.Visible:=false; main.FresnelButton.Caption:='Fresnel'; main.FresnelButton.Color:=clsilver; main.FresnelescButton.Visible:=false; main.getposButton.Visible:=true; fit1b:=false; fit2b:=false; fresnelb:=false; loaddraw; end; procedure Tmain.SelectXButtonClick(Sender: TObject); var x,x1,x2:double; i:longint; begin if main.SelectXButton.Caption='Select X' then begin main.SelectXButton.Caption:='Select Interval'; main.SelectXButton.Color:=clRed; main.ChartConstantLine1.Active:=true; main.ChartConstantLine2.Active:=true; main.ChartConstantLine3.Active:=false; main.MarkerConstantLine.Active:=false; main.ChartConstantLine1.Position:= main.IChart.AxisList[1].Range.Min+ 0.25*(main.IChart.AxisList[1].Range.Max-main.IChart.AxisList[1].Range.Min); main.ChartConstantLine2.Position:= main.IChart.AxisList[1].Range.Max- 0.25*(main.IChart.AxisList[1].Range.Max-main.IChart.AxisList[1].Range.Min); end else begin x1:=main.ChartConstantLine1.position; x2:=main.ChartConstantLine2.position; if x1>x2 then begin x:=x1; x1:=x2; x2:=x; end; main.SelectXButton.Caption:='Select X'; main.SelectXButton.Color:=clSilver; main.ChartConstantLine1.Active:=false; main.ChartConstantLine2.Active:=false; main.ChartConstantLine3.Active:=false; main.MarkerConstantLine.Active:=false; getinterval; IChartLineSeries.clear; main.Xminedit.value:=x1; main.Xmaxedit.value:=x2; main.IChart.AxisList[1].Range.Max:=x2; main.IChart.AxisList[1].Range.Min:=x1; for i:=1 to datanum do add_draw(data_list[i]); end; end; procedure Tmain.StepsizeButtonClick(Sender: TObject); begin if resetb then exit; if running then exit; sendUSB('STEPSIZE '+floatTostrF(main.Stepsizeedit.Value,ffFixed,10,3)); end; procedure Tmain.StepsizeEditKeyPress(Sender: TObject; var Key: char); begin if running then exit; if resetb then exit; if byte(key) =13 then begin sendUSB('STEPSIZE '+floatTostrF(main.Stepsizeedit.Value,ffFixed,10,3)); end; end; procedure Tmain.StepsizeEditMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if running then exit; if resetb then exit; sendUSB('STEPSIZE '+floatTostrF(main.Stepsizeedit.Value,ffFixed,10,3)); end; procedure Tmain.Timer1Timer(Sender: TObject); begin Timer1.Enabled:=false; if evalueb then begin connectform.visible:=false; initposbutton.visible:=false; xzerobutton.visible:=false; ratebutton.visible:=false; movebutton.visible:=false; startbutton.visible:=false; stepsizebutton.visible:=false; rateEdit.visible:=false; moveEdit.visible:=false; stepsizeEdit.visible:=false; IEdit.visible:=false; xout.visible:=false; status.visible:=false; redrawbutton.Top:=xzerobutton.Top; redrawbutton.Left:=xzerobutton.Left; fitbutton.Left:=xzerobutton.Left; fitbutton2.Left:=xzerobutton.Left; fresnelbutton.Left:=xzerobutton.Left; getposbutton.Left:=xzerobutton.Left; fitbutton.Top:=xzerobutton.Top+55; fitbutton2.Top:=xzerobutton.Top+2*55; fresnelbutton.Top:=xzerobutton.Top+3*55; getposbutton.Top:=xzerobutton.Top+4*55; savebutton.Top:=xzerobutton.Top+5*55; saveimagebutton.Top:=xzerobutton.Top+6*55; end; Main.SelectDirectoryDialog.InitialDir:=mainpath+'measures'+bbs; Main.SelectDirectoryDialog.Execute; savedirectory:=Main.SelectDirectoryDialog.FileName+bbs; imagedirectory:=Main.SelectDirectoryDialog.FileName+bbs; //writeln(savedirectory); end; procedure Tmain.ChartToolsetDataPointDragToolAfterMouseUp(ATool: TChartTool; APoint: TPoint); begin end; procedure setXmax; var y0,y1:double; begin main.IChartLineSeries.Clear; main.IChart.AxisList[1].Range.Max:=main.Xmaxedit.value; main.IChart.AxisList[1].Range.Min:=main.Xminedit.value; end; procedure setImax; var y0,y1:double; begin main.IChartLineSeries.Clear; if main.Imaxedit.value<=main.Iminedit.value then main.Imaxedit.value:=main.Iminedit.value+0.001; main.IChart.AxisList[0].Range.Min:=main.Iminedit.value; main.IChart.AxisList[0].Range.Max:=main.Imaxedit.value; y0:=main.IChart.AxisList[0].Range.Min; y1:=main.IChart.AxisList[0].Range.Max; end; procedure setImin; var y0,y1:double; begin main.IChartLineSeries.Clear; if main.Iminedit.value>=main.Imaxedit.value then main.Iminedit.value:=main.Imaxedit.value-0.001; main.IChart.AxisList[0].Range.Min:=main.Iminedit.value; main.IChart.AxisList[0].Range.Max:=main.Imaxedit.value; y0:=main.IChart.AxisList[0].Range.Min; y1:=main.IChart.AxisList[0].Range.Max; end; procedure Tmain.ImaxEditKeyPress(Sender: TObject; var Key: char); begin if byte(key) =13 then begin setImax; redraw; end; end; procedure Tmain.ImaxEditMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if main.IChart.AxisList[0].Range.Max=main.Imaxedit.value then exit; setImax; redraw; end; procedure Tmain.IminEditKeyPress(Sender: TObject; var Key: char); begin if byte(key) =13 then begin setImin; redraw end; end; procedure Tmain.IminEditMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if main.IChart.AxisList[0].Range.Min=main.Iminedit.value then exit; setImin; redraw; end; procedure Tmain.XmaxEditKeyPress(Sender: TObject; var Key: char); begin if byte(key) =13 then begin setXmax; redraw; end; end; procedure Tmain.XmaxEditMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if main.IChart.AxisList[1].Range.Max=main.Xmaxedit.value then exit; setXmax; redraw; end; procedure Tmain.XminEditKeyPress(Sender: TObject; var Key: char); begin if byte(key) =13 then begin setXmax; redraw; end; end; procedure Tmain.XminEditMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if main.IChart.AxisList[1].Range.Min=main.Xminedit.value then exit; setXmax; redraw; end; procedure Tmain.XzeroButtonClick(Sender: TObject); begin if resetb then exit; if running then exit; sendUSB('SPS 0'); end; procedure Tmain.StartButtonClick(Sender: TObject); var i:longint=0; y0,y1:double; step,vel:double; begin if resetb then exit; if resetb2 then exit; if running then begin running:=false; main.Startbutton.caption:='Start'; sendUSB('START 0'); sendUSB('HLD 0'); end else begin if main.MoveButton.caption='Stop' then begin sendUSB('HLD 1'); main.MoveButton.caption:='Move [mm]'; end; savequestion; running:=true; main.Startbutton.caption:='Stop'; IChartLineSeries.Active:=true; IChartLineSeries.clear; main.ChartConstantLine1.Active:=false; main.ChartConstantLine2.Active:=false; main.ChartConstantLine3.Active:=false; main.MarkerConstantLine.Active:=false; main.FitIChartLineSeries.active:=false; main.FitIChartLineSeries1.active:=false; main.FresnelChartLineSeries.Active:=false; main.FitescButton.Visible:=false;; main.FitButton.Caption:='Fit 1'; main.FitButton.Color:=clsilver; main.FitescButton.Visible:=false; main.FitButton2.Caption:='Fit 2'; main.FitButton2.Color:=clsilver; main.FitescButton2.Visible:=false; main.getposButton.Visible:=true; fit1b:=false; fit2b:=false; datanum:=0; vel:=main.Rateedit.Value; step:=main.Stepsizeedit.Value; if vel*step<0.1 then vel:=10*step; sendUSB('VEL '+floatTostrF(vel,ffFixed,10,3)); sendUSB('STEPSIZE '+floatTostrF(step,ffFixed,10,3)); sendUSB('START 1'); sendUSB('MOV '+floatTostrF(main.moveedit.Value,ffFixed,10,3)); //if curdata.X