John's Vademecum

Try to learn something about everything, and everything about something -Thomas Huxley “Darwin's bulldog” (1824-1895)

User Tools

Site Tools


public:radio:radio_database:ic-r75

This is an old revision of the document!


Rig and Key List

IC-R75

1. Details

2. Repairs / Mods

  • -5V DC/DC converter
    • various capacitor failures
  • “Turn Off” fault - due to overheating of 13V regulator
    • Cured by
      • Reduce input voltage to 13.8V
      • Improve heatsinking of regulator IC to chassis

3. Remote Control

  • connected to shack server via RS232
  • shack server running Python netradio server.py to give TCP/IP network control
  • laptop PC running Python netradio client.py to give user access
    • Available controls:
      gm4slv@laptop:~/Python/PythonProjects/netradio $ python2 client.py
      There are currently 1 radios connected.
      =================================
      Status of Radio 1 (IC-R75)
      
      Frequency : 391.000 kHz
      Mode: CW
      S-Meter: -113.0dBm
      1 : 0
      =================================
      
      Please choose a radio
      
      There are currently 1 radios connected.
      Radio 1 is IC-R75
      Choose a radio number from the list : 1
      
      The available commands are:
      lr   : List Radios
      sr   : Select the Radio to control
      gr   : Get currently selected Radio name
      gm   : Get Mode
      sm   : Set Mode
      gf   : Get Freq
      sf   : Set Freq
      gs   : Get S-meter
      gp   : Get Pre-amp
      pon  : Set Pre-amp On
      poff : Set Pre-amp Off
      gatt : Get Attn
      aton : Set Attn On
      atoff: Set Attn Off
      ga   : Get All (status of all radios)
      sync : Sync freq/mode on two radios
      log  : Setup background logging to file
      h    : Help (show this command list)
      q    : quit
      
      IC-R75 >
  • audio via network using PicoPhone
    • running on shack laptop via Wine
    • running on Windows laptop natively

Remote control is achieved via a SSH connection to shack laptop to run the netradio client.py and the RX audio can be heard via PicoPhone.

4. Further Reading

server.py

Code....

icom.py

import serial
import threading
from conf import *
import time
#sport = "COM1"
sport = "/dev/ttyS0"
sbaud = 9600
 
lock = threading.Lock()
 
 
class Icom(object):
    def __init__(self, model, radio_address, cal):
        self.ser = serial.Serial(sport, sbaud, timeout=0.1)
        self.model = model
        self.radio_address = radio_address
        self.cal = cal
 
    def digi_off(self):
        sendStr = preamble + preamble + self.radio_address + controller + digi_off_cmd + eom
        result = self.tx_rx(sendStr)
        if result[4] == ack:
            return "Success"
        elif result[4] == nak:
            return "NAK received"
 
    def get_pre(self):
        sendStr = preamble + preamble + self.radio_address + controller + set_pre_cmd + eom
 
        result = self.tx_rx(sendStr)
        if not result:
            return "0"
        if result[6] == "\x00":
            return 0
        elif result[6] == "\x01":
            return 1
 
    def get_pwr(self):
        sendStr = preamble + preamble + self.radio_address + controller + pwr_cmd + eom
        result = self.tx_rx(sendStr)
        if not result:
            return "0"
        p1 = ord(result[7]) / 16
        p2 = ord(result[7]) % 16
        p3 = ord(result[6]) / 16
        p4 = ord(result[6]) % 16
        pwr = float(100 * (10 * p3 + p4) + (10 * p1 + p2))
        return int(pwr*100/255)
 
    def set_pwr(self, pwr):
        #if pwr == "25":
        #    spwr = "\x00" + "\x63"
        #elif pwr == "50":
        #    spwr = "\x01" + "\x27"
        #elif pwr == "75":
        #    spwr = "\x01" + "\x91"
        #elif pwr == "100":
        #    spwr = "\x02" + "\x55"
        rigpwr = int(pwr) * 255 / 100
        print "rigpwr ", rigpwr
        pwr1 = rigpwr / 100
        pwr2 = rigpwr % 100
        spwr1 = (pwr1 / 10 * 16)
        spwr2 = (pwr1 % 10)
        spwr3 =  (pwr2 / 10 * 16)
        spwr4 =  (pwr2 % 10)
        spwr = chr(spwr1+spwr2) + chr(spwr3+spwr4)
        #print "spwr ", spwr
        sendStr = preamble + preamble + self.radio_address + controller + pwr_cmd + spwr + eom
        result = self.tx_rx(sendStr)
        if result[4] == ack:
            return self.get_pwr()
        elif result[4] == nak:
            return "NAK received"
 
    def pre_on(self):
        sendStr = preamble + preamble + self.radio_address + controller + set_pre_cmd + set_pre_on + eom
        result = self.tx_rx(sendStr)
        if result[4] == ack:
            return "Success"
        elif result[4] == nak:
            return "NAK received"
 
    def pre_off(self):
        sendStr = preamble + preamble + self.radio_address + controller + set_pre_cmd + set_pre_off + eom
        result = self.tx_rx(sendStr)
        if result[4] == ack:
            return "Success"
        elif result[4] == nak:
            return "NAK received"
 
    def ptt_on(self):
        sendStr = preamble + preamble + self.radio_address + controller + ptt_on_cmd + eom
        result = self.tx_rx(sendStr)
        #print result[5]
        if not result[4] == ack:
            return "ptt on"
        elif result[4] == nak:
            return "Error"
 
    def ptt_off(self):
        sendStr = preamble + preamble + self.radio_address + controller + ptt_off_cmd + eom
        result = self.tx_rx(sendStr)
        #print result[5]
        if not result[4] == ack:
            return "ptt off"
        elif result[4] == nak:
            return "Error"
 
    def get_att(self):
        sendStr = preamble + preamble + self.radio_address + controller + set_att_cmd + eom
        result = self.tx_rx(sendStr)
        if not result:
            return "0"
        if result[5] == "\x00":
            return 0
        elif result[5] == "\x20":
            return 1
 
    def att_on(self):
        sendStr = preamble + preamble + self.radio_address + controller + set_att_cmd + set_att_on + eom
        result = self.tx_rx(sendStr)
        if result[4] == ack:
            return "Success"
        elif result[4] == nak:
            return "NAK received"
 
    def att_off(self):
        sendStr = preamble + preamble + self.radio_address + controller + set_att_cmd + set_att_off + eom
        result = self.tx_rx(sendStr)
        if result[4] == ack:
            return "Success"
        elif result[4] == nak:
            return "NAK received"
 
    def set_freq(self, freq):
        fdig = "%010d" % int(freq * 1000)
        bcd = ()
        for i in (8, 6, 4, 2, 0):
            bcd += self.freq_bcd(int(fdig[i]), int(fdig[i + 1]))
        set_freq_val = ""
        for byte in bcd:
            set_freq_val += chr(byte)
        sendStr = preamble + preamble + self.radio_address + controller + set_freq_cmd + set_freq_val + eom
        result = self.tx_rx(sendStr)
        if result[4] == ack:
            return "Set Freq success"
        elif result[4] == nak:
            return "NAK received / Freq not supported"
 
    def get_freq(self):
        sendStr = preamble + preamble + self.radio_address + controller + get_freq_cmd + eom
        result = self.tx_rx(sendStr)
        if not result:
            return "0"
        if len(result) > 0:
            f = 0
        for k in [18, 19, 16, 17, 14, 15, 12, 13, 11, 10]:
            f = 10 * f + self.nib(result, k)
        self.freq = (float(f) / 1000)
        return "%.3f" % self.freq
 
    def set_mode(self, mode):
        print "in set_mode() with ", mode
        if mode == "lsb":
            set_mode_val = "\x00"
        elif mode == "usb":
            set_mode_val = "\x01"
        elif mode == "am":
            set_mode_val = "\x02"
        elif mode == "cw":
            set_mode_val = "\x03"
        elif mode == "rtty":
            set_mode_val = "\x04"
        elif mode == "fm":
            set_mode_val = "\x05"
        elif mode == "cw-r":
            set_mode_val = "\x07"
        elif mode == "rtty-r":
            set_mode_val = "\x08"
        elif mode == "s-am":
            set_mode_val = "\x11"
        else:
            return "Mode not recognized"
        sendStr = preamble + preamble + self.radio_address + controller + set_mode_cmd + set_mode_val + eom
        result = self.tx_rx(sendStr)
        if result[4] == ack:
            return "Set Mode Success"
        elif result[4] == nak:
            return "NAK received / Mode not supported"
 
    def get_mode(self):
        sendStr = preamble + preamble + self.radio_address + controller + get_mode_cmd + eom
        result = self.tx_rx(sendStr)
        if not result:
            return "0"
        mode = ""
        if result[5] == "\x00":
            mode = "lsb"
        elif result[5] == "\x01":
            mode = "usb"
        elif result[5] == "\x02":
            mode = "am"
        elif result[5] == "\x03":
            mode = "cw"
        elif result[5] == "\x04":
            mode = "rtty"
        elif result[5] == "\x05":
            mode = "fm"
        elif result[5] == "\x08":
            mode = "rtty-r"
        elif result[5] == "\x07":
            mode = "cw-r"
        elif result[5] == "\x11":
            mode = "s-am"
        self.mode = mode
        return self.mode.upper()
 
    def get_s(self):
        sendStr = preamble + preamble + self.radio_address + controller + get_smeter_cmd + eom
        result = self.tx_rx(sendStr)
        if not result:
            return "0"
        sm1 = ord(result[7]) / 16
        sm2 = ord(result[7]) % 16
        sm3 = ord(result[6]) / 16
        sm4 = ord(result[6]) % 16
        s = float(100 * (10 * sm3 + sm4) + (10 * sm1 + sm2))
        return s
 
    def get_swr(self):
        sendStr = preamble + preamble + self.radio_address + controller + get_swr_cmd + eom
        result = self.tx_rx(sendStr)
        if not result:
            return "0"
        sm1 = ord(result[7]) / 16
        sm2 = ord(result[7]) % 16
        sm3 = ord(result[6]) / 16
        sm4 = ord(result[6]) % 16
        swr = float(100 * (10 * sm3 + sm4) + (10 * sm1 + sm2))
        return swr
 
    def get_smeter(self):
        s = float(self.get_s())
        cal = self.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 get_name(self):
        return self.model
 
    def tune(self):
        print "tuning"
        curmode = self.get_mode().lower()
        #print "Current Mode ",curmode
 
        curpwr = self.get_pwr()
        if curpwr < 98:
            curpwr = curpwr + 1
 
        #print "Current Power ", curpwr
 
        #print "Current percent power ", curpwr
        self.set_mode("rtty")
        self.set_pwr(25)
        #print "Tuning power ", self.get_pwr()
        #print "PTT On"
        self.ptt_on()
        time.sleep(2)
        swr =  self.get_swr()
        #print "SWR :", swr
        time.sleep(1)
        self.ptt_off()
        #print "PTT Off"
        self.set_mode(curmode)
        #print "Mode reset ",self.get_mode()
        self.set_pwr(curpwr)
        print "Tuned : (ref pwr : %s)" % swr
        return "Tuned : (ref pwr : %s)" % swr
 
    def tx_rx(self, sendStr):
        lock.acquire()
        self.ser.write(sendStr)
        echo = self.ser.read(len(sendStr))
        if len(echo) != len(sendStr):
            return "0"
        byte = "0"
        result = ""
        count = 0
        while byte != eom:
            byte = self.ser.read()
            #print "%#02x" % ord(byte)
            result += byte
            count += 1
            if count > 10:
                break
        lock.release()
        #print ""
        return result
 
 
    def nib(self, s, i):
        k = ord(s[i / 2])
        if i % 2 == 0:
            k = k >> 4
        return k & 0xf
 
 
    def freq_bcd(self, d1, d2):
        return (16 * d1 + d2),
 
 

conf.py

# header
preamble = "\xfe"
controller = "\xe0"
 
# commands/requests
set_freq_cmd = "\x05"
set_mode_cmd = "\x06"
get_freq_cmd = "\x03"
get_mode_cmd = "\x04"
get_smeter_cmd = "\x15" + "\x02"
get_swr_cmd = "\x15" + "\x12"
digi_off_cmd = "\x1a" + "\x04" + "\x00" + "\x00"
 
set_pre_cmd = "\x16" + "\x02"
 
set_pre_off = "\x00"
set_pre_on = "\x01"
 
set_att_cmd = "\x11"
set_att_on = "\x20"
set_att_off = "\x00"
 
ptt_on_cmd = "\x1c" + "\x00" + "\x01"
ptt_off_cmd = "\x1c" + "\x00" + "\x00"
 
pwr_cmd = "\x14" + "\x0a"
 
# end of message
eom = "\xfd"
 
# controller responses
ack = "\xfb"
nak = "\xfa"
 
a1 = "\x5A"
n1 = "IC-R75"
cal1 = ( 25, 1, 36, 47, 31, 18, 34, 35 )
 
a2 = "\x5e"
# a2 = "\x01"
n2 = "IC-718"
cal2 = ( 27, 28, 58, 10, 14, 14, 35, 42 )
 
n3 = "AR7030"
 
n4 = "IC-M710"

client.py

__author__ = 'gm4slv'
# client to work with server_oo.py
# 
 
# # v0.1
 
import socket
 
try:
    import readline
except ImportError:
    pass
 
import threading
import time
 
 
HOST, PORT = "shack", 9999
 
smlog = "pymon.txt"
log_active = []
 
 
def make_con():
    global sock
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect((HOST, PORT))
 
 
def get_rnum():
    global num
    global radios
 
    names = connect("listradios")
 
    radios = names.split()
    num = len(radios)
    return num
 
 
def get_rname(i):
    r = radios[i]
    return r
 
 
def list_radios():
    num = get_rnum()
    global radio
    print "\r\nThere are currently %d radios connected." % num
    for i in range(0, num):
        r = get_rname(i)
        print "Radio %d is %s" % (i + 1, r)
 
 
def get_lradio():
    num = get_rnum()
 
    lradio = raw_input("Select radio to log: ").strip()
 
    if not lradio:
        print "Please select a radio"
        return False
    elif int(lradio) > num:
        print "Selected radio not recognized"
        return False
 
    else:
 
        return lradio
 
 
def set_radio():
    num = get_rnum()
    # global radio
    global radio_num
    global rname
    print "There are currently %d radios connected." % num
    for i in range(0, num):
        r = get_rname(i)
        print "Radio %d is %s" % (i + 1, r)
 
    radio = raw_input("Choose a radio number from the list : ").strip()
    try:
        if not radio:
            print "Please select a radio"
            return False, False
 
        elif int(radio) > num:
            print "Selected radio not recognized"
            return False, False
    except ValueError:
        print "Please enter a number"
        return False, False
 
    else:
        radio_num = "".join(("r", radio))
        rname = get_rname(int(radio) - 1)
        return radio_num, rname
 
 
def prompt():
    print ""
    print "The available commands are:"
    print "lr   : List Radios"
    print "sr   : Select the Radio to control"
    print "gr   : Get currently selected Radio name"
    print "gm   : Get Mode"
    print "sm   : Set Mode"
    print "gf   : Get Freq"
    print "sf   : Set Freq"
    print "gs   : Get S-meter"
    print "gp   : Get Pre-amp"
    print "pon  : Set Pre-amp On"
    print "poff : Set Pre-amp Off"
    print "gatt : Get Attn"
    print "aton : Set Attn On"
    print "atoff: Set Attn Off"
    print "ga   : Get All (status of all radios)"
    print "sync : Sync freq/mode on two radios"
    print "log  : Setup background logging to file"
    print "h    : Help (show this command list)"
    print "q    : quit"
    print ""
 
 
def start():
    global radio_num
    global rname
    global sock
 
    data = raw_input(rname + " > ").lower().strip()
    if len(data.split()) > 1:
        print "only one command at a time please"
        start()
 
    elif data == "lr":
        list_radios()
        start()
    elif data == "sr":
 
        radio_num, rname = set_radio()
 
        while not radio_num:
            radio_num, rname = set_radio()
 
        start()
 
    elif data == "gr":
        print "Radio selected is %s" % rname
        start()
 
    elif data == "gm":
        mode = connect("getmode" + " " + radio_num)
        print "%s replied: %s" % (rname, mode)
        start()
 
    elif data == "sm":
        smode = raw_input("Enter mode: ")
        mode = connect("setmode" + " " + smode + " " + radio_num)
        print "%s replied: %s" % (rname, mode)
        start()
 
    elif data == "gf":
        freq = connect("getfreq" + " " + radio_num)
        print "%s replied: %s kHz" % (rname, freq)
        start()
 
    elif data == "sf":
        sfreq = raw_input("Enter freq (kHz): ")
        freq = connect("setfreq" + " " + sfreq + " " + radio_num)
        print "%s replied: %s" % (rname, freq)
        start()
 
    elif data == "gs":
        smeter = connect("getsmeter" + " " + radio_num)
        print "%s replied: %sdBm" % (rname, smeter)
        start()
 
    elif data == "gp":
        preamp = connect("getpreamp" + " " + radio_num)
        print "%s replied: %s" % (rname, preamp)
        start()
 
    elif data == "pon":
        preamp = connect("preampon" + " " + radio_num)
        print "%s replied: %s" % (rname, preamp)
        start()
 
    elif data == "poff":
        preamp = connect("preampoff" + " " + radio_num)
        print "%s replied: %s" % (rname, preamp)
        start()
 
    elif data == "gatt":
        preamp = connect("getatt" + " " + radio_num)
        print "%s replied: %s" % (rname, preamp)
        start()
 
    elif data == "aton":
        att = connect("atton" + " " + radio_num)
        print "%s replied: %s" % (rname, att)
        start()
 
    elif data == "atoff":
        att = connect("attoff" + " " + radio_num)
        print "%s replied: %s" % (rname, att)
        start()
 
    elif data == "ga":
        get_all()
        start()
 
 
    elif data == "log":
        fname = raw_input("Enter a filename (or \"Return\" for default) :")
        if fname == "":
            fname = smlog
        # check file is valid
        try:
            f = open(fname, 'a+')
            f.close()
        except IOError:
            print "File/path not valid"
            start()
 
        list_radios()
 
        lradio = get_lradio()
 
        while not lradio:
            lradio = get_lradio()
 
        rname = get_rname(int(lradio) - 1)
        if lradio in log_active:
            print "Logging already active on " + rname
        else:
            tlog = int(raw_input("Enter a polling interval (seconds) :"))
            p = threading.Thread(target=log, args=(lradio, tlog, fname))
            p.setDaemon(True)
            p.start()
            log_active.append(lradio)
        start()
 
    elif data == "sync":
        sync_result = sync()
        print sync_result
        start()
 
 
    elif data == "h" or data == "help":
        prompt()
        start()
 
 
    elif data == "q" or data == "quit":
        rx = connect("quit")
        print "Server says: %s " % rx
 
    else:
        prompt()
        start()
 
 
def get_all():
    num = get_rnum()
    global radio
    print "There are currently %d radios connected." % num
    print "=" * 33
    for i in range(0, num):
        r = get_rname(i)
        n = "".join(("r", str(i + 1)))
        freq = connect("getfreq" + " " + n)
        mode = connect("getmode" + " " + str(n))
        smeter = connect("getsmeter" + " " + str(n))
        preamp = connect("getpreamp" + " " + str(n))
        att = connect("getatt" + " " + str(n))
 
        print "Status of Radio %d (%s) \r\n" % (i + 1, r)
        print "Frequency : %s kHz" % freq
        print "Mode: %s" % mode
        print "S-Meter: %sdBm" % smeter
        print "%s : %s " % (preamp, att)
        print "=" * 33
 
    print ""
 
 
def log(p, t, f):
    print "\n\n"
    tlog = t
    sradio = get_rname(int(p) - 1)
 
    sr = "".join(("r", str(p)))
    while True:
        try:
            frequency = connect("getfreq" + " " + sr + "\n")
            smeter = connect("getsmeter" + " " + sr + "\n")
            mode = connect("getmode" + " " + sr + "\n")
            write_file(f, sradio, mode, frequency, smeter)
            time.sleep(tlog)
        finally:
            pass
 
 
def get_mradio():
    num = get_rnum()
 
    mradio = raw_input("Choose Master radio number from the list: ").strip()
 
    if not mradio:
        print "Please select a radio"
        return False
    elif int(mradio) > num:
        print "Selected radio not recognized"
        return False
 
    else:
 
        return mradio
 
 
def get_sradio():
    num = get_rnum()
    sradio = raw_input("Choose Slave radio number from the list: ").strip()
 
    if not sradio:
        print "Please select a radio"
        return False
    elif int(sradio) > num:
        print "Selected radio not recognized"
        return False
 
    else:
 
        return sradio
 
 
def sync():
    num = get_rnum()
    print ""
    print "Set SLAVE to the same Frequency and Mode as MASTER.\r\n"
    print "Currently connected radios are:"
    for i in range(0, num):
        r = get_rname(i)
        print "%d is %s" % (i + 1, r)
 
    mradio = get_mradio()
    while not mradio:
        mradio = get_mradio()
 
    sradio = get_sradio()
    while not sradio:
        sradio = get_sradio()
    sr = "".join(("r", sradio))
    mr = "".join(("r", mradio))
    mfreq = connect("getfreq" + " " + mr)
    mmode = connect("getmode" + " " + mr)
 
    sfreq = connect("setfreq" + " " + mfreq + " " + sr)
    smode = connect("setmode" + " " + mmode + " " + sr)
 
    return (sfreq + "\r\n" + smode + "\r\n")
 
 
# Try to send and receive in one-go, to prevent the logging thread and the main prog
# getting the wrong receive data
 
def connect(data):
    try:
        lock.acquire()
        global sock
        sock.sendall(data + "\n")
        received = sock.recv(2048)
    finally:
        lock.release()
 
    return received
 
 
def write_file(fname, rname, mode, freq, smeter):
    filename = fname
    f = open(filename, 'a+')
    timenow = time.strftime("%d/%m/%Y %H:%M:%S", time.gmtime(time.time()))
    log = " ".join((timenow, rname, mode, freq, smeter, "\r\n"))
    f.write(log)
    f.close()
 
 
make_con()
 
lock = threading.Lock()
get_all()
print "Please choose a radio\r\n"
radio_num, rname = set_radio()
while not radio_num:
    radio_num, rname = set_radio()
 
prompt()
start()

Page Info

Page created Wed May 25 00:06:01 2022 by John Pumford-Green

Page last updated: 06/03/25 06:49 GMT

public/radio/radio_database/ic-r75.1683299650.txt.gz · Last modified: 06/03/25 06:49 GMT (external edit)