diff --git a/apsct_lib.py b/apsct_lib.py
new file mode 100644
index 0000000000000000000000000000000000000000..99309c6c99b0140bf4499697e2c9cc513bf45d57
--- /dev/null
+++ b/apsct_lib.py
@@ -0,0 +1,357 @@
+'''
+Copyright 2021 Stichting Nederlandse Wetenschappelijk Onderzoek Instituten,
+ASTRON Netherlands Institute for Radio Astronomy
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Set APSCT_CLK
+
+'''
+import sys
+import time
+sys.path.insert(0,'.')
+import os
+if os.name =="posix":
+    from I2C_serial_pi2 import *
+else:
+    from I2C_serial import *
+
+DEBUG = False
+I2CBUSNR=5
+sleep_time = 0.15
+SET_PLL = True
+READ_LOCK = True
+READ_ALL = False
+CHECK_EEPROM = False
+PWR_RST = False #True #False
+READ_SENSOR = False #True
+READ_REGS = False #True
+
+CLK_FREQ = '200MHz'
+dev_i2c_eeprom = I2C(0x50)
+dev_i2c_eeprom.bus_nr = I2CBUSNR
+
+CS = 6
+SCLK = 4
+SDO = 5
+SDI = 7
+
+PLL_200M = 0x20
+PLL_160M = 0x21
+
+def Write_byte_PLL(reg_address, wr_data, ADDRESS=0x20):
+    #
+    # Write Byte to the ADC
+    #
+    I2C_device = I2C(ADDRESS, BUSNR=I2CBUSNR)
+    PLL_rw = 0x00 # 0 for write, 1 for read
+    stri = "Write to address : 0x{1:{fill}2x} value  0x{0:{fill}2x}".format(wr_data, reg_address, fill='0')
+    print(stri)
+    I2C_device.write_bytes(0x06, 0x2C)
+    if DEBUG:
+        rd_bytes = I2C_device.read_bytes(0x06, 1)
+        stri = "IO expander wrote 0x{0:x}, read 0x{1}".format(0x2C, rd_bytes[1])
+        print(stri)
+    data = (reg_address << 9) + (PLL_rw << 8) + wr_data
+    bit_array = "{0:{fill}16b}".format(data, fill='0')
+    I2C_device.write_bytes(0x02, 0x02 | (0x1 << CS))
+    for bit in bit_array:
+        for clk in range(2):
+            Write_data = 0x02 | (0 << CS) | (clk << SCLK) | (int(bit) << SDI)
+            I2C_device.write_bytes(0x02, Write_data)
+    for clk in range(2):
+            Write_data = 0x02 | (0 << CS) | (clk << SCLK)
+            I2C_device.write_bytes(0x02, Write_data)
+    for clk in range(2):
+            Write_data = 0x02 | (1 << CS) | (clk << SCLK)
+            I2C_device.write_bytes(0x02, Write_data)
+
+    Write_data = 0x02 | (1 << CS) | (0 << SCLK) | (0 << SDI)
+    I2C_device.write_bytes(0x02, Write_data)
+    if DEBUG:
+        read_bits = Read_byte_PLL(reg_address, nof_bytes=1, ADDRESS=ADDRESS)
+#        stri = "Bits written 0x{0:x} to register 0x{1:x} read from PLL are {2}".format(wr_data, reg_address, read_bits)
+#        print(stri)
+
+
+def Read_byte_PLL(reg_address, nof_bytes=1, ADDRESS=0x20 ):
+    #
+    # Read Byte from the ADC
+    #
+    I2C_device = I2C(ADDRESS, BUSNR=I2CBUSNR)
+    PLL_rw    = 0x01 # 0 for write, 1 for read
+
+    I2C_device.write_bytes(0x06, 0x2C)
+    data =  ( reg_address << 7 ) + PLL_rw
+
+    bit_array = "{0:{fill}8b}".format(data, fill='0')
+    for bit in bit_array:
+        for clk in range(2):
+            Write_data = 0x02 | (0 << CS) | (clk << SCLK) | ( int(bit) << SDI)
+            I2C_device.write_bytes(0x02, Write_data)
+            sleep(sleep_time)
+
+#    print("read byte")
+    read_bit = ''
+    for cnt in range(8*nof_bytes):
+        for clk in [0, 1]: # Read after rizing edge
+            Write_data = 0x02 | (clk << SCLK) | ( int(bit) << SDI )
+            I2C_device.write_bytes(0x02, Write_data)
+        ret_ack, ret_value = I2C_device.read_bytes(0x00, 1)
+#        stri= "ret_value = {}".format(int(ret_value,16))
+#        print(stri)
+        if ret_ack:
+            read_bit += str((int(ret_value, 16) >> SDO) & 0x01)
+        else:
+            print("ACK nok")
+    Write_data = 0x02 | (1 << CS) | (0 << SCLK) | (0 << SDI)
+    I2C_device.write_bytes(0x02, Write_data)
+    stri = "Read back at address 0x{0:{fill}2x} result : 0x{1:{fill}2x} ".format(reg_address, int(read_bit, 2), fill='0')
+    print(stri)
+    return read_bit;
+
+def read_all_regs_pll(pll_frequency='200MHz') :
+    I2C_device = I2C(0x20, BUSNR=I2CBUSNR) #clock selection
+    I2C_device.write_bytes(0x07, 0x00)
+    if pll_frequency == '160MHz':
+        print("Read PLL 160 MHz")
+        pll_address = PLL_160M
+#        I2C_device.write_bytes(0x03, 0x0F)
+    else:
+        print("Read PLL 200 MHz")
+        pll_address=PLL_200M
+#        I2C_device.write_bytes(0x03, 0xF8)
+#    for reg_cnt in range(0x15):
+    bytes_to_read = 24
+    ret_value = Read_byte_PLL(0, nof_bytes = bytes_to_read, ADDRESS=pll_address)
+    for cnt in range(bytes_to_read):
+        start = cnt*8
+        stri = "Reg nr 0x{:0>2x} value: 0x{:0>2x}".format(cnt, int(ret_value[start:start+8], 2))
+        print(stri)
+
+def read_IO_expanderis():
+    i2c_addr = [0x20, 0x21]
+    for addr in i2c_addr:
+        I2C_device = I2C(addr, BUSNR=I2CBUSNR) #clock selection
+        for reg_cnt in range(8):
+            ack, ret_value = I2C_device.read_bytes(reg_cnt, 2)
+            stri = "Expander : 0x{:0>2x}, Reg 0x{:0>2x}, value 0x{}{}".format(addr, reg_cnt, ret_value[0], ret_value[1]) #[start+2:start])
+            print(stri)
+
+def setup_pll(pll_frequency='200MHz') :
+    I2C_device = I2C(0x20, BUSNR=I2CBUSNR) #clock selection
+    I2C_device.write_bytes(0x07, 0x00)
+    if pll_frequency == '160MHz':
+        print("Set PLL to 160 MHz mode")
+        pll_address = PLL_160M
+        I2C_device.write_bytes(0x03, 0x08)
+    else:
+        print("Set PLL to 200 MHz mode")
+        pll_address=PLL_200M
+        I2C_device.write_bytes(0x03, 0x28)
+    Write_byte_PLL(0x03, 0x0C, pll_address)
+    sleep(0.5)
+    Write_byte_PLL(0x03, 0x08, pll_address)
+    Write_byte_PLL(0x03, 0x08, pll_address)
+    Write_byte_PLL(0x04, 0xCF, pll_address) # CF disable not used outputs, 00 enable all
+    Write_byte_PLL(0x05, 0x97, pll_address)
+    Write_byte_PLL(0x06, 0x10, pll_address) # cp inv = 0xF4 other 0xE4
+    Write_byte_PLL(0x07, 0x04, pll_address) # Divider R = 1 dec
+    Write_byte_PLL(0x08, 0x01, pll_address)
+    Write_byte_PLL(0x07, 0x00, pll_address)
+    Write_byte_PLL(0x09, 0x10, pll_address) # reset
+    if pll_frequency == '160MHz' :
+        Write_byte_PLL(0x0A, 0x10, pll_address)
+    else:
+        Write_byte_PLL(0x0A, 0x14, pll_address)
+    Write_byte_PLL(0x09, 0x00, pll_address)
+    Write_byte_PLL(0x0C, 0x8F, pll_address)
+    Write_byte_PLL(0x0D, 0x88, pll_address) # Dig CLK     = 200/1 = 200 MHz
+    Write_byte_PLL(0x0F, 0x08, pll_address) # RCU CLK     = 200/1 = 200 MHz
+    Write_byte_PLL(0x11, 0x08, pll_address) # PPS ref CLK = 200/1 = 200 MHz
+    Write_byte_PLL(0x13, 0x88, pll_address) # T.P.    CLK = 200/1 = 200 MHz
+
+
+def power(state):
+    stri = "Power to {}".format(state)
+    print(stri)
+    I2C_IO_device_A = I2C(0x20, BUSNR=I2CBUSNR)
+    I2C_IO_device_A.write_bytes(0x06, 0x2C) # '0' is output
+    I2C_IO_device_A.write_bytes(0x07, 0x00) # '0' is output
+    I2C_IO_device_B = I2C(0x21, BUSNR=I2CBUSNR)
+    I2C_IO_device_B.write_bytes(0x06, 0x2C) # '0' is output
+    if state:
+        bits_to_set_A1 = 0x02 | (1 << CS) | (0 << SCLK) | (0 << SDI)
+        bits_to_set_A2 = 0x04
+        bits_to_set_B1 = 0x02 | (1 << CS) | (0 << SCLK) | (0 << SDI)
+    else:
+        bits_to_set_A1 = 0x00 | (1 << CS) | (0 << SCLK) | (0 << SDI)
+        bits_to_set_A2 = 0x00
+        bits_to_set_B1 = 0x00 | (1 << CS) | (0 << SCLK) | (0 << SDI)
+    if DEBUG :
+        stri = "Bits to reg 0 0x{0:x}".format(bits_to_set_A1)
+        print(stri)
+    I2C_IO_device_A.write_bytes(0x02, bits_to_set_A1)
+    I2C_IO_device_A.write_bytes(0x03, bits_to_set_A2)
+    I2C_IO_device_B.write_bytes(0x02, bits_to_set_B1)
+
+def write_eeprom( data=0x01):
+    #
+    # Write the EEPROM with the serial number etc.
+    #
+    ret_ack, ret_value = dev_i2c_eeprom.read_bytes(0)
+    if ret_ack < 1:
+        print("EEPROM not found during write")
+        return False
+    else:
+        dev_i2c_eeprom.write_bytes(0x00, data)
+        sleep(0.1)
+        return True
+
+def read_eeprom():
+    #
+    # Read the EEPROM with the serial number etc.
+    #
+    ret_ack, ret_value = dev_i2c_eeprom.read_last_reg(1)
+    if ret_ack < 1:
+        print("no EEPROM found during read")
+        return False
+    else:
+        ret_ack, ret_value = dev_i2c_eeprom.read_bytes(0x00, 1)
+        return ret_value
+
+def wr_rd_eeprom(value=0x34):
+    #
+    # Write and Read the EEPROM to check functionality
+    #
+    if write_eeprom(value):
+        ret_value = read_eeprom()
+        stri = "Wrote to EEPROM: 0x{0:X}, Read from EEPROM: 0x{1} ".format(value, ret_value)
+        print(stri)
+    return True
+
+def apsct_sensors():
+    for sens_line in range(7):
+        read_voltage(sens_line)
+    read_temp()
+
+def read_voltage(input_channel=0):
+    addr = 0x74
+    Vref = 3.0
+    one_step = Vref/(2**(16))
+    I2C_device = I2C(addr, BUSNR=I2CBUSNR)
+    channel_select_word = 0xB0 | ((input_channel%2) << 3) | ((input_channel >> 1) & 0x7)
+    if DEBUG:
+        stri = "Word to select sens input is 0x{0:x}".format(channel_select_word)
+        print(stri)
+    sleep(0.1)
+    I2C_device.write_bytes(channel_select_word, 0xB8)
+    sleep(0.5)
+    ret_ack, ret_value = I2C_device.read_last_reg(3)
+    if 1: #ret_ack:
+        if DEBUG:
+            stri = "Return value input 0 : 0x{0} ".format(ret_value)
+            print(stri)
+        if int(ret_value, 16) >= 0xC00000:
+            print("over range")
+        else:
+            steps = (int(ret_value, 16) & 0x1FFFFF) >> 6
+            voltage = one_step * steps
+            voltage = ((4.7+2.2)/2.2)*2*voltage
+            string = "Voltage sens line {1} is {0:.4f} V".format(voltage, input_channel)
+            print(string)
+    else:
+        stri = " No ACK on device 0x{0:x} ".format(addr)
+        print(stri)
+
+def read_temp():
+    Vref = 3.0
+    addr = 0x74
+    one_step = Vref/(2**(16))
+    I2C_device = I2C(addr, BUSNR=I2CBUSNR)
+    temp_slope = 93.5E-6 * 2**(16+1) / Vref
+    sleep(1.0)
+    I2C_device.write_bytes(0xA0, 0xC0)
+    sleep(1.0)
+    ret_ack, ret_value = I2C_device.read_last_reg(3)
+    if ret_ack:
+        raw_value  = (int(ret_value, 16) & 0x1FFFFF) >> 6
+        temperature_K = (raw_value/temp_slope)
+        temperature = temperature_K-273
+        stri = "Temperature : {0:.2f} gr. C".format(temperature)
+        print(stri)
+    else:
+        print("Error reading tempeature")
+
+
+def read_lol(pll_frequency='200MHz'):
+    I2C_IO_device_A = I2C(0x20, BUSNR=I2CBUSNR)
+    I2C_IO_device_A.write_bytes(0x06, 0x2C)  # '0' is output
+    I2C_IO_device_A.write_bytes(0x07, 0x00)  # '0' is output
+    I2C_IO_device_B = I2C(0x21, BUSNR=I2CBUSNR)
+    I2C_IO_device_B.write_bytes(0x06, 0x2C)  # '0' is output
+    I2C_IO_device_B.write_bytes(0x07, 0xFF)  # '0' is output
+
+    ack, ret_value = I2C_IO_device_B.read_bytes(0x01, 1)
+    status_reg = int(ret_value,16)
+    if (pll_frequency=='200MHz') & ((status_reg & 0x10) > 0):
+        print("lost lock 200MHz")
+    if ((status_reg & 0x20) > 0) & (pll_frequency=='160MHz'):
+        print("lost lock 160MHz")
+    ack, ret_value = I2C_IO_device_A.read_bytes(0x01, 1)
+    old_reg = int(ret_value,16)
+    I2C_IO_device_A.write_bytes(0x03, (old_reg | 0x10))  # '0' is output
+    sleep(1)
+    I2C_IO_device_A.write_bytes(0x03, (old_reg & 0xEF))  # '0' is output
+
+
+
+
+
+#if READ_REGS:
+#    read_all_regs_pll(CLK_FREQ)
+
+read_temp()
+
+if CHECK_EEPROM :
+    wr_rd_eeprom()
+
+if PWR_RST :
+    power(False)
+    sleep(10)
+    power(True)
+
+if SET_PLL :
+    setup_pll(CLK_FREQ)
+
+if READ_LOCK:
+    if CLK_FREQ == '160MHz' :
+        pll_addr = PLL_160M
+    else:
+        pll_addr = PLL_200M
+    ret_value = Read_byte_PLL(0x00, nof_bytes = 1, ADDRESS=pll_addr)
+    status_pll = int(ret_value,2)
+    if status_pll == 0x04:
+        print("PLL in lock")
+    elif (status_pll & 0x10) > 0:
+        print("Not Locked --> No 10 MHz ref")
+    else:
+        print("Not locked --> PLL Error")
+
+if READ_REGS:
+    read_all_regs_pll(CLK_FREQ)
+
+if READ_ALL:
+    read_all_regs_pll(CLK_FREQ)
+    read_IO_expanderis()
+
+if READ_SENSOR:
+    apsct_sensors()
+read_lol(CLK_FREQ)