diff --git a/vmmTblApp/Db/channels.sub b/vmmTblApp/Db/channels.sub
new file mode 100644
index 0000000000000000000000000000000000000000..b30992b94a7ef286c6d47cd0c41243a24d6c2202
--- /dev/null
+++ b/vmmTblApp/Db/channels.sub
@@ -0,0 +1,7 @@
+file channels.template {
+pattern {HYB, VMM}
+{0, 0}
+{0, 1}
+{1, 0}
+{1, 1}
+}
diff --git a/vmmTblApp/Db/channels.template b/vmmTblApp/Db/channels.template
new file mode 100644
index 0000000000000000000000000000000000000000..6e97182a095948e62e8a89b7e5b1812bbfc7bccf
--- /dev/null
+++ b/vmmTblApp/Db/channels.template
@@ -0,0 +1,28 @@
+##### Records to set all register channels for given Hybrid
+##### and given VMM chip.
+##### 
+##### The aao record sets the register channel by channel.
+##### The bo record sets all channels at once.
+
+# ST register
+record(aao, "$(P)$(R)Hyb$(HYB)Vmm$(VMM)ST-S") {
+    field(DESC, "Set ST channels array")
+    field(DTYP, "asynInt8ArrayOut")
+    field(NELM, "64")
+    field(FTVL, "CHAR")
+    field(OUT,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))HYB_$(HYB)_$(VMM)_ST")
+}
+
+record(bo, "$(P)$(R)Hyb$(HYB)Vmm$(VMM)AllST-S") {
+    field(DESC, "Set all ST channels")
+    field(VAL,  "0")
+}
+
+record(acalcout, "$(P)$(R)Hyb$(HYB)Vmm$(VMM)#AllST-S") {
+    field(NELM, "64")
+    field(CALC, "A=1?1:0")
+    field(OOPT, "On Change")
+    field(INPA, "$(P)$(R)Hyb$(HYB)Vmm$(VMM)AllST-S CPP")
+    field(INAA, "$(P)$(R)Hyb$(HYB)Vmm$(VMM)ST-S")
+    field(OUT,  "$(P)$(R)Hyb$(HYB)Vmm$(VMM)ST-S PP")
+}
diff --git a/vmmTblApp/Db/hybrid.template b/vmmTblApp/Db/hybrid.template
index 59cb2a30903ba71dee6305fdce9de054e3e815c7..323e111b4e66dd9faadf2d191f4f11baf436e5c1 100644
--- a/vmmTblApp/Db/hybrid.template
+++ b/vmmTblApp/Db/hybrid.template
@@ -37,25 +37,3 @@ record(mbbi, "$(P)$(R)Hyb$(HYB)LinkStatus-R") {
     field(DTYP, "asynInt32")
     field(INP,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))HYB_$(HYB)_LINK_STATUS")
 }
-
-record(aao, "$(P)$(R)Hyb$(HYB)ST-S"){
-    field(DESC, "Set ST channels array")
-    field(DTYP, "asynInt8ArrayOut")
-    field(NELM, "64")
-    field(FTVL, "CHAR")
-    field(OUT,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))HYB_ST0_SETTER")
-}
-
-record(bo, "$(P)$(R)Hyb$(HYB)AllST-S") {
-    field(DESC, "Set all ST channels")
-    field(VAL,  "0")
-}
-
-record(acalcout, "$(P)$(R)Hyb$(HYB)#AllST-S") {
-    field(NELM, "64")
-    field(CALC, "A=1?1:0")
-    field(OOPT, "On Change")
-    field(INPA, "$(P)$(R)Hyb$(HYB)AllST-S CPP")
-    field(INAA, "$(P)$(R)Hyb$(HYB)ST-S")
-    field(OUT,  "$(P)$(R)Hyb$(HYB)ST-S PP")
-}
diff --git a/vmmTblApp/src/vmm_tbl.cpp b/vmmTblApp/src/vmm_tbl.cpp
index 1a1fe5fb3f6b1f50ab6f74bebf6942a3ebaaf906..d66fb430b1a7b3cf7c7ff85faa28882c29d87741 100644
--- a/vmmTblApp/src/vmm_tbl.cpp
+++ b/vmmTblApp/src/vmm_tbl.cpp
@@ -37,7 +37,6 @@ asynStatus VMMTbl::createEpicsParams() {
   pRMM->createParam(addr_list, "ADC_VALUE_VMM0", asynParamFloat64, &vmmMonitorValueVMM0_);
   pRMM->createParam(addr_list, "ADC_VALUE_VMM1", asynParamFloat64, &vmmMonitorValueVMM1_);
   pRMM->createParam(addr_list, "VMM_FEN_ACQUIRE", asynParamInt32, &vmmAcquire_);
-  pRMM->createParam(addr_list, "HYB_ST0_SETTER",  asynParamInt8Array, &vmmST);
 
   for (int hyb = 0; hyb < number_hybrids; hyb++) {
     std::ostringstream param_name;
@@ -52,6 +51,12 @@ asynStatus VMMTbl::createEpicsParams() {
     param_name.str("");
     param_name << "HYB_" << hyb <<"_LINK_STATUS";
     pRMM->createParam(addr_list, param_name.str().c_str(), asynParamInt32, &vmmHybLinkStatus_[hyb]);
+    for (int vmm=0; vmm < VMMS_PER_HYBRID; vmm++)
+    {
+    param_name.str("");
+    param_name << "HYB_" << hyb <<"_" << vmm << "_ST";
+    pRMM->createParam(addr_list, param_name.str().c_str(), asynParamInt8Array, &vmmST_[hyb][vmm]);
+    }
   }
 
   return asynSuccess;
@@ -99,14 +104,27 @@ asynStatus VMMTbl::writeInt32(asynUser *pasynUser, epicsInt32 value) {
 asynStatus VMMTbl::writeInt8Array(asynUser *pasynUser, epicsInt8 *value, size_t nElements)
 {
 
-  int function = pasynUser->reason;
-  asynStatus status = asynSuccess;
+  int function, addr;
   int ncopy = CHANNELS_PER_VMM;
+  const char *paramName;
+  const char *functionName = "writeInt8Array";
+  asynStatus status = asynSuccess;
   std::vector<epicsInt8> int8Array;
+  Pair pair;
+
+  status = pRMM->parseAsynUser(pasynUser, &function, &addr, &paramName);
+  if (status != asynSuccess) return status;
+
+  pair = findPair(function, vmmST_);
+  pRMM->getParamName(addr, function, &paramName);
+
+  asynPrint(pasynUser, ASYN_TRACEIO_DRIVER,
+            "%s:%s: function=%d, name=%s, value=%d, hybrid=%d, vmm=%d\n",
+            driverName, functionName, function, paramName, value, pair.hyb, pair.vmm);
 
   for (epicsInt8 i = 0; i < ncopy; ++i) {
     int8Array.push_back(static_cast<int>(value[i]) >= 1 ? 1 : 0);
-    pVMMConfig.getHybrid(0).getVMM(0).setRegister("st",
+    pVMMConfig.getHybrid(pair.hyb).getVMM(pair.vmm).setRegister("st",
                                                   static_cast<int>(value[i]),
                                                   i);
   }
@@ -116,6 +134,25 @@ asynStatus VMMTbl::writeInt8Array(asynUser *pasynUser, epicsInt8 *value, size_t
 
 }
 
+Pair VMMTbl::findPair(int function, int array[HYBRIDS_PER_FEN][VMMS_PER_HYBRID]){
+
+  Pair ret;
+
+  for (int h = 0; h < number_hybrids; h++){
+    for (int v = 0; v < VMMS_PER_HYBRID; v++)
+    {
+      if (array[h][v] == function){
+        ret.hyb = h;
+        ret.vmm = v;
+        return ret;
+      }
+    }
+  }
+
+  return ret;
+
+}
+
 asynStatus VMMTbl::writeFloat64(asynUser *pasynUser, epicsFloat64 value) {
   asynStatus status = asynSuccess;
   int function = pasynUser->reason;
diff --git a/vmmTblApp/src/vmm_tbl.h b/vmmTblApp/src/vmm_tbl.h
index b9ee7bd1a559d4ae22ff63ca52534163bdc5172a..325337fad41dce7c7660d8eb7b396e1d36cd449c 100644
--- a/vmmTblApp/src/vmm_tbl.h
+++ b/vmmTblApp/src/vmm_tbl.h
@@ -5,6 +5,12 @@
 #include "vmm_tbl_regs_map.h"
 #include "vmm_config.h"
 
+/* Struct to hold Hyb, VMM pair values */
+struct Pair {
+  int hyb = -1;
+  int vmm = -1;
+};
+
 /** Class definition for the VMMTbl class */
 class VMMTbl : public FrontEndBase {
 public:
@@ -15,6 +21,7 @@ public:
   virtual asynStatus writeInt8Array(asynUser *pasynUser, epicsInt8 *value, size_t nElements);
   void setInitialEpicsParams();
   void configFE();
+  Pair findPair(int function, int array[HYBRIDS_PER_FEN][VMMS_PER_HYBRID]);
 
 protected:
   int vmmSelectMonitorVMM0_;
@@ -23,13 +30,15 @@ protected:
   int vmmMonitorValueVMM0_;
   int vmmMonitorValueVMM1_;
   int vmmAcquire_;
-  int vmmST;
   int vmmHybFwVersion_[HYBRIDS_PER_FEN];
   int vmmHybId_[HYBRIDS_PER_FEN];
   int vmmHybGeoPos_[HYBRIDS_PER_FEN];
   int vmmHybLinkStatus_[HYBRIDS_PER_FEN];
+  //Registers channels per hybrid, per VMM
+  int vmmST_[HYBRIDS_PER_FEN][VMMS_PER_HYBRID];
 
 private:
+  static constexpr const char *driverName = "VMMTbl";
   FENConfigModule pVMMConfig;
   RMM *pRMM;
   int addr_list = 0;