{ This is a sample program for the wm-iiro-8. It will set the outputs to the POD individually, read the current input state of the POD, and allows the user to send clear text directly to the POD view its responses.} 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; 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; AquireButton: TButton; SaveDialog: TSaveDialog; IORich: TRichEdit; SendEdit: TEdit; SendButton: TButton; StopButton: 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 HelloButtonClick(Sender: TObject); procedure VersionButtonClick(Sender: TObject); procedure ResendButtonClick(Sender: TObject); procedure DetectPBClick(Sender: TObject); procedure EndTestClick(Sender: TObject); procedure PODButtonClick(Sender: TObject); procedure AquireButtonClick(Sender: TObject); procedure CountTimerTimer(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure SendButtonClick(Sender: TObject); procedure StopButtonClick(Sender: TObject); private procedure ReadCom(Data: string); { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation uses InterCOMs; {$R *.DFM} {Global variables - Variables that stay constant between procedures } var LevelBMP: array[0..2] of TBitmap; EnableBMP: array[0..2] of TBitmap; DisableBMP: array[0..2] of TBitmap; InputImage: array[0..7] of TImage; EnableImage: array[0..7] of TImage; StuffedMemo: TStringList; Commo: TInterCom; LastStr, GlobalComValue: String; OutputToRich, PodReset, LoopCont : Boolean; TestForDisconnect,POD, BaudIndex : Integer; Stop : Boolean; 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; Stop := True; {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; DisableBMP[I] := TBitmap.Create; DIOImages.GetBitmap(I, EnableBMP[I]); DIOImages.GetBitmap(I + 3, LevelBMP[I]); DIOImages.GetBitmap(I + 9, DisableBMP[I]); GreyMapCanvas(EnableBMP[I].Canvas, 19, 19); GreyMapCanvas(LevelBMP[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]); end; // End creating lists for I := 0 to 7 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 := 250 - 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 := 250 - 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 := 250 - 24 * I; Top := SinkLabel.Top; Picture.Assign(DisableBMP[0]); Enabled := False; OnMouseDown := EnableImageMouseDown; OnMouseMove := EnableImageMouseMove; OnMouseUp := EnableImageMouseUp; 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: 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; if (Stop = False) then begin // if the timer is going then that procedure will take care of outputting the data Exit; end; {Initialize variables for repeat loop} CountTimer.Enabled := False; Passed := False; TestForDisconnect := 0; repeat //Begin loop to set Sinking or Not Sinking O1 := 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); GlobalComValue := 'Test'; // GlobalComValue gets set to nonsense value {Write value to Pod through the com port} Commo.WriteComLine('O' + 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 end; //End EnableImageMouseUp 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; 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 7 do begin //Reset pictures to disabled EnableImage[y].Enabled := False; EnableImage[y].Picture.Assign(DisableBMP[0]); InputImage[y].Picture.Assign(DisableBMP[2]); end; Status.Panels[0].Text := 'Disconnected'; ConnectButton.Caption := 'Connect'; EndTestClick(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('O00'); 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 7 do begin EnableImage[y].Enabled := True; EnableImage[y].Picture.Assign(EnableBMP[0]); 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 7do begin EnableImage[y].Enabled := True; EnableImage[y].Picture.Assign(EnableBMP[0]); 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.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; BaudIndex := 2; POD := 0; OutputToRich := False; SettingsGroup.Visible := False; CommandGroup.Visible := False; repeat DetectLabel.Caption := 'Looking for Pod Address at '+ IntToHex(Pod,2); 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; until (PodFound) or (LoopCont = False); SettingsGroup.Visible := True; CommandGroup.Visible := True; if PodFound then Status.SimpleText := 'Found Pod Address at ' + IntToHex(Pod,2); end; // End Detect Pod/Baud 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.AquireButtonClick(Sender: TObject); var y : Integer; begin //Begin Aquire data from Pod Stop := False; CountTimer.Enabled := True; end; //End Aquire data from Pod procedure TForm1.CountTimerTimer(Sender: TObject); var y:Integer; temp: Integer; I, count, O1: Integer; Passed : Boolean; begin //Begin counter to check Pod data CountTimer.Enabled := False; GlobalComValue := ''; Commo.WriteCOMLine('I'); y := GetTickCount + 250; Repeat Application.ProcessMessages; until (GlobalComValue <> '') or (GetTickCount > y); temp := StrToInt('$' + GlobalComValue); for y := 0 to 7 do begin if ((temp shl y) and 1 = 1) then begin InputImage[y].Picture.Assign(LevelBMP[1]); end else begin InputImage[y].Picture.Assign(LevelBMP[0]); end; end; Passed := False; TestForDisconnect := 0; repeat //Begin loop to set Sinking or Not Sinking O1 := 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); GlobalComValue := 'Test'; // GlobalComValue gets set to nonsense value {Write value to Pod through the com port} Commo.WriteComLine('O' + 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 (Stop = False) then begin CountTimer.Enabled := True; end; 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.StopButtonClick(Sender: TObject); var y : Integer; begin Stop := True; CountTimer.Enabled := False; end; end.