mirror of
https://github.com/nonoo/kappanhang.git
synced 2026-01-05 08:19:58 +01:00
Add support for displaying/adjusting the tuning step
This commit is contained in:
parent
70609960a6
commit
b7c79a2bd4
21
README.md
21
README.md
|
|
@ -85,8 +85,12 @@ kappanhang displays a "realtime" status bar (when the audio/serial connection
|
|||
is up) with the following info:
|
||||
|
||||
- First status bar line:
|
||||
- `S meter`: periodically refreshed S meter value
|
||||
|
||||
- Second status bar line:
|
||||
- `state`: RX/TX/TUNE depending on the PTT status
|
||||
- `freq`: operating frequency in MHz
|
||||
- `ts`: tuning step
|
||||
- `mode`: LSB/USB/FM etc.
|
||||
- `filter`: active filter (FIL1, FIL2 etc.)
|
||||
- `preamp`: PAMP0 means the preamp is off
|
||||
|
|
@ -94,9 +98,8 @@ is up) with the following info:
|
|||
- `txpwr`: current transmit power setting in percent
|
||||
- `audio`: current status of the audio monitor (see the *Hotkeys* section
|
||||
in this README for more information about this feature)
|
||||
- `S meter`: periodically refreshed S meter value
|
||||
|
||||
- Second status bar line:
|
||||
- Third status bar line:
|
||||
- `up`: how long the audio/serial connection is active
|
||||
- `rtt`: roundtrip communication latency with the server
|
||||
- `up/down`: currently used upload/download bandwidth (only considering UDP
|
||||
|
|
@ -104,8 +107,8 @@ is up) with the following info:
|
|||
- `retx`: audio/serial retransmit request count to/from the server
|
||||
- `lost`: lost audio/serial packet count from the server
|
||||
|
||||
Data for the first status bar line is acquired by monitoring CiV traffic in
|
||||
the serial stream.
|
||||
Data for the first 2 status bar lines are acquired by monitoring CiV traffic
|
||||
in the serial stream. S value is queried periodically.
|
||||
|
||||
`retx` and `lost` are displayed in a 1 minute window, which means they will be
|
||||
reset to 0 if they don't increase for 1 minute. A `retx` value other than 0
|
||||
|
|
@ -116,7 +119,7 @@ audio and serial communication disruptions.
|
|||
|
||||
If status bar interval (can be changed with the `-i` command line
|
||||
argument) is equal to or above 1 second, then the realtime status bar will be
|
||||
disabled and the contents of the second line of the status bar will be written
|
||||
disabled and the contents of the last line of the status bar will be written
|
||||
as new console log lines. This is also the case if a Unix/VT100 terminal is
|
||||
not available.
|
||||
|
||||
|
|
@ -135,12 +138,8 @@ Some basic CAT control hotkeys are also supported:
|
|||
- `t`: toggles the tune process
|
||||
- `+`: increases TX power
|
||||
- `-`: decreases TX power
|
||||
- `<`, `>`: decreases, increases frequency 1Hz
|
||||
- `,`, `.`: decreases, increases frequency 10Hz
|
||||
- `:`, `"`: decreases, increases frequency 100Hz
|
||||
- `;`, `'`: decreases, increases frequency 1kHz
|
||||
- `{`, `}`: decreases, increases frequency 10kHz
|
||||
- `[`, `]`: decreases, increases frequency 100kHz
|
||||
- `[`, `]`: decreases, increases frequency
|
||||
- `{`, `}`: decreases, increases tuning step
|
||||
- `n`, `m`: cycles through operating modes
|
||||
- `d`, `f`: cycles through filters
|
||||
- `D`: toggles data mode
|
||||
|
|
|
|||
|
|
@ -79,6 +79,8 @@ type civControlStruct struct {
|
|||
bandIdx int
|
||||
bandChanging bool
|
||||
preamp int
|
||||
tsValue byte
|
||||
ts uint
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -100,6 +102,8 @@ func (s *civControlStruct) decode(d []byte) {
|
|||
s.decodeFreq(payload)
|
||||
case 0x04:
|
||||
s.decodeMode(payload)
|
||||
case 0x10:
|
||||
s.decodeTS(payload)
|
||||
case 0x1a:
|
||||
s.decodeDataMode(payload)
|
||||
case 0x14:
|
||||
|
|
@ -174,6 +178,46 @@ func (s *civControlStruct) decodeMode(d []byte) {
|
|||
_ = s.getDataMode()
|
||||
}
|
||||
|
||||
func (s *civControlStruct) decodeTS(d []byte) {
|
||||
if len(d) < 1 {
|
||||
return
|
||||
}
|
||||
|
||||
s.state.tsValue = d[0]
|
||||
|
||||
switch s.state.tsValue {
|
||||
default:
|
||||
s.state.ts = 1
|
||||
case 1:
|
||||
s.state.ts = 100
|
||||
case 2:
|
||||
s.state.ts = 500
|
||||
case 3:
|
||||
s.state.ts = 1000
|
||||
case 4:
|
||||
s.state.ts = 5000
|
||||
case 5:
|
||||
s.state.ts = 6250
|
||||
case 6:
|
||||
s.state.ts = 8330
|
||||
case 7:
|
||||
s.state.ts = 9000
|
||||
case 8:
|
||||
s.state.ts = 10000
|
||||
case 9:
|
||||
s.state.ts = 12500
|
||||
case 10:
|
||||
s.state.ts = 20000
|
||||
case 11:
|
||||
s.state.ts = 25000
|
||||
case 12:
|
||||
s.state.ts = 50000
|
||||
case 13:
|
||||
s.state.ts = 100000
|
||||
}
|
||||
statusLog.reportTS(s.state.ts)
|
||||
}
|
||||
|
||||
func (s *civControlStruct) decodeDataMode(d []byte) {
|
||||
if len(d) < 3 || d[0] != 0x06 {
|
||||
return
|
||||
|
|
@ -304,12 +348,12 @@ func (s *civControlStruct) getDigit(v uint, n int) byte {
|
|||
return byte(uint(f) % 10)
|
||||
}
|
||||
|
||||
func (s *civControlStruct) incFreq(v uint) error {
|
||||
return s.setFreq(s.state.freq + v)
|
||||
func (s *civControlStruct) incFreq() error {
|
||||
return s.setFreq(s.state.freq + s.state.ts)
|
||||
}
|
||||
|
||||
func (s *civControlStruct) decFreq(v uint) error {
|
||||
return s.setFreq(s.state.freq - v)
|
||||
func (s *civControlStruct) decFreq() error {
|
||||
return s.setFreq(s.state.freq - s.state.ts)
|
||||
}
|
||||
|
||||
func (s *civControlStruct) setFreq(f uint) error {
|
||||
|
|
@ -448,6 +492,26 @@ func (s *civControlStruct) togglePreamp() error {
|
|||
return s.st.send([]byte{254, 254, civAddress, 224, 0x16, 0x02, b, 253})
|
||||
}
|
||||
|
||||
func (s *civControlStruct) incTS() error {
|
||||
var b byte
|
||||
if s.state.tsValue == 13 {
|
||||
b = 0
|
||||
} else {
|
||||
b = s.state.tsValue + 1
|
||||
}
|
||||
return s.st.send([]byte{254, 254, civAddress, 224, 0x10, b, 253})
|
||||
}
|
||||
|
||||
func (s *civControlStruct) decTS() error {
|
||||
var b byte
|
||||
if s.state.tsValue == 0 {
|
||||
b = 13
|
||||
} else {
|
||||
b = s.state.tsValue - 1
|
||||
}
|
||||
return s.st.send([]byte{254, 254, civAddress, 224, 0x10, b, 253})
|
||||
}
|
||||
|
||||
func (s *civControlStruct) getFreq() error {
|
||||
return s.st.send([]byte{254, 254, civAddress, 224, 3, 253})
|
||||
}
|
||||
|
|
@ -475,6 +539,10 @@ func (s *civControlStruct) getS() error {
|
|||
return s.st.send([]byte{254, 254, civAddress, 224, 0x15, 0x02, 253})
|
||||
}
|
||||
|
||||
func (s *civControlStruct) getTS() error {
|
||||
return s.st.send([]byte{254, 254, civAddress, 224, 0x10, 253})
|
||||
}
|
||||
|
||||
func (s *civControlStruct) loop() {
|
||||
for {
|
||||
select {
|
||||
|
|
@ -517,6 +585,9 @@ func (s *civControlStruct) init(st *serialStream) error {
|
|||
if err := s.getS(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.getTS(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.deinitNeeded = make(chan bool)
|
||||
s.deinitFinished = make(chan bool)
|
||||
|
|
|
|||
76
hotkeys.go
76
hotkeys.go
|
|
@ -24,78 +24,30 @@ func handleHotkey(k byte) {
|
|||
log.Error("can't decrease power: ", err)
|
||||
}
|
||||
}
|
||||
case '>':
|
||||
if civControl != nil {
|
||||
if err := civControl.incFreq(1); err != nil {
|
||||
log.Error("can't increase freq: ", err)
|
||||
}
|
||||
}
|
||||
case '<':
|
||||
if civControl != nil {
|
||||
if err := civControl.decFreq(1); err != nil {
|
||||
log.Error("can't decrease freq: ", err)
|
||||
}
|
||||
}
|
||||
case '.':
|
||||
if civControl != nil {
|
||||
if err := civControl.incFreq(10); err != nil {
|
||||
log.Error("can't increase freq: ", err)
|
||||
}
|
||||
}
|
||||
case ',':
|
||||
if civControl != nil {
|
||||
if err := civControl.decFreq(10); err != nil {
|
||||
log.Error("can't decrease freq: ", err)
|
||||
}
|
||||
}
|
||||
case '"':
|
||||
if civControl != nil {
|
||||
if err := civControl.incFreq(100); err != nil {
|
||||
log.Error("can't increase freq: ", err)
|
||||
}
|
||||
}
|
||||
case ':':
|
||||
if civControl != nil {
|
||||
if err := civControl.decFreq(100); err != nil {
|
||||
log.Error("can't decrease freq: ", err)
|
||||
}
|
||||
}
|
||||
case '\'':
|
||||
if civControl != nil {
|
||||
if err := civControl.incFreq(1000); err != nil {
|
||||
log.Error("can't increase freq: ", err)
|
||||
}
|
||||
}
|
||||
case ';':
|
||||
if civControl != nil {
|
||||
if err := civControl.decFreq(1000); err != nil {
|
||||
log.Error("can't decrease freq: ", err)
|
||||
}
|
||||
}
|
||||
case '}':
|
||||
if civControl != nil {
|
||||
if err := civControl.incFreq(10000); err != nil {
|
||||
log.Error("can't increase freq: ", err)
|
||||
}
|
||||
}
|
||||
case '{':
|
||||
if civControl != nil {
|
||||
if err := civControl.decFreq(10000); err != nil {
|
||||
log.Error("can't decrease freq: ", err)
|
||||
}
|
||||
}
|
||||
case ']':
|
||||
if civControl != nil {
|
||||
if err := civControl.incFreq(100000); err != nil {
|
||||
if err := civControl.incFreq(); err != nil {
|
||||
log.Error("can't increase freq: ", err)
|
||||
}
|
||||
}
|
||||
case '[':
|
||||
if civControl != nil {
|
||||
if err := civControl.decFreq(100000); err != nil {
|
||||
if err := civControl.decFreq(); err != nil {
|
||||
log.Error("can't decrease freq: ", err)
|
||||
}
|
||||
}
|
||||
case '}':
|
||||
if civControl != nil {
|
||||
if err := civControl.incTS(); err != nil {
|
||||
log.Error("can't increase ts: ", err)
|
||||
}
|
||||
}
|
||||
case '{':
|
||||
if civControl != nil {
|
||||
if err := civControl.decTS(); err != nil {
|
||||
log.Error("can't decrease ts: ", err)
|
||||
}
|
||||
}
|
||||
case 'm':
|
||||
if civControl != nil {
|
||||
if err := civControl.incOperatingMode(); err != nil {
|
||||
|
|
|
|||
52
statuslog.go
52
statuslog.go
|
|
@ -15,15 +15,16 @@ type statusLogData struct {
|
|||
line2 string
|
||||
line3 string
|
||||
|
||||
stateStr string
|
||||
frequency uint
|
||||
mode string
|
||||
dataMode string
|
||||
filter string
|
||||
preamp string
|
||||
vd string
|
||||
txPowerStr string
|
||||
s string
|
||||
stateStr string
|
||||
frequency uint
|
||||
mode string
|
||||
dataMode string
|
||||
filter string
|
||||
preamp string
|
||||
vd string
|
||||
txPower string
|
||||
s string
|
||||
ts string
|
||||
|
||||
startTime time.Time
|
||||
rttStr string
|
||||
|
|
@ -167,6 +168,27 @@ func (s *statusLogStruct) reportS(sValue string) {
|
|||
s.data.s = sValue
|
||||
}
|
||||
|
||||
func (s *statusLogStruct) reportTS(ts uint) {
|
||||
s.mutex.Lock()
|
||||
defer s.mutex.Unlock()
|
||||
|
||||
if s.data == nil {
|
||||
return
|
||||
}
|
||||
s.data.ts = "TS"
|
||||
if ts >= 1000 {
|
||||
if ts%1000 == 0 {
|
||||
s.data.ts += fmt.Sprintf("%.0fk", float64(ts)/1000)
|
||||
} else if ts%100 == 0 {
|
||||
s.data.ts += fmt.Sprintf("%.1fk", float64(ts)/1000)
|
||||
} else {
|
||||
s.data.ts += fmt.Sprintf("%.2fk", float64(ts)/1000)
|
||||
}
|
||||
} else {
|
||||
s.data.ts += fmt.Sprint(ts)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *statusLogStruct) reportPTT(ptt, tune bool) {
|
||||
s.mutex.Lock()
|
||||
defer s.mutex.Unlock()
|
||||
|
|
@ -190,7 +212,7 @@ func (s *statusLogStruct) reportTxPower(percent int) {
|
|||
if s.data == nil {
|
||||
return
|
||||
}
|
||||
s.data.txPowerStr = fmt.Sprint(percent, "%")
|
||||
s.data.txPower = fmt.Sprint(percent, "%")
|
||||
}
|
||||
|
||||
func (s *statusLogStruct) clearInternal() {
|
||||
|
|
@ -229,6 +251,10 @@ func (s *statusLogStruct) update() {
|
|||
|
||||
s.data.line1 = fmt.Sprint(s.data.s)
|
||||
|
||||
var tsStr string
|
||||
if s.data.ts != "" {
|
||||
tsStr = " " + s.data.ts
|
||||
}
|
||||
var modeStr string
|
||||
if s.data.mode != "" {
|
||||
modeStr = " " + s.data.mode + s.data.dataMode
|
||||
|
|
@ -246,11 +272,11 @@ func (s *statusLogStruct) update() {
|
|||
vdStr = " " + s.data.vd
|
||||
}
|
||||
var txPowerStr string
|
||||
if s.data.txPowerStr != "" {
|
||||
txPowerStr = " txpwr " + s.data.txPowerStr
|
||||
if s.data.txPower != "" {
|
||||
txPowerStr = " txpwr " + s.data.txPower
|
||||
}
|
||||
s.data.line2 = fmt.Sprint(s.data.stateStr, " ", fmt.Sprintf("%.6f", float64(s.data.frequency)/1000000),
|
||||
modeStr, filterStr, preampStr, vdStr, txPowerStr, " audio ", s.data.audioStateStr)
|
||||
tsStr, modeStr, filterStr, preampStr, vdStr, txPowerStr, " audio ", s.data.audioStateStr)
|
||||
|
||||
up, down, lost, retransmits := netstat.get()
|
||||
lostStr := "0"
|
||||
|
|
|
|||
Loading…
Reference in a new issue