2 Commits
Author SHA1 Message Date
James C. Ahlstrom d8aee9284d Quisk version 4.2.47 2025-11-22 13:39:10 -05:00
James C. Ahlstrom 7121dacbbd Quisk version 4.2.46 2025-10-12 12:43:21 -04:00
12 changed files with 282 additions and 240 deletions
+18
View File
@@ -1,3 +1,21 @@
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
==================================
I fixed a bug in Hamlib rig 2 which happens with the new Pure Signal code. The Hamlib "f" command
now always returns the main receiver frequency, not one of the added receiver frequencies. This is
consistent with the Flex ZZ commands.
Quisk Version 4.2.45 October 2025 Quisk Version 4.2.45 October 2025
================================== ==================================
The new FreeDV including RADE mode is now a built-in mode of Quisk. Just press "FDV" to talk FreeDV. The new FreeDV including RADE mode is now a built-in mode of Quisk. Just press "FDV" to talk FreeDV.
+1 -1
View File
@@ -1,2 +1,2 @@
#Quisk version 4.2.45 #Quisk version 4.2.47
from .quisk import main from .quisk import main
+7 -4
View File
@@ -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
+31
View File
@@ -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
View File
@@ -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[:]
+3 -9
View File
@@ -1,8 +1,5 @@
# This is the hardware control file for my shack. # This is the hardware control file for my shack.
# It is for the Hermes-Lite2 5 watt output which uses only the antenna tuner. # It is for the Hermes-Lite2 RF1 output and Alt Rx input.
from __future__ import print_function
from __future__ import absolute_import
from __future__ import division
from hermes.quisk_hardware import Hardware as BaseHw from hermes.quisk_hardware import Hardware as BaseHw
from n2adr import station_hardware from n2adr import station_hardware
@@ -17,7 +14,7 @@ class Hardware(BaseHw):
self.controlbox = station_hardware.ControlBox(app, conf) # Control my Station Control Box self.controlbox = station_hardware.ControlBox(app, conf) # Control my Station Control Box
self.v2filter = station_hardware.FilterBoxV2(app, conf) # Control V2 filter box self.v2filter = station_hardware.FilterBoxV2(app, conf) # Control V2 filter box
def open(self): def open(self):
if False: if False: # Start the station control GUI
from n2adr.station_hardware import StationControlGUI from n2adr.station_hardware import StationControlGUI
self.GUI = StationControlGUI(self.application.main_frame, self, self.application, self.conf) self.GUI = StationControlGUI(self.application.main_frame, self, self.application, self.conf)
self.GUI.Show() self.GUI.Show()
@@ -29,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)
@@ -42,8 +38,6 @@ class Hardware(BaseHw):
# band is a string: "60", "40", "WWV", etc. # band is a string: "60", "40", "WWV", etc.
ret = BaseHw.ChangeBand(self, band) ret = BaseHw.ChangeBand(self, band)
self.anttuner.ChangeBand(band) self.anttuner.ChangeBand(band)
#self.lpfilter.ChangeBand(band)
#self.hpfilter.ChangeBand(band)
self.v2filter.ChangeBand(band) self.v2filter.ChangeBand(band)
self.CorrectSmeter() self.CorrectSmeter()
return ret return ret
+4 -50
View File
@@ -1,56 +1,10 @@
# 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. # This module is used to add extra widgets to the QUISK screen.
from __future__ import print_function
from __future__ import absolute_import
from __future__ import division
import wx, time import wx, time
import _quisk as QS import _quisk as QS
class BottomWidgets: # Add extra widgets to the bottom of the screen from hermes.quisk_widgets import BottomWidgets as BaseWidgets
class BottomWidgets(BaseWidgets): # Add extra widgets to the bottom of the screen
def __init__(self, app, hardware, conf, frame, gbs, vertBox): def __init__(self, app, hardware, conf, frame, gbs, vertBox):
#self.config = conf BaseWidgets.__init__(self, app, hardware, conf, frame, gbs, vertBox)
#self.hardware = hardware
#self.application = app
#start_row = app.widget_row # The first available row
#start_col = app.button_start_col # The start of the button columns
#b = app.QuiskCycleCheckbutton(frame, self.OnAntTuner, ('Antenna', 'Ant 0', 'Ant 1'))
#bw, bh = b.GetMinSize()
#gbs.Add(b, (start_row, start_col), (1, 2), flag=wx.EXPAND)
#b = app.QuiskPushbutton(frame, self.OnAntTuner, 'L+')
#b.Enable(0)
#gbs.Add(b, (start_row, start_col + 2), (1, 2), flag=wx.EXPAND)
#b = app.QuiskPushbutton(frame, self.OnAntTuner, 'L-')
#b.Enable(0)
#gbs.Add(b, (start_row, start_col + 4), (1, 2), flag=wx.EXPAND)
#b = app.QuiskPushbutton(frame, self.OnAntTuner, 'C+')
#b.Enable(0)
#gbs.Add(b, (start_row, start_col + 6), (1, 2), flag=wx.EXPAND)
#b = app.QuiskPushbutton(frame, self.OnAntTuner, 'C-')
#b.Enable(0)
#gbs.Add(b, (start_row, start_col + 8), (1, 2), flag=wx.EXPAND)
#b = app.QuiskPushbutton(frame, self.OnAntTuner, 'Save')
#b.Enable(0)
#gbs.Add(b, (start_row, start_col + 10), (1, 2), flag=wx.EXPAND)
#self.swr_label = app.QuiskText(frame, 'Watts 000 SWR 10.1 Zh Ind 22 Cap 33 Freq 28100 (7777)', bh)
#gbs.Add(self.swr_label, (start_row, start_col + 2), (1, 10), flag=wx.EXPAND)
#b = app.QuiskCheckbutton(frame, None, text='')
#gbs.Add(b, (start_row, start_col + 25), (1, 2), flag=wx.EXPAND)
# Example of a horizontal slider:
# lab = wx.StaticText(frame, -1, 'Preamp', style=wx.ALIGN_CENTER)
# gbs.Add(lab, (5,0), flag=wx.EXPAND)
# sl = wx.Slider(frame, -1, 1024, 0, 2048) # parent, -1, initial, min, max
# gbs.Add(sl, (5,1), (1, 5), flag=wx.EXPAND)
# sl.Bind(wx.EVT_SCROLL, self.OnPreamp)
# def OnPreamp(self, event):
# print event.GetPosition()
self.num_rows_added = 0
#def OnAntTuner(self, event):
# btn = event.GetEventObject()
# text = btn.GetLabel()
# self.hardware.OnAntTuner(text)
#def UpdateText(self, text):
# self.swr_label.SetLabel(text)
+85 -123
View File
@@ -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
@@ -411,18 +407,15 @@ class AntennaTuner: # Control my homebrew antenna tuner and my KI8BV dipole
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 = 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
@@ -484,10 +476,10 @@ class AntennaTuner: # Control my homebrew antenna tuner and my KI8BV dipole
if tx_freq < 17000000: if tx_freq < 17000000:
if DEBUG and self.antnum == 1: print ("antnum 0") if DEBUG and self.antnum == 1: print ("antnum 0")
self.antnum = 0 self.antnum = 0
else: elif self.dipole2:
if DEBUG and self.antnum == 0: print ("antnum 1") if DEBUG and self.antnum == 0: print ("antnum 1")
self.antnum = 1 self.antnum = 1
if self.antnum == 1: if self.antnum == 1 and self.dipole2:
self.dipole2.SetTxFreq(tx_freq) self.dipole2.SetTxFreq(tx_freq)
if not self.socket: if not self.socket:
return return
@@ -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
@@ -521,7 +513,8 @@ class AntennaTuner: # Control my homebrew antenna tuner and my KI8BV dipole
self.timer = 0 self.timer = 0
else: else:
self.timer = 0 self.timer = 0
self.dipole2.HeartBeat() if self.dipole2:
self.dipole2.HeartBeat()
def Send(self): def Send(self):
try: try:
self.socket.send(self.want_data) self.socket.send(self.want_data)
@@ -539,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)
@@ -568,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)
@@ -604,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)
@@ -611,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)
@@ -622,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:
@@ -647,46 +639,22 @@ 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
else: elif anttuner.dipole2:
anttuner.antnum = 1 anttuner.antnum = 1
if anttuner.antnum == 1: 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()
@@ -730,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
@@ -751,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():
@@ -763,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())
@@ -1072,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()
+1 -1
View File
@@ -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'
+9 -18
View File
@@ -995,17 +995,12 @@ class HamlibHandlerRig2: # Test with telnet localhost 4532
else: else:
self.Send('0\n') self.Send('0\n')
def GetFreq(self): # The Rx frequency def GetFreq(self): # The Rx frequency
rx = self.app.multi_rx_screen.receiver_list # This is always the main Rx frequency without reference to added receivers.
if rx: self.Reply('Frequency', self.app.rxFreq + self.app.VFO, 0)
rx = rx[0] if HAMLIB_DEBUG:
self.Reply('Frequency', rx.txFreq + rx.VFO, 0) print ("GetFreq app", self.app.rxFreq, self.app.txFreq, self.app.VFO)
if HAMLIB_DEBUG:
print ("GetFreq rx", rx.txFreq, rx.VFO)
else:
self.Reply('Frequency', self.app.rxFreq + self.app.VFO, 0)
if HAMLIB_DEBUG:
print ("GetFreq app", self.app.rxFreq, self.app.txFreq, self.app.VFO)
def SetFreq(self): # The Rx frequency def SetFreq(self): # The Rx frequency
# This is always the main Rx frequency without reference to added receivers.
freq = self.GetParamNumber() freq = self.GetParamNumber()
try: try:
freq = float(freq) freq = float(freq)
@@ -1014,12 +1009,7 @@ class HamlibHandlerRig2: # Test with telnet localhost 4532
self.ErrParam() self.ErrParam()
else: else:
freq = int(freq + 0.5) freq = int(freq + 0.5)
# For multiple receivers this controls the first added receiver frequency; else it controls split Rx/Tx frequency. self.app.ChangeRxTxFrequency(freq, None)
rx = self.app.multi_rx_screen.receiver_list
if rx:
rx[0].ChangeRxTxFrequency(freq)
else:
self.app.ChangeRxTxFrequency(freq, None)
def GetSplitFreq(self): # The Tx Frequency def GetSplitFreq(self): # The Tx Frequency
self.Reply('TX Frequency', self.app.txFreq + self.app.VFO, 0) self.Reply('TX Frequency', self.app.txFreq + self.app.VFO, 0)
def SetSplitFreq(self): # The Tx Frequency def SetSplitFreq(self): # The Tx Frequency
@@ -3728,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)
@@ -3949,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:
@@ -6808,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
View File
@@ -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.
+1 -1
View File
@@ -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.45' 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)