6
* Copyright 2009, Dave Freese, W1HKJ
7
* Copyright 2011-2012, Terry Embry, KJ4EED
15
static const char FT450name_[] = "FT-450";
17
static const char *FT450modes_[] = {
18
"LSB", "USB", "CW", "FM", "AM", "RTTY-L", "CW-R", "USER-L", "RTTY-U", "FM-N", "USER-U", NULL};
19
static const char mode_chr[] = { '1', '2', '3', '4', '5', '6', '7', '8', '9', 'B', 'C' };
20
static const char mode_type[] = { 'L', 'U', 'U', 'U', 'U', 'L', 'L', 'L', 'U', 'U', 'U' };
22
static const char *FT450_widths[] = {"NARR", "NORM", "WIDE", NULL};
24
static const char *FT450_US_60m[] = {NULL, "126", "127", "128", "130", NULL};
25
// US has 5 60M presets. Using dummy numbers for all.
26
// First NULL means skip 60m sets in set_band_selection().
27
// Maybe someone can do a cat command MC; on all 5 presets and add returned numbers above.
28
// To send cat commands in flrig goto menu Config->Xcvr select->Send Cmd.
30
static const char **Channels_60m = FT450_US_60m;
32
static GUI rig_widgets[]= {
33
{ (Fl_Widget *)btnVol, 2, 125, 50 },
34
{ (Fl_Widget *)sldrVOLUME, 54, 125, 156 },
35
{ (Fl_Widget *)btnIFsh, 214, 105, 50 },
36
{ (Fl_Widget *)sldrIFSHIFT, 266, 105, 156 },
37
{ (Fl_Widget *)btnNotch, 214, 125, 50 },
38
{ (Fl_Widget *)sldrNOTCH, 266, 125, 156 },
39
{ (Fl_Widget *)sldrMICGAIN, 54, 145, 156 },
40
{ (Fl_Widget *)sldrPOWER, 54, 165, 368 },
41
{ (Fl_Widget *)btnNR, 214, 145, 50 },
42
{ (Fl_Widget *)sldrNR, 266, 145, 156 },
43
{ (Fl_Widget *)NULL, 0, 0, 0 }
46
RIG_FT450::RIG_FT450() {
50
bandwidths_ = FT450_widths;
52
widgets = rig_widgets;
54
comm_baudrate = BR38400;
76
has_xcvr_auto_on_off =
78
has_noise_reduction_control =
101
has_bandwidth_control =
102
has_micgain_control =
104
has_attenuator_control =
106
has_ifshift_control =
108
has_tune_control = true;
118
void RIG_FT450::initialize()
120
rig_widgets[0].W = btnVol;
121
rig_widgets[1].W = sldrVOLUME;
122
rig_widgets[2].W = btnIFsh;
123
rig_widgets[3].W = sldrIFSHIFT;
124
rig_widgets[4].W = btnNotch;
125
rig_widgets[5].W = sldrNOTCH;
126
rig_widgets[6].W = sldrMICGAIN;
127
rig_widgets[7].W = sldrPOWER;
128
rig_widgets[8].W = btnNR;
129
rig_widgets[9].W = sldrNR;
131
// set progStatus defaults
132
if (progStatus.noise_reduction_val < 1) progStatus.noise_reduction_val = 1;
133
// first-time-thru, or reset
134
if (progStatus.cw_qsk < 15) {
135
progStatus.cw_qsk = 15;
136
progStatus.cw_spot_tone = 700;
137
progStatus.cw_weight = 3.0;
138
progStatus.cw_wpm = 18;
139
progStatus.vox_gain = 50;
140
progStatus.vox_hang = 500;
143
// turn off auto information mode
149
void RIG_FT450::set_band_selection(int v)
153
waitN(27, 100, "get vfo mode in set_band_selection", ASC);
154
size_t p = replystr.rfind("IF");
155
if (p == string::npos) return;
156
if (replystr[p+21] != '0') { // vfo 60M memory mode
160
if (v == 12) { // 5MHz 60m presets
161
if (Channels_60m[0] == NULL) return; // no 60m Channels so skip
163
if (Channels_60m[++m_60m_indx] == NULL)
166
cmd.assign("MC").append(Channels_60m[m_60m_indx]).append(";");
167
} else { // v == 1..11 band selection OR return to vfo mode == 0
173
cmd.assign("BS").append(to_decimal(v, 2)).append(";");
178
showresp(WARN, ASC, "Select Band Stacks", cmd, replystr);
181
int RIG_FT450::adjust_bandwidth(int m)
186
void RIG_FT450::selectA()
192
void RIG_FT450::selectB()
198
void RIG_FT450::A2B()
202
showresp(WARN, ASC, "vfo A --> B", cmd, replystr);
205
long RIG_FT450::get_vfoA ()
209
waitN(11, 100, "get vfo A", ASC);
211
size_t p = replystr.rfind(rsp);
212
if (p == string::npos) return freqA;
214
for (size_t n = 2; n < 10; n++)
215
f = f*10 + replystr[p+n] - '0';
220
void RIG_FT450::set_vfoA (long freq)
224
for (int i = 9; i > 1; i--) {
229
showresp(WARN, ASC, "SET vfo A", cmd, replystr);
232
long RIG_FT450::get_vfoB ()
236
waitN(11, 100, "get vfo B", ASC);
238
size_t p = replystr.rfind(rsp);
239
if (p == string::npos) return freqB;
241
for (size_t n = 2; n < 10; n++)
242
f = f*10 + replystr[p+n] - '0';
247
void RIG_FT450::set_vfoB (long freq)
251
for (int i = 9; i > 1; i--) {
256
showresp(WARN, ASC, "SET vfo B", cmd, replystr);
259
void RIG_FT450::set_split(bool on)
261
if (on) cmd = "FT1;";
264
showresp(WARN, ASC, "SET split", cmd, replystr);
267
int RIG_FT450::get_split()
275
waitN(4, 100, "get split tx vfo", ASC);
276
p = replystr.rfind(rsp);
277
if (p == string::npos) return false;
278
tx = replystr[p+2] - '0';
283
waitN(4, 100, "get split rx vfo", ASC);
285
p = replystr.rfind(rsp);
286
if (p == string::npos) return false;
287
rx = replystr[p+2] - '0';
289
split = (tx == 1 ? 2 : 0) + (rx >= 4 ? 1 : 0);
294
int RIG_FT450::get_smeter()
298
waitN(7, 100, "get smeter", ASC);
300
size_t p = replystr.rfind(rsp);
301
if (p == string::npos) return 0;
303
int mtr = atoi(&replystr[p+3]);
304
mtr = mtr * 100.0 / 256.0;
309
// SWR..... mtr ... display
310
// 6:1..... 255 ... 100
311
// 3:1..... 132 ... 50
312
// 2:1..... 066 ... 26
313
// 2.5:1... 099 ... 39
314
// 1.5:1... 033 ... 13
315
// 1.1:1... 008 ... 3
317
int RIG_FT450::get_swr()
321
waitN(7, 100, "get swr", ASC);
323
size_t p = replystr.rfind(rsp);
324
if (p == string::npos) return 0;
326
int mtr = atoi(&replystr[p+3]);
331
int RIG_FT450::get_power_out()
334
sendCommand(cmd.append(";"));
335
waitN(7, 100, "get pout", ASC);
337
size_t p = replystr.rfind(rsp);
338
if (p == string::npos) return 0;
340
double mtr = (double)(atoi(&replystr[p+3]));
341
mtr = -6.6263535 + .11813178 * mtr + .0013607405 * mtr * mtr;
345
int RIG_FT450::get_power_control()
349
waitN(6, 100, "get power", ASC);
351
size_t p = replystr.rfind(rsp);
352
if (p == string::npos) return 0;
354
int mtr = atoi(&replystr[p+2]);
358
void RIG_FT450::set_power_control(double val)
362
for (int i = 4; i > 1; i--) {
367
showresp(WARN, ASC, "SET power", cmd, replystr);
370
// Volume control return 0 ... 100
371
int RIG_FT450::get_volume_control()
375
waitN(7, 100, "get vol", ASC);
377
size_t p = replystr.rfind(rsp);
378
if (p == string::npos) return progStatus.volume;
379
if (p + 6 >= replystr.length()) return progStatus.volume;
380
int val = atoi(&replystr[p+3]) * 100 / 250;
381
if (val > 100) val = 100;
385
void RIG_FT450::set_volume_control(int val)
387
int ivol = (int)(val * 250 / 100);
389
for (int i = 5; i > 2; i--) {
394
showresp(WARN, ASC, "SET vol", cmd, replystr);
397
void RIG_FT450::get_vol_min_max_step(int &min, int &max, int &step)
399
min = 0; max = 255; step = 1;
402
// Tranceiver PTT on/off
403
void RIG_FT450::set_PTT_control(int val)
405
cmd = val ? "TX1;" : "TX0;";
407
showresp(WARN, ASC, "SET PTT", cmd, replystr);
410
void RIG_FT450::tune_rig()
414
showresp(WARN, ASC, "tune rig", cmd, replystr);
417
void RIG_FT450::set_attenuator(int val)
419
if (val) cmd = "RA01;";
422
showresp(WARN, ASC, "get att", cmd, replystr);
425
int RIG_FT450::get_attenuator()
429
waitN(5, 100, "get att", ASC);
431
size_t p = replystr.rfind(rsp);
432
if (p == string::npos) return 0;
433
return (replystr[p+3] == '1' ? 1 : 0);
436
void RIG_FT450::set_preamp(int val)
438
if (val) cmd = "PA00;";
441
showresp(WARN, ASC, "set preamp", cmd, replystr);
444
int RIG_FT450::get_preamp()
448
waitN(5, 100, "get pre", ASC);
450
size_t p = replystr.rfind(rsp);
451
if (p == string::npos) return 0;
452
return (replystr[p+3] == '1' ? 0 : 1);
455
void RIG_FT450::set_modeA(int val)
459
cmd += mode_chr[val];
462
showresp(WARN, ASC, "SET mode A", cmd, replystr);
463
if (val == 2 || val == 6) return;
464
if (progStatus.spot_onoff) {
465
progStatus.spot_onoff = false;
469
showresp(WARN, ASC, "SET spot off", cmd, replystr);
474
int RIG_FT450::get_modeA()
478
waitN(5, 100, "get mode A", ASC);
480
size_t p = replystr.rfind(rsp);
481
if (p == string::npos) return modeA;
482
int md = replystr[p+3];
483
if (md <= '9') md = md - '1';
484
else md = 9 + md - 'B';
489
void RIG_FT450::set_bwA(int val)
493
case 0 : cmd = "SH000;"; break;
494
case 1 : cmd = "SH016;"; break;
495
case 2 : cmd = "SH031;"; break;
496
default: cmd = "SH031;";
499
showresp(WARN, ASC, "SET bwA", cmd, replystr);
502
int RIG_FT450::get_bwA()
506
waitN(6, 100, "get bw A", ASC);
508
size_t p = replystr.rfind(rsp);
509
if (p == string::npos) return bwA;
510
string bws = replystr.substr(p+3,2);
511
if (bws == "00") bwA = 0;
512
else if (bws == "16") bwA = 1;
513
else if (bws == "31") bwA = 2;
517
void RIG_FT450::set_modeB(int val)
521
cmd += mode_chr[val];
524
showresp(WARN, ASC, "SET mode B", cmd, replystr);
525
if (val == 2 || val == 6) return;
526
if (progStatus.spot_onoff) {
527
progStatus.spot_onoff = false;
531
showresp(WARN, ASC, "SET spot off", cmd, replystr);
536
int RIG_FT450::get_modeB()
540
waitN(5, 100, "get mode B", ASC);
542
size_t p = replystr.rfind(rsp);
543
if (p == string::npos) return modeB;
544
int md = replystr[p+3];
545
if (md <= '9') md = md - '1';
546
else md = 9 + md - 'B';
551
void RIG_FT450::set_bwB(int val)
555
case 0 : cmd = "SH000;"; break;
556
case 1 : cmd = "SH016;"; break;
557
case 2 : cmd = "SH031;"; break;
558
default: cmd = "SH031;";
561
showresp(WARN, ASC, "SET bwB", cmd, replystr);
564
int RIG_FT450::get_bwB()
568
waitN(6, 100, "get bw B", ASC);
570
size_t p = replystr.rfind(rsp);
571
if (p == string::npos) return bwB;
572
string bws = replystr.substr(p+3,2);
573
if (bws == "00") bwB = 0;
574
else if (bws == "16") bwB = 1;
575
else if (bws == "31") bwB = 2;
579
int RIG_FT450::get_modetype(int n)
584
void RIG_FT450::set_if_shift(int val)
587
if (val < 0) cmd[3] = '-';
589
for (int i = 4; i > 0; i--) {
590
cmd[3+i] += val % 10;
594
showresp(WARN, ASC, "SET ifshift", cmd, replystr);
597
bool RIG_FT450::get_if_shift(int &val)
601
waitN(9, 100, "get if shift", ASC);
603
size_t p = replystr.rfind(rsp);
604
val = progStatus.shift_val;
605
if (p == string::npos) return progStatus.shift;
606
val = atoi(&replystr[p+4]);
607
if (replystr[p+3] == '-') val = -val;
611
void RIG_FT450::get_if_min_max_step(int &min, int &max, int &step)
618
void RIG_FT450::set_notch(bool on, int val)
623
showresp(WARN, ASC, "SET notch off", cmd, replystr);
629
showresp(WARN, ASC, "SET notch on", cmd, replystr);
632
cmd[3] = '1'; // manual NOTCH position
634
val = val / 10 + 200;
635
for (int i = 3; i > 0; i--) {
636
cmd[3 + i] += val % 10;
640
showresp(WARN, ASC, "SET notch val", cmd, replystr);
643
bool RIG_FT450::get_notch(int &val)
648
waitN(8, 100, "get notch on/off", ASC);
650
size_t p = replystr.rfind(rsp);
651
val = progStatus.notch_val = 0; // disabled default slider position
652
if (p == string::npos) return ison;
654
if (replystr[p+6] == '1') { // manual notch enabled
656
val = progStatus.notch_val;
659
waitN(8, 100, "get notch val", ASC);
660
p = replystr.rfind(rsp);
661
if (p == string::npos) return ison;
662
val = atoi(&replystr[p+4]);
663
val = (val - 200) * 10;
668
void RIG_FT450::get_notch_min_max_step(int &min, int &max, int &step)
675
void RIG_FT450::set_noise(bool b)
682
showresp(WARN, ASC, "SET NB", cmd, replystr);
685
void RIG_FT450::set_xcvr_auto_on()
687
if (!progStatus.xcvr_auto_on) return;
691
waitN(4, 100, "Test: Is Rig ON", ASC);
692
size_t p = replystr.rfind(rsp);
693
if (p == string::npos) { // rig is off, power on
696
MilliSleep(1500); // 1.0 < T < 2.0 seconds
698
MilliSleep(3000); // Wait for rig startup? Maybe not needed.
702
void RIG_FT450::set_xcvr_auto_off()
704
if (!progStatus.xcvr_auto_off) return;
711
void RIG_FT450::set_mic_gain(int val)
714
val = (int)(val * 2.55); // convert to 0 .. 255
715
for (int i = 3; i > 0; i--) {
716
cmd[1+i] += val % 10;
720
showresp(WARN, ASC, "SET mic", cmd, replystr);
723
int RIG_FT450::get_mic_gain()
727
waitN(6, 100, "get mic", ASC);
729
size_t p = replystr.rfind(rsp);
730
if (p == string::npos) return 0;
732
return atoi(&replystr[p+2]);;
735
void RIG_FT450::get_mic_min_max_step(int &min, int &max, int &step)
742
void RIG_FT450::set_special(int v)
747
showresp(WARN, ASC, "Set special", cmd, replystr);
750
void RIG_FT450::set_vox_onoff()
753
if (progStatus.vox_onoff) cmd[2] = '1';
755
showresp(WARN, ASC, "SET vox on/off", cmd, replystr);
758
void RIG_FT450::set_vox_gain()
761
cmd.append(to_decimal(progStatus.vox_gain, 3)).append(";");
763
showresp(WARN, ASC, "SET vox gain", cmd, replystr);
766
void RIG_FT450::set_vox_hang()
769
cmd.append(to_decimal(progStatus.vox_hang, 4)).append(";");
771
showresp(WARN, ASC, "SET vox delay", cmd, replystr);
774
void RIG_FT450::set_cw_wpm()
777
if (progStatus.cw_wpm > 60) progStatus.cw_wpm = 60;
778
if (progStatus.cw_wpm < 4) progStatus.cw_wpm = 4;
779
cmd.append(to_decimal(progStatus.cw_wpm, 3)).append(";");
781
showresp(WARN, ASC, "SET cw wpm", cmd, replystr);
785
void RIG_FT450::enable_keyer()
788
if (progStatus.enable_keyer) cmd[2] = '1';
790
showresp(WARN, ASC, "SET keyer on/off", cmd, replystr);
793
bool RIG_FT450::set_cw_spot()
795
if (vfo.imode == 2 || vfo.imode == 6) {
797
if (progStatus.spot_onoff) cmd[2] = '1';
799
showresp(WARN, ASC, "SET spot on/off", cmd, replystr);
805
void RIG_FT450::set_cw_weight()
807
int n = round(progStatus.cw_weight * 10);
808
cmd.assign("EX024").append(to_decimal(n, 2)).append(";");
810
showresp(WARN, ASC, "SET cw weight", cmd, replystr);
813
void RIG_FT450::set_cw_qsk()
815
int n = progStatus.cw_qsk / 5 - 3;
816
cmd.assign("EX018").append(to_decimal(n, 1)).append(";");
818
showresp(WARN, ASC, "SET cw qsk", cmd, replystr);
821
void RIG_FT450::set_cw_spot_tone()
823
int n = (progStatus.cw_spot_tone - 400) / 50 + 1;
825
cmd.append(to_decimal(n, 2)).append(";");
827
showresp(WARN, ASC, "SET cw tone", cmd, replystr);
831
void RIG_FT450::set_noise_reduction_val(int val)
833
cmd.assign("RL0").append(to_decimal(val, 2)).append(";");
835
showresp(WARN, ASC, "SET_noise_reduction_val", cmd, replystr);
838
int RIG_FT450::get_noise_reduction_val()
843
waitN(6, 100, "GET noise reduction val", ASC);
844
size_t p = replystr.rfind(rsp);
845
if (p == string::npos) return val;
846
val = atoi(&replystr[p+3]);
851
void RIG_FT450::set_noise_reduction(int val)
853
cmd.assign("NR0").append(val ? "1" : "0" ).append(";");
855
showresp(WARN, ASC, "SET noise reduction", cmd, replystr);
858
int RIG_FT450::get_noise_reduction()
863
waitN(5, 100, "GET noise reduction", ASC);
864
size_t p = replystr.rfind(rsp);
865
if (p == string::npos) return 0;
866
val = replystr[p+3] - '0';