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
    • 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

#from aor import *
from icom import *
from conf import *
#from m710 import *
import SocketServer
import time
 
try:
    import readline
except:
    pass
 
lock = threading.Lock()
 
radios = []
 
 
#r1 = m710(n4)
#radios.append(n4)
 
r1 = Icom(n1, a1, cal1)
radios.append(n1)
 
#r2 = Icom(n2, a2, cal2)
#radios.append(n2)
 
#r3 = Ar7030(n3)
#radios.append(n3)
 
print radios
print r1.digi_off()
 
def list_radios():
    radiolist = ""
    for n in range(0, len(radios)):
        r = radios[n]
        radiolist += (r + " ")
    return radiolist
 
 
def write_file(text):
    filename = 'commandlog.txt'
    f = open(filename, 'a+')  # a+ is "append to file, create it if it doesn't exist"
    timenow = time.strftime("%d/%m/%Y %H:%M:%S", time.gmtime(time.time()))
    log = " ".join((timenow, text))  # make an entry for the log by joining the timestamp with the text passed in
    f.write(log)
    f.close()
 
 
def write_con(text):
    filename = 'conlog.txt'
    f = open(filename, 'a+')  # a+ is "append to file, create it if it doesn't exist"
    timenow = time.strftime("%d/%m/%Y %H:%M:%S", time.gmtime(time.time()))
    log = " ".join((timenow, text))  # make an entry for the log by joining the timestamp with the text passed in
    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("Connect from %s using %s \n" % ((self.client_address[0]), cur_thread.getName()))
        # print to the server's console the new connection IP address/port
        print self.client_address
        # loop to handle client requests....
        while True:
            # using StreamRequestHandler means our input from the client
            # is  "file-like" and can be read with "file-like" commands
            # 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
            # "printable" simple ASCII
            # 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 = "".join(x for x in cmd if ord(x) < 128 and ord(x) > 31)
            # we make a list called "words" holding the received words which
            # 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 "" on the dead
            # socket, which puts CPU to 100%.
            #
            # The "While" loop is probably responsible, but I can't see another
            # 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 "" and then breaking
            # 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 "rnames"
            elif words[0] == "getnames":
                self.wfile.write(rnames)
            # words[-1] (the last word in the list) will always be the
            # radio name. We give the variable "my_radio" this value, for
            # identifying which radio object to apply the method to
            elif words[0] == "getmode":
                my_radio = eval(words[-1])
                mode = my_radio.get_mode()
                self.wfile.write(mode)
            elif words[0] == "getfreq":
                my_radio = eval(words[-1])
                freq = words[1]
                freq = my_radio.get_freq()
                self.wfile.write(freq)
            elif words[0] == "setmode":
                my_radio = eval(words[-1])
                mode = words[1]
                newmode = my_radio.set_mode(mode)
                self.wfile.write(newmode)
            elif words[0] == "setfreq":
                my_radio = eval(words[-1])
                freq = float(words[1])
                newfreq = my_radio.set_freq(freq)
                self.wfile.write(newfreq)
            elif words[0] == "getsmeter":
                my_radio = eval(words[-1])
                smeter = round(float(my_radio.get_smeter()), 1)
                self.wfile.write(smeter)
            elif words[0] == "gets":
                my_radio = eval(words[-1])
                s = my_radio.get_s()
                self.wfile.write(s)
            elif words[0] == "listradios":
                radios = list_radios()
                self.wfile.write(radios)
            elif words[0] == "getpreamp":
                my_radio = eval(words[-1])
                preamp = my_radio.get_pre()
                self.wfile.write(preamp)
            elif words[0] == "preampon":
                my_radio = eval(words[-1])
                preamp = my_radio.pre_on()
                self.wfile.write(preamp)
            elif words[0] == "preampoff":
                my_radio = eval(words[-1])
                preamp = my_radio.pre_off()
                self.wfile.write(preamp)
            elif words[0] == "getatt":
                my_radio = eval(words[-1])
                att = my_radio.get_att()
                self.wfile.write(att)
            elif words[0] == "atton":
                my_radio = eval(words[-1])
                att = my_radio.att_on()
                self.wfile.write(att)
            elif words[0] == "attoff":
                my_radio = eval(words[-1])
                att = my_radio.att_off()
                self.wfile.write(att)
            elif words[0] == "tune":
                my_radio = eval(words[-1])
                tune = my_radio.tune()
                self.wfile.write(tune)
            elif words[0] == "getpwr":
                my_radio = eval(words[-1])
                pwr = my_radio.get_pwr()
                self.wfile.write(pwr)
            elif words[0] == "setpwr":
                my_radio = eval(words[-1])
                spwr = words[1]
                pwr = my_radio.set_pwr(spwr)
                self.wfile.write(pwr)
            elif words[0] == "quit":
                write_con("Got quit from {}\n".format(self.client_address[0]))  # log it
                self.wfile.write("Goodbye! \r\n")  # say Goodbye
                break
            else:  # nothing in words[0] matches a pre-set command....
                write_file("Received %s\n" % words)  # log it, it's unusual
                self.wfile.write("Command not recognized\r\n")  # inform the client
 
 
class ThreadedIcomServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
    pass
 
 
if __name__ == '__main__':
    # define the lock to be used on the serial port access
    lock = threading.Lock()
 
    # address ('' = all available interfaces) to listen on, and port number
    address = ('', 9999)
    server = ThreadedIcomServer(address, ThreadedRequestHandler)
    server.allow_reuse_address = True
 
    # define that the server will be threaded, and will serve "forever" ie. not quit after the client disconnects
    t = threading.Thread(target=server.serve_forever)
    # start the server thread
    t.start()
 
    write_con(
        "Server loop running in thread: %s\n" % "".join(t.getName())) 

icom.py

import serial
import threading
from conf import *
import time
#sport = "COM1"
sport = "/dev/ttyS0"
sbaud = 19200
 
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),
 
 

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.1657658618.txt.gz · Last modified: 06/03/25 06:49 GMT (external edit)