Quisk version 4.2.47
This commit is contained in:
@@ -1,3 +1,15 @@
|
|||||||
|
Quisk Version 4.2.47 November 2025
|
||||||
|
===================================
|
||||||
|
To improve the performance of Quisk with the Anan 10-E and other OpenHPSDR radios, I added
|
||||||
|
a new type of radio "OpenHPSDR". Use this type for the Anan 10-E and similar radios. It removes
|
||||||
|
all the protocol extensions added by the Hermes-Lite2 project. I removed the configuration
|
||||||
|
option "Hermes Lite2 protocol enable". This is now automatic.
|
||||||
|
|
||||||
|
I added buttons for antennas 0, 1, 2 and 3 for OpenHPSDR radios that support more antennas.
|
||||||
|
I added controls for the OpenHPSDR preamplifier and attenuator.
|
||||||
|
|
||||||
|
I do not have any Apache Labs radios, so I must depend on my users to report problems and solutions.
|
||||||
|
|
||||||
Quisk Version 4.2.46 October 2025
|
Quisk Version 4.2.46 October 2025
|
||||||
==================================
|
==================================
|
||||||
I fixed a bug in Hamlib rig 2 which happens with the new Pure Signal code. The Hamlib "f" command
|
I fixed a bug in Hamlib rig 2 which happens with the new Pure Signal code. The Hamlib "f" command
|
||||||
|
|||||||
+1
-1
@@ -1,2 +1,2 @@
|
|||||||
#Quisk version 4.2.46
|
#Quisk version 4.2.47
|
||||||
from .quisk import main
|
from .quisk import main
|
||||||
|
|||||||
+7
-4
@@ -88,6 +88,7 @@ class Configuration:
|
|||||||
platform_ignore = 'win_'
|
platform_ignore = 'win_'
|
||||||
self.sections = []
|
self.sections = []
|
||||||
self.receiver_data = []
|
self.receiver_data = []
|
||||||
|
self.receiver_explain = []
|
||||||
self.StatePath = conf.settings_file_path
|
self.StatePath = conf.settings_file_path
|
||||||
if not self.StatePath:
|
if not self.StatePath:
|
||||||
self.StatePath = os.path.join(app.QuiskFilesDir, "quisk_settings.json")
|
self.StatePath = os.path.join(app.QuiskFilesDir, "quisk_settings.json")
|
||||||
@@ -601,6 +602,7 @@ class Configuration:
|
|||||||
# Receiver sections start with 16 #, "Receivers ", receiver name, explain
|
# Receiver sections start with 16 #, "Receivers ", receiver name, explain
|
||||||
# self.receiver_data is a list of [receiver_name, receiver_data]
|
# self.receiver_data is a list of [receiver_name, receiver_data]
|
||||||
# receiver_data is a list of [data_name, text, fmt, help_text, values]
|
# receiver_data is a list of [data_name, text, fmt, help_text, values]
|
||||||
|
# self.receiver_explain is a list of the text in Receivers: the name, a comma and the explanation.
|
||||||
|
|
||||||
# Variable names start with ## variable_name variable_text, format
|
# Variable names start with ## variable_name variable_text, format
|
||||||
# The format is integer, number, text, boolean, integer choice, text choice, rfile
|
# The format is integer, number, text, boolean, integer choice, text choice, rfile
|
||||||
@@ -638,6 +640,7 @@ class Configuration:
|
|||||||
continue
|
continue
|
||||||
if line[0:27] == '################ Receivers ':
|
if line[0:27] == '################ Receivers ':
|
||||||
section = 'Receivers'
|
section = 'Receivers'
|
||||||
|
self.receiver_explain.append(line[27:].strip())
|
||||||
args = line[27:].split(',', 1)
|
args = line[27:].split(',', 1)
|
||||||
rxname = args[0].strip()
|
rxname = args[0].strip()
|
||||||
section_data = []
|
section_data = []
|
||||||
@@ -2298,7 +2301,7 @@ class ControlMixin:
|
|||||||
if self.radio_name == Settings[1]: # changed for current radio
|
if self.radio_name == Settings[1]: # changed for current radio
|
||||||
if name in ('hot_key_ptt_toggle', 'hot_key_ptt_if_hidden', 'keyupDelay', 'cwTone', 'pulse_audio_verbose_output',
|
if name in ('hot_key_ptt_toggle', 'hot_key_ptt_if_hidden', 'keyupDelay', 'cwTone', 'pulse_audio_verbose_output',
|
||||||
'start_cw_delay', 'start_ssb_delay', 'maximum_tx_secs', 'quisk_serial_cts', 'quisk_serial_dsr',
|
'start_cw_delay', 'start_ssb_delay', 'maximum_tx_secs', 'quisk_serial_cts', 'quisk_serial_dsr',
|
||||||
'hot_key_ptt1', 'hot_key_ptt2', 'midi_ptt_toggle', 'TxRxSilenceMsec', 'hermes_lite2_enable',
|
'hot_key_ptt1', 'hot_key_ptt2', 'midi_ptt_toggle', 'TxRxSilenceMsec',
|
||||||
'fixed_tune_offset'):
|
'fixed_tune_offset'):
|
||||||
setattr(conf, name, x)
|
setattr(conf, name, x)
|
||||||
application.ImmediateChange(name)
|
application.ImmediateChange(name)
|
||||||
@@ -2737,8 +2740,8 @@ class Radios(BaseWindow): # The "Radios" first-level page
|
|||||||
self.NextRow()
|
self.NextRow()
|
||||||
rb = self.AddRadioButton(1, "Add a new radio with the general type", self.NewTop)
|
rb = self.AddRadioButton(1, "Add a new radio with the general type", self.NewTop)
|
||||||
choices = []
|
choices = []
|
||||||
for name, data in local_conf.receiver_data:
|
for explain in local_conf.receiver_explain:
|
||||||
choices.append(name)
|
choices.append(explain)
|
||||||
choices.sort()
|
choices.sort()
|
||||||
self.add_type = self.AddComboCtrl(2, '', choices=choices, no_edit=True)
|
self.add_type = self.AddComboCtrl(2, '', choices=choices, no_edit=True)
|
||||||
self.add_type.SetSelection(0)
|
self.add_type.SetSelection(0)
|
||||||
@@ -2810,7 +2813,7 @@ class Radios(BaseWindow): # The "Radios" first-level page
|
|||||||
if not name or self.DuplicateName(name):
|
if not name or self.DuplicateName(name):
|
||||||
return
|
return
|
||||||
self.add_name.SetValue('')
|
self.add_name.SetValue('')
|
||||||
typ = self.add_type.GetValue().strip()
|
typ = self.add_type.GetValue().split(',')[0].strip()
|
||||||
if local_conf.AddRadio(name, typ):
|
if local_conf.AddRadio(name, typ):
|
||||||
self.NewRadioNames()
|
self.NewRadioNames()
|
||||||
local_conf.settings_changed = True
|
local_conf.settings_changed = True
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
# Please do not change this widgets module for Quisk. Instead copy
|
||||||
|
# it to your own quisk_widgets.py and make changes there.
|
||||||
|
#
|
||||||
|
# This module is used to add extra widgets to the QUISK screen.
|
||||||
|
|
||||||
|
import wx
|
||||||
|
|
||||||
|
class BottomWidgets: # Add extra widgets to the bottom of the screen
|
||||||
|
def __init__(self, app, hardware, conf, frame, gbs, vertBox):
|
||||||
|
self.config = conf
|
||||||
|
self.hardware = hardware
|
||||||
|
self.application = app
|
||||||
|
self.start_row = app.widget_row # The first available row
|
||||||
|
self.start_col = app.button_start_col # The start of the button columns
|
||||||
|
self.num_rows_added = 1
|
||||||
|
self.btnPreamp = app.QuiskCheckbutton(frame, self.OnBtnPreamp, text='Preamp')
|
||||||
|
gbs.Add(self.btnPreamp, (self.start_row, self.start_col), flag=wx.EXPAND)
|
||||||
|
init = app.hermes_atten_dB
|
||||||
|
self.sliderAtten = app.SliderBoxHH(frame, 'Atten %d dB', init, 0, 31, self.OnAtten, True)
|
||||||
|
self.sliderAtten.idName = "RfAtten"
|
||||||
|
app.midiControls["RfAtten"] = (self.sliderAtten, self.OnAtten)
|
||||||
|
hardware.ChangeAtten(init)
|
||||||
|
gbs.Add(self.sliderAtten, (self.start_row, self.start_col + 2), (1, 6), flag=wx.EXPAND)
|
||||||
|
def OnBtnPreamp(self, event):
|
||||||
|
self.hardware.ChangePreamp(self.btnPreamp.GetValue())
|
||||||
|
def OnAtten(self, event):
|
||||||
|
value = self.sliderAtten.GetValue()
|
||||||
|
self.hardware.ChangeAtten(value)
|
||||||
|
self.application.hermes_atten_dB = value
|
||||||
|
def UpdateText(self): # Called at intervals
|
||||||
|
pass
|
||||||
+23
-11
@@ -48,6 +48,8 @@ class IOBoard:
|
|||||||
def HeartBeat(self): # Called at 10 Hz for housekeeping tasks
|
def HeartBeat(self): # Called at 10 Hz for housekeeping tasks
|
||||||
if not QS.get_params('rx_udp_started'):
|
if not QS.get_params('rx_udp_started'):
|
||||||
return
|
return
|
||||||
|
if self.hardware.hermes_board_id != 6:
|
||||||
|
return
|
||||||
if self.have_IO_Board is None:
|
if self.have_IO_Board is None:
|
||||||
resp = self.hardware.ReadI2C(0x7d, 0x41, 0) # Check for the N2ADR HL2 IO Board
|
resp = self.hardware.ReadI2C(0x7d, 0x41, 0) # Check for the N2ADR HL2 IO Board
|
||||||
if resp and resp[1] == 0xF1:
|
if resp and resp[1] == 0xF1:
|
||||||
@@ -166,7 +168,10 @@ class Hardware(BaseHardware):
|
|||||||
self.vna_count = 0
|
self.vna_count = 0
|
||||||
self.vna_started = False
|
self.vna_started = False
|
||||||
self.repeater_freq = None # original repeater output frequency
|
self.repeater_freq = None # original repeater output frequency
|
||||||
self.antenna_labels = ('Ant 0', 'Ant 1') # labels for the antenna button
|
if conf.hardware_file_type == "Red Pitaya":
|
||||||
|
self.antenna_labels = ('Ant 0', 'Ant 1') # labels for the antenna button
|
||||||
|
else:
|
||||||
|
self.antenna_labels = ('Ant 0', 'Ant 1', 'Ant 2', 'Ant 3')
|
||||||
self.antenna_index = 0 # index of antenna in use
|
self.antenna_index = 0 # index of antenna in use
|
||||||
self.delay_config = True # Delay sending message to HL2 until after sound starts
|
self.delay_config = True # Delay sending message to HL2 until after sound starts
|
||||||
self.TFRC_counter = 0 # Call for power etc. at intervals
|
self.TFRC_counter = 0 # Call for power etc. at intervals
|
||||||
@@ -529,7 +534,9 @@ class Hardware(BaseHardware):
|
|||||||
def ChangeBandFilters(self):
|
def ChangeBandFilters(self):
|
||||||
if not hasattr(self.application, "multi_rx_screen"):
|
if not hasattr(self.application, "multi_rx_screen"):
|
||||||
return # Needed for the VNA program
|
return # Needed for the VNA program
|
||||||
self.SetControlBit(0x00, 13, self.antenna_index)
|
self.SetControlBit(0x00, 13, self.antenna_index & 0x01)
|
||||||
|
self.SetControlBit(0x00, 14, self.antenna_index & 0x02)
|
||||||
|
self.SetControlBit(0x00, 15, self.antenna_index > 0)
|
||||||
highest = self.band
|
highest = self.band
|
||||||
freq = self.conf.BandEdge.get(highest, (0, 0))[0]
|
freq = self.conf.BandEdge.get(highest, (0, 0))[0]
|
||||||
for pane in self.application.multi_rx_screen.receiver_list:
|
for pane in self.application.multi_rx_screen.receiver_list:
|
||||||
@@ -606,12 +613,7 @@ class Hardware(BaseHardware):
|
|||||||
return (48000, 384000)
|
return (48000, 384000)
|
||||||
## Hardware AGC is no longer supported in HL2 identifying as version >=40
|
## Hardware AGC is no longer supported in HL2 identifying as version >=40
|
||||||
def ChangeAGC(self, value):
|
def ChangeAGC(self, value):
|
||||||
if value:
|
pass
|
||||||
self.pc2hermes[2] |= 0x10 # C0 index == 0, C3[4]: AGC enable
|
|
||||||
else:
|
|
||||||
self.pc2hermes[2] &= ~0x10
|
|
||||||
QS.pc_to_hermes(self.pc2hermes)
|
|
||||||
if DEBUG: print ("Change AGC to", value)
|
|
||||||
## Simpler LNA setting for HL2 identifying as version >=40, see HL2 wiki for details
|
## Simpler LNA setting for HL2 identifying as version >=40, see HL2 wiki for details
|
||||||
def ChangeLNA(self, value): # LNA for Rx
|
def ChangeLNA(self, value): # LNA for Rx
|
||||||
# value is -12 to +48
|
# value is -12 to +48
|
||||||
@@ -624,7 +626,7 @@ class Hardware(BaseHardware):
|
|||||||
value = 51 - value
|
value = 51 - value
|
||||||
else:
|
else:
|
||||||
value = ((value+12) & 0x3f) | 0x40
|
value = ((value+12) & 0x3f) | 0x40
|
||||||
self.pc2hermes[4 * 10 + 3] = value # C0 index == 0x1010, C4[4:0] LNA 0-32 dB gain
|
self.pc2hermes[4 * 10 + 3] = value # C0 index == 0b1010, C4[4:0] LNA 0-32 dB gain
|
||||||
QS.pc_to_hermes(self.pc2hermes)
|
QS.pc_to_hermes(self.pc2hermes)
|
||||||
if DEBUG: print ("Change LNA to", value)
|
if DEBUG: print ("Change LNA to", value)
|
||||||
def ChangeTxLNA(self, value): # LNA for Tx
|
def ChangeTxLNA(self, value): # LNA for Tx
|
||||||
@@ -634,9 +636,17 @@ class Hardware(BaseHardware):
|
|||||||
elif value > 48:
|
elif value > 48:
|
||||||
value = 48
|
value = 48
|
||||||
value = ((value+12) & 0x3f) | 0x40 | 0x80
|
value = ((value+12) & 0x3f) | 0x40 | 0x80
|
||||||
self.SetControlByte(0x0e, 3, value, False) # C0 index == 0x0e, C3
|
self.SetControlByte(0x0e, 3, value, False) # C0 index == 0b1110 == 0x0e, C3
|
||||||
QS.pc_to_hermes(self.pc2hermes)
|
QS.pc_to_hermes(self.pc2hermes)
|
||||||
if DEBUG: print ("Change Tx LNA to", value)
|
if DEBUG: print ("Change Tx LNA to", value)
|
||||||
|
def ChangeAtten(self, value):
|
||||||
|
# value is 0 to 31
|
||||||
|
self.pc2hermes[4 * 10 + 3] = value & 0x1F # C0 index == 0b1010, C4[4:0] attenuator, 0 to 31 dB
|
||||||
|
self.SetControlBit(0b1010, 5, value) # enable attenuator
|
||||||
|
QS.pc_to_hermes(self.pc2hermes)
|
||||||
|
if DEBUG: print ("Change attenuator to", value)
|
||||||
|
def ChangePreamp(self, value):
|
||||||
|
self.SetControlBit(0b0000, 10, value) # enable preamp
|
||||||
def SetTxLevel(self):
|
def SetTxLevel(self):
|
||||||
try:
|
try:
|
||||||
tx_level = self.conf.tx_level[self.band]
|
tx_level = self.conf.tx_level[self.band]
|
||||||
@@ -653,7 +663,7 @@ class Hardware(BaseHardware):
|
|||||||
tx_level = 0
|
tx_level = 0
|
||||||
elif tx_level > 255:
|
elif tx_level > 255:
|
||||||
tx_level = 255
|
tx_level = 255
|
||||||
self.pc2hermes[4 * 9] = tx_level # C0 index == 0x1001, C1[7:0] Tx level
|
self.pc2hermes[4 * 9] = tx_level # C0 index == 0b1001, C1[7:0] Tx level
|
||||||
QS.pc_to_hermes(self.pc2hermes)
|
QS.pc_to_hermes(self.pc2hermes)
|
||||||
if DEBUG: print("Change tx_level to", tx_level)
|
if DEBUG: print("Change tx_level to", tx_level)
|
||||||
def MultiRxCount(self, count): # count == number of additional receivers besides the Tx/Rx receiver: 1, 2, 3
|
def MultiRxCount(self, count): # count == number of additional receivers besides the Tx/Rx receiver: 1, 2, 3
|
||||||
@@ -876,6 +886,8 @@ class Hardware(BaseHardware):
|
|||||||
QS.set_hermeslite_writepointer(0)
|
QS.set_hermeslite_writepointer(0)
|
||||||
return False
|
return False
|
||||||
def WriteQueue(self, wait=False):
|
def WriteQueue(self, wait=False):
|
||||||
|
if self.hermes_board_id != 6:
|
||||||
|
return False
|
||||||
self._wait_queue()
|
self._wait_queue()
|
||||||
# Send next write
|
# Send next write
|
||||||
self.old_writequeue = self.pc2hermeslitewritequeue[:]
|
self.old_writequeue = self.pc2hermeslitewritequeue[:]
|
||||||
|
|||||||
@@ -26,12 +26,11 @@ class Hardware(BaseHw):
|
|||||||
return BaseHw.close(self)
|
return BaseHw.close(self)
|
||||||
def ChangeFilterFrequency(self, tx_freq):
|
def ChangeFilterFrequency(self, tx_freq):
|
||||||
if tx_freq and tx_freq > 0:
|
if tx_freq and tx_freq > 0:
|
||||||
|
self.v2filter.SetTxFreq(tx_freq)
|
||||||
if self.GUI:
|
if self.GUI:
|
||||||
self.GUI.SetTxFreq(tx_freq)
|
self.GUI.SetTxFreq(tx_freq)
|
||||||
self.GUI.freq_entry.ChangeValue("%.3f" % (tx_freq * 1E-6))
|
|
||||||
else:
|
else:
|
||||||
self.anttuner.SetTxFreq(tx_freq)
|
self.anttuner.SetTxFreq(tx_freq)
|
||||||
self.v2filter.SetTxFreq(tx_freq)
|
|
||||||
def ChangeFrequency(self, tx_freq, vfo_freq, source='', band='', event=None):
|
def ChangeFrequency(self, tx_freq, vfo_freq, source='', band='', event=None):
|
||||||
self.ChangeFilterFrequency(tx_freq)
|
self.ChangeFilterFrequency(tx_freq)
|
||||||
return BaseHw.ChangeFrequency(self, tx_freq, vfo_freq, source, band, event)
|
return BaseHw.ChangeFrequency(self, tx_freq, vfo_freq, source, band, event)
|
||||||
|
|||||||
+80
-119
@@ -1,9 +1,5 @@
|
|||||||
# This file supports various hardware boxes at my shack
|
# This file supports various hardware boxes at my shack
|
||||||
|
|
||||||
from __future__ import print_function
|
|
||||||
from __future__ import absolute_import
|
|
||||||
from __future__ import division
|
|
||||||
|
|
||||||
import sys, struct, math, socket, select, time, traceback, os
|
import sys, struct, math, socket, select, time, traceback, os
|
||||||
import wx, wx.lib.buttons
|
import wx, wx.lib.buttons
|
||||||
|
|
||||||
@@ -410,19 +406,16 @@ class AntennaTuner: # Control my homebrew antenna tuner and my KI8BV dipole
|
|||||||
self.set_C = 0
|
self.set_C = 0
|
||||||
self.set_HighZ = 0
|
self.set_HighZ = 0
|
||||||
self.antnum = 0 # Antenna number 0 or 1
|
self.antnum = 0 # Antenna number 0 or 1
|
||||||
self.dipole2 = None #AntennaControl(app, conf) # Control the KI8BV dipole
|
self.dipole2 = AntennaControl(app, conf) # Control the KI8BV dipole
|
||||||
if False and conf.use_rx_udp == 10: # Hermes UDP protocol for Hermes-Lite2
|
path = 'TunerLCZ.txt'
|
||||||
path = 'TunerLCZ_HL2.txt'
|
|
||||||
else:
|
|
||||||
path = 'TunerLCZ.txt'
|
|
||||||
if sys.platform == "win32":
|
if sys.platform == "win32":
|
||||||
path = 'C:/pub/' + path
|
self.path = 'C:/pub/' + path
|
||||||
else:
|
else:
|
||||||
path = '/home/jim/pub/' + path
|
self.path = '/home/jim/pub/' + path
|
||||||
fp = open(path, "r")
|
fp = open(self.path, "r")
|
||||||
lines = fp.readlines()
|
lines = fp.readlines()
|
||||||
fp.close()
|
fp.close()
|
||||||
self.TunerLCZ = [(0, 0, 0, 0), (999111000, 0, 0, 0)] # Add dummy first and last entry.
|
self.TunerLCZ = []
|
||||||
for line in lines:
|
for line in lines:
|
||||||
freq, antL, antC, hilo = line.split()
|
freq, antL, antC, hilo = line.split()
|
||||||
freq = int(freq)
|
freq = int(freq)
|
||||||
@@ -451,7 +444,12 @@ class AntennaTuner: # Control my homebrew antenna tuner and my KI8BV dipole
|
|||||||
pass
|
pass
|
||||||
def ChangeBand(self, band):
|
def ChangeBand(self, band):
|
||||||
pass
|
pass
|
||||||
def FindLCZ(self, tx_freq):
|
def SaveLCZ(self):
|
||||||
|
fp = open(self.path, 'w')
|
||||||
|
for tup in self.TunerLCZ:
|
||||||
|
fp.write("%12d %2d %2d %d\n" % tup)
|
||||||
|
fp.close()
|
||||||
|
def FindIndexTup(self, tx_freq):
|
||||||
i1 = 0
|
i1 = 0
|
||||||
i2 = len(self.TunerLCZ) - 1
|
i2 = len(self.TunerLCZ) - 1
|
||||||
while 1: # binary partition
|
while 1: # binary partition
|
||||||
@@ -462,20 +460,14 @@ class AntennaTuner: # Control my homebrew antenna tuner and my KI8BV dipole
|
|||||||
i2 = i
|
i2 = i
|
||||||
if i2 - i1 <= 1:
|
if i2 - i1 <= 1:
|
||||||
break
|
break
|
||||||
# The correct setting is between i1 and i2.
|
# The correct setting is between i1 and i2, or below i1 or above i2.
|
||||||
# Choose the index that is closest in frequency.
|
# Choose the index that is closest in frequency.
|
||||||
delta1 = tx_freq - self.TunerLCZ[i1][0]
|
if abs(tx_freq - self.TunerLCZ[i1][0]) < abs(tx_freq - self.TunerLCZ[i2][0]):
|
||||||
delta2 = self.TunerLCZ[i2][0] - tx_freq
|
|
||||||
if i1 == 0: # below the first frequency
|
|
||||||
index = i1
|
index = i1
|
||||||
elif i2 == len(self.TunerLCZ) - 1: # above the last frequency
|
else:
|
||||||
index = i2
|
index = i2
|
||||||
elif delta2 < delta1: # i2 is closer
|
if DEBUG: print ("StatuinControlGUI FindIndexTup", tx_freq, i1, i2, len(self.TunerLCZ), index, self.TunerLCZ[index])
|
||||||
index = i2
|
return index, self.TunerLCZ[index]
|
||||||
else: # i1 is closer
|
|
||||||
index = i1
|
|
||||||
if DEBUG: print ("AntennaTuner FindLCZ", tx_freq, i1, i2, len(self.TunerLCZ), self.TunerLCZ[index])
|
|
||||||
return self.TunerLCZ[index]
|
|
||||||
def SetTxFreq(self, tx_freq, no_tune=False):
|
def SetTxFreq(self, tx_freq, no_tune=False):
|
||||||
#if DEBUG: print("AntennaTuner SetTxFreq", tx_freq)
|
#if DEBUG: print("AntennaTuner SetTxFreq", tx_freq)
|
||||||
self.tx_freq = tx_freq
|
self.tx_freq = tx_freq
|
||||||
@@ -496,7 +488,7 @@ class AntennaTuner: # Control my homebrew antenna tuner and my KI8BV dipole
|
|||||||
if abs(self.tune_freq - tx_freq) < 5000: # ignore small changes
|
if abs(self.tune_freq - tx_freq) < 5000: # ignore small changes
|
||||||
return
|
return
|
||||||
self.tune_freq = tx_freq
|
self.tune_freq = tx_freq
|
||||||
f, newL, newC, newH = self.FindLCZ(tx_freq)
|
index, (f, newL, newC, newH) = self.FindIndexTup(tx_freq)
|
||||||
if newH != self.set_HighZ or self.set_C != newC or self.set_L != newL:
|
if newH != self.set_HighZ or self.set_C != newC or self.set_L != newL:
|
||||||
self.set_HighZ = newH
|
self.set_HighZ = newH
|
||||||
self.set_C = newC
|
self.set_C = newC
|
||||||
@@ -540,26 +532,7 @@ class StationControlGUI(wx.Frame): # Display a stand-alone control window for
|
|||||||
self.conf = conf
|
self.conf = conf
|
||||||
self.data_saving = False
|
self.data_saving = False
|
||||||
self.tx_freq = 0
|
self.tx_freq = 0
|
||||||
if sys.platform == "win32":
|
self.anttuner = self.hware.anttuner
|
||||||
self.filename = 'C:/pub/TunerLCZ.tmp'
|
|
||||||
else:
|
|
||||||
self.filename = '/home/jim/pub/TunerLCZ.tmp'
|
|
||||||
try:
|
|
||||||
fp = open(self.filename, "r")
|
|
||||||
except FileNotFoundError:
|
|
||||||
lines = ()
|
|
||||||
else:
|
|
||||||
lines = fp.readlines()
|
|
||||||
fp.close()
|
|
||||||
self.TunerLCZ = [(0, 0, 0, 0), (999111000, 0, 0, 0)] # Add dummy first and last entry.
|
|
||||||
for line in lines:
|
|
||||||
freq, antL, antC, hilo = line.split()
|
|
||||||
freq = int(freq)
|
|
||||||
antL = int(antL)
|
|
||||||
antC = int(antC)
|
|
||||||
hilo = int(hilo)
|
|
||||||
self.TunerLCZ.append((freq, antL, antC, hilo))
|
|
||||||
self.TunerLCZ.sort()
|
|
||||||
self.SetBackgroundColour('light steel blue')
|
self.SetBackgroundColour('light steel blue')
|
||||||
self.Bind(wx.EVT_CHAR_HOOK, self.OnKeyDown)
|
self.Bind(wx.EVT_CHAR_HOOK, self.OnKeyDown)
|
||||||
sizer = wx.GridBagSizer(hgap=5, vgap=3)
|
sizer = wx.GridBagSizer(hgap=5, vgap=3)
|
||||||
@@ -569,6 +542,7 @@ class StationControlGUI(wx.Frame): # Display a stand-alone control window for
|
|||||||
self.bands = []
|
self.bands = []
|
||||||
for band in ('160', '80', '60', '40', '30', '20', '17', '15', '12', '10'):
|
for band in ('160', '80', '60', '40', '30', '20', '17', '15', '12', '10'):
|
||||||
b = wx.lib.buttons.GenToggleButton(self, -1, band)
|
b = wx.lib.buttons.GenToggleButton(self, -1, band)
|
||||||
|
b.Enable(False)
|
||||||
b.SetUseFocusIndicator(False)
|
b.SetUseFocusIndicator(False)
|
||||||
b.SetBezelWidth(4)
|
b.SetBezelWidth(4)
|
||||||
self.bands.append(b)
|
self.bands.append(b)
|
||||||
@@ -605,6 +579,7 @@ class StationControlGUI(wx.Frame): # Display a stand-alone control window for
|
|||||||
szr = wx.BoxSizer(wx.HORIZONTAL)
|
szr = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
szr.AddSpacer(20)
|
szr.AddSpacer(20)
|
||||||
b = wx.lib.buttons.GenToggleButton(self, -1, "Key Down")
|
b = wx.lib.buttons.GenToggleButton(self, -1, "Key Down")
|
||||||
|
b.Enable(False)
|
||||||
b.SetFont(font)
|
b.SetFont(font)
|
||||||
b.SetUseFocusIndicator(False)
|
b.SetUseFocusIndicator(False)
|
||||||
b.SetBezelWidth(4)
|
b.SetBezelWidth(4)
|
||||||
@@ -612,6 +587,7 @@ class StationControlGUI(wx.Frame): # Display a stand-alone control window for
|
|||||||
szr.Add(b)
|
szr.Add(b)
|
||||||
szr.AddSpacer(10)
|
szr.AddSpacer(10)
|
||||||
b = wx.lib.buttons.GenToggleButton(self, -1, "FilterV2 Preamp")
|
b = wx.lib.buttons.GenToggleButton(self, -1, "FilterV2 Preamp")
|
||||||
|
b.Enable(False)
|
||||||
b.SetFont(font)
|
b.SetFont(font)
|
||||||
b.SetUseFocusIndicator(False)
|
b.SetUseFocusIndicator(False)
|
||||||
b.SetBezelWidth(4)
|
b.SetBezelWidth(4)
|
||||||
@@ -623,16 +599,31 @@ class StationControlGUI(wx.Frame): # Display a stand-alone control window for
|
|||||||
b.SetFont(font)
|
b.SetFont(font)
|
||||||
szr.Add(b, flag=wx.ALIGN_CENTER_VERTICAL)
|
szr.Add(b, flag=wx.ALIGN_CENTER_VERTICAL)
|
||||||
szr.AddSpacer(10)
|
szr.AddSpacer(10)
|
||||||
self.freq_entry = wx.TextCtrl(self, value='0000.000', style=wx.TE_PROCESS_ENTER)
|
self.freq_entry = wx.StaticText(self, -1, "0000.000")
|
||||||
|
#self.freq_entry = wx.TextCtrl(self, value='0000.000', style=wx.TE_PROCESS_ENTER)
|
||||||
self.freq_entry.SetFont(font)
|
self.freq_entry.SetFont(font)
|
||||||
self.Bind(wx.EVT_TEXT_ENTER, self.OnFreqEntry, self.freq_entry)
|
#self.Bind(wx.EVT_TEXT_ENTER, self.OnFreqEntry, self.freq_entry)
|
||||||
szr.Add(self.freq_entry)
|
szr.Add(self.freq_entry, flag=wx.ALIGN_CENTER_VERTICAL)
|
||||||
szr.AddSpacer(10)
|
szr.AddSpacer(10)
|
||||||
b = wx.lib.buttons.GenButton(self, -1, "Search Freq")
|
b = wx.lib.buttons.GenButton(self, -1, "Freq-")
|
||||||
b.SetUseFocusIndicator(False)
|
b.SetUseFocusIndicator(False)
|
||||||
b.SetBezelWidth(4)
|
b.SetBezelWidth(4)
|
||||||
b.SetFont(font)
|
b.SetFont(font)
|
||||||
self.Bind(wx.EVT_BUTTON, self.OnButtonSearch, b)
|
self.Bind(wx.EVT_BUTTON, self.OnButtonDown, b)
|
||||||
|
szr.Add(b)
|
||||||
|
szr.AddSpacer(10)
|
||||||
|
b = wx.lib.buttons.GenButton(self, -1, "Freq+")
|
||||||
|
b.SetUseFocusIndicator(False)
|
||||||
|
b.SetBezelWidth(4)
|
||||||
|
b.SetFont(font)
|
||||||
|
self.Bind(wx.EVT_BUTTON, self.OnButtonUp, b)
|
||||||
|
szr.Add(b)
|
||||||
|
szr.AddSpacer(10)
|
||||||
|
b = wx.lib.buttons.GenButton(self, -1, "Delete")
|
||||||
|
b.SetUseFocusIndicator(False)
|
||||||
|
b.SetBezelWidth(4)
|
||||||
|
b.SetFont(font)
|
||||||
|
self.Bind(wx.EVT_BUTTON, self.OnButtonDelete, b)
|
||||||
szr.Add(b)
|
szr.Add(b)
|
||||||
sizer.Add(szr, pos=(row, 0), span=(1, 3))
|
sizer.Add(szr, pos=(row, 0), span=(1, 3))
|
||||||
if frame is None:
|
if frame is None:
|
||||||
@@ -648,13 +639,13 @@ class StationControlGUI(wx.Frame): # Display a stand-alone control window for
|
|||||||
self.Bind(wx.EVT_TIMER, self.HeartBeat)
|
self.Bind(wx.EVT_TIMER, self.HeartBeat)
|
||||||
self.timer.Start(100)
|
self.timer.Start(100)
|
||||||
def SetTxFreq(self, tx_freq):
|
def SetTxFreq(self, tx_freq):
|
||||||
#print("StationControlGUI SetTxFreq", tx_freq)
|
tx_freq = ((tx_freq + 500) // 1000) * 1000
|
||||||
self.tx_freq = tx_freq
|
self.tx_freq = tx_freq
|
||||||
index, tup = self.FindIndexTup(tx_freq)
|
anttuner = self.anttuner
|
||||||
|
index, tup = anttuner.FindIndexTup(tx_freq)
|
||||||
self.sliderL.SetValue(tup[1])
|
self.sliderL.SetValue(tup[1])
|
||||||
self.sliderC.SetValue(tup[2])
|
self.sliderC.SetValue(tup[2])
|
||||||
self.btnHiLo.SetValue(tup[3])
|
self.btnHiLo.SetValue(tup[3])
|
||||||
anttuner = self.hware.anttuner
|
|
||||||
fff, anttuner.set_L, anttuner.set_C, anttuner.set_HighZ = tup
|
fff, anttuner.set_L, anttuner.set_C, anttuner.set_HighZ = tup
|
||||||
if tx_freq < 17000000:
|
if tx_freq < 17000000:
|
||||||
anttuner.antnum = 0
|
anttuner.antnum = 0
|
||||||
@@ -663,31 +654,7 @@ class StationControlGUI(wx.Frame): # Display a stand-alone control window for
|
|||||||
if anttuner.antnum == 1 and anttuner.dipole2:
|
if anttuner.antnum == 1 and anttuner.dipole2:
|
||||||
anttuner.dipole2.SetTxFreq(tx_freq)
|
anttuner.dipole2.SetTxFreq(tx_freq)
|
||||||
anttuner.WantData()
|
anttuner.WantData()
|
||||||
def FindIndexTup(self, tx_freq):
|
self.freq_entry.SetLabel("%.3f" % (tx_freq * 1E-6))
|
||||||
i1 = 0
|
|
||||||
i2 = len(self.TunerLCZ) - 1
|
|
||||||
while 1: # binary partition
|
|
||||||
i = (i1 + i2) // 2
|
|
||||||
if self.TunerLCZ[i][0] < tx_freq:
|
|
||||||
i1 = i
|
|
||||||
else:
|
|
||||||
i2 = i
|
|
||||||
if i2 - i1 <= 1:
|
|
||||||
break
|
|
||||||
# The correct setting is between i1 and i2.
|
|
||||||
# Choose the index that is closest in frequency.
|
|
||||||
delta1 = tx_freq - self.TunerLCZ[i1][0]
|
|
||||||
delta2 = self.TunerLCZ[i2][0] - tx_freq
|
|
||||||
if i1 == 0: # below the first frequency
|
|
||||||
index = i1
|
|
||||||
elif i2 == len(self.TunerLCZ) - 1: # above the last frequency
|
|
||||||
index = i2
|
|
||||||
elif delta2 < delta1: # i2 is closer
|
|
||||||
index = i2
|
|
||||||
else: # i1 is closer
|
|
||||||
index = i1
|
|
||||||
if DEBUG: print ("StatuinControlGUI FindLCZ", tx_freq, i1, i2, len(self.TunerLCZ), index, self.TunerLCZ[index])
|
|
||||||
return index, self.TunerLCZ[index]
|
|
||||||
def OnBtnClose(self, event):
|
def OnBtnClose(self, event):
|
||||||
self.hware.anttuner.close()
|
self.hware.anttuner.close()
|
||||||
self.hware.controlbox.close()
|
self.hware.controlbox.close()
|
||||||
@@ -731,16 +698,15 @@ class StationControlGUI(wx.Frame): # Display a stand-alone control window for
|
|||||||
f = ((f + 500) // 1000) * 1000
|
f = ((f + 500) // 1000) * 1000
|
||||||
if self.hware.v2filter:
|
if self.hware.v2filter:
|
||||||
self.hware.v2filter.SetTxFreq(f)
|
self.hware.v2filter.SetTxFreq(f)
|
||||||
self.hware.anttuner.SetTxFreq(f, no_tune=True)
|
self.anttuner.SetTxFreq(f, no_tune=True)
|
||||||
self.freq_entry.ChangeValue("%.3f" % (f * 1E-6))
|
self.freq_entry.ChangeValue("%.3f" % (f * 1E-6))
|
||||||
self.SetTxFreq(f)
|
self.SetTxFreq(f)
|
||||||
def OnButtonHiLo(self, event):
|
def OnButtonHiLo(self, event):
|
||||||
anttuner = self.hware.anttuner
|
|
||||||
if self.btnHiLo.GetValue():
|
if self.btnHiLo.GetValue():
|
||||||
anttuner.set_HighZ = 1
|
self.anttuner.set_HighZ = 1
|
||||||
else:
|
else:
|
||||||
anttuner.set_HighZ = 0
|
self.anttuner.set_HighZ = 0
|
||||||
anttuner.WantData()
|
self.anttuner.WantData()
|
||||||
def OnFreqEntry(self, event=None):
|
def OnFreqEntry(self, event=None):
|
||||||
freq = self.freq_entry.GetValue()
|
freq = self.freq_entry.GetValue()
|
||||||
freq = float(freq) * 1E6
|
freq = float(freq) * 1E6
|
||||||
@@ -752,11 +718,27 @@ class StationControlGUI(wx.Frame): # Display a stand-alone control window for
|
|||||||
freq = int(freq + 0.1)
|
freq = int(freq + 0.1)
|
||||||
self.tx_freq = freq
|
self.tx_freq = freq
|
||||||
self.SetTxFreq(self.tx_freq)
|
self.SetTxFreq(self.tx_freq)
|
||||||
|
def OnButtonDown(self, event):
|
||||||
|
index, tup = self.anttuner.FindIndexTup(self.tx_freq)
|
||||||
|
index -= 1
|
||||||
|
if index >= 0:
|
||||||
|
self.SetTxFreq(self.anttuner.TunerLCZ[index][0])
|
||||||
|
def OnButtonUp(self, event):
|
||||||
|
index, tup = self.anttuner.FindIndexTup(self.tx_freq)
|
||||||
|
index += 1
|
||||||
|
if index < len(self.anttuner.TunerLCZ):
|
||||||
|
self.SetTxFreq(self.anttuner.TunerLCZ[index][0])
|
||||||
|
def OnButtonDelete(self, event):
|
||||||
|
index, tup = self.anttuner.FindIndexTup(self.tx_freq)
|
||||||
|
if self.tx_freq == self.anttuner.TunerLCZ[index][0]:
|
||||||
|
del self.anttuner.TunerLCZ[index]
|
||||||
|
if index > 0:
|
||||||
|
self.SetTxFreq(self.anttuner.TunerLCZ[index - 1][0])
|
||||||
|
elif len(self.anttuner.TunerLCZ) > 0:
|
||||||
|
self.SetTxFreq(self.anttuner.TunerLCZ[0][0])
|
||||||
|
else:
|
||||||
|
self.SetTxFreq(0)
|
||||||
def OnButtonSave(self, event):
|
def OnButtonSave(self, event):
|
||||||
freq = self.freq_entry.GetValue()
|
|
||||||
freq = float(freq) * 1E6
|
|
||||||
freq = int(freq + 0.1)
|
|
||||||
self.tx_freq = freq
|
|
||||||
L = self.sliderL.GetValue()
|
L = self.sliderL.GetValue()
|
||||||
C = self.sliderC.GetValue()
|
C = self.sliderC.GetValue()
|
||||||
if self.btnHiLo.GetValue():
|
if self.btnHiLo.GetValue():
|
||||||
@@ -764,22 +746,19 @@ class StationControlGUI(wx.Frame): # Display a stand-alone control window for
|
|||||||
else:
|
else:
|
||||||
hilo = 0
|
hilo = 0
|
||||||
tup = (self.tx_freq, L, C, hilo)
|
tup = (self.tx_freq, L, C, hilo)
|
||||||
index, t = self.FindIndexTup(self.tx_freq)
|
index, t = self.anttuner.FindIndexTup(self.tx_freq)
|
||||||
if self.tx_freq == self.TunerLCZ[index][0]:
|
if self.tx_freq == self.anttuner.TunerLCZ[index][0]:
|
||||||
self.TunerLCZ[index] = tup
|
self.anttuner.TunerLCZ[index] = tup
|
||||||
else:
|
else:
|
||||||
self.TunerLCZ.append(tup)
|
self.anttuner.TunerLCZ.append(tup)
|
||||||
self.TunerLCZ.sort()
|
self.anttuner.TunerLCZ.sort()
|
||||||
fp = open(self.filename, 'w')
|
self.anttuner.SaveLCZ()
|
||||||
for tup in self.TunerLCZ[1:-1]: # Throw away dummy entries
|
|
||||||
fp.write("%12d %2d %2d %d\n" % tup)
|
|
||||||
fp.close()
|
|
||||||
def OnSliderL(self, event=None):
|
def OnSliderL(self, event=None):
|
||||||
self.hware.anttuner.set_L = self.sliderL.GetValue()
|
self.anttuner.set_L = self.sliderL.GetValue()
|
||||||
self.hware.anttuner.WantData()
|
self.anttuner.WantData()
|
||||||
def OnSliderC(self, event=None):
|
def OnSliderC(self, event=None):
|
||||||
self.hware.anttuner.set_C = self.sliderC.GetValue()
|
self.anttuner.set_C = self.sliderC.GetValue()
|
||||||
self.hware.anttuner.WantData()
|
self.anttuner.WantData()
|
||||||
def OnBtnV2Preamp(self, event):
|
def OnBtnV2Preamp(self, event):
|
||||||
if self.hware.v2filter:
|
if self.hware.v2filter:
|
||||||
self.hware.v2filter.SetPreamp(event.GetEventObject().GetValue())
|
self.hware.v2filter.SetPreamp(event.GetEventObject().GetValue())
|
||||||
@@ -1073,21 +1052,3 @@ class AT200PC: # Control an AT-200PC autotuner made by LDG
|
|||||||
self.set_C += 1
|
self.set_C += 1
|
||||||
elif text == 'C-':
|
elif text == 'C-':
|
||||||
self.set_C -= 1
|
self.set_C -= 1
|
||||||
|
|
||||||
class App(wx.App):
|
|
||||||
def OnInit(self):
|
|
||||||
if sys.path[0] != "'.'": # Make sure the current working directory is on path
|
|
||||||
sys.path.insert(0, '.')
|
|
||||||
import quisk_conf_defaults as conf
|
|
||||||
import quisk_hardware_model as hardware
|
|
||||||
self.bottom_widgets = None
|
|
||||||
hardware.anttuner = AntennaTuner(self, conf) # Control the antenna tuner
|
|
||||||
hardware.v2filter = FilterBoxV2(self, conf) # Control V2 filter box
|
|
||||||
hardware.controlbox = ControlBox(self, conf) # Control my Station Control Box
|
|
||||||
self.main_frame = frame = StationControlGUI (None, hardware, self, conf)
|
|
||||||
frame.Open()
|
|
||||||
frame.Show()
|
|
||||||
return True
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
App().MainLoop()
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ from quisk_hardware_model import Hardware as BaseHardware
|
|||||||
DEBUG = 1
|
DEBUG = 1
|
||||||
|
|
||||||
# Define the name of the hardware and the items on the hardware screen (see quisk_conf_defaults.py):
|
# Define the name of the hardware and the items on the hardware screen (see quisk_conf_defaults.py):
|
||||||
################ Receivers PerseusSDR, The PerseusSDR interface to multiple hardware SDRs.
|
################ Receivers PerseusSDR, The PerseusSDR interface to multiple SDRs.
|
||||||
## hardware_file_name Hardware file path, rfile
|
## hardware_file_name Hardware file path, rfile
|
||||||
# This is the file that contains the control logic for each radio.
|
# This is the file that contains the control logic for each radio.
|
||||||
#hardware_file_name = 'perseuspkg/quisk_hardware.py'
|
#hardware_file_name = 'perseuspkg/quisk_hardware.py'
|
||||||
|
|||||||
@@ -3718,7 +3718,7 @@ class App(wx.App):
|
|||||||
'wfallScaleZ', 'wfallGrScaleZ', 'graphScaleZ', 'split_rxtx_play', 'modeFilter',
|
'wfallScaleZ', 'wfallGrScaleZ', 'graphScaleZ', 'split_rxtx_play', 'modeFilter',
|
||||||
'file_name_rec_audio', 'file_name_rec_samples', 'file_name_rec_mic', 'file_name_rec_tmp',
|
'file_name_rec_audio', 'file_name_rec_samples', 'file_name_rec_mic', 'file_name_rec_tmp',
|
||||||
'file_name_play_audio', 'file_name_play_samples', 'file_name_play_cq',
|
'file_name_play_audio', 'file_name_play_samples', 'file_name_play_cq',
|
||||||
'file_play_source', 'hermes_LNA_dB']
|
'file_play_source', 'hermes_LNA_dB', 'hermes_atten_dB']
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
global application
|
global application
|
||||||
QS.AppStatus(1)
|
QS.AppStatus(1)
|
||||||
@@ -3939,6 +3939,7 @@ class App(wx.App):
|
|||||||
self.serial_ptt_active = False
|
self.serial_ptt_active = False
|
||||||
self.vox_ptt_active = False
|
self.vox_ptt_active = False
|
||||||
self.hermes_LNA_dB = 20
|
self.hermes_LNA_dB = 20
|
||||||
|
self.hermes_atten_dB = 0
|
||||||
if hasattr(Hardware, "OnChangeRxTx"):
|
if hasattr(Hardware, "OnChangeRxTx"):
|
||||||
self.want_RxTx = True
|
self.want_RxTx = True
|
||||||
else:
|
else:
|
||||||
@@ -6798,7 +6799,7 @@ class App(wx.App):
|
|||||||
if self.timer - self.heart_time0 > 0.10: # call hardware to perform background tasks:
|
if self.timer - self.heart_time0 > 0.10: # call hardware to perform background tasks:
|
||||||
self.heart_time0 = self.timer
|
self.heart_time0 = self.timer
|
||||||
Hardware.HeartBeat()
|
Hardware.HeartBeat()
|
||||||
if conf.hermes_lite2_enable:
|
if conf.use_rx_udp == 10 and Hardware.hermes_board_id == 6:
|
||||||
self.tx_inhibit = QS.get_params('quisk_tx_inhibit')
|
self.tx_inhibit = QS.get_params('quisk_tx_inhibit')
|
||||||
else:
|
else:
|
||||||
self.tx_inhibit = 0
|
self.tx_inhibit = 0
|
||||||
|
|||||||
+99
-22
@@ -48,7 +48,7 @@ quisk_widgets = None
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
################ Receivers SoftRock USB, Devices controlled by USB that capture samples from a sound card, and (for Tx) play samples to a sound card
|
################ Receivers SoftRock USB, Sound card radios controlled by USB.
|
||||||
## hardware_file_name Hardware file path, rfile
|
## hardware_file_name Hardware file path, rfile
|
||||||
# This is the file that contains the control logic for each radio.
|
# This is the file that contains the control logic for each radio.
|
||||||
#hardware_file_name = 'softrock/hardware_usb.py'
|
#hardware_file_name = 'softrock/hardware_usb.py'
|
||||||
@@ -133,7 +133,7 @@ digital_tx_level = 100
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
################ Receivers SoftRock Fixed, Fixed frequency devices that capture samples from a sound card, and (for Tx) play samples to a sound card
|
################ Receivers SoftRock Fixed, Fixed frequency sound card radios.
|
||||||
## hardware_file_name Hardware file path, rfile
|
## hardware_file_name Hardware file path, rfile
|
||||||
# This is the file that contains the control logic for each radio.
|
# This is the file that contains the control logic for each radio.
|
||||||
#hardware_file_name = 'quisk_hardware_fixed.py'
|
#hardware_file_name = 'quisk_hardware_fixed.py'
|
||||||
@@ -174,7 +174,7 @@ digital_tx_level = 100
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
################ Receivers HiQSDR, The original N2ADR hardware and the improved HiQSDR using UDP
|
################ Receivers HiQSDR, The original N2ADR and HiQSDR radios.
|
||||||
## hardware_file_name Hardware file path, rfile
|
## hardware_file_name Hardware file path, rfile
|
||||||
# This is the file that contains the control logic for each radio.
|
# This is the file that contains the control logic for each radio.
|
||||||
#hardware_file_name = 'hiqsdr/quisk_hardware.py'
|
#hardware_file_name = 'hiqsdr/quisk_hardware.py'
|
||||||
@@ -258,7 +258,7 @@ sndp_active = True
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
################ Receivers Hermes, The Hermes-Lite Project and possibly other hardware with the Hermes FPGA code.
|
################ Receivers Hermes, The Hermes-Lite project by Steve Haynal.
|
||||||
## hardware_file_name Hardware file path, rfile
|
## hardware_file_name Hardware file path, rfile
|
||||||
# This is the file that contains the control logic for each radio.
|
# This is the file that contains the control logic for each radio.
|
||||||
#hardware_file_name = 'hermes/quisk_hardware.py'
|
#hardware_file_name = 'hermes/quisk_hardware.py'
|
||||||
@@ -275,7 +275,7 @@ sndp_active = True
|
|||||||
# You can set these options:
|
# You can set these options:
|
||||||
|
|
||||||
## use_rx_udp Hardware type, integer choice
|
## use_rx_udp Hardware type, integer choice
|
||||||
# This is the type of UDP hardware. Use 10 for the Hermes protocol.
|
# This is the type of UDP hardware. Use 10 for the Hermes Lite2 protocol.
|
||||||
#use_rx_udp = 10
|
#use_rx_udp = 10
|
||||||
|
|
||||||
## udp_rx_ip Hermes known IP, text
|
## udp_rx_ip Hermes known IP, text
|
||||||
@@ -373,6 +373,7 @@ hermes_disable_sync = False
|
|||||||
# be sure to write it down. To use this address you must set "Eeprom IP Usage".
|
# be sure to write it down. To use this address you must set "Eeprom IP Usage".
|
||||||
# And you may want to set "Hermes known IP" too. Make sure the address does not conflict
|
# And you may want to set "Hermes known IP" too. Make sure the address does not conflict
|
||||||
# with your DHCP server.
|
# with your DHCP server.
|
||||||
|
# Power cycle the HL2 after changing this item.
|
||||||
Hware_Hl2_EepromIP = '192.168.1.6'
|
Hware_Hl2_EepromIP = '192.168.1.6'
|
||||||
#Hware_Hl2_EepromIP = '192.168.1.241'
|
#Hware_Hl2_EepromIP = '192.168.1.241'
|
||||||
|
|
||||||
@@ -380,6 +381,7 @@ Hware_Hl2_EepromIP = '192.168.1.6'
|
|||||||
# This is the way the EEPROM IP address is used at power on.
|
# This is the way the EEPROM IP address is used at power on.
|
||||||
# "Ignore" means it is not used at all. "Set address" means DHCP is not used and the EEPROM IP address is used.
|
# "Ignore" means it is not used at all. "Set address" means DHCP is not used and the EEPROM IP address is used.
|
||||||
# "Use DHCP first" means the EEPROM IP address is only used if DHCP fails.
|
# "Use DHCP first" means the EEPROM IP address is only used if DHCP fails.
|
||||||
|
# Power cycle the HL2 after changing this item.
|
||||||
Hware_Hl2_EepromIPUse = 'Ignore'
|
Hware_Hl2_EepromIPUse = 'Ignore'
|
||||||
#Hware_Hl2_EepromIPUse = 'Use DHCP first'
|
#Hware_Hl2_EepromIPUse = 'Use DHCP first'
|
||||||
#Hware_Hl2_EepromIPUse = 'Set address'
|
#Hware_Hl2_EepromIPUse = 'Set address'
|
||||||
@@ -390,6 +392,7 @@ Hware_Hl2_EepromIPUse = 'Ignore'
|
|||||||
# at power on instead of the factory supplied MAC address 0:1c:c0:a2:13:dd. It is only used at power on,
|
# at power on instead of the factory supplied MAC address 0:1c:c0:a2:13:dd. It is only used at power on,
|
||||||
# and it is only used if it is marked valid by setting "Eeprom MAC usage" to "Set address".
|
# and it is only used if it is marked valid by setting "Eeprom MAC usage" to "Set address".
|
||||||
# If you have two HL2's, you must have a unique MAC address for each.
|
# If you have two HL2's, you must have a unique MAC address for each.
|
||||||
|
# Power cycle the HL2 after changing this item.
|
||||||
Hware_Hl2_EepromMAC = '0xA1 0x6B'
|
Hware_Hl2_EepromMAC = '0xA1 0x6B'
|
||||||
#Hware_Hl2_EepromMAC = '0x4C 0x33'
|
#Hware_Hl2_EepromMAC = '0x4C 0x33'
|
||||||
|
|
||||||
@@ -398,6 +401,7 @@ Hware_Hl2_EepromMAC = '0xA1 0x6B'
|
|||||||
# the HL2 will use the last two MAC bytes from "Eeprom MAC address"; otherwise the default MAC is used.
|
# the HL2 will use the last two MAC bytes from "Eeprom MAC address"; otherwise the default MAC is used.
|
||||||
# If you change this item, the bit is written to the HL2.
|
# If you change this item, the bit is written to the HL2.
|
||||||
# The HL2 only uses these bits at power on.
|
# The HL2 only uses these bits at power on.
|
||||||
|
# Power cycle the HL2 after changing this item.
|
||||||
Hware_Hl2_EepromMACUse = 'Ignore'
|
Hware_Hl2_EepromMACUse = 'Ignore'
|
||||||
#Hware_Hl2_EepromMACUse = 'Set address'
|
#Hware_Hl2_EepromMACUse = 'Set address'
|
||||||
|
|
||||||
@@ -474,13 +478,6 @@ hermes_iob_rxin = 'J10 available'
|
|||||||
#hermes_iob_rxin = 'HL2 Rx to J9'
|
#hermes_iob_rxin = 'HL2 Rx to J9'
|
||||||
#hermes_iob_rxin = 'Use J9 and J10'
|
#hermes_iob_rxin = 'Use J9 and J10'
|
||||||
|
|
||||||
## hermes_lite2_enable Hermes Lite2 protocol, boolean
|
|
||||||
# This turns on some of the protocol extensions for the Hermes Lite2 that are not part
|
|
||||||
# of the official Hermes Protocol 1. Currently this only enables Tx Inhibit (CN8).
|
|
||||||
# Changes are immediate (no need to restart).
|
|
||||||
hermes_lite2_enable = True
|
|
||||||
#hermes_lite2_enable = False
|
|
||||||
|
|
||||||
|
|
||||||
# These are known power meter calibration tables. This table is not present in the JSON settings file.
|
# These are known power meter calibration tables. This table is not present in the JSON settings file.
|
||||||
power_meter_std_calibrations = {}
|
power_meter_std_calibrations = {}
|
||||||
@@ -508,17 +505,17 @@ Hermes_BandDictEnTx = False
|
|||||||
#Hermes_BandDictEnTx = True
|
#Hermes_BandDictEnTx = True
|
||||||
|
|
||||||
|
|
||||||
################ Receivers Red Pitaya, The Red Pitaya Project by Pavel Demin. This uses the Hermes FPGA code.
|
################ Receivers Red Pitaya, The Red Pitaya project by Pavel Demin.
|
||||||
## hardware_file_name Hardware file path, rfile
|
## hardware_file_name Hardware file path, rfile
|
||||||
# This is the file that contains the control logic for each radio.
|
# This is the file that contains the control logic for each radio.
|
||||||
#hardware_file_name = 'hermes/quisk_hardware.py'
|
#hardware_file_name = 'hermes/quisk_hardware.py'
|
||||||
|
|
||||||
## widgets_file_name Widget file path, rfile
|
## widgets_file_name Widget file path, rfile
|
||||||
# This optional file adds additional controls for the radio.
|
# This optional file adds additional controls for the radio.
|
||||||
#widgets_file_name = ''
|
#widgets_file_name = 'hermes/hpsdr_widgets.py'
|
||||||
|
|
||||||
## use_rx_udp Hardware type, integer choice
|
## use_rx_udp Hardware type, integer choice
|
||||||
# This is the type of UDP hardware. Use 10 for the Hermes protocol.
|
# This is the type of UDP hardware. Use 10 for the Red Pitaya using the OpenHPSDR protocol.
|
||||||
#use_rx_udp = 10
|
#use_rx_udp = 10
|
||||||
|
|
||||||
## rx_udp_ip IP change, text
|
## rx_udp_ip IP change, text
|
||||||
@@ -586,7 +583,87 @@ Hermes_BandDictEnTx = False
|
|||||||
#Hermes_BandDictEnTx = True
|
#Hermes_BandDictEnTx = True
|
||||||
|
|
||||||
|
|
||||||
################ Receivers SoapySDR, The SoapySDR interface to multiple hardware SDRs.
|
################ Receivers OpenHPSDR, Radios using the HPSDR Protocol 1.
|
||||||
|
## hardware_file_name Hardware file path, rfile
|
||||||
|
# This is the file that contains the control logic for each radio.
|
||||||
|
#hardware_file_name = 'hermes/quisk_hardware.py'
|
||||||
|
|
||||||
|
## widgets_file_name Widget file path, rfile
|
||||||
|
# This optional file adds additional controls for the radio.
|
||||||
|
#widgets_file_name = 'hermes/hpsdr_widgets.py'
|
||||||
|
|
||||||
|
## use_rx_udp Hardware type, integer choice
|
||||||
|
# This is the type of UDP hardware. Use 10 for hardware using the OpenHPSDR protocol 1.
|
||||||
|
#use_rx_udp = 10
|
||||||
|
|
||||||
|
## rx_udp_ip IP change, text
|
||||||
|
# This item should be left blank. It is used to change the IP address of the hardware to a different
|
||||||
|
# IP once the hardware is found. Not all Hermes firmware supports changing the IP address.
|
||||||
|
#rx_udp_ip = ""
|
||||||
|
|
||||||
|
## rx_udp_port Hardware UDP port, integer
|
||||||
|
# This is the UDP port number of your hardware.
|
||||||
|
#rx_udp_port = 1024
|
||||||
|
|
||||||
|
## rx_udp_ip_netmask Network netmask, text
|
||||||
|
# This is the netmask for the network.
|
||||||
|
#rx_udp_ip_netmask = '255.255.255.0'
|
||||||
|
|
||||||
|
## tx_ip Transmit IP, text
|
||||||
|
# Leave this blank to use the same IP address as the receive hardware. Otherwise, enter "disable"
|
||||||
|
# to disable sending transmit I/Q samples, or enter the actual IP address. You must enter "disable"
|
||||||
|
# if you have multiple hardwares on the network, and only one should transmit. This item is normally blank.
|
||||||
|
tx_ip = ""
|
||||||
|
#tx_ip = "disable"
|
||||||
|
|
||||||
|
## tx_audio_port Tx audio UDP port, integer
|
||||||
|
# This is the UDP port for transmit audio I/Q samples. Enter zero to calculate this from the
|
||||||
|
# base hardware port. Otherwise enter the special custom port.
|
||||||
|
tx_audio_port = 0
|
||||||
|
|
||||||
|
## rx_udp_clock Clock frequency Hertz, integer
|
||||||
|
# This is the clock frequency of the hardware in Hertz.
|
||||||
|
#rx_udp_clock = 122880000
|
||||||
|
#rx_udp_clock = 76800000
|
||||||
|
#rx_udp_clock = 125000000
|
||||||
|
|
||||||
|
## tx_level Tx Level, dict
|
||||||
|
# This sets the transmit level 0 to 255 for each band.
|
||||||
|
# The config screen has a slider 0 to 100% so you can reduce the transmit power.
|
||||||
|
# The hardware only supports a limited adjustment range, so zero is still a small amount of power.
|
||||||
|
tx_level = {}
|
||||||
|
|
||||||
|
## digital_tx_level Digital Tx power %, integer
|
||||||
|
# Digital modes reduce power by the percentage on the config screen.
|
||||||
|
# This is the maximum value of the slider.
|
||||||
|
#digital_tx_level = 100
|
||||||
|
|
||||||
|
## hermes_code_version Hermes code version, integer
|
||||||
|
# There can be multiple Hermes devices on a network, but Quisk can only use one of these. If you have multiple
|
||||||
|
# hermes devices, you can use this to specify a unique device. Or use -1 to accept any board.
|
||||||
|
hermes_code_version = -1
|
||||||
|
|
||||||
|
## hermes_board_id Hermes board ID, integer
|
||||||
|
# There can be multiple Hermes devices on a network, but Quisk can only use one of these. If you have multiple
|
||||||
|
# hermes devices, you can use this to specify a unique device. Or use -1 to accept any board.
|
||||||
|
hermes_board_id = -1
|
||||||
|
|
||||||
|
## Hermes_BandDict Hermes Bus, dict
|
||||||
|
# The Hermes_BandDict sets the 7 bits on the J16 connector.
|
||||||
|
Hermes_BandDict = {
|
||||||
|
'160':0b0000001, '80':0b0000010, '60':0b0000100, '40':0b0001000, '30':0b0010000, '20':0b0100000, '15':0b1000000}
|
||||||
|
|
||||||
|
## Hermes_BandDictTx Tx IO Bus, dict
|
||||||
|
# The Hermes_BandDictTx sets the 7 bits on the J16 connector for Tx if enabled.
|
||||||
|
Hermes_BandDictTx = {'160':0, '80':0, '60':0, '40':0, '30':0, '20':0, '17':0, '15':0, '12':0, '10':0}
|
||||||
|
|
||||||
|
## Hermes_BandDictEnTx Enable Tx Filt, boolean
|
||||||
|
# Enable the separate Rx and Tx settings for the J16 connector.
|
||||||
|
Hermes_BandDictEnTx = False
|
||||||
|
#Hermes_BandDictEnTx = True
|
||||||
|
|
||||||
|
|
||||||
|
################ Receivers SoapySDR, The SoapySDR interface to multiple SDRs.
|
||||||
## hardware_file_name Hardware file path, rfile
|
## hardware_file_name Hardware file path, rfile
|
||||||
# This is the file that contains the control logic for each radio.
|
# This is the file that contains the control logic for each radio.
|
||||||
#hardware_file_name = 'soapypkg/quisk_hardware.py'
|
#hardware_file_name = 'soapypkg/quisk_hardware.py'
|
||||||
@@ -602,7 +679,7 @@ Hermes_BandDictEnTx = False
|
|||||||
# Further items are present in the radio dictionary with names soapy_*
|
# Further items are present in the radio dictionary with names soapy_*
|
||||||
|
|
||||||
|
|
||||||
################ Receivers SdrIQ, The SDR-IQ receiver by RfSpace
|
################ Receivers SdrIQ, The SDR-IQ receiver by RfSpace.
|
||||||
## hardware_file_name Hardware file path, rfile
|
## hardware_file_name Hardware file path, rfile
|
||||||
# This is the file that contains the control logic for each radio.
|
# This is the file that contains the control logic for each radio.
|
||||||
hardware_file_name = 'quisk_hardware_sdriq.py'
|
hardware_file_name = 'quisk_hardware_sdriq.py'
|
||||||
@@ -633,7 +710,7 @@ sdriq_decimation = 1250
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
################ Receivers Odyssey, The Odyssey project using a UDP protocol similar to the HiQSDR
|
################ Receivers Odyssey, The Odyssey project.
|
||||||
## hardware_file_name Hardware file path, rfile
|
## hardware_file_name Hardware file path, rfile
|
||||||
# This is the file that contains the control logic for each radio.
|
# This is the file that contains the control logic for each radio.
|
||||||
#hardware_file_name = 'hiqsdr/quisk_hardware.py'
|
#hardware_file_name = 'hiqsdr/quisk_hardware.py'
|
||||||
@@ -744,7 +821,7 @@ sndp_active = True
|
|||||||
#radio_sound_mic_boost = True
|
#radio_sound_mic_boost = True
|
||||||
|
|
||||||
|
|
||||||
################ Receivers Odyssey2, The Odyssey-2 project using the HPSDR Hermes protocol
|
################ Receivers Odyssey2, The Odyssey-2 project.
|
||||||
## hardware_file_name Hardware file path, rfile
|
## hardware_file_name Hardware file path, rfile
|
||||||
# This is the file that contains the control logic for each radio.
|
# This is the file that contains the control logic for each radio.
|
||||||
#hardware_file_name = 'hermes/quisk_hardware.py'
|
#hardware_file_name = 'hermes/quisk_hardware.py'
|
||||||
@@ -759,7 +836,7 @@ sndp_active = True
|
|||||||
# You can set these options:
|
# You can set these options:
|
||||||
|
|
||||||
## use_rx_udp Hardware type, integer choice
|
## use_rx_udp Hardware type, integer choice
|
||||||
# This is the type of UDP hardware. Use 10 for the Hermes protocol.
|
# This is the type of UDP hardware. Use 10 for the Odyssey-2.
|
||||||
#use_rx_udp = 10
|
#use_rx_udp = 10
|
||||||
|
|
||||||
## rx_udp_ip IP change, text
|
## rx_udp_ip IP change, text
|
||||||
@@ -828,7 +905,7 @@ Hermes_BandDictEnTx = False
|
|||||||
#Hermes_BandDictEnTx = True
|
#Hermes_BandDictEnTx = True
|
||||||
|
|
||||||
|
|
||||||
################ Receivers Afedri, The Afedri SDR receiver with the Ethernet interface.
|
################ Receivers Afedri, The Afedri SDR receiver with Ethernet.
|
||||||
## hardware_file_name Hardware file path, rfile
|
## hardware_file_name Hardware file path, rfile
|
||||||
# This is the file that contains the control logic for each radio.
|
# This is the file that contains the control logic for each radio.
|
||||||
#hardware_file_name = 'afedrinet/quisk_hardware.py'
|
#hardware_file_name = 'afedrinet/quisk_hardware.py'
|
||||||
@@ -860,7 +937,7 @@ Hermes_BandDictEnTx = False
|
|||||||
#default_rf_gain = 11
|
#default_rf_gain = 11
|
||||||
|
|
||||||
|
|
||||||
################ Receivers Control Head, Use Quisk to control a remote radio. No real hardware is used here.
|
################ Receivers Control Head, Use Quisk to control a remote Quisk radio.
|
||||||
## hardware_file_name Hardware file path, rfile
|
## hardware_file_name Hardware file path, rfile
|
||||||
# Quisk can be used as a control head to control a real radio located remotely.
|
# Quisk can be used as a control head to control a real radio located remotely.
|
||||||
# This file contains the control logic for remote radios of type Hermes, SoftRock or HiQSDR.
|
# This file contains the control logic for remote radios of type Hermes, SoftRock or HiQSDR.
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import os
|
|||||||
# You must define the version here. A title string including
|
# You must define the version here. A title string including
|
||||||
# the version will be written to __init__.py and read by quisk.py.
|
# the version will be written to __init__.py and read by quisk.py.
|
||||||
|
|
||||||
Version = '4.2.46'
|
Version = '4.2.47'
|
||||||
|
|
||||||
fp = open("__init__.py", "w") # write title string
|
fp = open("__init__.py", "w") # write title string
|
||||||
fp.write("#Quisk version %s\n" % Version)
|
fp.write("#Quisk version %s\n" % Version)
|
||||||
|
|||||||
Reference in New Issue
Block a user