unit MainUnit; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Buttons, StdCtrls, ExtCtrls, ImgList, ComCtrls; type TForm1 = class(TForm) CountTimer: TTimer; InputLabel: TLabel; SinkLabel: TLabel; DIOImages: TImageList; Key: TGroupBox; Image1: TImage; Label2: TLabel; Image2: TImage; Label4: TLabel; Image3: TImage; Label5: TLabel; Label6: TLabel; Image4: TImage; Label7: TLabel; Panel1: TPanel; ComGroup: TGroupBox; Label8: TLabel; PortLabel: TLabel; PortEdit: TEdit; BaudCombo: TComboBox; ConnectButton: TButton; BaudStatic: TStaticText; CommandGroup: TGroupBox; PodNumber: TLabel; Status: TStatusBar; HelloButton: TButton; VersionButton: TButton; ResendButton: TButton; DetectGroup: TGroupBox; DetectLabel: TLabel; DetectPB: TButton; EndTest: TButton; SettingsGroup: TGroupBox; Label10: TLabel; PODBox: TEdit; Label9: TLabel; PODButton: TButton; Label11: TLabel; BaudBox: TComboBox; BaudRateButton: TButton; AquireButton: TButton; Image5: TImage; Image6: TImage; Label12: TLabel; Label13: TLabel; DirectionLabel: TLabel; SaveDialog: TSaveDialog; IORich: TRichEdit; SendEdit: TEdit; SendButton: TButton; SinkAllButton: TButton; DirectionAllButton: TButton; procedure FormCreate(Sender: TObject); procedure EnableImageMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure EnableImageMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); procedure EnableImageMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure FormDestroy(Sender: TObject); procedure ConnectButtonClick(Sender: TObject); procedure BaudComboChange(Sender: TObject); procedure HelloButtonClick(Sender: TObject); procedure VersionButtonClick(Sender: TObject); procedure ResendButtonClick(Sender: TObject); procedure DetectPBClick(Sender: TObject); procedure EndTestClick(Sender: TObject); procedure PODButtonClick(Sender: TObject); procedure BaudRateButtonClick(Sender: TObject); procedure AquireButtonClick(Sender: TObject); procedure CountTimerTimer(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure SendButtonClick(Sender: TObject); procedure SinkAllButtonClick(Sender: TObject); procedure DirectionAllButtonClick(Sender: TObject); private procedure ReadCom(Data: string); procedure ChangeBaud; procedure StopAquireClick(Sender: TObject); procedure DirectionImageMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure DirectionImageMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); procedure DirectionImageMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation uses InterCOMs; const CurrentBaud: array[0..6] of String = ('1200','2400','4800','9600','14400','19200','28800'); {$R *.DFM} {Global variables - Variables that stay constant between procedures } var LevelBMP: array[0..2] of TBitmap; EnableBMP: array[0..2] of TBitmap; DirectionBMP: array[0..2] of TBitmap; DisableBMP: array[0..2] of TBitmap; InputImage: array[0..23] of TImage; EnableImage: array[0..23] of TImage; DirectionImage: array[0..23] of TImage; StuffedMemo: TStringList; Commo: TInterCom; LastStr, GlobalComValue: String; OutputToRich, PodReset, LoopCont : Boolean; CounterTest, TestForDisconnect,POD, BaudIndex : Integer; procedure GreyMapCanvas(Who: TCanvas; MX, MY: Integer); var X, Y: Integer; begin { Changes the button colors to match those of the user selected colors } for Y := 0 to MY do for X := 0 to MX do case Who.Pixels[X, Y] of $808080: Who.Pixels[X, Y] := clBtnShadow; $C0C0C0: Who.Pixels[X, Y] := clBtnFace; $FFFFFF: Who.Pixels[X, Y] := clBtnHighlight; end ; end; procedure TForm1.FormCreate(Sender: TObject); var I: Integer; begin //Begin FormCreate { Set all the global variables } StuffedMemo := TStringList.Create; LastStr := ''; TestForDisconnect := 0; PodReset := True; OutputToRich := False; BaudCombo.ItemIndex := 3; {Create and initialize Commo variable which is used to interact with the com card } Commo := TInterCom.Create(self); Commo.Parent := Self; Commo.ReadAsLines := True; Commo.OnReadCom := ReadCom; {Assign pictures to flow control buttons } Icon.Assign(Application.Icon); for I := 0 to 2 do begin //Begin creating lists EnableBMP[I] := TBitmap.Create; LevelBMP[I] := TBitmap.Create; DirectionBMP[I] := TBitmap.Create; DisableBMP[I] := TBitmap.Create; DIOImages.GetBitmap(I, EnableBMP[I]); DIOImages.GetBitmap(I + 3, LevelBMP[I]); DIOImages.GetBitmap(I + 6, DirectionBMP[I]); DIOImages.GetBitmap(I + 9, DisableBMP[I]); GreyMapCanvas(EnableBMP[I].Canvas, 19, 19); GreyMapCanvas(LevelBMP[I].Canvas, 19, 19); GreyMapCanvas(DirectionBMP[I].Canvas, 19, 19); GreyMapCanvas(DisableBMP[I].Canvas, 19, 19); Image1.Picture.Assign(LevelBMP[1]); Image2.Picture.Assign(LevelBMP[0]); Image3.Picture.Assign(EnableBMP[0]); Image4.Picture.Assign(EnableBMP[2]); Image5.Picture.Assign(DirectionBMP[1]); Image6.Picture.Assign(DirectionBMP[2]); end; // End creating lists for I := 0 to 23 do begin // Begin loop to create all 24 buttons/labels { Create labels '0' to '23' for all 24 bits } with TLabel.Create(Self) do begin Parent := Self; AutoSize := False; Left := 616 - 24 * I; Top := InputLabel.Top - 16; Width := 20; Height := 14; Caption := IntToStr(I); Alignment := taCenter; Layout := tlBottom; end; { Create 24 input buttons } InputImage[I] := TImage.Create(Self); with InputImage[I] do begin Parent := Self; AutoSize := True; Left := 616 - 24 * I; Top := InputLabel.Top; Picture.Assign(DisableBMP[2]); end; {Create 24 sink control buttons } EnableImage[I] := TImage.Create(Self); with EnableImage[I] do begin Tag := I; Parent := Self; AutoSize := True; Left := 616 - 24 * I; Top := SinkLabel.Top; Picture.Assign(DisableBMP[0]); Enabled := False; OnMouseDown := EnableImageMouseDown; OnMouseMove := EnableImageMouseMove; OnMouseUp := EnableImageMouseUp; end; {Create 24 direction control buttons } DirectionImage[I] := TImage.Create(Self); with DirectionImage[I] do begin Tag := I; Parent := Self; AutoSize := True; Left := 616 - 24 * I; Top := DirectionLabel.Top; Picture.Assign(DisableBMP[1]); Enabled := False; OnMouseDown := DirectionImageMouseDown; OnMouseMove := DirectionImageMouseMove; OnMouseUp := DirectionImageMouseUp; end; end; // End loop to create all 24 buttons/labels end; //End FormCreate procedure TForm1.EnableImageMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var I: Integer; begin //Begin EnableImageMouseDown if Button <> mbLeft then Exit; I := (Sender as TImage).Tag and 31; EnableImage[I].Picture.Assign(EnableBMP[1]); EnableImage[I].Tag := EnableImage[I].Tag or 64; end; //End EnableImageMouseDown procedure TForm1.EnableImageMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); var I: Integer; begin //Begin EnableImageMouseMove if not (ssLeft in Shift) then Exit; I := (Sender as TImage).Tag and 31; if (X >= 0) and (Y >= 0) and (X < EnableImage[I].Width) and (Y < EnableImage[I].Height) then begin if EnableImage[I].Tag and 64 = 0 then begin EnableImage[I].Picture.Assign(EnableBMP[1]); EnableImage[I].Tag := EnableImage[I].Tag or 64; end; end else begin if EnableImage[I].Tag and 64 <> 0 then begin if EnableImage[I].Tag and 32 <> 0 then begin EnableImage[I].Picture.Assign(EnableBMP[2]); end else begin EnableImage[I].Picture.Assign(EnableBMP[0]); end; EnableImage[I].Tag := EnableImage[I].Tag and not 64; end; end; end; //End EnableImageMouseMove procedure TForm1.EnableImageMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var I, count, O1, O2, O3: Integer; Passed : Boolean; begin //Begin EnableImageMouseUp if Button <> mbLeft then Exit; I := (Sender as TImage).Tag and 31; if EnableImage[I].Tag and 64 <> 0 then EnableImage[I].Tag := EnableImage[I].Tag xor 32; if EnableImage[I].Tag and 32 <> 0 then begin EnableImage[I].Picture.Assign(EnableBMP[2]); end else begin EnableImage[I].Picture.Assign(EnableBMP[0]); end; {Initialize variables for repeat loop} CountTimer.Enabled := False; Passed := False; TestForDisconnect := 0; repeat //Begin loop to set Sinking or Not Sinking O1 := 0; O2 := 0; O3 := 0; {Use Image tag's to tell if bit is set to sinking or not} for Count := 0 to 7 do if EnableImage[Count].Tag and 32 <> 0 then O1 := O1 or (1 shl count); for Count := 0 to 7 do if EnableImage[Count + 8].Tag and 32 <> 0 then O2 := O2 or (1 shl count); for Count := 0 to 7 do if EnableImage[Count + 16].Tag and 32 <> 0 then O3 := O3 or (1 shl count); GlobalComValue := 'Test'; // GlobalComValue gets set to nonsense value {Write value to Pod through the com port} Commo.WriteComLine('O' + IntToHex(O3, 2) + IntToHex(O2, 2) + IntToHex(O1, 2)); count := GetTickCount + 500; {Wait for pod to receive and return values} Repeat Application.ProcessMessages; until (GlobalComValue = '') or (GetTickCount > Count); {If pod received and understood command then GlobalComValue will equal '' clearing the nonsense value earlier set} if GlobalComValue = '' then Passed := True //End loop else Inc(TestForDisconnect); //Else inc error count if TestForDisconnect > 5 then begin //If Error count > 3 then end loop and warn user CountTimer.Enabled := False; StuffedMemo.SaveToFile(SaveDialog.Filename); Application.MessageBox('Connection with Pod lost. Please check all connections and power then try again.', 'Lost connection!', MB_OK); ConnectButtonClick(Self); Exit; end; until Passed; //End loop to set Sinking or Not Sinking if AquireButton.Caption = 'Stop aquiring data' then CountTimer.Enabled := True; end; //End EnableImageMouseUp procedure TForm1.DirectionImageMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var I: Integer; begin //Begin DirectionImageMouseDown if Button <> mbLeft then Exit; I := (Sender as TImage).Tag and 31; DirectionImage[I].Picture.Assign(DirectionBMP[0]); DirectionImage[I].Tag := DirectionImage[I].Tag or 64; end; //End DirectionImageMouseDown procedure TForm1.DirectionImageMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); var I: Integer; begin //Begin DirectionImageMouseMove if not (ssLeft in Shift) then Exit; I := (Sender as TImage).Tag and 31; if (X >= 0) and (Y >= 0) and (X < DirectionImage[I].Width) and (Y < DirectionImage[I].Height) then begin if DirectionImage[I].Tag and 64 = 0 then begin DirectionImage[I].Picture.Assign(DirectionBMP[0]); DirectionImage[I].Tag := DirectionImage[I].Tag or 64; end; end else begin if DirectionImage[I].Tag and 64 <> 0 then begin if DirectionImage[I].Tag and 32 <> 0 then begin DirectionImage[I].Picture.Assign(DirectionBMP[2]); end else begin DirectionImage[I].Picture.Assign(DirectionBMP[1]); end; DirectionImage[I].Tag := DirectionImage[I].Tag and not 64; end; end; end; //End DirectionImageMouseMove procedure TForm1.DirectionImageMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var I, count, M1, M2, M3: Integer; Passed1, Passed2, Passed3 : Boolean; begin //Begin DirectionImageMouseUp if Button <> mbLeft then Exit; I := (Sender as TImage).Tag and 31; if DirectionImage[I].Tag and 64 <> 0 then DirectionImage[I].Tag := DirectionImage[I].Tag xor 32; if DirectionImage[I].Tag and 32 <> 0 then begin DirectionImage[I].Picture.Assign(DirectionBMP[2]); end else begin DirectionImage[I].Picture.Assign(DirectionBMP[1]); end; {Initialize variables for repeat loop} CountTimer.Enabled := False; Passed1 := False; Passed2 := False; Passed3 := False; TestForDisconnect := 0; repeat //Begin loop to set bits as inputs or outputs M1 := 0; M2 := 0; M3 := 0; if not(Passed1) then begin //Begin Test bits 0-7 {Test image tags to see if bit is set to input or output} for Count := 0 to 7 do if DirectionImage[Count].Tag and 32 <> 0 then M1 := M1 or (1 shl count); GlobalComValue := 'Test'; // GlobalComValue gets set to nonsense value Commo.WriteComLine('Ml' + IntToHex(M1,2)); //Write to pod count := GetTickCount + 500; {Wait for pod to receive and return data or for wait to expire} Repeat Application.ProcessMessages; until (GlobalComValue = '') or (GetTickCount > Count); if GlobalComValue = '' then Passed1 := True //If pod received and returned valid data then continue else Inc(TestForDisconnect); //Else, inc error check if TestForDisconnect > 5 then begin CountTimer.Enabled := False; StuffedMemo.SaveToFile(SaveDialog.Filename); Application.MessageBox('Connection with Pod lost. Please check all connections and power then try again.', 'Lost connection!', MB_OK); ConnectButtonClick(Self); Exit; end; end; //End Test bits 0-7 if not(Passed2) then begin //Begin Test bits 8-15 {Test image tags to see if bit is set to input or output} for Count := 0 to 7 do if DirectionImage[Count + 8].Tag and 32 <> 0 then M2 := M2 or (1 shl count); GlobalComValue := 'Test'; // GlobalComValue gets set to nonsense value Commo.WriteComLine('Mm' + IntToHex(M2,2)); //Write to pod count := GetTickCount + 500; {Wait for pod to receive and return data or for wait to expire} Repeat Application.ProcessMessages; until (GlobalComValue = '') or (GetTickCount > Count); if GlobalComValue = '' then Passed2 := True //If pod received and returned valid data then continue else Inc(TestForDisconnect); //Else, inc error check if TestForDisconnect > 5 then begin CountTimer.Enabled := False; StuffedMemo.SaveToFile(SaveDialog.Filename); Application.MessageBox('Connection with Pod lost. Please check all connections and power then try again.', 'Lost connection!', MB_OK); ConnectButtonClick(Self); Exit; end; end; //End Test bits 8-15 if not(Passed3) then begin //Begin Test bits 16-23 {Test image tags to see if bit is set to input or output} for Count := 0 to 7 do if DirectionImage[Count + 16].Tag and 32 <> 0 then M3 := M3 or (1 shl count); GlobalComValue := 'Test'; // GlobalComValue gets set to nonsense value Commo.WriteComLine('Mh' + IntToHex(M3,2)); //Write to pod count := GetTickCount + 500; {Wait for pod to receive and return data or for wait to expire} Repeat Application.ProcessMessages; until (GlobalComValue = '') or (GetTickCount > Count); if GlobalComValue = '' then Passed3 := True //If pod received and returned valid data then continue else Inc(TestForDisconnect); //Else, inc error check if TestForDisconnect > 5 then begin CountTimer.Enabled := False; StuffedMemo.SaveToFile(SaveDialog.Filename); Application.MessageBox('Connection with Pod lost. Please check all connections and power then try again.', 'Lost connection!', MB_OK); ConnectButtonClick(Self); Exit; end; end; //End Test bits 16-23 until Passed1 and Passed2 and Passed3; //End loop to set bits as inputs or outputs if AquireButton.Caption = 'Stop aquiring data' then CountTimer.Enabled := True; end; //End DirectionImageMouseUp procedure TForm1.FormDestroy(Sender: TObject); var I: Integer; begin {Free arrays and instance of TInterComs} Commo.Free; for I := 0 to 2 do begin EnableBMP[I].Free; LevelBMP[I].Free; DirectionBMP[I].Free; end; end; procedure TForm1.ConnectButtonClick(Sender: TObject); var y : integer; Msg: PChar; begin if ConnectButton.Caption = 'Disconnect' then begin //If disconnecting Begin Commo.Close; //Close TInterComs instance for y := 0 to 23 do begin //Reset pictures to disabled EnableImage[y].Enabled := False; DirectionImage[y].Enabled := False; EnableImage[y].Picture.Assign(DisableBMP[0]); DirectionImage[y].Picture.Assign(DisableBMP[1]); InputImage[y].Picture.Assign(DisableBMP[2]); end; Status.Panels[0].Text := 'Disconnected'; ConnectButton.Caption := 'Connect'; EndTestClick(self); StopAquireClick(self); CommandGroup.Visible := False; DetectGroup.Visible := False; SettingsGroup.Visible := False; AquireButton.Enabled := False; end else if Commo.Open(StrToInt(PortEdit.Text), StrToInt(BaudStatic.Caption)) then begin //Else connect to com if PodReset then begin //If first time in program connecting, reset the pod {Send commands to reset pod} GlobalComValue := 'Test'; Commo.WriteComLine('Ml00'); y := GetTickCount + 500; Repeat Application.ProcessMessages; Until (GlobalComValue = '') or (GetTickCount > y); GlobalComValue := 'Test'; Commo.WriteComLine('Mm00'); y := GetTickCount + 500; Repeat Application.ProcessMessages; Until (GlobalComValue = '') or (GetTickCount > y); GlobalComValue := 'Test'; Commo.WriteComLine('Mh00'); y := GetTickCount + 500; Repeat Application.ProcessMessages; Until (GlobalComValue = '') or (GetTickCount > y); GlobalComValue := 'Test'; Commo.WriteComLine('O000000'); y := GetTickCount + 500; Repeat Application.ProcessMessages; Until (GlobalComValue = '') or (GetTickCount > y); if GlobalComValue <> '' then begin //If communications failed, warn user Commo.Close; Application.MessageBox('Program could not communicate with the Pod. Please check connections and power for the Pod card.', 'Error Communicating with Pod.', MB_OK); PodReset := True; end else begin Status.Panels[0].Text := 'Connected on COM' + PortEdit.Text; ConnectButton.Caption := 'Disconnect'; CommandGroup.Visible := True; DetectGroup.Visible := True; SettingsGroup.Visible := True; AquireButton.Enabled := True; for y := 0 to 23 do begin EnableImage[y].Enabled := True; DirectionImage[y].Enabled := True; EnableImage[y].Picture.Assign(EnableBMP[0]); DirectionImage[y].Picture.Assign(DirectionBMP[1]); InputImage[y].Picture.Assign(LevelBMP[1]); end; PodReset := False; // If no errors occured, then pod is reset and won't need to be until new program is started end; end else begin // If connect failed, warn user Status.Panels[0].Text := 'Connected on COM' + PortEdit.Text; ConnectButton.Caption := 'Disconnect'; CommandGroup.Visible := True; DetectGroup.Visible := True; SettingsGroup.Visible := True; AquireButton.Enabled := True; for y := 0 to 23 do begin EnableImage[y].Enabled := True; DirectionImage[y].Enabled := True; EnableImage[y].Picture.Assign(EnableBMP[0]); DirectionImage[y].Picture.Assign(DirectionBMP[1]); InputImage[y].Picture.Assign(LevelBMP[1]); end; end; end else begin FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_ALLOCATE_BUFFER, nil, GetLastError, 0, PChar(@Msg), 0, nil); Application.MessageBox(@Trim('Failed to connect: ' + Msg)[1], 'Can''t Connect', MB_APPLMODAL or MB_SETFOREGROUND or MB_TOPMOST or MB_ICONEXCLAMATION); LocalFree(LongWord(Msg)); end; end; procedure TForm1.BaudComboChange(Sender: TObject); var y : integer; begin //Begin BaudComboChange if ConnectButton.Caption = 'Connect' then BaudStatic.Caption := BaudCombo.Items[BaudCombo.ItemIndex] else begin OutputToRich := True; GlobalComValue := ''; Commo.WriteComLine('BAUD='+ IntToStr(BaudBox.ItemIndex) + IntToStr(BaudBox.ItemIndex)+ IntToStr(BaudBox.ItemIndex)); y := GetTickCount + 260; Repeat Application.ProcessMessages; until (GlobalComValue <> '') or (GetTickCount > y); if GlobalComValue = '' then Application.MessageBox('Incorrect Pod Address/Baud, please run Autodetect to find and set to the correct Address/Baud so you can change the setting.','Error talking to Pod.', MB_OK) else IORICH.Lines.Add('Pod now set to Baud ' + BaudBox.Items[BaudBox.ItemIndex]); BaudStatic.Caption := BaudCombo.Items[BaudCombo.ItemIndex]; end; end; //End BaudComboChange procedure TForm1.ReadCom(Data : string); begin //Begin ReadCom {Receives Data from Com and stores it to a global variable} GlobalComValue := Data; if OutputToRich then begin IORich.Lines.Add(Data); end; end; //End ReadCom procedure TForm1.HelloButtonClick(Sender: TObject); begin OutputToRich := True; Commo.WriteComLine('H'); //Send hello command to Pod end; procedure TForm1.VersionButtonClick(Sender: TObject); begin OutputToRich := True; Commo.WriteComLine('V'); //Send version command to Pod end; procedure TForm1.ResendButtonClick(Sender: TObject); begin OutputToRich := True; Commo.WriteComLine('N'); //Send resend command to Pod end; procedure TForm1.SendButtonClick(Sender: TObject); begin OutputToRich := True; Commo.WriteComLine(SendEdit.Text); //Send user inputed command to Pod end; procedure TForm1.DetectPBClick(Sender: TObject); var FirstLoop,PodFound : Boolean; y : integer; begin // Begin Detect Pod/Baud LoopCont := True; PodFound := False; FirstLoop := True; BaudIndex := 2; POD := 0; ChangeBaud; OutputToRich := False; SettingsGroup.Visible := False; CommandGroup.Visible := False; repeat if FirstLoop then begin // If first time talking to pod DetectLabel.Caption := 'Looking for Pod Address at '+ IntToHex(Pod,2) + ' on Baud ' + CurrentBaud[BaudIndex]; GlobalComValue := ''; Commo.WriteComLine('H'); Y := GetTickCount + 250; repeat Application.ProcessMessages; until (GlobalComValue <> '') or (GetTickCount > y); if GlobalComValue <> '' then PodFound := True else ChangeBaud; if BaudIndex = 3 then FirstLoop := False; end else begin // Else if POD = 256 then ChangeBaud; DetectLabel.Caption := 'Looking for Pod Address at '+ IntToHex(Pod,2) + ' on Baud ' + CurrentBaud[BaudIndex]; GlobalComValue := ''; Commo.WriteComLine('!' + IntToHex(POD,2)); Y := GetTickCount + 260; repeat Application.ProcessMessages; until (GlobalComValue <> '') or (GetTickCount > y); if GlobalComValue <> '' then PodFound := True else begin GlobalComValue := ''; Commo.WriteComLine('H'); Y := GetTickCount + 500; repeat Application.ProcessMessages; until (GlobalComValue <> '') or (GetTickCount > y); if GlobalComValue <> '' then PodFound := True else inc(POD); end; end; until (PodFound) or (LoopCont = False); SettingsGroup.Visible := True; CommandGroup.Visible := True; if PodFound then Status.SimpleText := 'Found Pod Address at ' + IntToHex(Pod,2) + ' on Baud ' + CurrentBaud[BaudIndex]; end; // End Detect Pod/Baud Procedure TForm1.ChangeBaud; var Msg: PChar; begin if BaudIndex = 6 then BaudIndex := 0 else inc(BaudIndex); //Cycle through all valid baud rates Commo.Close; //Close instance of InterComs for reopening with new Baud rate if Commo.Open(StrToInt(PortEdit.Text), StrToInt(CurrentBaud[BaudIndex])) then //Reopen instance of InterComs Pod := 0 //Reset Pod address check to 0 else begin //Else warn user FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_ALLOCATE_BUFFER, nil, GetLastError, 0, PChar(@Msg), 0, nil); Application.MessageBox(@Trim('Failed to connect: ' + Msg)[1], 'Can''t Connect', MB_APPLMODAL or MB_SETFOREGROUND or MB_TOPMOST or MB_ICONEXCLAMATION); LocalFree(LongWord(Msg)); end; end; procedure TForm1.EndTestClick(Sender: TObject); begin LoopCont := False; //If test is ended before Pod Address found then end the loop end; procedure TForm1.PODButtonClick(Sender: TObject); var y : integer; begin //Begin change pod address OutputToRich := True; //Enable outputting to Rich Edit box If (StrToInt('$' + PodBox.Text) >= $00) and (StrToInt('$' + PodBox.Text) <= $FF) then begin GlobalComValue := ''; Commo.WriteComLine('POD=' + IntToHex(StrToInt(PodBox.Text),2)); y := GetTickCount + 260; Repeat Application.ProcessMessages; until (GlobalComValue <> '') or (GetTickCount > y); if GlobalComValue = '' then Application.MessageBox('Incorrect Pod Address/Baud, please run Autodetect to find and set to the correct Address/Baud so you can change the setting.','Error talking to Pod.', MB_OK) else IORICH.Lines.Add('Pod now set to Address ' + IntToHex(StrToInt(PodBox.Text), 2)); end else Application.MessageBox('Invalid Pod Address value, please enter a value between $00 and $FF (0 and 255)','Invalid Pod Address Value.',MB_OK); end; //End change pod address procedure TForm1.BaudRateButtonClick(Sender: TObject); var y : integer; begin //Begin change baud rate OutputToRich := True; GlobalComValue := ''; Commo.WriteComLine('BAUD='+ IntToStr(BaudBox.ItemIndex) + IntToStr(BaudBox.ItemIndex)+ IntToStr(BaudBox.ItemIndex)); y := GetTickCount + 260; Repeat Application.ProcessMessages; until (GlobalComValue <> '') or (GetTickCount > y); if GlobalComValue = '' then Application.MessageBox('Incorrect Pod Address/Baud, please run Autodetect to find and set to the correct Address/Baud so you can change the setting.','Error talking to Pod.', MB_OK) else IORICH.Lines.Add('Pod now set to Baud ' + BaudBox.Items[BaudBox.ItemIndex]); end; //End change baud rate procedure TForm1.AquireButtonClick(Sender: TObject); var Present: TDateTime; Year, Month, Day: Word; TempStr, TempMonth, TempDay : String; begin //Begin Aquire data from Pod OutputToRich := False; //Disable writing to Rich Edit box Present:= Now; //Get current time DecodeDate(Present, Year, Month, Day); //Decode current time if Month < 10 then TempMonth := '0' + IntToStr(Month) else TempMonth := IntToStr(Month); if Day < 10 then TempDay := '0' + IntToStr(Day) else TempDay := IntToStr(Day); TempStr := copy(IntToStr(Year),3,2) + TempMonth + TempDay; //Store current time SaveDialog.FileName := ExtractFilePath(SaveDialog.FileName) + 'Log' + TempStr + '.CSV'; repeat //Begin Save dialog loop if not(SaveDialog.Execute) then Break else if FileExists(SaveDialog.FileName) then begin if Application.MessageBox('A file with that name already exists - Overwrite?', 'File already Exists', MB_OKCANCEL) = IDOK then begin SinkAllButton.Visible := True; DirectionAllButton.Visible := True; DetectGroup.Visible := False; SettingsGroup.Visible := False; CommandGroup.Visible := False; AquireButton.Caption := 'Stop aquiring data'; AquireButton.OnClick := StopAquireClick; CountTimer.Enabled := True; Break; end else Break; end else begin SinkAllButton.Visible := True; DirectionAllButton.Visible := True; DetectGroup.Visible := False; SettingsGroup.Visible := False; CommandGroup.Visible := False; AquireButton.Caption := 'Stop aquiring data'; AquireButton.OnClick := StopAquireClick; CountTimer.Enabled := True; Break; end; until False; //End Save dialog loop end; //End Aquire data from Pod procedure TForm1.StopAquireClick(Sender: TObject); begin {Save file and change settings so aquire can be recalled if needed} if SaveDialog.FileName <> '.\.' then StuffedMemo.SaveToFile(SaveDialog.Filename); CountTimer.Enabled := False; SinkAllButton.Visible := False; DirectionAllButton.Visible := False; AquireButton.Caption := 'Begin aquiring data'; AquireButton.OnClick := AquireButtonClick; DetectGroup.Visible := True; SettingsGroup.Visible := True; CommandGroup.Visible := True; end; procedure TForm1.CountTimerTimer(Sender: TObject); var Test,y,i,count : integer; TempStr, FileStr : String; begin //Begin counter to check Pod data CountTimer.Enabled := False; //Disable Counter while in counter loop GlobalComValue := ''; Commo.WriteComLine('I'); //Request current state of Pod y := GetTickCount + 500; repeat Application.ProcessMessages; until (GlobalComValue <> '') or (GetTickCount > y); if GlobalComValue <> '' then begin //If pod responded then CounterTest := 0; try TempStr := GlobalComValue; //Store response from pod FileStr := ''; Count := 0; If TempStr <> LastStr then begin //If pod response is different from last pod response then {Verify the string from pod is valid hex characters and length} For i := 1 to Length(TempStr) do if ((TempStr[i] in ['0'..'9']) or (TempStr[i] in ['A'..'F'])) then inc(count); if Count = Length(TempStr) then begin {If valid break down string to datetime stamp and 24 bits of data} for count := 0 to 2 do begin Test := StrToInt('$' + Copy(TempStr, 1 + (count * 2), 2)); for i := 0 to 7 do if Test and (1 shl i) <> 0 then FileStr := FileStr + ',1' else FileStr := FileStr + ',0'; end; StuffedMemo.Add(DateTimeToStr(now) + FileStr); //Store human readable string {Change input buttons to reflect new values} for count := 0 to 2 do begin Test := StrToInt('$' + Copy(TempStr, 1 + (count * 2), 2)); for i := 0 to 7 do if Test and (1 shl i) <> 0 then InputImage[i + (8 * (2 -count))].Picture.Assign(LevelBMP[1]) else InputImage[i + (8 * (2 -count))].Picture.Assign(LevelBMP[0]); end; LastStr := TempStr; //Store received string for later comparison end; end; except end; end else Inc(CounterTest); //Else increment disconnect watch if CounterTest > 3 then begin CountTimer.Enabled := False; StuffedMemo.SaveToFile(SaveDialog.Filename); Application.MessageBox('Connection with Pod lost. Please check all connections and power then try again.', 'Lost connection!', MB_OK); ConnectButtonClick(Self); Exit; end; {If Aquire loop wasn't ended by user then restart counter timer} if AquireButton.Caption <> 'Begin aquiring data' then CountTimer.Enabled := True; end; //End counter to check Pod data procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin {If program closes Free instances} StuffedMemo.Free; end; procedure TForm1.SinkAllButtonClick(Sender: TObject); var i, count : integer; Passed : Boolean; begin //Begin change all sinks {Clear any data waiting on pod} GlobalComValue := ''; count := GetTickCount + 200; Repeat Application.ProcessMessages; until (GlobalComValue <> '') or (GetTickCount > Count); CountTimer.Enabled := False; //disable counter {Set all sink images to in-between images} for I := 0 to 23 do begin EnableImage[I].Picture.Assign(EnableBMP[1]); EnableImage[I].Tag := (I or 64) xor 32; end; if SinkAllButton.Tag = 0 then //If tag is 0 set bits high begin Passed := False; TestForDisconnect := 0; Repeat GlobalComValue := 'Test'; Commo.WriteComLine('OFFFFFF'); //Set all bits high count := GetTickCount + 200; {Wait for timeout or data from Pod} Repeat Application.ProcessMessages; until (GlobalComValue = '') or (GetTickCount > Count); if GlobalComValue = '' then Passed := True else Inc(TestForDisconnect); if TestForDisconnect > 5 then begin CountTimer.Enabled := False; StuffedMemo.SaveToFile(SaveDialog.Filename); Application.MessageBox('Connection with Pod lost. Please check all connections and power then try again.', 'Lost connection!', MB_OK); ConnectButtonClick(Self); Exit; end; until Passed; SinkAllButton.Tag := 1; {Set all images as sinking} for I := 0 to 23 do begin EnableImage[I].Picture.Assign(EnableBMP[2]); EnableImage[I].Tag := (I or 64) xor 32; end; end else //If tag is 1 set bits low begin Passed := False; TestForDisconnect := 0; Repeat GlobalComValue := 'Test'; Commo.WriteComLine('O000000'); //Set all bits low count := GetTickCount + 200; {Wait for timeout or data from Pod} Repeat Application.ProcessMessages; until (GlobalComValue = '') or (GetTickCount > Count); if GlobalComValue = '' then Passed := True else Inc(TestForDisconnect); if TestForDisconnect > 5 then begin CountTimer.Enabled := False; StuffedMemo.SaveToFile(SaveDialog.Filename); Application.MessageBox('Connection with Pod lost. Please check all connections and power then try again.', 'Lost connection!', MB_OK); ConnectButtonClick(Self); Exit; end; until Passed; SinkAllButton.Tag := 0; {Set all images as not sinking} for I := 0 to 23 do begin EnableImage[I].Picture.Assign(EnableBMP[0]); EnableImage[I].Tag := I or 64; end; end; if AquireButton.Caption = 'Stop aquiring data' then CountTimer.Enabled := True; end; //End change all sinks procedure TForm1.DirectionAllButtonClick(Sender: TObject); var i, count : integer; Passed1, Passed2, Passed3 : Boolean; begin GlobalComValue := ''; count := GetTickCount + 200; Repeat Application.ProcessMessages; until (GlobalComValue <> '') or (GetTickCount > Count); CountTimer.Enabled := False; for I := 0 to 23 do begin DirectionImage[I].Picture.Assign(DirectionBMP[0]); DirectionImage[I].Tag := I or 64; end; if DirectionAllButton.Tag = 0 then begin Passed1 := False; Passed2 := False; Passed3 := False; TestForDisconnect := 0; repeat if not(Passed1) then begin GlobalComValue := 'Test'; Commo.WriteComLine('MlFF'); count := GetTickCount + 500; Repeat Application.ProcessMessages; until (GlobalComValue = '') or (GetTickCount > Count); if GlobalComValue = '' then Passed1 := True else Inc(TestForDisconnect); if TestForDisconnect > 3 then begin CountTimer.Enabled := False; StuffedMemo.SaveToFile(SaveDialog.Filename); Application.MessageBox('Connection with Pod lost. Please check all connections and power then try again.', 'Lost connection!', MB_OK); ConnectButtonClick(Self); Exit; end; end; if not(Passed2) then begin GlobalComValue := 'Test'; Commo.WriteComLine('MmFF'); count := GetTickCount + 500; Repeat Application.ProcessMessages; until (GlobalComValue = '') or (GetTickCount > Count); if GlobalComValue = '' then Passed2 := True else Inc(TestForDisconnect); if TestForDisconnect > 6 then begin CountTimer.Enabled := False; StuffedMemo.SaveToFile(SaveDialog.Filename); Application.MessageBox('Connection with Pod lost. Please check all connections and power then try again.', 'Lost connection!', MB_OK); ConnectButtonClick(Self); Exit; end; end; if not(Passed3) then begin GlobalComValue := 'Test'; Commo.WriteComLine('MhFF'); count := GetTickCount + 500; Repeat Application.ProcessMessages; until (GlobalComValue = '') or (GetTickCount > Count); if GlobalComValue = '' then Passed3 := True else Inc(TestForDisconnect); if TestForDisconnect > 9 then begin CountTimer.Enabled := False; StuffedMemo.SaveToFile(SaveDialog.Filename); Application.MessageBox('Connection with Pod lost. Please check all connections and power then try again.', 'Lost connection!', MB_OK); ConnectButtonClick(Self); Exit; end; end; until Passed1 and Passed2 and Passed3; DirectionAllButton.Tag := 1; for I := 0 to 23 do begin DirectionImage[I].Picture.Assign(DirectionBMP[2]); DirectionImage[I].Tag := (I or 64) xor 32; end; end else begin Passed1 := False; Passed2 := False; Passed3 := False; TestForDisconnect := 0; repeat if not(Passed1) then begin GlobalComValue := 'Test'; Commo.WriteComLine('Ml00'); count := GetTickCount + 500; Repeat Application.ProcessMessages; until (GlobalComValue = '') or (GetTickCount > Count); if GlobalComValue = '' then Passed1 := True else Inc(TestForDisconnect); if TestForDisconnect > 3 then begin CountTimer.Enabled := False; StuffedMemo.SaveToFile(SaveDialog.Filename); Application.MessageBox('Connection with Pod lost. Please check all connections and power then try again.', 'Lost connection!', MB_OK); ConnectButtonClick(Self); Exit; end; end; if not(Passed2) then begin GlobalComValue := 'Test'; Commo.WriteComLine('Mm00'); count := GetTickCount + 500; Repeat Application.ProcessMessages; until (GlobalComValue = '') or (GetTickCount > Count); if GlobalComValue = '' then Passed2 := True else Inc(TestForDisconnect); if TestForDisconnect > 6 then begin CountTimer.Enabled := False; StuffedMemo.SaveToFile(SaveDialog.Filename); Application.MessageBox('Connection with Pod lost. Please check all connections and power then try again.', 'Lost connection!', MB_OK); ConnectButtonClick(Self); Exit; end; end; if not(Passed3) then begin GlobalComValue := 'Test'; Commo.WriteComLine('Mh00'); count := GetTickCount + 500; Repeat Application.ProcessMessages; until (GlobalComValue = '') or (GetTickCount > Count); if GlobalComValue = '' then Passed3 := True else Inc(TestForDisconnect); if TestForDisconnect > 9 then begin CountTimer.Enabled := False; StuffedMemo.SaveToFile(SaveDialog.Filename); Application.MessageBox('Connection with Pod lost. Please check all connections and power then try again.', 'Lost connection!', MB_OK); ConnectButtonClick(Self); Exit; end; end; until Passed1 and Passed2 and Passed3; DirectionAllButton.Tag := 0; for I := 0 to 23 do begin DirectionImage[I].Picture.Assign(DirectionBMP[1]); DirectionImage[I].Tag := I or 64; end; end; if AquireButton.Caption = 'Stop aquiring data' then CountTimer.Enabled := True; end; end.