diff --git a/config/RECVTR.yaml b/config/RECVTR.yaml
index c0f3ca0552d85eaa4396d22d9896bc68a5d93668..83d2fbaafd384879582e5beaa7a2a15601b3a295 100644
--- a/config/RECVTR.yaml
+++ b/config/RECVTR.yaml
@@ -21,20 +21,25 @@ drivers:
    devreg: [0x40.0xFF] #I2C broadcast register
    parameters: [24] #PPS GPIO pin
  - name: I2Cbb1 
-   type: i2cbitbang1 #I2C bitbang via GPIO expander
+   type: i2cbitbangp #I2C bitbang via GPIO expander
    devreg: [IO3.GPIO2,IO3.GPIO2,IO3.CONF2]
    parameters: [5,6,6] #pins
    parent: I2C_RCU
  - name: I2Cbb2
-   type: i2cbitbang1
+   type: i2cbitbangp
    devreg: [IO3.GPIO2,IO3.GPIO2,IO3.CONF2]
    parameters: [4,6,6]
    parent: I2C_RCU
  - name: I2Cbb3
-   type: i2cbitbang1
+   type: i2cbitbangp
    devreg: [IO3.GPIO2,IO3.GPIO2,IO3.CONF2]
    parameters: [3,6,6]
    parent: I2C_RCU
+# - name: I2Cbbp
+#   type: i2cbitbangp
+#   devreg: [IO3.GPIO2,IO3.GPIO2,IO3.CONF2]
+#   parameters: [5,4,3,6,6,6,6,6,6]
+#   parent: I2C_RCU
  - name: SPIbb1 
    type: spibitbang1 #SPI bitbang via GPIO expander: CLK, SDIO, SDIOdir,CS
    devreg: [IO3.GPIO1,IO3.GPIO1,IO3.CONF1,IO3.GPIO2]
@@ -50,6 +55,12 @@ drivers:
    devreg: [IO3.GPIO1,IO3.GPIO1,IO3.CONF1,IO3.GPIO2]
    parameters: [5,4,4,2]
    parent: I2C_RCU
+
+# - name: SPI3bb 
+#   type: spibitbang3 #SPI bitbang via GPIO expander: CLK, SDIO, SDIOdir,CS
+#   devreg: [IO3.GPIO1,IO3.GPIO1,IO3.CONF1,IO3.GPIO2]
+#   parameters: [1,3,5,  0,2,4,  0,2,4,  0,1,2]
+#   parent: I2C_RCU
 # - name: HBA_trigger
 #   type: gpio_hba_trigger
 #   parameters: [15] #PPS GPIO pin
@@ -459,7 +470,7 @@ variables:
      dim: 96
      dim2: [3,32]
      read_parallel: true
-     monitor: true
+#     monitor: true
      mask: RECVTR_I2C_error
 
    - name: RCU_PWR_ANT2_VIN
@@ -473,7 +484,7 @@ variables:
      dim: 96
      dim2: [3,32]
      read_parallel: true
-     monitor: true
+#     monitor: true
      mask: RECVTR_I2C_error
 
 
@@ -512,12 +523,12 @@ variables:
      mask: RCU_mask
 
    - name: RCU_DTH_shutdown
-     description: False means dither source powered on. Controlled by TBD
+     description: False means dither source & ADC powered on.
      driver: I2C_RCU
      devreg:  [IO3.GPIO1,IO3.GPIO1,IO3.GPIO2]
      width: 1
      bitoffset: [7,6,7]
-     rw:  rw
+     rw:  ro
      dtype: boolean
      dim: 96
      dim2: [3,32]
@@ -639,6 +650,7 @@ variables:
      dim: 96
      dim2: [3,32]
 #     monitor: true
+     read_parallel: true
 
    - name: RCU_ADC_sync
      driver: I2C_RCU
@@ -680,6 +692,7 @@ variables:
      dim: 96
      dim2: [3,32]
      mask: ANT_mask
+     read_parallel: all
 
    - name: RCU_DTH_PWR
      description: RCU Dither source power
@@ -692,30 +705,33 @@ variables:
      dim: 96
      dim2: [3,32]
      mask: ANT_mask
+     read_parallel: all
 #     debug: true
 
 
-   - name: RCU_DTH_tune
-     driver: I2C_RCU
-     devreg:  [DTH1.Tune,DTH2.Tune,DTH3.Tune]
-     width: 16
-     rw:  rw
-     dtype: uint32
-     dim: 96
-     dim2: [3,32]
-     mask: ANT_mask
-     debug: true
+#   - name: RCU_DTH_tune
+#     driver: I2C_RCU
+#     devreg:  [DTH1.Tune,DTH2.Tune,DTH3.Tune]
+#     width: 16
+#     rw:  rw
+#     dtype: uint32
+#     dim: 96
+#     dim2: [3,32]
+#     mask: ANT_mask
+#     debug: true
+#     read_parallel: all
 
-   - name: RCU_DTH_config
-     driver: I2C_RCU
-     devreg:  [DTH1.CONF,DTH2.CONF,DTH3.CONF]
-     width: 8
-     rw:  rw
-     dtype: uint32
-     dim: 96
-     dim2: [3,32]
-     mask: ANT_mask
-     debug: true
+#   - name: RCU_DTH_config
+#     driver: I2C_RCU
+#     devreg:  [DTH1.CONF,DTH2.CONF,DTH3.CONF]
+#     width: 8
+#     rw:  rw
+#     dtype: uint32
+#     dim: 96
+#     dim2: [3,32]
+#     mask: ANT_mask
+#     debug: true
+#     read_parallel: all
 
    - name: RCU_DTH_on
      description: RCU Dither on. Controlled by RCU_DTH_on/off
@@ -728,17 +744,19 @@ variables:
      dim: 96
      dim2: [3,32]
      mask: ANT_mask
+     read_parallel: all
 
-   - name: RCU_DTH_Rev
-     driver: I2C_RCU
-     devreg:  [DTH1.Rev,DTH2.Rev,DTH3.Rev]
-     width: 88
-     rw:  rw
-     dtype: uint32
-     dim: 96
-     dim2: [3,32]
-     mask: ANT_mask
-     debug: true
+#   - name: RCU_DTH_Rev
+#     driver: I2C_RCU
+#     devreg:  [DTH1.Rev,DTH2.Rev,DTH3.Rev]
+#     width: 88
+#     rw:  rw
+#     dtype: uint32
+#     dim: 96
+#     dim2: [3,32]
+#     mask: ANT_mask
+#     debug: true
+#     read_parallel: all
 
 methods:
   - name: RECVTR_Init #Called after startup to load. Should have all stored registers  
@@ -758,6 +776,8 @@ methods:
 #    - IO3.GPIO2: Update
     - IO3.CONF1: Update
     - RCU_update: 0
+    - RCU_ADC_locked: Update #check if not also in RCU_update
+    - RCU_DTH_on: Update #check if not also in RCU_update
     - RCU_IO4_GPIO1: Update #should be last, as it will fail for low-band
     - RCU_IO4_GPIO2: Update
 
@@ -770,30 +790,39 @@ methods:
      - IO2.CONF1: 0x80 #Pgood on 0x80
      - IO2.GPIO1: 0x4A #0x40 Dig on, 0x0a =10dB att
      - IO2.GPIO2: 0x55 #0x15 #Band0 (or 0x2a band 1)  #LED green=on=low
-     - IO3.GPIO1: 0xD5 #ADC_SDIO=high, clk=low, DTH_EN=high
-     - IO3.GPIO2: 0xC7 #ADC SC=high, DTH_SDA=high, DTH_EN=high
+     - IO3.GPIO1: 0x15 #ADC_SDIO=high, clk=low, DTH_EN=low
+     - IO3.GPIO2: 0x47 #ADC SC=high, DTH_SDA=high, DTH_EN=low
      - IO1.GPIO1: 0x0A #0x0a = 10dB att
      - IO1.GPIO2: 0x8A #0x80 Analog on, 0x0a=10dB att
      - IO2.CONF2: 0
      - IO3.CONF1: 0
      - IO3.CONF2: 0
+     - IO3.DIR1: 0
+     - IO3.DIR2: 0
      - IO1.CONF1: 0
      - IO1.CONF2: 0
 #     - RCU_GPIO1: Update
 #     - RCU_GPIO2: Update
 #     - RCU_attenuator: [10,10,10]  #Set OPC-UA variable
 #name="RCU_DTH_shutdown"
-     - IO3.GPIO1: 0x55 #enable ADC 0 (DTH_EN=low)
-     - IO3.GPIO1: 0x15 #enable ADC 1
-     - IO3.GPIO2: 0x47 #enable ADC 2
+     - RCU_update: 0
      - WAIT: 500         #ms to wait
      - ADC1_on: 0        #call another opc-ua method
-     - WAIT: 1000         #ms to wait
+#     - WAIT: 1000         #ms to wait
      - ADC2_on: 0
-     - WAIT: 1000         #ms to wait
+#     - WAIT: 1000         #ms to wait
      - ADC3_on: 0
-     - WAIT: 500         #ms to wait
-     - RCU_update: 0
+#     - WAIT: 500         #ms to wait
+#Toggle enable pin
+     - IO3.GPIO1: 0xD5 #ADC_SDIO=high, clk=low, DTH_EN=high
+     - IO3.GPIO2: 0xC7 #ADC SC=high, DTH_SDA=high, DTH_EN=high
+     - WAIT: 100         #ms to wait #todo: test if necessary
+     - IO3.GPIO1: 0x15 #enable ADC 0,1
+     - IO3.GPIO2: 0x47 #enable ADC 2
+
+     - RCU_DTH_on: Update #check dither while giving ADCs some time to lock
+#     - WAIT: 500         #ms to wait
+     - RCU_ADC_locked: Update #disabled for testing
 
   - name: RCU_on2
     description: Initialize RCU and it in the ON state
@@ -857,11 +886,11 @@ methods:
       - RCU_LED_green_on: Update
       - RCU_attenuator_dB: Update
       - RCU_band_select: Update
-      - RCU_ADC_locked: Update
-      - RCU_ADC_sync: Update
-      - RCU_DTH_shutdown: Update
+#      - RCU_ADC_locked: Update #disabled for testing
+#      - RCU_ADC_sync: Update #disabled for testing
+#      - RCU_DTH_shutdown: Update
 #      - RCU_DTH_freq: Update
-#      - RCU_DTH_on: Update
+#      - RCU_DTH_on: Update #disabled for testing
       - RCU_hband_select: Update
       - RCU_DAB_select: Update
       - RCU_firmware_version: Update
@@ -883,6 +912,7 @@ methods:
      - ADC1.JESD_control1 : 0x14
      - ADC1.SYNC_control: 1  #Setup ADCs
      - ADC1.CML_level: 0x7
+     - ADC1.dither : 0x00
      - ADC1.Update: 1       #Needed to update ADC registers
      
   - name: ADC2_on
@@ -893,6 +923,7 @@ methods:
      - ADC2.JESD_control1 : 0x14
      - ADC2.SYNC_control: 1  #Setup ADCs
      - ADC2.CML_level: 0x7
+     - ADC2.dither : 0x00
      - ADC2.Update: 1       #Needed to update ADC registers
 
   - name: ADC3_on
@@ -903,6 +934,7 @@ methods:
      - ADC3.JESD_control1 : 0x14
      - ADC3.SYNC_control: 1  #Setup ADCs
      - ADC3.CML_level: 0x7
+     - ADC3.dither : 0x00
      - ADC3.Update: 1       #Needed to update ADC registers
 
   - name: RCU_off
@@ -938,8 +970,11 @@ methods:
     mask: RCU_mask
 #    rw: hidden
     instructions:
-     - RCU_DTH_config : [0,0,0]
+#     - RCU_DTH_config : [0,0,0]
 #     - RCU_DTH_config: Update #debug
+     - DTH1.CONF : [0,0,0]
+     - DTH2.CONF : [0,0,0]
+     - DTH3.CONF : [0,0,0]
      - DTH1.Tune :    [0,0] #no tuning
      - DTH2.Tune :    [0,0] #no tuning
      - DTH3.Tune :    [0,0] #no tuning
@@ -965,7 +1000,7 @@ methods:
 #     - DTH1.State :    [0,0]
 #     - DTH2.State :    [0,0]
 #     - DTH3.State :    [0,0]
-     - RCU_DTH_on: Update
+     - RCU_DTH_on: Update 
 
   - name: RCU_DTH_restart #restart to update frequency
     driver: I2C_RCU
@@ -979,20 +1014,20 @@ methods:
      - DTH2.Start :    [0,1,0,0,1]
      - DTH3.Start :    [0,1,0,0,1]
 
-  - name: RCU_DTH_shutdown
-    description: shutdown dither source
-    driver: I2C_RCU
-    debug: True
-    mask: RCU_mask
+#  - name: RCU_DTH_shutdown
+#    description: shutdown dither source
+#    driver: I2C_RCU
+#    debug: True
+#    mask: RCU_mask
 #    rw: hidden
-    instructions:
+#    instructions:
 #     - RCU_DTH_SHUTDOWN : [1,1,1]
 #     - WAIT: 100
 #     - RCU_DTH_SHUTDOWN : [0,0,0]
 #     - RCU_DTH_SHUTDOWN : 1
-     - DTH1.State :    [1,0]
-     - DTH2.State :    [1,0]
-     - DTH3.State :    [1,0]
+#     - DTH1.State :    [1,0]
+#     - DTH2.State :    [1,0]
+#     - DTH3.State :    [1,0]
 
   - name: ADC0_test
     driver: I2C_RCU
diff --git a/i2cserv/i2c_array.py b/i2cserv/i2c_array.py
index de8f24ee7449537be59dbd666225d24b5b318235..ed4b86010629f467126a28704ef1ba18c853f7a7 100644
--- a/i2cserv/i2c_array.py
+++ b/i2cserv/i2c_array.py
@@ -16,6 +16,7 @@ class i2c_array(i2c_dev):
 #        self.previousHBA=np.zeros([number,3,32],dtype='int')
         pars=config['parameters'];
         self.RCU_Switch1=pars; #range(pars[0],pars[1]+1);
+        self.RCUorder=sorted(range(len(pars)),key=lambda k:pars[k])
         self.N=len(self.RCU_Switch1);
         self.I2Cmask=[0]*self.N
         self.I2Ccut=config.get('I2Ccut',5);#pars[2];
@@ -33,11 +34,13 @@ class i2c_array(i2c_dev):
 
     def SetSwitchMask(self,mask):
         m=0;
+        self.mask=[]
         self.conf['parentcls'].ClearNewChannel();
-        for RCUi in range(self.N):
+        for RCUi in self.RCUorder:
            if (mask[RCUi]) and (self.I2Cmask[RCUi]<=self.I2Ccut): 
                self.conf['parentcls'].AddNewChannel(self.RCU_Switch1[RCUi]);
                self.RCUi=RCUi
+               self.mask+=[RCUi]
         self.conf['parentcls'].UpdateNewChannel();
 
     def SetGetVarValueMask(self,var1,data,mask,getalso=True):
@@ -56,7 +59,41 @@ class i2c_array(i2c_dev):
             return;
 #        if (len(value1)==V1.nVars) and (self.N>1):  value1=(value1*self.N);
 #        logging.debug(str(("Step=",Step,"Mask=",mask)))
-        for RCUi in range(self.N):
+        if var1.get('read_parallel')=='all':
+             for Vari in range(Step):
+               devreg=var1['devreg'][Vari];
+               width=var1.get('width',8)
+               bitoffset=GetField(var1,'bitoffset',Vari,0)
+               mask2=[mask[RCUi*Step+Vari] & (self.I2Cmask[RCUi]<=self.I2Ccut) for RCUi in range(self.N)]
+               #self.mask=mask2;
+               isthesame=True;
+               self.SetSwitchMask(mask2);
+               for RCUi in self.mask: 
+#                    if not(mask2[RCUi]): continue;
+                    for i in range(Step2):
+                        if data[(Vari+RCUi*Step)*Step2+i]!=data[(Vari+self.RCUi*Step)*Step2+i]:
+                             isthesame=False;
+               if isthesame:
+                  data2=data[(Vari+self.RCUi*Step)*Step2:(Vari+self.RCUi*Step+1)*Step2]
+                  res=self.SetVarValue(devreg,width,bitoffset,data2)
+               else:
+                 for RCUi in self.RCUorder:
+                    if not(mask[RCUi*Step+Vari]): continue
+                    self.mask=[RCUi];
+                    self.SetSwitch(RCUi);
+                    self.RCUi=RCUi;
+                    i0=(RCUi*Step+    Vari)*Step2
+                    i1=(RCUi*Step+(Vari+1))*Step2
+                    res=self.SetVarValue(devreg,width,bitoffset,data[i0:i1])
+               if getalso:
+                 self.SetSwitchMask(mask2);
+                 value2=[0]*self.N*Step2;               
+                 res=self.GetVarValue(devreg,width,bitoffset,value2,0)
+#                print(Vari,mask2,value2)
+                 for r in range(self.N): value1[(Vari+r*Step)*Step2:(Vari+r*Step+1)*Step2]=value2[r*Step2:(r+1)*Step2]
+#              print(len(value1),value1)
+             return value1,mask
+        for RCUi in self.RCUorder:
             for Vari in range(Step):
                 if not(mask[RCUi*Step+Vari]): continue
                 if not(self.I2Cmask[RCUi]<=self.I2Ccut):
@@ -86,6 +123,10 @@ class i2c_array(i2c_dev):
                   self.I2Cmask[RCUi]=0;
         return value1,mask
 
+#    def GetVarValueParallel(self,var1,mask):
+#         mask2=[mask[RCUi*Step] & (self.I2Cmask[RCUi]<=self.I2Ccut) for RCUi in range(self.N)]
+#         self.SetSwitchMask(mask2);
+#         def 
 
     def GetVarValueMask(self,var1,mask):
         Step,Step2=GetSteps(var1);
@@ -99,6 +140,24 @@ class i2c_array(i2c_dev):
 #        if (len(value1)==V1.nVars) and (self.N>1):  value1=(value1*self.N);
         i2c=self.conf['parentcls'];
 #        logging.debug(str(("Step=",Step,"Mask=",mask)))
+#        if var1.get('read_parallel')=='all':
+#              return self.GetVarValueParallel(self,var1,mask)
+#        print(Step,Step2,len(mask),len(value1))
+        if var1.get('read_parallel')=='all':
+             for Vari in range(Step):
+               devreg=var1['devreg'][Vari];
+               width=var1.get('width',8)
+               bitoffset=GetField(var1,'bitoffset',Vari,0)
+               mask2=[mask[RCUi*Step+Vari] & (self.I2Cmask[RCUi]<=self.I2Ccut) for RCUi in range(self.N)]
+               self.SetSwitchMask(mask2);
+#               self.mask=mask2;
+               value2=[0]*self.N*Step2;
+               res=self.GetVarValue(devreg,width,bitoffset,value2,0)
+#               print(Vari,mask2,value2)
+               for r in range(self.N): value1[(Vari+r*Step)*Step2:(Vari+r*Step+1)*Step2]=value2[r*Step2:(r+1)*Step2]
+#             print(len(value1),value1)
+             return value1,mask
+           
         mode=(1 if var1.get('read_parallel') else 0)
         for Vari in range(Step):
           if mode==1:
@@ -114,7 +173,7 @@ class i2c_array(i2c_dev):
                res=self.GetVarValue(devreg,width,bitoffset,[],mode=3) #wait if needed
 #            for Vari in range(Step):
 #        else:
-          for RCUi in range(self.N):
+          for RCUi in self.RCUorder:
 #            for Vari in range(Step):
                 if not(mask[RCUi*Step+Vari]): continue
                 i0=(RCUi*Step+    Vari)*Step2
@@ -152,6 +211,7 @@ class i2c_array(i2c_dev):
         if len(mask)==0: 
              mask=[True]*self.N;
              self.RCUi=0; 
+#        self.mask=mask;
         self.SetSwitchMask(mask)
         if not(self.SetVarValue(devreg,8,0,value)): return False;
         if devreg.get('store'):
@@ -170,7 +230,7 @@ class i2c_array(i2c_dev):
         if devreg.get('store'):
                 storearray=self.getstorearray(devreg);
         i2c=self.conf['parentcls'];
-        for RCUi in range(self.N):
+        for RCUi in self.RCUorder:
                 if not(mask[RCUi]): continue
                 if not(self.I2Cmask[RCUi]<=self.I2Ccut): continue
                 self.SetSwitch(RCUi);
@@ -187,6 +247,8 @@ class i2c_array(i2c_dev):
         logging.debug(str(("Stored values:",self.getstorearray(devreg))))
         return True;
 
+
+
     def SetVarValue(self,devreg,width,bitoffset,value):
             if devreg['register_W']==-1: return True; #We can not set it, only read it e.g. temperature
             logging.debug(str(("RCU1 Set ",self.RCUi,devreg['addr'],value)))
@@ -250,3 +312,65 @@ class i2c_array(i2c_dev):
         return True;
 
 
+    def GetVarValuePar(self,devreg,width,bitoffset,value,buffer=False):
+    #setup self.mask, switch channels and self.RCUi before 
+        logging.debug(str(("GetVarValueP",self.RCUi,devreg['addr'],value,buffer)))
+#                self.GetI2C(RCUi,devreg,width,bitoffset,value)
+#        if dev.store>0:
+#            value[0]=self.previous[RCUi,dev.store-1]
+#        return True
+        callback=devreg['drivercls'].i2csetget;
+        reg=devreg['register_R']
+        step2=len(value);
+        value2=[0]*self.N;
+        l1=int(np.floor((width+bitoffset+7)/8))
+#        print(width,bitoffset,l1)
+        #for x in range(self.N):
+        #   value2[x*step2]=None; #default
+        if buffer:
+           if devreg.get('store'):
+             storearray=self.getstorearray(devreg,step2);
+             for x in self.mask:
+                  value2[x*step2:(x+1)*step2]=storearray[x]
+        else:
+           if len(self.mask)<1: self.conf['parentcls'].UpdateNewChannel();
+           callback(devreg['addr'],int2bytes(reg),read=2)
+           for x in self.mask:
+              value3=value2[x*step2:(x+1)*step2]
+              self.SetSwitch(x);
+              callback(devreg['addr'],value3,read=1)
+              if devreg.get('store')==True:
+                 storearray=self.getstorearray(devreg,step2);
+                 storearray[x]=(value3[0] if step2==1 else value3[:])
+              value2[x*step2:(x+1)*step2]=value3;
+                 # logging.debug(str(("Store buffer",self.RCUi,storearray[self.RCUi])))
+ #            print("Stored values:",self.getstorearray(devreg))
+        logging.debug(str(("GetVarValueP",value2)))
+        if (width!=l1*8) or (bitoffset>0):
+            if (width<8):
+              for i in range(len(value2)):
+                value2[i]=UnMask(value2[i],width,bitoffset)
+            else:
+                value2[0]=UnMask(value2[0],width-(l1-1)*8,bitoffset) #not implemented correctly!!
+        logging.debug(str(("GetVarValueP2",value2)))
+        return value2;
+
+
+    def SetVarValuePar(self,devreg,width,bitoffset,value,buffer=False):
+    #setup self.mask, switch channels and self.RCUi before 
+            if devreg['register_W']==-1: return True; #We can not set it, only read it e.g. temperature
+            logging.debug(str(("RCU1 Set Par ",self.RCUi,devreg['addr'],value)))
+            #self.parentcls.SetChannel(1<<RCU_Switch[RCUi]);
+            if devreg['store']:
+                storearray=self.getstorearray(devreg);
+                previous=storearray[self.RCUi];
+#                print(value,previous)
+                for x in range(len(value)):
+                    value[x]=ApplyMask(value[x],width,bitoffset,(previous[x] if isinstance(previous,list) else previous));
+                for x in self.mask:
+                    storearray[x]=(value[0] if len(value)==1 else value[:])
+                              #print("buffer",devreg['addr'],devreg['register_W'],x,storearray[x])
+            #  devreg['drivercls'].i2csetget
+            if buffer: return True;
+            if len(self.mask)>1: self.conf['parentcls'].UpdateNewChannel();
+            return devreg['drivercls'].i2csetget(devreg['addr'],value,reg=devreg['register_W'])
diff --git a/i2cserv/i2cbitbangp.py b/i2cserv/i2cbitbangp.py
new file mode 100644
index 0000000000000000000000000000000000000000..4acbf91a83166c12e8ce0d553bdce3e1c041512c
--- /dev/null
+++ b/i2cserv/i2cbitbangp.py
@@ -0,0 +1,189 @@
+from enum import Enum
+import logging
+import numpy as np
+from .hwdev import hwdev
+import time
+#This is copy of spibitbang. Need to be updated!!
+class SPIBB_pins(Enum):
+    CLK = 0  
+    SDA = 1  
+    SDAdir = 2 
+
+class i2cbitbangp(hwdev):
+  def __init__(self,config):
+    hwdev.__init__(self,config)
+    self.N=len(self.conf['parameters'])//3;
+
+  def i2csetget(self,addr,data,reg=None,read=0):
+    logging.debug(str(("I2Cbbpset",addr,data,reg,read)));
+    if read==0: 
+       if not(reg is None): 
+            if reg>255: data=[reg//256,reg%256]+data;
+            else:       data=[reg]+data;
+       if not(self.SetI2Cbb(addr,data)): return False;
+       return self.GetI2Cbb(addr,[]);
+    if read==2: return self.SetI2Cbb(addr,data)
+    elif read==1: 
+       if not(reg is None): 
+            if reg>255: reg=[reg//256,reg%256];
+            else:       reg=[reg];
+            self.SetI2Cbb(addr,reg)
+       return self.GetI2Cbb(addr,data)
+    elif read==3: 
+              time.sleep(data[0]/1000);
+              return True
+    else: logging.warn("Not implemented!")
+    return False;
+
+
+  def SetI2Cbb(self,address,value):
+        SDAdev=self.conf['devreg'][SPIBB_pins.SDA.value]
+        SDApin=[self.conf['parameters'][SPIBB_pins.SDA.value*self.N+x] for x in range(self.N)]
+        CLKdev=self.conf['devreg'][SPIBB_pins.CLK.value]
+        CLKpin=[self.conf['parameters'][SPIBB_pins.CLK.value*self.N+x] for x in range(self.N)]
+        DIRdev=self.conf['devreg'][SPIBB_pins.SDAdir.value]
+        DIRpin=[self.conf['parameters'][SPIBB_pins.SDAdir.value*self.N+x] for x in range(self.N)]
+        SetI2C=self.conf['parentcls'].SetVarValuePar
+        GetI2C=self.conf['parentcls'].GetVarValuePar
+
+        def SetReg(dev,pin,value):
+#           print("SetReg",pin,value)
+           for x in range(1,self.N):
+              SetI2C(dev,1,pin[x],value,buffer=True)
+           SetI2C(dev,1,pin[0],value,buffer=False)
+
+        def GetReg(dev,pin):
+#           print("SetReg",pin,value)
+           value=GetI2C(dev,1,pin[0],[0],buffer=False);
+           for x in range(1,self.N):
+              value+=GetI2C(dev,1,pin[x],[0],buffer=True)
+#           value=np.array(value).T
+#           print(value.shape)
+           return value
+
+#        ADC_address=dev.Register_W<<1; #Write
+        ADC_address=address<<1;#dev.Register_W<<1; #Write
+        logging.debug(str(("I2Cbb set",hex(ADC_address),value)))
+        
+        SetReg(DIRdev,DIRpin,[1]) #Input = high
+        SetReg(CLKdev,CLKpin,[1]) #Should be high for start
+	#start
+        SetReg(SDAdev,SDApin,[0]) #Output = low
+        SetReg(DIRdev,DIRpin,[0]) #Output = low
+        SetReg(CLKdev,CLKpin,[0]) 
+#        ack=[0];
+        def TXbyte(b):
+          for bit in "{0:{fill}8b}".format(b, fill='0'):
+              SetReg(DIRdev,DIRpin,[int(bit)]) 
+              SetReg(CLKdev,CLKpin,[1]) 
+              SetReg(CLKdev,CLKpin,[0]) 
+          SetReg(DIRdev,DIRpin,[1]) #input 
+#          GetI2C(SDAdev,1,SDApin,ack)
+#          print("Ack=",ack[0]);
+          SetReg(CLKdev,CLKpin,[1]) 
+          ack=GetReg(SDAdev,SDApin)
+#          print("Ack=",ack[0]);
+          SetReg(CLKdev,CLKpin,[0]) 
+          return ack;
+ 
+        ack=TXbyte(ADC_address);
+        #print(len(ack),ack)
+        for v in value:
+           TXbyte(v);
+        #stop
+        SetReg(DIRdev,DIRpin,[0]) #low
+        SetReg(CLKdev,CLKpin,[1]) #Should be high
+        SetReg(DIRdev,DIRpin,[1]) #Input = high
+        SetReg(CLKdev,CLKpin,[0]) #keep low between transmission to not generate stop/start when other i2c actice
+        
+        return True;
+
+  def GetI2Cbb(self,reg_address,value):
+        SDAdev=self.conf['devreg'][SPIBB_pins.SDA.value]
+        SDApin=[self.conf['parameters'][SPIBB_pins.SDA.value*self.N+x] for x in range(self.N)]
+        CLKdev=self.conf['devreg'][SPIBB_pins.CLK.value]
+        CLKpin=[self.conf['parameters'][SPIBB_pins.CLK.value*self.N+x] for x in range(self.N)]
+        DIRdev=self.conf['devreg'][SPIBB_pins.SDAdir.value]
+        DIRpin=[self.conf['parameters'][SPIBB_pins.SDAdir.value*self.N+x] for x in range(self.N)]
+        SetI2C=self.conf['parentcls'].SetVarValuePar
+        GetI2C=self.conf['parentcls'].GetVarValuePar
+        def SetReg(dev,pin,value):
+#           print("SetReg",pin,value)
+           for x in range(1,self.N):
+              SetI2C(dev,1,pin[x],value,buffer=True)
+           SetI2C(dev,1,pin[0],value,buffer=False)
+
+        def GetReg(dev,pin):
+#           print("SetReg",pin,value)
+           value=[GetI2C(dev,1,pin[0],[0],buffer=False)];
+           for x in range(1,self.N):
+              value.append(GetI2C(dev,1,pin[x],[0],buffer=True))
+           value=np.array(value).T
+           #print(value.shape)
+           return value.flatten();
+
+        ADC_address=1+(reg_address<<1); #Read
+        logging.debug(str(("I2Cbb get",hex(ADC_address),len(value),value)))
+
+        SetReg(DIRdev,DIRpin,[1]) #Input = high
+        SetReg(CLKdev,CLKpin,[1]) #Should be high for start bit
+	#start
+        SetReg(SDAdev,SDApin,[0]) #Output = low
+        SetReg(DIRdev,DIRpin,[0]) #Output = low
+        SetReg(CLKdev,CLKpin,[0]) 
+        ack=[0];
+        def TXbyte(b):
+          for bit in "{0:{fill}8b}".format(b, fill='0'):
+              SetReg(DIRdev,DIRpin,[int(bit)]) 
+              SetReg(CLKdev,CLKpin,[1]) 
+              SetReg(CLKdev,CLKpin,[0]) 
+          SetReg(DIRdev,DIRpin,[1]) #input 
+#          GetI2C(SDAdev,1,SDApin,ack)
+#          print("Ack=",ack[0]);
+          SetReg(CLKdev,CLKpin,[1]) 
+          ack=GetReg(SDAdev,SDApin)
+#          print("Ack=",ack[0]);
+          SetReg(SDAdev,SDApin,[0]) 
+          SetReg(CLKdev,CLKpin,[0]) 
+          return ack;
+
+        def RXbyte(last=False):
+          b=None;
+          for i in range(8):
+              SetReg(CLKdev,CLKpin,[1]) 
+              ack=GetReg(SDAdev,SDApin)
+#              print(ack[0])
+#              if ack[0] is None: b=None
+#              elif not b is None: b=(b<<1)+ack[0];
+              if b is None:
+                 b=ack
+              else:
+                 b=[(b[i]<<1)+ack[i] for i in range(len(ack))]
+#              print("RX step",b,ack)
+              SetReg(CLKdev,CLKpin,[0]) 
+#          print("RXbyte",hex(b));
+          SetReg(SDAdev,SDApin,[0]) 
+          SetReg(DIRdev,DIRpin,[1 if last else 0]) #outout = low = ack 
+          SetReg(CLKdev,CLKpin,[1]) 
+          SetReg(CLKdev,CLKpin,[0]) 
+          SetReg(DIRdev,DIRpin,[1])
+          return b;
+ 
+        TXbyte(ADC_address);
+        status=RXbyte(last=(len(value)==0))
+        step=len(status);
+        step2=len(value)//step
+#        print("step=",step);
+#        if not(RXbyte()==0x80): return False;
+        for i in range(step2):
+          value2=RXbyte(last=(i==step2-1))
+          for j in range(step):
+            value[i+j*step2]=value2[j];
+        logging.debug(str(("si status:",[hex(s) for s in status],[hex(v) for v in value])))#should be 0x80 - will fail for None!!
+        #stop
+        #SetI2C(DIRdev,1,DIRpin,[0]) #low
+        SetReg(CLKdev,CLKpin,[1]) 
+        SetReg(DIRdev,DIRpin,[1]) #Input = high
+        SetReg(CLKdev,CLKpin,[0]) #keep low between transmission to not generate stop/start when other i2c actice
+
+        return True;
\ No newline at end of file
diff --git a/i2cserv/spibitbang1.py b/i2cserv/spibitbang1.py
index b41e5fecb62f0ce0772c1b315092f8d491df357c..e73b65d32b81deb8d339943f2c2ccc24d1081995 100644
--- a/i2cserv/spibitbang1.py
+++ b/i2cserv/spibitbang1.py
@@ -15,8 +15,10 @@ class spibitbang1(hwdev):
 #    logging.info("spibitbang todo")
 
   def i2csetget(self,addr,data,reg=None,read=0):
+    logging.debug(str(("spibitbang:",addr,data,reg,read)))
     if read==0: return self.SetSPIbb(reg,data)
     elif read==1: return self.GetSPIbb(reg,data)
+    elif read==2: return self.GetSPIbb(data[0],None) #Set register in parallel
     else: logging.warn("Not implemented!")
     return False;
 
@@ -62,35 +64,36 @@ class spibitbang1(hwdev):
 #        print("SDO",SDOdev,SDOpin)
 #        print("CLK",CLKdev,CLKpin)
 #        print("DIR",SDIOdirdev,SDIOdirpin)
-        logging.debug(str(("SPIbb get",ADC_reg_address)))
-          
+        logging.debug(str(("SPIbb get",ADC_reg_address,value)))
+        SetI2C=self.conf['parentcls'].SetVarValue
+        GetI2C=self.conf['parentcls'].GetVarValue
         ADC_bytes = 0x00
-        ADC_rw    = 0x01 # 0 for write, 1 for read
+        if not(ADC_reg_address is None):  
+          ADC_rw    = 0x01 # 0 for write, 1 for read
         
-        data = ( ADC_rw << 15) + ( ADC_bytes << 13 ) + ADC_reg_address
+          data = ( ADC_rw << 15) + ( ADC_bytes << 13 ) + ADC_reg_address
 
-        SetI2C=self.conf['parentcls'].SetVarValue
-        GetI2C=self.conf['parentcls'].GetVarValue
-        if not(SetI2C(CSdev,1,CSpin,[0])): return False #enable
+          if not(SetI2C(CSdev,1,CSpin,[0])): return False #enable
 
 
-        bit_array = "{0:{fill}16b}".format(data, fill='0')
+          bit_array = "{0:{fill}16b}".format(data, fill='0')
         #print("SPI TX bits",bit_array)
-        for bit in bit_array:
+          for bit in bit_array:
               SetI2C(SDOdev,1,SDOpin,[int(bit)]) 
               SetI2C(CLKdev,1,CLKpin,[1]) 
               SetI2C(CLKdev,1,CLKpin,[0]) 
 
-        SetI2C(CSdev,1,CSpin,[1]) #disable
+          SetI2C(CSdev,1,CSpin,[1]) #disable
 
           #    print("read byte")
-        SetI2C(SDIOdirdev,1,SDIOdirpin,[1]) #input
-        SetI2C(CSdev,1,CSpin,[0]) #enable
-        a=[0]
-        N=1;#len(value)
-        ret_value=[0];
-        for i in range(N): value[i]=0
-        for cnt in range(8*(ADC_bytes+1)):
+        if not(value is None):  
+           SetI2C(SDIOdirdev,1,SDIOdirpin,[1]) #input
+           SetI2C(CSdev,1,CSpin,[0]) #enable
+           a=[0]
+           N=1;#len(value)
+           ret_value=[0];
+           for i in range(N): value[i]=0
+           for cnt in range(8*(ADC_bytes+1)):
               GetI2C(SDOdev,1,SDOpin,ret_value) #enable
 #              logging.debug("Got bit"+str((ret_value)))
               for i in range(N): 
@@ -98,9 +101,9 @@ class spibitbang1(hwdev):
                    elif not value[i] is None: value[i]=(value[i]<<1)+ ret_value[i]
               SetI2C(CLKdev,1,CLKpin,[1]) 
               SetI2C(CLKdev,1,CLKpin,[0])  #read after falling edge
-        SetI2C(CSdev,1,CSpin,[1]) #disable
-        SetI2C(SDIOdirdev,1,SDIOdirpin,[0]) #output
-#        logging.debug(str(("SPIbb got",value)))
+           SetI2C(CSdev,1,CSpin,[1]) #disable
+           SetI2C(SDIOdirdev,1,SDIOdirpin,[0]) #output
+           logging.debug(str(("SPIbb got",value)))
         return True;
 
 def GetSPIbb2(SetI2C,GetI2C,RCUi,SPIdev,I2Cdev,I2Cpins,value):
diff --git a/opcuaserv/smbus_float.py b/opcuaserv/smbus_float.py
index 7e02ece7e6dc378e57c02c40c51b2b1d18cc3665..60a5e30c78e699478e3a91db15c15264684d52fe 100644
--- a/opcuaserv/smbus_float.py
+++ b/opcuaserv/smbus_float.py
@@ -38,7 +38,7 @@ def si4012_6bytes_to_pwr_inv(data):
     pwr=(pwr-Reg0)/M
     pwr-=Step/M*(pwr>75)
     pwr=int(pwr)
-    print(pwr)
+#    print(pwr)
     if pwr>=128: pwr+=128;
     pwr<<=32
 #    pwr+=0<<16 #Cap
diff --git a/opcuaserv/yamlreader.py b/opcuaserv/yamlreader.py
index bcf8792abbe0608826b21f74d63d99da0653d64a..5c1616274bca3eb3848be16b7b0950aaaf658a17 100644
--- a/opcuaserv/yamlreader.py
+++ b/opcuaserv/yamlreader.py
@@ -201,6 +201,7 @@ class yamlreader(yamlconfig):
 #        print(notvalid)
         for x in range(len(data)):
                if data[x] is None: data[x]=0; 
+#        print(data)
         if dtype=="boolean": 
                 data2=[d==1 for d in data]; 
                 convert=v.get("convert_unit")
@@ -250,11 +251,12 @@ class yamlreader(yamlconfig):
            logging.warn("OPC variable not found!!");
            return;
         data3=var1.get_value();
+        datatype=var1.get_data_value().Value.VariantType
         if not(isinstance(data3,list)): data3=[data3];
 #        print("OPCset",v['name'],data2[:64],mask)
         if mask: #Only update masked values
             step=len(data2)//len(mask)
-            #print("mask step=",step)
+#            print("mask step=",step,len(mask),len(data2),len(data3),data2)
             for i in range(len(data2)):
                 if mask[i//step]: data3[i]=data2[i]
         else:
@@ -263,7 +265,7 @@ class yamlreader(yamlconfig):
         logging.info(str(("OPCset",v['name'],data3[:64])))
 #        if v['name']=='UNB2_FPGA_POL_ERAM_IOUT': logging.warn(str((data3,data2,mask,var1.get_value(),[hex(d) for d in data])));
         if len(data3)==1: data3=data3[0];
-        var1.set_value(data3);
+        var1.set_value(data3,datatype);
 
     def Monitor(self):
         if self.monitorvar is None: return;
@@ -278,7 +280,7 @@ class yamlreader(yamlconfig):
           if v.get('monitor'):
                mask=(v['maskOPC'].get_value() if v.get('maskOPC') else [])
 #               print("monitor",v['name'],mask)
-               self.SetBusy()
+#               self.SetBusy()
                self.server.readvar(self.monitorvarcnt,mask=mask)
           self.monitorvarcnt+=1;
           if self.monitorvarcnt>=len(self.conf['variables']): 
diff --git a/scripts/DTH_off.py b/scripts/DTH_off.py
new file mode 100644
index 0000000000000000000000000000000000000000..d4e5896cfaacc0f6833c68ee57723ae42e2b5e82
--- /dev/null
+++ b/scripts/DTH_off.py
@@ -0,0 +1,9 @@
+from test_common import *
+import numpy as np
+
+RCU=[0,1,2,3,4,5,6,7,8,9,10];
+connect()
+setAntmask(RCU)
+setRCUmask(RCU)
+callmethod("RCU_DTH_stop")
+disconnect()
\ No newline at end of file
diff --git a/scripts/DTH_test.py b/scripts/DTH_test.py
index 4a688ad819982811a7f0677134ef020bc08698e7..cb359c3ba0ed2403aad309c8a4181b4849784bb5 100644
--- a/scripts/DTH_test.py
+++ b/scripts/DTH_test.py
@@ -1,18 +1,18 @@
 from test_common import *
 import numpy as np
 
-RCU=[0];
+RCU=[0,1,2,3,4,5,6,7,8,9,10];
 connect()
 setAntmask(RCU)
 setRCUmask(RCU)
 #call_debug_method("DTH_off")
-FRCU=0.05;
-FCH=0.425;
+FRCU=0.05*0;
+FCH=0.425*0;
 #F0=101.0
 F0=97.0
 name="RCU_DTH_freq"
 
-if False:
+if True:
  att=get_value(name+"_R")
  print("freq old:",att[3*RCU[0]:3*RCU[-1]+3])
 
@@ -29,7 +29,7 @@ if False:
 
 name="RCU_DTH_PWR"
 Pwr=-40.0
-if False:
+if True:
  att=get_value(name+"_R")
  print("pwr old:",att[3*RCU[0]:3*RCU[-1]+3])
 
@@ -42,7 +42,7 @@ if False:
  att=get_value(name+"_R")
  print("pwr new :",att[3*RCU[0]:3*RCU[-1]+3])
 
-#callmethod("RCU_DTH_on")
-callmethod("RCU_DTH_off")
+callmethod("RCU_DTH_on")
+#callmethod("RCU_DTH_stop")
 
 disconnect()
\ No newline at end of file