1 unit uCWKeying;
2
3 {$mode objfpc}{$H+}
4
5 interface
6
7 uses
8 Classes, SysUtils, synaser, synautil, lNet, lNetComponents, Forms;
9
10 type TKeyType = (ktCWdaemon, ktWinKeyer);
11 type TKeyStatus = (ksReady, ksBusy);
12
13 type
14 TCWDevice = class
15 protected
16 fPort : String;
17 fLastErrNr : Word;
18 fLastErrSt : String;
19 fDevice : String;
20 fDebugMode : Boolean;
21 fMinSpeed : Word;
22 fMaxSpeed : Word;
23 fPortSpeed : dWord;
24 public
25 property Port : String read fPort write fPort;
26 property Device : String read fDevice write fDevice;
27 property LastErrNr : Word read fLastErrNr;
28 property LastErrSt : String read fLastErrSt;
29 property DebugMode : Boolean read fDebugMode write fDebugMode;
30 property MinSpeed : Word read fMinSpeed;
31 property MaxSpeed : Word read fMaxSpeed;
32 property PortSpeed : dWord read fPortSpeed write fPortSpeed;
33
34 constructor Create; virtual; abstract;
35
GetSpeednull36 function GetSpeed : Word; virtual; abstract;
GetStatusnull37 function GetStatus : TKeyStatus; virtual; abstract;
38
39 procedure Open; virtual; abstract;
40 procedure Close; virtual; abstract;
41 procedure SetSpeed(speed : Word); virtual; abstract;
42 procedure SendText(text : String); virtual; abstract;
43 procedure StopSending; virtual; abstract;
44 procedure DelLastChar; virtual; abstract;
45 procedure SetMixManSpeed(min,max : Word); virtual; abstract;
46 procedure TuneStart; virtual; abstract;
47 procedure TuneStop; virtual; abstract;
48 end;
49
50 TCWWinKeyerUSB = class(TCWDevice)
51 private
52 fActive : Boolean;
53 fSpeed : Word;
54 ser : TBlockSerial;
55
56 public
57 constructor Create; override;
58 destructor Destroy; override;
59
GetSpeednull60 function GetSpeed : Word; override;
GetStatusnull61 function GetStatus : TKeyStatus; override;
62
63 procedure Open; override;
64 procedure Close; override;
65 procedure SetSpeed(speed : Word); override;
66 procedure SendText(text : String); override;
67 procedure StopSending; override;
68 procedure DelLastChar; override;
69 procedure SetMixManSpeed(min,max : Word); override;
70 procedure TuneStart; override;
71 procedure TuneStop; override;
72 end;
73
74 TCWDaemon = class(TCWDevice)
75 private
76 fActive : Boolean;
77 fSpeed : Word;
78 udp : TLUDPComponent;
79 public
80 constructor Create; override;
81 destructor Destroy; override;
82
GetSpeednull83 function GetSpeed : Word; override;
GetStatusnull84 function GetStatus : TKeyStatus; override;
85
86 procedure Open; override;
87 procedure Close; override;
88 procedure SetSpeed(speed : Word); override;
89 procedure SendText(text : String); override;
90 procedure StopSending; override;
91 procedure DelLastChar; override;
92 procedure SetMixManSpeed(min,max : Word); override;
93 procedure TuneStart; override;
94 procedure TuneStop; override;
95 end;
96
97 TCWK3NG = class(TCWDevice)
98 private
99 fActive : Boolean;
100 fSpeed : Word;
101 ser : TBlockSerial;
102 public
103 constructor Create; override;
104 destructor Destroy; override;
105
GetSpeednull106 function GetSpeed : Word; override;
GetStatusnull107 function GetStatus : TKeyStatus; override;
108
109 procedure Open; override;
110 procedure Close; override;
111 procedure SetSpeed(speed : Word); override;
112 procedure SendText(text : String); override;
113 procedure StopSending; override;
114 procedure DelLastChar; override;
115 procedure SetMixManSpeed(min,max : Word); override;
116 procedure TuneStart; override;
117 procedure TuneStop; override;
118 end;
119
120 TCWHamLib = class(TCWDevice)
121 private
122 AllowCW : Boolean;
123 fActive : Boolean;
124 fSpeed : Word;
125 tcp : TLTCPComponent;
126 Rmsg : String;
127 procedure OnReceived(aSocket: TLSocket);
128 procedure OnHamLibConnect(aSocket: TLSocket);
129 procedure OnHamLibError(const msg: AnsiString; aSocket: TLSocket);
130 public
131 constructor Create; override;
132 destructor Destroy; override;
133
GetSpeednull134 function GetSpeed : Word; override;
GetStatusnull135 function GetStatus : TKeyStatus; override;
136
137 procedure Open; override;
138 procedure Close; override;
139 procedure WaitMorse;
140 procedure SetSpeed(speed : Word); override;
141 procedure SendText(text : String); override;
142 procedure StopSending; override;
143 procedure DelLastChar; override;
144 procedure SetMixManSpeed(min,max : Word); override;
145 procedure TuneStart; override;
146 procedure TuneStop; override;
147 end;
148
149
150 implementation
151
152 uses fTRXControl;
153
154 constructor TCWWinKeyerUSB.Create;
155 begin
156 fActive := False;
157 fDebugMode := False;
158 ser := TBlockserial.Create;
159 ser.LinuxLock := False;
160 fMinSpeed := 5;
161 fMaxSpeed := 60
162 end;
163
164 procedure TCWWinKeyerUSB.Open;
165 var
166 rec : byte;
167 begin
168 if fActive then Close();
169
170 if fDebugMode then Writeln('Device: ',fDevice);
171 ser.RaiseExcept := False;
172 ser.Connect(fDevice);
173 ser.Config(1200,8,'N',2,false,false);
174 ser.DTR:=True;
175 ser.RTS:=False;
176 fLastErrNr := ser.LastError;
177 fLastErrSt := ser.LastErrorDesc;
178 if fDebugMode then
179 begin
180 Writeln('Last error nr: ',fLastErrNr);
181 Writeln('Last error desc:',fLastErrSt)
182 end;
183 if LastErrNr > 0 then
184 exit;
185 ser.SendByte($13);
186 ser.SendByte($13); //sending null commands
187 ser.SendByte($13);
188 sleep(50);
189 if fDebugMode then Writeln('After sending null command');
190 ser.SendByte(0);
191 ser.SendByte(4); //send echo command
192 ser.SendByte(20);
193 sleep(50);
194 while ser.CanReadex(10) do
195 begin
196 rec := (ser.recvByte(0))
197 end;
198 if fDebugMode then Writeln('After sending echo command: ',rec);
199 if rec = 20 then
200 fActive := True
201 else begin
202 fLastErrNr := 1000;
203 fLastErrSt := 'WinKeyer USB inicialization failed';
204 exit
205 end;
206 ser.SendByte(0);
207 ser.SendByte(2); //enable communication
208 sleep(50);
209 while ser.CanReadex(10) do
210 begin
211 rec := (ser.recvByte(0))
212 end;
213 if fDebugMode then Writeln('Firmware version: ',rec);
214 fActive := True;
215
216 SetSpeed(fSpeed)
217 end;
218
219 procedure TCWWinKeyerUSB.SetSpeed(speed : Word);
220 begin
221 if fDebugMode then Writeln('Speed: ',speed);
222 fSpeed := speed;
223 ser.Flush;
224 ser.SendByte(2);
225 ser.SendByte(speed);
226 sleep(50)
227 end;
228
GetSpeednull229 function TCWWinKeyerUSB.GetSpeed : Word;
230 begin
231 Result := fSpeed
232 end;
233
TCWWinKeyerUSB.GetStatusnull234 function TCWWinKeyerUSB.GetStatus : TKeyStatus;
235 begin
236 Result := ksBusy //not implemented, default value
237 end;
238
239 procedure TCWWinKeyerUSB.DelLastChar;
240 begin
241 ser.SendByte($8)
242 end;
243
244 procedure TCWWinKeyerUSB.SetMixManSpeed(min,max : Word);
245 begin
246 ser.SendByte(5);
247 ser.SendByte(min);
248 ser.SendByte(max)
249 end;
250
251 procedure TCWWinKeyerUSB.TuneStart;
252 begin
253 ser.SendByte($0B);
254 ser.SendByte(1)
255 end;
256
257 procedure TCWWinKeyerUSB.TuneStop;
258 begin
259 ser.SendByte($0B);
260 ser.SendByte(0)
261 end;
262
263 procedure TCWWinKeyerUSB.StopSending;
264 begin
265 ser.SendByte($A)
266 end;
267
268 procedure TCWWinKeyerUSB.SendText(text : String);
269 var
270 i : Integer;
271 spd : Integer;
272 begin
273 spd := fSpeed;
274 text := UpperCase(text);
275 if fDebugMode then Writeln('Sending text: ',text);
276 if (Pos('+',text) > 0) or (Pos('-',text) > 0) then
277 begin
278 for i:=1 to Length(text) do
279 begin
280 if text[i] = '+' then
281 begin
282 spd := spd+5;
283 if spd>fMaxSpeed then spd:=fMaxSpeed;
284 ser.SendByte($1C);
285 ser.SendByte(spd);
286 Continue
287 end
288 else begin
289 if text[i] = '-' then
290 begin
291 spd := spd-5;
292 if spd<fMinSpeed then spd:=fMinSpeed;
293 ser.SendByte($1C);
294 ser.SendByte(spd);
295 Continue
296 end
297 end;
298 case text[i] of
299 '/' : begin
300 ser.SendByte($1B);
301 ser.SendString('D');
302 ser.SendString('N');
303 end;
304 '?' : begin
305 ser.SendByte($1B);
306 ser.SendString('U');
307 ser.SendString('D');
308 end;
309 '=' : begin
310 ser.SendByte($1B);
311 ser.SendString('B');
312 ser.SendString('T');
313 end;
314 '.' : begin
315 ser.SendByte($1B);
316 ser.SendString('Z');
317 ser.SendString('M');
318 end;
319 ':' : begin
320 ser.SendByte($1B);
321 ser.SendString('K');
322 ser.SendString('N');
323 end;
324 ';' : begin
325 ser.SendByte($1B);
326 ser.SendString('A');
327 ser.SendString('A');
328 end;
329 '<' : begin
330 ser.SendByte($1B);
331 ser.SendString('A');
332 ser.SendString('R');
333 end;
334 '>' : begin
335 ser.SendByte($1B);
336 ser.SendString('S');
337 ser.SendString('K');
338 end;
339 '(' : begin
340 ser.SendByte($1B);
341 ser.SendString('K');
342 ser.SendString('N');
343 end;
344 ')' : begin
345 ser.SendByte($1B);
346 ser.SendString('K');
347 ser.SendString('K');
348 end;
349 '@' : begin
350 ser.SendByte($1B);
351 ser.SendString('A');
352 ser.SendString('C');
353 end;
354 { 'ß' : begin
355 ser.SendByte($1B);
356 ser.SendString('S');
357 ser.SendString('Z');
358 end;
359 'Ü' : begin
360 ser.SendByte($1B);
361 ser.SendString('I');
362 ser.SendString('M');
363 end;
364 'Ö' : begin
365 ser.SendByte($1B);
366 ser.SendString('O');
367 ser.SendString('E');
368 end;
369 'Ä' : begin
370 ser.SendByte($1B);
371 ser.SendString('A');
372 ser.SendString('A');
373 end
374 }
375 else
376 Ser.SendString(text[i])
377 end //case
378 end;
379 ser.SendByte($1F)
380 end
381 else
382 ser.SendString(text)
383 end;
384
385 procedure TCWWinKeyerUSB.Close;
386 begin
387 ser.SendByte(0);
388 ser.SendByte(3); // close keyer
389 if fDebugMode then Writeln('WinKeyer closed');
390 ser.CloseSocket;
391 fActive := False
392 end;
393
394 destructor TCWWinKeyerUSB.Destroy;
395 begin
396 if fActive then
397 Close();
398 FreeAndNil(ser)
399 end;
400
401 constructor TCWDaemon.Create;
402 begin
403 fActive := False;
404 fDebugMode := False;
405 udp := TLUDPComponent.Create(nil);
406 fMinSpeed := 5;
407 fMaxSpeed := 60
408 end;
409
410 procedure TCWDaemon.Open;
411 begin
412 if fDebugMode then
413 begin
414 Writeln('address: ',fDevice);
415 Writeln('port: ',fPort)
416 end;
417 udp.Host := fDevice;
418 udp.Port := StrToInt(fPort);
419 fActive := udp.Connect;
420
421 SetSpeed(fSpeed)
422 end;
423
424 procedure TCWDaemon.SetSpeed(speed : Word);
425 begin
426 fSpeed := speed;
427 if fActive then
428 udp.SendMessage(Chr(27)+'2'+IntToStr(speed))
429 end;
430
GetSpeednull431 function TCWDaemon.GetSpeed : Word;
432 begin
433 Result := fSpeed
434 end;
435
TCWDaemon.GetStatusnull436 function TCWDaemon.GetStatus : TKeyStatus;
437 begin
438 Result := ksBusy //not implemented, yet
439 end;
440
441 procedure TCWDaemon.DelLastChar;
442 begin
443 //not implemented
444 end;
445
446 procedure TCWDaemon.SetMixManSpeed(min,max : Word);
447 begin
448 //not supported in cwdaemon
449 end;
450
451 procedure TCWDaemon.TuneStart;
452 begin
453 if fActive then
454 udp.SendMessage(Chr(27)+'c10')
455 end;
456
457 procedure TCWDaemon.TuneStop;
458 begin
459 if fActive then
460 udp.SendMessage(Chr(27)+'c0')
461 end;
462
463 procedure TCWDaemon.StopSending;
464 begin
465 if fActive then
466 udp.SendMessage(Chr(27)+'4')
467 end;
468
469 procedure TCWDaemon.SendText(text : String);
470 var
471 i : Integer;
472 spd : Word;
473 old_spd : Word = 0;
474 begin
475 if not fActive then
476 exit;
477
478 text := UpperCase(Trim(text));
479 if text = '' then
480 exit;
481 spd := fSpeed;
482 old_spd := spd;
483 if (Pos('+',text) > 0) or (Pos('-',text) > 0) then
484 begin
485 for i:=1 to Length(text) do
486 begin
487 if text[i] = '+' then
488 begin
489 spd := spd+5;
490 if spd>fMaxSpeed then spd:=fMaxSpeed;
491 udp.SendMessage(Chr(27)+'2'+IntToStr(spd))
492 end
493 else begin
494 if text[i] = '-' then
495 begin
496 spd := spd-5;
497 if spd<fMinSpeed then spd:=fMinSpeed;
498 udp.SendMessage(Chr(27)+'2'+IntToStr(spd))
499 end
500 else
501 udp.SendMessage(text[i])
502 end
503 end;
504 udp.SendMessage(Chr(27)+'2'+IntToStr(old_spd))
505 end
506 else
507 udp.SendMessage(text)
508 end;
509
510 procedure TCWDaemon.Close;
511 begin
512 if udp.Connected then
513 udp.Disconnect;
514 fActive := False
515 end;
516
517 destructor TCWDaemon.Destroy;
518 begin
519 if fActive then
520 Close();
521 FreeAndNil(udp)
522 end;
523
524 constructor TCWK3NG.Create;
525 begin
526 fActive := False;
527 fDebugMode := False;
528 ser := TBlockserial.Create;
529 ser.LinuxLock := False;
530 fMinSpeed := 5;
531 fMaxSpeed := 60
532 end;
533
534 procedure TCWK3NG.Open;
535 var
536 rec : byte;
537 begin
538 if fActive then Close();
539
540 if fDebugMode then Writeln('Device: ',fDevice);
541 ser.RaiseExcept := False;
542 ser.Connect(fDevice);
543 ser.Config(fPortSpeed,8,'N',2,false,false);
544 ser.DTR := False;
545 ser.RTS := False;
546 fLastErrNr := ser.LastError;
547 fLastErrSt := ser.LastErrorDesc;
548 if fDebugMode then
549 begin
550 Writeln('Last error nr: ',fLastErrNr);
551 Writeln('Last error desc:',fLastErrSt)
552 end;
553 if LastErrNr > 0 then
554 exit;
555 fActive := True;
556 SetSpeed(fSpeed)
557 end;
558
559 procedure TCWK3NG.SetSpeed(speed : Word);
560 begin
561 Writeln(Speed);
562 fSpeed := speed;
563 ser.SendByte($5C);
564 ser.SendByte($57);
565 ser.SendString(IntToStr(speed));
566 ser.SendString(CR)
567 end;
568
GetSpeednull569 function TCWK3NG.GetSpeed : Word;
570 begin
571 Result := fSpeed
572 end;
573
TCWK3NG.GetStatusnull574 function TCWK3NG.GetStatus : TKeyStatus;
575 begin
576 Result := ksBusy //not implemented, yet
577 end;
578
579 procedure TCWK3NG.DelLastChar;
580 begin
581 //not implemented
582 end;
583
584 procedure TCWK3NG.SetMixManSpeed(min,max : Word);
585 begin
586 //not supported
587 end;
588
589 procedure TCWK3NG.TuneStart;
590 begin
591 ser.SendByte($5C);
592 ser.SendByte($54)
593 end;
594
595 procedure TCWK3NG.TuneStop;
596 begin
597 StopSending
598 end;
599
600 procedure TCWK3NG.StopSending;
601 begin
602 if fActive then
603 begin
604 ser.SendByte($5C);
605 ser.SendByte($5C)
606 end
607 end;
608
609 procedure TCWK3NG.SendText(text : String);
610
611 procedure ChangeSpeed(spd : Word);
612 begin
613 ser.SendByte($5C);
614 ser.SendByte($57);
615 ser.SendString(IntToStr(spd));
616 ser.SendString(CR)
617 end;
618
619 var
620 i : Integer;
621 spd : Word;
622 old_spd : Word = 0;
623 begin
624 if not fActive then
625 exit;
626
627 text := UpperCase(Trim(text));
628 if text = '' then
629 exit;
630 spd := fSpeed;
631 old_spd := spd;
632 if (Pos('+',text) > 0) or (Pos('-',text) > 0) then
633 begin
634 for i:=1 to Length(text) do
635 begin
636 if text[i] = '+' then
637 begin
638 spd := spd+5;
639 if spd>fMaxSpeed then spd:=fMaxSpeed;
640 ChangeSpeed(spd)
641 end
642 else begin
643 if text[i] = '-' then
644 begin
645 spd := spd-5;
646 if spd<fMinSpeed then spd:=fMinSpeed;
647 ChangeSpeed(spd)
648 end
649 else
650 ser.SendString(text[i])
651 end
652 end;
653 ChangeSpeed(old_spd)
654 end
655 else
656 ser.SendString(text)
657 end;
658
659 procedure TCWK3NG.Close;
660 begin
661 if fDebugMode then Writeln('K3NG keyer closed');
662 ser.CloseSocket;
663 fActive := False
664 end;
665
666
667 destructor TCWK3NG.Destroy;
668 begin
669 if fActive then
670 Close();
671 FreeAndNil(ser)
672 end;
673
674 constructor TCWHamLib.Create;
675 begin
676 fActive := False;
677 fDebugMode := False;
678 tcp := TLTCPComponent.Create(nil);
679 tcp.ReuseAddress:= True;
680 tcp.OnReceive := @OnReceived;
681 tcp.OnConnect := @OnHamLibConnect;
682 tcp.OnError := @onHamLibError;
683 fMinSpeed := 5;
684 fMaxSpeed := 60
685 end;
686
687 procedure TCWHamLib.OnHamLibConnect(aSocket: TLSocket);
688 begin
689 fActive := True;
690 if DebugMode then
691 Writeln('CWint connected to hamlib');
692
693 tcp.SendMessage('fmv'+LineEnding);
694 SetSpeed(fSpeed)
695 end;
696
697 procedure TCWHamLib.OnHamLibError(const msg: AnsiString; aSocket: TLSocket);
698 begin
699 if DebugMode then
700 Writeln('CWint connect to hamlib FAILED: '+msg);
701
702 fActive := False
703 end;
704
705 procedure TCWHamLib.Open;
706 begin
707 if fActive then Close();
708
709 if fDebugMode then
710 begin
711 Writeln('address: ',fDevice);
712 Writeln('port: ',fPort)
713 end;
714 tcp.Host := fDevice;
715 tcp.Port := StrToInt(fPort);
716 tcp.Connect(fDevice,StrToInt(fPort));
717 end;
718
719 procedure TCWHamLib.OnReceived(aSocket: TLSocket);
720 begin
721 if aSocket.GetMessage(Rmsg) > 0 then
722 begin
723 Rmsg := StringReplace(Rmsg,LineEnding,' ',[rfReplaceAll]);
724 if DebugMode then Writeln('HLresp MSG:',Rmsg,':');
725 end;
726 end;
727 procedure TCWHamLib.WaitMorse;
728 begin
729 tcp.SendMessage('\wait_morse' +LineEnding);
730 end;
731
732 procedure TCWHamLib.SetSpeed(speed : Word);
733 begin
734 if Speed>fMaxSpeed then speed:= fMaxSpeed;
735 if Speed<fMinSpeed then speed:= fMinSpeed;
736 fSpeed := speed;
737 if fActive then
738 tcp.SendMessage('L KEYSPD '+IntToStr(speed)+LineEnding);
739 if fDebugMode then
740 Writeln('CW speed changed to:',fSpeed)
741 end;
742
GetSpeednull743 function TCWHamLib.GetSpeed : Word;
744 begin
745 Result := fSpeed
746 end;
747
TCWHamLib.GetStatusnull748 function TCWHamLib.GetStatus : TKeyStatus;
749 begin
750 Result := ksBusy //not implemented, yet
751 end;
752
753 procedure TCWHamLib.DelLastChar;
754 begin
755 //not implemented
756 end;
757
758 procedure TCWHamLib.SetMixManSpeed(min,max : Word);
759 begin
760 //not supported
761 end;
762
763 procedure TCWHamLib.TuneStart;
764 begin
765 //supported via AM mode
766 frmTRXControl.HLTune(true);
767 end;
768
769 procedure TCWHamLib.TuneStop;
770 begin
771 //supported via AM mode
772 frmTRXControl.HLTune(false);
773 end;
774
775 procedure TCWHamLib.StopSending;
776 begin
777 AllowCW := false;
778 //not implemented in hamlib command set
779 //sending 0xFF as text works with Icom
780 tcp.SendMessage('b'+#$0FF+LineEnding);
781 //All chrs are spaces stops cw for kenwood. Empty chrs (max24) in buffer are filled with spaces.
782 // (info by ts480 manual, not tested)
783 tcp.SendMessage('b '+LineEnding);
784 end;
785
786 procedure TCWHamLib.SendText(text : String);
787 const
788 _REPEATS = 500; //times
789 _TIMEOUT = 20; //x10-milliseconds
790 var
791 c, i,
792 tout,
793 rpt : integer;
794 Wcw : char;
795 dSpd: integer;
796 //-----------------------------------------------------------------------------------
797 Procedure SendToHamlib(t:string);
798 Begin
799 tout :=_TIMEOUT; //used away in sleep(10) bloks
800 rpt := _REPEATS;
801
802 while ((rpt > 0) and AllowCW) do
803 Begin
804 if fDebugMode then Writeln('HLsend MSG:','b'+t+':');
805 Rmsg:='';
806 tcp.SendMessage('b'+t+LineEnding);
807 dec(rpt);
808 repeat
809 begin
810 sleep(10);
811 Application.ProcessMessages;
812 dec(tout);
813 end;
814 until ((pos('RPRT',Rmsg)>0) or (tout < 1 ));
815 if fDebugMode then Writeln(' Ack timeout left: ',tout,'(/',_TIMEOUT,')');
816 if fDebugMode then Writeln(' Repeats left: ',rpt,'(/',_REPEATS,')');
817 if pos('-9',Rmsg)>0 then
818 Begin
819 dec(rpt);
820 sleep(300);
821 end
822 else
823 rpt :=0;
824 end;
825
826 end;
827 //-----------------------------------------------------------------------------------
828 Procedure ModSpeed(m:char);
829 Begin
830 if Wcw<>m then WaitMorse;
831 //check if more m
832 While ((text[i]=m) and (i<=length(text))) do
833 Begin
834 if m='+' then inc(dSpd) else dec(dSpd);
835 inc(i)
836 end;
837 if (i<length(text)) then dec(i); //there is still text left
838 SetSpeed(fSpeed+dSpd*5);
839 if fDebugMode then Writeln(m,' speed with ',dSpd*5);
840 dSpd:=0;
841 end;
842 //-----------------------------------------------------------------------------------
843 begin
844 if text<>'' then
845 begin
846 Wcw:=#0;
847 dSpd:=0;
848 AllowCW := true;
849 //different rigs support different length of b-command. 10chr should be safe for all
850 c:= length(text);
851 if (c>10) or (pos('+',text)>0) or (pos('-',text)>0) then
852 Begin
853 i := 1;
854 if fDebugMode then Writeln('Ltr send: ');
855 repeat
856 Begin
857 case text[i] of
858 '+','-' : ModSpeed(text[i]);
859 else
860 Begin
861 if fDebugMode then Writeln('send letter ',i,' ',text[i]);
862 SendToHamlib(text[i]);
863 Wcw:=#0;
864 end;
865 end;
866 inc(i);
867 end;
868 until (i > c);
869 end
870 else
871 SendToHamlib(text);
872 end
873 else if fDebugMode then Writeln('Empty message!');
874 end;
875
876 procedure TCWHamLib.Close;
877 begin
878 if tcp.Connected then
879 tcp.Disconnect;
880 fActive := False
881 end;
882
883 destructor TCWHamLib.Destroy;
884 begin
885 if fActive then
886 Close();
887 FreeAndNil(tcp);
888 if fDebugMode then
889 Writeln('Keying over HamLib closed')
890 end;
891
892 end.
893