feat(k3): a mode row on the Elecraft console — CW/USB/LSB/DATA/DATA-RTTY
The report: switching the K3 to a data mode 'does not work for FT8 — the K3 does not go into DATA'. The mode digit is only half the answer on that radio: MD6 keeps whatever DT submode the previous session left, and with FSK D still armed the rig keys FT8 with no rear-audio modulation. The panel buttons say the whole thing: DATA is MD6+DT0 (DATA A, the soundcard path), DATA RTTY is MD6+DT2 (FSK D). The DT submode is also read on the settings beat — Elecraft only, a plain Kenwood would '?;' it — so the active DATA button follows what the rig is actually in, front-panel changes included. A dedicated SetKenwoodPanelMode rather than the logger's SetMode: a panel button is the operator saying exactly what the rig should do, not an ADIF mode to be mapped through preferences.
This commit is contained in:
@@ -35,6 +35,11 @@ type KenwoodTXState struct {
|
||||
Model string `json:"model,omitempty"`
|
||||
Elecraft bool `json:"elecraft"` // a K3/K4 rather than a Kenwood
|
||||
Mode string `json:"mode,omitempty"`
|
||||
// DataSub is the K3/K4 DATA submode while in DATA mode (DT): "DATA A",
|
||||
// "AFSK A", "FSK D" or "PSK D". Empty on a Kenwood, and outside DATA. The
|
||||
// panel's two DATA buttons need it to show WHICH data mode the rig is in —
|
||||
// FT8 wants DATA A, RTTY wants FSK D, and MD6 alone cannot say which.
|
||||
DataSub string `json:"data_sub,omitempty"`
|
||||
|
||||
Transmitting bool `json:"transmitting"`
|
||||
Split bool `json:"split"`
|
||||
@@ -111,6 +116,7 @@ type KenwoodPanelController interface {
|
||||
SetKenwoodTX(bool) error
|
||||
TuneKenwoodATU() error
|
||||
ToggleKenwoodATU() error
|
||||
SetKenwoodPanelMode(string) error
|
||||
}
|
||||
|
||||
// kenwoodPanelSlowBeat is how many polls pass between full re-reads of the
|
||||
@@ -212,6 +218,14 @@ func (k *Kenwood) readPanelSettings() {
|
||||
if v, ok := k.askNum("NR;", "NR", 1); ok {
|
||||
k.panel.NR = v != 0
|
||||
}
|
||||
// The DATA submode, Elecraft only (a plain Kenwood has no DT and would "?;"
|
||||
// it). Read every settings beat: the operator changes it from the rig's own
|
||||
// front panel mid-session, and the two DATA buttons must follow.
|
||||
if k.elecraft {
|
||||
if v, ok := k.askNum("DT;", "DT", 1); ok {
|
||||
k.panel.DataSub = kenwoodDataSubName(v)
|
||||
}
|
||||
}
|
||||
if v, ok := k.askNum("GT;", "GT", 3); ok {
|
||||
k.panel.AGC = kenwoodAGCName(v)
|
||||
}
|
||||
@@ -650,3 +664,58 @@ func (k *Kenwood) askNum(cmd, prefix string, digits int) (int, bool) {
|
||||
}
|
||||
return n, true
|
||||
}
|
||||
|
||||
// kenwoodDataSubName decodes DT (K3/K4 programmer's reference).
|
||||
func kenwoodDataSubName(v int) string {
|
||||
switch v {
|
||||
case 0:
|
||||
return "DATA A"
|
||||
case 1:
|
||||
return "AFSK A"
|
||||
case 2:
|
||||
return "FSK D"
|
||||
case 3:
|
||||
return "PSK D"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// SetKenwoodPanelMode is the panel's mode row: CW / USB / LSB / DATA / RTTY.
|
||||
//
|
||||
// It exists because SetMode is the LOGGER's path — it maps an ADIF mode and
|
||||
// honours the data-mode preference — while a panel button is the operator
|
||||
// saying exactly what the rig should do. The two DATA cases are the point:
|
||||
// "DATA" is MD6 + DT0 (DATA A, the soundcard submode FT8/FT4 modulate through)
|
||||
// and "RTTY" is MD6 + DT2 (FSK D, the K3's direct-keyed RTTY). MD6 alone keeps
|
||||
// whatever submode a prior session left, which is how a K3 "in DATA" transmits
|
||||
// FT8 with no audio — the report behind this row.
|
||||
func (k *Kenwood) SetKenwoodPanelMode(mode string) error {
|
||||
k.mu.Lock()
|
||||
defer k.mu.Unlock()
|
||||
if k.port == nil {
|
||||
return fmt.Errorf("kenwood: not connected")
|
||||
}
|
||||
var cmds []string
|
||||
switch strings.ToUpper(strings.TrimSpace(mode)) {
|
||||
case "CW":
|
||||
cmds = []string{"MD3;"}
|
||||
case "USB":
|
||||
cmds = []string{"MD2;"}
|
||||
case "LSB":
|
||||
cmds = []string{"MD1;"}
|
||||
case "DATA":
|
||||
cmds = []string{"MD6;", "DT0;"}
|
||||
case "RTTY":
|
||||
cmds = []string{"MD6;", "DT2;"}
|
||||
default:
|
||||
return fmt.Errorf("kenwood panel: unknown mode %q", mode)
|
||||
}
|
||||
for _, c := range cmds {
|
||||
if err := k.write(c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// Re-read the settings on the next poll so Mode and DataSub confirm at once.
|
||||
k.panelCycle = kenwoodPanelSlowBeat
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user