public:radio:radio_database:ar_7030
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
public:radio:radio_database:ar_7030 [20/07/22 07:17 BST] – [3. Remote Control] john | public:radio:radio_database:ar_7030 [06/03/25 06:49 GMT] (current) – external edit 127.0.0.1 | ||
---|---|---|---|
Line 2: | Line 2: | ||
- | ====== AR7030 ====== | + | ====== |
===== - Faults/ | ===== - Faults/ | ||
Line 9: | Line 9: | ||
* Bourns ECW1J-B24-AC0024L available at Farnell at £3.80 | * Bourns ECW1J-B24-AC0024L available at Farnell at £3.80 | ||
* Ordered 4 off 16/7/22 | * Ordered 4 off 16/7/22 | ||
+ | * Replaced vol encoder : July 2022 | ||
+ | * July 2022 - VFO Tuning encoder u/s | ||
+ | * Only changed freq. over a small portion of a revolution | ||
+ | * Using remote control via LAN to operate until a new encoder is sourced | ||
===== - Filters ===== | ===== - Filters ===== | ||
====Currently fitted:==== | ====Currently fitted:==== | ||
+ | |||
+ | Before change (below) | ||
^PCB ref^Description^Model^Bandwidth^ | ^PCB ref^Description^Model^Bandwidth^ | ||
Line 39: | Line 45: | ||
CW / Data / SSB narrow : CFJ455K8 : 1.4 | CW / Data / SSB narrow : CFJ455K8 : 1.4 | ||
| | ||
- | Remove un-needed AM-Wide 6.4kHz from X7 and install 1.4kHz " | + | |
+ | === July 2022 === | ||
- | This would give : | + | Removed un-needed AM-Wide 6.4kHz from X7 and installed 1.4kHz " |
- | 0.5 CW | + | This gives : |
- | 1.4 CW/Data | + | |
- | 2.1 SSB | + | ^PCB ref^Description^Model^Bandwidth^ |
- | 3.9 AM-Narrow | + | | X3 | AM Narrow |
- | 5.5 AM-Normal | + | | X4 | AM Normal # | CFW455IT |
- | 9.5 FM | + | | X5 | SSB # | CFJ455K14 |
+ | | X6 | FM # | CFU455G2 | ||
+ | | X7 | Data | ||
+ | | X8 | CW Collins | ||
+ | |||
+ | # = factory supplied | ||
+ | |||
+ | In order of Bandwidth | ||
+ | |||
+ | 1 : 0.5 CW | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
===== - Remote Control ===== | ===== - Remote Control ===== | ||
- | The Python module used in [[https:// | + | The Python module used in [[https:// |
+ | |||
+ | ++++ Generic aor.py | | ||
<file python | <file python | ||
Line 397: | Line 420: | ||
</ | </ | ||
+ | |||
+ | ++++ | ||
+ | |||
+ | |||
+ | |||
+ | === Update July 2022 === | ||
+ | |||
+ | I've modified the server/ | ||
+ | |||
+ | |||
+ | {{: | ||
+ | |||
+ | ++++ New (July 2022) version of Tkinter GUI with S-Meter graph and IF filter Selection | | ||
+ | |||
+ | <file python gui_smeter.py> | ||
+ | # # new class-based gui | ||
+ | |||
+ | from Tkinter import * | ||
+ | import socket | ||
+ | import threading | ||
+ | import time | ||
+ | |||
+ | |||
+ | |||
+ | class Network(object): | ||
+ | def __init__(self): | ||
+ | self.sock = self.make_con() | ||
+ | | ||
+ | def make_con(self): | ||
+ | self.sock = socket.socket(socket.AF_INET, | ||
+ | self.sock.connect((" | ||
+ | return self.sock | ||
+ | |||
+ | def connect(self, | ||
+ | try: | ||
+ | lock.acquire() | ||
+ | self.sock.sendall(data + " | ||
+ | self.received = self.sock.recv(2048) | ||
+ | finally: | ||
+ | lock.release() | ||
+ | return self.received | ||
+ | | ||
+ | class Dash(object): | ||
+ | def __init__(self, | ||
+ | self.master = master | ||
+ | | ||
+ | self.s = (n1.sock.getsockname()) | ||
+ | self.p = (n1.sock.getpeername()) | ||
+ | | ||
+ | | ||
+ | | ||
+ | dash_frame = Toplevel(master, | ||
+ | dash_frame.title(" | ||
+ | dash_frame.protocol(" | ||
+ | dash_frame.resizable(0, | ||
+ | dash_frame.geometry(" | ||
+ | dash_frame.grid() | ||
+ | | ||
+ | self.utc_time = StringVar() | ||
+ | Label(dash_frame, | ||
+ | | ||
+ | Label(dash_frame, | ||
+ | | ||
+ | Label(dash_frame, | ||
+ | | ||
+ | Label(dash_frame, | ||
+ | |||
+ | self.server_msg_l = StringVar() | ||
+ | Label(dash_frame, | ||
+ | | ||
+ | q_button = Button(dash_frame, | ||
+ | q_button.grid(row = 3, column = 0, sticky = E) | ||
+ | | ||
+ | def handler(self): | ||
+ | pass | ||
+ | | ||
+ | def up_dash(self): | ||
+ | self.server_msg = n1.connect(" | ||
+ | self.server_msg_l.set(self.server_msg) | ||
+ | self.utc_time.set(time.strftime(" | ||
+ | return | ||
+ | |||
+ | class nRadio(object): | ||
+ | def __init__(self, | ||
+ | self.master = master | ||
+ | | ||
+ | self.radio = radio | ||
+ | self.num = "" | ||
+ | |||
+ | | ||
+ | radio_frame = Frame(master, | ||
+ | | ||
+ | radio_frame.grid() | ||
+ | self.smeter_list = [] | ||
+ | |||
+ | filter_frame = Frame(radio_frame) | ||
+ | filter_frame.grid(row=5, | ||
+ | |||
+ | mode_frame = Frame(radio_frame) | ||
+ | mode_frame.grid(row=3, | ||
+ | |||
+ | control_frame = Frame(radio_frame) | ||
+ | control_frame.grid(row=5, | ||
+ | |||
+ | q_button = Checkbutton(control_frame, | ||
+ | q_button.grid(row = 1, column = 1, sticky = W) | ||
+ | | ||
+ | Label(radio_frame, | ||
+ | Label(radio_frame, | ||
+ | Label(radio_frame, | ||
+ | Label(radio_frame, | ||
+ | Label(radio_frame, | ||
+ | Label(radio_frame, | ||
+ | Label(radio_frame, | ||
+ | |||
+ | self.name_l = StringVar() | ||
+ | self.l_name = Label(radio_frame, | ||
+ | self.l_name.grid(row=1, | ||
+ | |||
+ | | ||
+ | | ||
+ | self.freq_l = StringVar() | ||
+ | self.l_freq = Label(radio_frame, | ||
+ | self.l_freq.grid(row=1, | ||
+ | | ||
+ | self.mode_l = StringVar() | ||
+ | self.l_mode = Label(radio_frame, | ||
+ | self.l_mode.grid(row=1, | ||
+ | |||
+ | self.filt_l = IntVar() | ||
+ | self.r_filt_1 = Radiobutton(filter_frame, | ||
+ | self.r_filt_1.grid(row=5, | ||
+ | self.r_filt_2 = Radiobutton(filter_frame, | ||
+ | self.r_filt_2.grid(row=5, | ||
+ | self.r_filt_3 = Radiobutton(filter_frame, | ||
+ | self.r_filt_3.grid(row=5, | ||
+ | self.r_filt_4 = Radiobutton(filter_frame, | ||
+ | self.r_filt_4.grid(row=6, | ||
+ | self.r_filt_5 = Radiobutton(filter_frame, | ||
+ | self.r_filt_5.grid(row=6, | ||
+ | self.r_filt_6 = Radiobutton(filter_frame, | ||
+ | self.r_filt_6.grid(row=6, | ||
+ | # | ||
+ | | ||
+ | # | ||
+ | # | ||
+ | | ||
+ | | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | | ||
+ | | ||
+ | # | ||
+ | self.b_mode_usb = Radiobutton(mode_frame, | ||
+ | self.b_mode_usb.grid(row = 0, column = 0) | ||
+ | | ||
+ | self.b_mode_lsb = Radiobutton(mode_frame, | ||
+ | self.b_mode_lsb.grid(row = 0, column = 1) | ||
+ | | ||
+ | self.b_mode_cw = Radiobutton(mode_frame, | ||
+ | self.b_mode_cw.grid(row = 0, column = 2) | ||
+ | | ||
+ | self.b_mode_am = Radiobutton(mode_frame, | ||
+ | self.b_mode_am.grid(row = 1, column = 1) | ||
+ | |||
+ | self.b_mode_am = Radiobutton(mode_frame, | ||
+ | self.b_mode_am.grid(row = 1, column = 3) | ||
+ | | ||
+ | self.b_mode_data = Radiobutton(mode_frame, | ||
+ | self.b_mode_data.grid(row = 1, column = 0) | ||
+ | |||
+ | self.b_mode_fm = Radiobutton(mode_frame, | ||
+ | self.b_mode_fm.grid(row = 1, column = 2) | ||
+ | |||
+ | self.b_qsy_up = Button(radio_frame, | ||
+ | self.b_qsy_up.grid(row = 2, column = 2) | ||
+ | |||
+ | self.b_qsy_down = Button(radio_frame, | ||
+ | self.b_qsy_down.grid(row = 2, column = 0) | ||
+ | |||
+ | self.b_update = Button(radio_frame, | ||
+ | # | ||
+ | | ||
+ | | ||
+ | self.smeter_l = StringVar() | ||
+ | self.l_smeter = Label(radio_frame, | ||
+ | self.l_smeter.grid(row=1, | ||
+ | |||
+ | self.max_var = StringVar() | ||
+ | self.l_max = Label(radio_frame, | ||
+ | self.l_max.grid(row=1, | ||
+ | | ||
+ | self.ave_var = StringVar() | ||
+ | self.l_average = Label(radio_frame, | ||
+ | self.l_average.grid(row=1, | ||
+ | |||
+ | self.min_var = StringVar() | ||
+ | self.l_min = Label(radio_frame, | ||
+ | self.l_min.grid(row=1, | ||
+ | |||
+ | self.e_freq = Entry(radio_frame, | ||
+ | self.e_freq.grid(row=2, | ||
+ | self.e_freq.focus() | ||
+ | self.e_freq.bind('< | ||
+ | | ||
+ | | ||
+ | | ||
+ | self.pre = IntVar() | ||
+ | self.cb_pre = Checkbutton(control_frame, | ||
+ | self.cb_pre.grid(row=0, | ||
+ | |||
+ | self.l_pre = Label(control_frame, | ||
+ | # | ||
+ | |||
+ | self.att = IntVar() | ||
+ | self.cb_att = Checkbutton(control_frame, | ||
+ | self.cb_att.grid(row=1, | ||
+ | | ||
+ | self.l_att = Label(control_frame, | ||
+ | # | ||
+ | | ||
+ | self.set_log = IntVar() | ||
+ | self.cb_log = Checkbutton(control_frame, | ||
+ | self.cb_log.grid(row = 0, column = 1, sticky = W) | ||
+ | | ||
+ | self.l_log = Label(control_frame, | ||
+ | # | ||
+ | |||
+ | self.c1 = Canvas(radio_frame, | ||
+ | self.c1.grid(row=2, | ||
+ | |||
+ | name = self.get_name(radio) | ||
+ | |||
+ | |||
+ | def get_all(self): | ||
+ | | ||
+ | | ||
+ | self.get_freq(self.num) | ||
+ | self.get_mode(self.num) | ||
+ | self.get_smeter(self.num) | ||
+ | self.get_preamp(self.num) | ||
+ | self.get_atten(self.num) | ||
+ | self.graph_points() | ||
+ | self.avg() | ||
+ | self.max() | ||
+ | self.min() | ||
+ | self.get_filt(self.num) | ||
+ | | ||
+ | if self.set_log.get() == 1: | ||
+ | if int(time.time()) % 10.0 == 0: | ||
+ | self.write_file() | ||
+ | return | ||
+ | |||
+ | |||
+ | def get_filt(self, | ||
+ | self.filt = n1.connect(" | ||
+ | self.filt_l.set(self.filt) | ||
+ | return | ||
+ | |||
+ | def set_filt(self, | ||
+ | self.filt = str(self.filt_l.get()) | ||
+ | self.newfilt = n1.connect(" | ||
+ | # | ||
+ | self.get_all() | ||
+ | return | ||
+ | |||
+ | | ||
+ | def get_freq(self, | ||
+ | |||
+ | self.freq = n1.connect(" | ||
+ | self.freq_l.set(self.freq) | ||
+ | return | ||
+ | |||
+ | def set_freq(self, | ||
+ | self.freq = str(self.e_freq.get()) | ||
+ | self.newfreq = n1.connect(" | ||
+ | self.e_freq.delete(0, | ||
+ | self.get_all() | ||
+ | return | ||
+ | |||
+ | def qsy_up(self, | ||
+ | | ||
+ | oldf = n1.connect(" | ||
+ | newf = str(float(oldf) + 1) | ||
+ | freq = n1.connect(" | ||
+ | self.get_all() | ||
+ | return | ||
+ | |||
+ | def qsy_down(self, | ||
+ | oldf = n1.connect(" | ||
+ | newf = str(float(oldf) - 1) | ||
+ | freq = n1.connect(" | ||
+ | self.get_all() | ||
+ | return | ||
+ | |||
+ | def get_mode(self, | ||
+ | self.mode = n1.connect(" | ||
+ | self.mode_l.set(self.mode) | ||
+ | return | ||
+ | |||
+ | def set_mode(self, | ||
+ | #self.mode = str(self.e_mode.get()) | ||
+ | self.newmode = n1.connect(" | ||
+ | # | ||
+ | self.get_all() | ||
+ | return | ||
+ | |||
+ | def get_smeter(self, | ||
+ | self.smeter = n1.connect(" | ||
+ | self.smeter_l.set(self.smeter) | ||
+ | self.smeter_list.append(float(self.smeter)) | ||
+ | if len(self.smeter_list) > 129: | ||
+ | self.smeter_list.pop(0) | ||
+ | return | ||
+ | |||
+ | def avg(self): | ||
+ | s = self.smeter_list | ||
+ | total = 0 | ||
+ | for i in s: | ||
+ | total += i | ||
+ | self.av = round((total / len(s)), 1) | ||
+ | self.ave_var.set(str(self.av)) | ||
+ | self.c1.create_line(0, | ||
+ | return self.av | ||
+ | |||
+ | def min(self): | ||
+ | s = self.smeter_list | ||
+ | self.mn = s[0] | ||
+ | for i in s: | ||
+ | if i < self.mn: | ||
+ | self.mn = i | ||
+ | self.min_var.set(str(self.mn)) | ||
+ | self.c1.create_line(0, | ||
+ | return self.mn | ||
+ | |||
+ | def max(self): | ||
+ | s = self.smeter_list | ||
+ | self.mx = s[0] | ||
+ | for i in s: | ||
+ | if i > self.mx: | ||
+ | self.mx = i | ||
+ | self.max_var.set(str(self.mx)) | ||
+ | self.c1.create_line(0, | ||
+ | return self.mx | ||
+ | |||
+ | def get_preamp(self, | ||
+ | self.preamp = n1.connect(" | ||
+ | if self.preamp == " | ||
+ | self.cb_pre.select() | ||
+ | elif self.preamp == " | ||
+ | self.cb_pre.deselect() | ||
+ | return | ||
+ | |||
+ | def preamp_onoff(self, | ||
+ | self.prestate = self.pre.get() | ||
+ | if self.prestate: | ||
+ | n1.connect(" | ||
+ | else: | ||
+ | n1.connect(" | ||
+ | self.get_all() | ||
+ | return | ||
+ | |||
+ | def att_onoff(self, | ||
+ | self.attstate = self.att.get() | ||
+ | if self.attstate: | ||
+ | n1.connect(" | ||
+ | else: | ||
+ | n1.connect(" | ||
+ | self.get_all() | ||
+ | return | ||
+ | |||
+ | |||
+ | def get_atten(self, | ||
+ | self.atten = n1.connect(" | ||
+ | if self.atten == " | ||
+ | self.cb_att.select() | ||
+ | elif self.atten == " | ||
+ | self.cb_att.deselect() | ||
+ | return | ||
+ | |||
+ | def get_name(self, | ||
+ | print radio | ||
+ | self.all_names = n1.connect(" | ||
+ | self.radios = self.all_names.split() | ||
+ | print self.radios | ||
+ | self.name = self.radios[int(radio) - 1] | ||
+ | self.name_l.set(self.name) | ||
+ | return | ||
+ | | ||
+ | |||
+ | |||
+ | def graph_points(self): | ||
+ | seq = self.smeter_list | ||
+ | y_stretch = 1 | ||
+ | y_gap = 5 | ||
+ | x_stretch = 0 | ||
+ | x_width = 2 | ||
+ | x_gap = 2 | ||
+ | height = 100 | ||
+ | self.c1.delete(ALL) | ||
+ | self.c1.create_line(0, | ||
+ | for x, y in enumerate(seq): | ||
+ | yd = y + 123 | ||
+ | x0 = x * x_stretch + x * x_width + x_gap | ||
+ | y0 = height - (yd * y_stretch + y_gap) | ||
+ | x1 = x * x_stretch + x * x_width + x_width + x_gap | ||
+ | y1 = height - y_gap | ||
+ | self.c1.create_rectangle(x0, | ||
+ | |||
+ | def write_file(self): | ||
+ | self.filename = self.name+" | ||
+ | self.f = open(self.filename, | ||
+ | timenow = time.strftime(" | ||
+ | log = " " | ||
+ | self.f.write(log) | ||
+ | self.f.close() | ||
+ | |||
+ | def update(): | ||
+ | #loops = 0 | ||
+ | |||
+ | try: | ||
+ | nRadio1.get_all() | ||
+ | except: | ||
+ | pass | ||
+ | try: | ||
+ | nRadio2.get_all() | ||
+ | except: | ||
+ | pass | ||
+ | try: | ||
+ | nRadio3.get_all() | ||
+ | except: | ||
+ | pass | ||
+ | try: | ||
+ | nRadio4.get_all() | ||
+ | except: | ||
+ | pass | ||
+ | # | ||
+ | |||
+ | return | ||
+ | |||
+ | def main(): | ||
+ | #loops = 0 | ||
+ | while True: | ||
+ | try: | ||
+ | nRadio1.get_all() | ||
+ | except: | ||
+ | pass | ||
+ | try: | ||
+ | nRadio2.get_all() | ||
+ | except: | ||
+ | pass | ||
+ | try: | ||
+ | nRadio3.get_all() | ||
+ | except: | ||
+ | pass | ||
+ | try: | ||
+ | nRadio4.get_all() | ||
+ | except: | ||
+ | pass | ||
+ | # | ||
+ | #loops += 1 | ||
+ | #print threading.currentThread().name, | ||
+ | time.sleep(1) | ||
+ | |||
+ | def close(): | ||
+ | n1.connect(" | ||
+ | root.destroy() | ||
+ | | ||
+ | | ||
+ | if __name__ == " | ||
+ | version = " | ||
+ | lock = threading.Lock() | ||
+ | root = Tk() | ||
+ | #w, h = root.winfo_screenwidth(), | ||
+ | # | ||
+ | # | ||
+ | | ||
+ | root.title(" | ||
+ | | ||
+ | # | ||
+ | n1 = Network() | ||
+ | # | ||
+ | # | ||
+ | | ||
+ | radio_count = int(n1.connect(" | ||
+ | #if radio_count > 0: | ||
+ | # nRadio1 = nRadio(root, | ||
+ | #if radio_count > 1: | ||
+ | # nRadio2 = nRadio(root, | ||
+ | #if radio_count > 2: | ||
+ | # nRadio3 = nRadio(root, | ||
+ | #if radio_count > 3: | ||
+ | # nRadio4 = nRadio(root, | ||
+ | | ||
+ | nRadio1 = nRadio(root, | ||
+ | #d1 = Dash(root) | ||
+ | | ||
+ | #print threading.currentThread().name | ||
+ | m1 = threading.Thread(target = main) | ||
+ | m1.setDaemon(True) | ||
+ | m1.start() | ||
+ | | ||
+ | update() | ||
+ | | ||
+ | root.mainloop() | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | </ | ||
+ | ++++ | ||
+ | |||
+ | ++++ New (July 2022) version of aor module, with access to IF filter selection | | ||
+ | |||
+ | <file python aor_filter.py> | ||
+ | import serial | ||
+ | import threading | ||
+ | |||
+ | |||
+ | #sport = "/ | ||
+ | sport = "/ | ||
+ | sbaud = 1200 | ||
+ | |||
+ | lock = threading.Lock() | ||
+ | fract = float(2 ** 24) / 44545 | ||
+ | |||
+ | |||
+ | class Ar7030(object): | ||
+ | def __init__(self, | ||
+ | self.ser = serial.Serial(sport, | ||
+ | self.model = model | ||
+ | self.filter = self.get_filter() | ||
+ | |||
+ | def check_bit(self, | ||
+ | mask = 1 << bit | ||
+ | result = (ord(byte) & mask) | ||
+ | if result: | ||
+ | return 1 | ||
+ | else: | ||
+ | return 0 | ||
+ | |||
+ | def set_bit(self, | ||
+ | mask = 1 << bit | ||
+ | result = ord(byte) | mask | ||
+ | return result | ||
+ | |||
+ | def clear_bit(self, | ||
+ | mask = ~(1 << bit) | ||
+ | result = (ord(byte) & mask) | ||
+ | return result | ||
+ | |||
+ | def get_ident(self): | ||
+ | sendStr = ' | ||
+ | ident = self.tx_rx(sendStr, | ||
+ | return ident | ||
+ | |||
+ | def get_pre(self): | ||
+ | sendStr = ' | ||
+ | byte = self.tx_rx(sendStr, | ||
+ | p = self.check_bit(byte, | ||
+ | if p: | ||
+ | return 1 | ||
+ | else: | ||
+ | return 0 | ||
+ | return | ||
+ | |||
+ | def get_filter(self): | ||
+ | sendStr= ' | ||
+ | byte = self.tx_rx(sendStr, | ||
+ | #print ord(byte) | ||
+ | |||
+ | return ord(byte) | ||
+ | |||
+ | def set_filter(self, | ||
+ | #print "In set_filter with ", filt_no | ||
+ | try: | ||
+ | filt_no = int(filt_no) | ||
+ | except ValueError: | ||
+ | return "Not a number" | ||
+ | |||
+ | if filt_no > 6: | ||
+ | return "Out of range" | ||
+ | |||
+ | high = 48 + (filt_no >> 4) | ||
+ | low = 96 + (filt_no & 15) | ||
+ | |||
+ | sendStr= ' | ||
+ | self.tx_rx(sendStr, | ||
+ | | ||
+ | # | ||
+ | |||
+ | return " | ||
+ | |||
+ | |||
+ | |||
+ | def pre_on(self): | ||
+ | #get current 8-bit rxcon byte : | ||
+ | # bit0 = filter FS3 | ||
+ | # bit1 = filter FS2 | ||
+ | # bit2 = filter FS1 | ||
+ | # bit3 = filter FS4 | ||
+ | # bit4 = preamp enabled | ||
+ | # bit5 = atten 0 = 20dB / 1 = 40dB | ||
+ | # bit6 = input filter 0 = HF / 1 = LF | ||
+ | # bit7 = attenuator enabled | ||
+ | |||
+ | sendStr = ' | ||
+ | |||
+ | byte = self.tx_rx(sendStr, | ||
+ | |||
+ | # set bit 4 ON = preamp ON and get the new 8-bit rxcon byte | ||
+ | pon = self.set_bit(byte, | ||
+ | |||
+ | # split new rxcon byte into two 4-bit nibbles, add 48/96 (\x30 and \x60) | ||
+ | high = 48 + (pon >> 4) | ||
+ | low = 96 + (pon & 15) | ||
+ | |||
+ | sendStr = ' | ||
+ | |||
+ | self.tx_rx(sendStr, | ||
+ | |||
+ | return " | ||
+ | |||
+ | |||
+ | def pre_off(self): | ||
+ | #get current 8-bit rxcon byte | ||
+ | sendStr = ' | ||
+ | byte = self.tx_rx(sendStr, | ||
+ | |||
+ | # set bit 4 OFF = preamp OFF and get the new 8-bit rxcon byte | ||
+ | pon = self.clear_bit(byte, | ||
+ | |||
+ | |||
+ | # split new rxcon byte into two 4-bit nibbles, add 48/96 (\x30 and \x60) | ||
+ | high = 48 + (pon >> 4) | ||
+ | low = 96 + (pon & 15) | ||
+ | |||
+ | sendStr = ' | ||
+ | |||
+ | self.tx_rx(sendStr, | ||
+ | return " | ||
+ | |||
+ | |||
+ | def get_att(self): | ||
+ | sendStr = ' | ||
+ | |||
+ | byte = self.tx_rx(sendStr, | ||
+ | |||
+ | a = self.check_bit(byte, | ||
+ | |||
+ | if a: | ||
+ | return 1 | ||
+ | else: | ||
+ | return 0 | ||
+ | |||
+ | |||
+ | def att_on(self): | ||
+ | #get current 8-bit rxcon byte | ||
+ | sendStr = ' | ||
+ | byte = self.tx_rx(sendStr, | ||
+ | |||
+ | # set bit 7 ON = ATT ON and get the new 8-bit rxcon byte | ||
+ | pon = self.set_bit(byte, | ||
+ | |||
+ | |||
+ | # split new rxcon byte into two 4-bit nibbles, add 48/96 (\x30 and \x60) | ||
+ | high = 48 + (pon >> 4) | ||
+ | low = 96 + (pon & 15) | ||
+ | |||
+ | sendStr = ' | ||
+ | |||
+ | self.tx_rx(sendStr, | ||
+ | return " | ||
+ | |||
+ | |||
+ | def att_off(self): | ||
+ | #get current 8-bit rxcon byte | ||
+ | sendStr = ' | ||
+ | byte = self.tx_rx(sendStr, | ||
+ | |||
+ | # set bit 7 OFF = att OFF and get the new 8-bit rxcon byte | ||
+ | pon = self.clear_bit(byte, | ||
+ | |||
+ | |||
+ | # split new rxcon byte into two 4-bit nibbles, add 48/96 (\x30 and \x60) | ||
+ | high = 48 + (pon >> 4) | ||
+ | low = 96 + (pon & 15) | ||
+ | |||
+ | sendStr = ' | ||
+ | |||
+ | self.tx_rx(sendStr, | ||
+ | return " | ||
+ | |||
+ | |||
+ | def set_freq(self, | ||
+ | fval = freq * fract | ||
+ | #print fval | ||
+ | b1 = 48 + int(fval / 1048576) | ||
+ | fval = fval % 1048576 | ||
+ | b2 = 96 + int(fval / 65536) | ||
+ | fval = fval % 65536 | ||
+ | b3 = 48 + int(fval / 4096) | ||
+ | fval = fval % 4096 | ||
+ | b4 = 96 + int(fval / 256) | ||
+ | fval = fval % 256 | ||
+ | b5 = 48 + int(fval / 16) | ||
+ | b6 = 96 + int(fval % 16) | ||
+ | |||
+ | f_tuple = ( b1, b2, b3, b4, b5, b6 ) | ||
+ | |||
+ | freqStr = "" | ||
+ | for byte in f_tuple: | ||
+ | freqStr += chr(byte) | ||
+ | |||
+ | sendStr = ' | ||
+ | |||
+ | self.tx_rx(sendStr, | ||
+ | return "Freq Set" | ||
+ | |||
+ | def get_freq(self): | ||
+ | |||
+ | sendStr = ' | ||
+ | |||
+ | freqStr = self.tx_rx(sendStr, | ||
+ | |||
+ | f_val = 0 | ||
+ | for k in freqStr: | ||
+ | f_val = f_val * 256 + ord(k) | ||
+ | |||
+ | return " | ||
+ | | ||
+ | |||
+ | |||
+ | def set_mode(self, | ||
+ | |||
+ | if mode == " | ||
+ | set_mode_val = " | ||
+ | elif mode == " | ||
+ | set_mode_val = " | ||
+ | elif mode == " | ||
+ | set_mode_val = " | ||
+ | elif mode == " | ||
+ | set_mode_val = " | ||
+ | elif mode == " | ||
+ | set_mode_val = " | ||
+ | elif mode == " | ||
+ | set_mode_val = " | ||
+ | elif mode == " | ||
+ | set_mode_val = " | ||
+ | else: | ||
+ | return "Mode not recognized" | ||
+ | |||
+ | sendStr = ' | ||
+ | |||
+ | self.tx_rx(sendStr, | ||
+ | self.filter = self.get_filter() | ||
+ | |||
+ | return "Mode sent" | ||
+ | |||
+ | def get_mode(self): | ||
+ | |||
+ | sendStr = " | ||
+ | m = self.tx_rx(sendStr, | ||
+ | |||
+ | mode = "" | ||
+ | if m == " | ||
+ | mode = " | ||
+ | elif m == " | ||
+ | mode = " | ||
+ | elif m == " | ||
+ | mode = " | ||
+ | elif m == " | ||
+ | mode = " | ||
+ | elif m == " | ||
+ | mode = " | ||
+ | elif m == " | ||
+ | mode = " | ||
+ | elif m == " | ||
+ | mode = " | ||
+ | |||
+ | return mode.upper() | ||
+ | |||
+ | |||
+ | def get_s(self): | ||
+ | sendStr = ' | ||
+ | sraw = self.tx_rx(sendStr, | ||
+ | |||
+ | return ord(sraw) | ||
+ | |||
+ | def get_cal(self): | ||
+ | |||
+ | sendStr = ' | ||
+ | #print " | ||
+ | cbytes = self.tx_rx(sendStr, | ||
+ | |||
+ | cal = [] | ||
+ | |||
+ | for c in cbytes: | ||
+ | cal.append(ord(c)) | ||
+ | #print cal | ||
+ | return cal | ||
+ | |||
+ | def get_smeter(self): | ||
+ | s = float(self.get_s()) | ||
+ | cal = self.get_cal() | ||
+ | |||
+ | s1 = s - cal[0] | ||
+ | s2 = s1 - cal[1] | ||
+ | s3 = s2 - cal[2] | ||
+ | s4 = s3 - cal[3] | ||
+ | s5 = s4 - cal[4] | ||
+ | s6 = s5 - cal[5] | ||
+ | s7 = s6 - cal[6] | ||
+ | |||
+ | if s1 <= 0: | ||
+ | dbm = -123 | ||
+ | adj = s / cal[0] * 10 | ||
+ | return str(dbm + adj) | ||
+ | |||
+ | elif s2 <= 0: | ||
+ | dbm = -113 | ||
+ | adj = s1 / cal[1] * 10 | ||
+ | return str(dbm + adj) | ||
+ | |||
+ | elif s3 <= 0: | ||
+ | dbm = -103 | ||
+ | adj = s2 / cal[2] * 10 | ||
+ | return str(dbm + adj) | ||
+ | |||
+ | elif s4 <= 0: | ||
+ | dbm = -93 | ||
+ | adj = s3 / cal[3] * 10 | ||
+ | return str(dbm + adj) | ||
+ | |||
+ | elif s5 <= 0: | ||
+ | dbm = -83 | ||
+ | adj = s4 / cal[4] * 10 | ||
+ | return str(dbm + adj) | ||
+ | |||
+ | elif s6 <= 0: | ||
+ | dbm = -73 | ||
+ | adj = s5 / cal[5] * 10 | ||
+ | return str(dbm + adj) | ||
+ | |||
+ | elif s7 <= 0: | ||
+ | dbm = -63 | ||
+ | adj = s6 / cal[6] * 20 | ||
+ | return str(dbm + adj) | ||
+ | |||
+ | else: | ||
+ | dbm = -43 | ||
+ | adj = s7 / cal[7] * 20 | ||
+ | return str(dbm + adj) | ||
+ | |||
+ | |||
+ | def tx_rx(self, sendStr, reply, n): | ||
+ | # apply thread lock | ||
+ | lock.acquire() | ||
+ | self.ser.write(sendStr) | ||
+ | |||
+ | if reply: | ||
+ | result = "" | ||
+ | while not result: | ||
+ | result = self.ser.read(1) | ||
+ | lock.release() | ||
+ | return result | ||
+ | else: | ||
+ | |||
+ | result = "" | ||
+ | byte = "" | ||
+ | while n != 0: | ||
+ | self.ser.write(' | ||
+ | #byte = "" | ||
+ | |||
+ | while not byte: | ||
+ | byte = self.ser.read(1) | ||
+ | |||
+ | result += byte | ||
+ | |||
+ | byte = "" | ||
+ | n -= 1 | ||
+ | lock.release() | ||
+ | return result | ||
+ | |||
+ | |||
+ | </ | ||
+ | |||
+ | ++++ | ||
+ | |||
+ | ++++ New (July 2022) server with AR7030 filter selection | | ||
+ | |||
+ | <file python ar_server_filter.py> | ||
+ | #from aor import * | ||
+ | from aor_filter import * | ||
+ | #from icom import * | ||
+ | from conf import * | ||
+ | #from m710 import * | ||
+ | import SocketServer | ||
+ | import time | ||
+ | |||
+ | try: | ||
+ | import readline | ||
+ | except: | ||
+ | pass | ||
+ | |||
+ | lock = threading.Lock() | ||
+ | |||
+ | radios = [] | ||
+ | |||
+ | |||
+ | |||
+ | #r1 = Icom(n1, a1, cal1) | ||
+ | # | ||
+ | |||
+ | #r2 = m710(n4) | ||
+ | # | ||
+ | |||
+ | #r2 = Icom(n2, a2, cal2) | ||
+ | # | ||
+ | |||
+ | #r3 = Ar7030(n3) | ||
+ | # | ||
+ | |||
+ | r1 = Ar7030(n3) | ||
+ | radios.append(n3) | ||
+ | |||
+ | print radios | ||
+ | #print r1.digi_off() | ||
+ | |||
+ | #print r2.remote_on() | ||
+ | |||
+ | def count_radios(): | ||
+ | count = len(radios) | ||
+ | return count | ||
+ | |||
+ | |||
+ | def list_radios(): | ||
+ | radiolist = "" | ||
+ | for n in range(0, len(radios)): | ||
+ | r = radios[n] | ||
+ | radiolist += (r + " ") | ||
+ | return radiolist | ||
+ | |||
+ | |||
+ | def write_file(text): | ||
+ | filename = ' | ||
+ | f = open(filename, | ||
+ | timenow = time.strftime(" | ||
+ | log = " " | ||
+ | f.write(log) | ||
+ | f.close() | ||
+ | |||
+ | |||
+ | def write_con(text): | ||
+ | filename = ' | ||
+ | f = open(filename, | ||
+ | timenow = time.strftime(" | ||
+ | log = " " | ||
+ | f.write(log) | ||
+ | f.close() | ||
+ | |||
+ | |||
+ | # The Server | ||
+ | class ThreadedRequestHandler(SocketServer.StreamRequestHandler): | ||
+ | def handle(self): | ||
+ | # we find the current thread for the client connection just set up, to | ||
+ | # use in the log file | ||
+ | cur_thread = threading.currentThread() | ||
+ | # log the new connection details | ||
+ | write_con(" | ||
+ | # print to the server' | ||
+ | print self.client_address | ||
+ | # loop to handle client requests.... | ||
+ | while True: | ||
+ | # using StreamRequestHandler means our input from the client | ||
+ | # is " | ||
+ | # we read a line at a time, using readline() | ||
+ | cmd = self.rfile.readline().lower() | ||
+ | # to keep things clean, we remove any characters that aren't | ||
+ | # " | ||
+ | # these are between 32 and 127 in the ASCII table | ||
+ | # we look at each character, and then make a new word by | ||
+ | # .join()ing each accepted character with no space in between | ||
+ | asccmd = "" | ||
+ | # we make a list called " | ||
+ | # will be inspected by various functions | ||
+ | words = asccmd.split() | ||
+ | # If a client uses sock.close() itself, to disconnect, it appears that | ||
+ | # we read a continuous stream of "" | ||
+ | # socket, which puts CPU to 100%. | ||
+ | # | ||
+ | # The " | ||
+ | # way to keep the connection up for multiple commands. | ||
+ | # | ||
+ | # Further connection are accepted due to the Threaded nature of the server. | ||
+ | # The CPU load is unacceptable though | ||
+ | # HACK ?>>>>> | ||
+ | # Looking for "" | ||
+ | # the connection from the server end (even though the client has | ||
+ | # gone) cures this. | ||
+ | if cmd == "": | ||
+ | break | ||
+ | else: | ||
+ | pass | ||
+ | # if the words list is empty, go back and get more input | ||
+ | if not words: | ||
+ | continue | ||
+ | # we have input.... | ||
+ | # filter based on the first word - these are the | ||
+ | # pre-set commands the server will accept | ||
+ | # the client wants to know the currently available | ||
+ | # radio names - held in the variable " | ||
+ | elif words[0] == " | ||
+ | self.wfile.write(rnames) | ||
+ | # words[-1] (the last word in the list) will always be the | ||
+ | # radio name. We give the variable " | ||
+ | # identifying which radio object to apply the method to | ||
+ | elif words[0] == " | ||
+ | count = count_radios() | ||
+ | self.wfile.write(count) | ||
+ | elif words[0] == " | ||
+ | ident_text = " | ||
+ | radio_list = list_radios() | ||
+ | self.wfile.write(ident_text + " | ||
+ | | ||
+ | elif words[0] == " | ||
+ | my_radio = eval(words[-1]) | ||
+ | filt_no = words[1] | ||
+ | newfilt = my_radio.set_filter(filt_no) | ||
+ | | ||
+ | self.wfile.write(newfilt) | ||
+ | elif words[0] == " | ||
+ | my_radio = eval(words[1]) | ||
+ | filt = my_radio.get_filter() | ||
+ | self.wfile.write(filt) | ||
+ | |||
+ | elif words[0] == " | ||
+ | my_radio = eval(words[-1]) | ||
+ | mode = my_radio.get_mode() | ||
+ | self.wfile.write(mode) | ||
+ | elif words[0] == " | ||
+ | my_radio = eval(words[-1]) | ||
+ | freq = words[1] | ||
+ | freq = my_radio.get_freq() | ||
+ | self.wfile.write(freq) | ||
+ | elif words[0] == " | ||
+ | my_radio = eval(words[-1]) | ||
+ | mode = words[1] | ||
+ | newmode = my_radio.set_mode(mode) | ||
+ | self.wfile.write(newmode) | ||
+ | elif words[0] == " | ||
+ | my_radio = eval(words[-1]) | ||
+ | try: | ||
+ | freq = float(words[1]) | ||
+ | newfreq = my_radio.set_freq(freq) | ||
+ | self.wfile.write(newfreq) | ||
+ | except ValueError: | ||
+ | #freq = float(my_radio.get_freq()) | ||
+ | self.wfile.write(" | ||
+ | | ||
+ | elif words[0] == " | ||
+ | my_radio = eval(words[-1]) | ||
+ | smeter = round(float(my_radio.get_smeter()), | ||
+ | self.wfile.write(smeter) | ||
+ | elif words[0] == " | ||
+ | my_radio = eval(words[-1]) | ||
+ | s = my_radio.get_s() | ||
+ | self.wfile.write(s) | ||
+ | elif words[0] == " | ||
+ | radios = list_radios() | ||
+ | self.wfile.write(radios) | ||
+ | elif words[0] == " | ||
+ | my_radio = eval(words[-1]) | ||
+ | preamp = my_radio.get_pre() | ||
+ | self.wfile.write(preamp) | ||
+ | elif words[0] == " | ||
+ | my_radio = eval(words[-1]) | ||
+ | preamp = my_radio.pre_on() | ||
+ | self.wfile.write(preamp) | ||
+ | elif words[0] == " | ||
+ | my_radio = eval(words[-1]) | ||
+ | preamp = my_radio.pre_2_on() | ||
+ | self.wfile.write(preamp) | ||
+ | elif words[0] == " | ||
+ | my_radio = eval(words[-1]) | ||
+ | preamp = my_radio.pre_off() | ||
+ | self.wfile.write(preamp) | ||
+ | elif words[0] == " | ||
+ | my_radio = eval(words[-1]) | ||
+ | att = my_radio.get_att() | ||
+ | self.wfile.write(att) | ||
+ | elif words[0] == " | ||
+ | my_radio = eval(words[-1]) | ||
+ | att = my_radio.att_on() | ||
+ | self.wfile.write(att) | ||
+ | elif words[0] == " | ||
+ | my_radio = eval(words[-1]) | ||
+ | att = my_radio.att_off() | ||
+ | self.wfile.write(att) | ||
+ | elif words[0] == " | ||
+ | my_radio = eval(words[-1]) | ||
+ | tune = my_radio.tune() | ||
+ | self.wfile.write(tune) | ||
+ | elif words[0] == " | ||
+ | my_radio = eval(words[-1]) | ||
+ | pwr = my_radio.get_pwr() | ||
+ | self.wfile.write(pwr) | ||
+ | elif words[0] == " | ||
+ | my_radio = eval(words[-1]) | ||
+ | spwr = words[1] | ||
+ | pwr = my_radio.set_pwr(spwr) | ||
+ | self.wfile.write(pwr) | ||
+ | elif words[0] == " | ||
+ | write_con(" | ||
+ | self.wfile.write(" | ||
+ | break | ||
+ | else: # nothing in words[0] matches a pre-set command.... | ||
+ | write_file(" | ||
+ | self.wfile.write(" | ||
+ | |||
+ | |||
+ | class ThreadedIcomServer(SocketServer.ThreadingMixIn, | ||
+ | pass | ||
+ | |||
+ | |||
+ | if __name__ == ' | ||
+ | # define the lock to be used on the serial port access | ||
+ | lock = threading.Lock() | ||
+ | |||
+ | # address ('' | ||
+ | address = ('', | ||
+ | server = ThreadedIcomServer(address, | ||
+ | server.allow_reuse_address = True | ||
+ | |||
+ | # define that the server will be threaded, and will serve " | ||
+ | t = threading.Thread(target=server.serve_forever) | ||
+ | # start the server thread | ||
+ | t.start() | ||
+ | |||
+ | write_con( | ||
+ | " | ||
+ | </ | ||
+ | ++++ | ||
+ | |||
+ | ===== Documentation ===== | ||
+ | |||
+ | * {{ : | ||
+ | * {{ : | ||
public/radio/radio_database/ar_7030.1658297859.txt.gz · Last modified: 06/03/25 06:49 GMT (external edit)