Index: fact/BIASctrl/BIASctrl.cc
===================================================================
--- fact/BIASctrl/BIASctrl.cc	(revision 10068)
+++ fact/BIASctrl/BIASctrl.cc	(revision 10070)
@@ -17,4 +17,5 @@
 
 #define LOCKFILE "/tmp/CTX_HV_LOCK"
+const char READLINE_HIST_FILE[] = "/tmp/.history.BIASctrl";
 
 //
@@ -51,4 +52,5 @@
   char str[MAX_COM_SIZE], *Command;
   int Lock;
+  std::string LastHist;
 
   // Assure only one instance runs
@@ -72,6 +74,6 @@
  
   // Install signal handler and set signal SIGUSR1 to interrupt blocking system calls
-  //signal(SIGUSR1, &DummyHandler);
-  //siginterrupt (SIGUSR1, true);
+  signal(SIGUSR1, &DummyHandler);
+  siginterrupt (SIGUSR1, true);
 
   // Assure lock file is deleted in case of a program crash or call to exit()
@@ -92,4 +94,7 @@
   signal(SIGTERM, &CrashHandler);
 
+  // Load history buffer
+  read_history(READLINE_HIST_FILE);
+
   // Handle command-line input
   while (!M.ExitRequest) {        
@@ -98,5 +103,10 @@
 	// NULL returned if interrupted by signal
     if (Command == NULL) continue;
-    if (strlen(Command) > 0) add_history(Command);
+
+	// Add command to history
+    if(strlen(Command) > 0 && LastHist != Command) {
+	  add_history(Command);
+	  LastHist = Command;
+	}
 
     // Process command (via DIM gives automatic thread serialisation)
@@ -104,3 +114,7 @@
     free(Command);
   }
+  
+  // Save history buffer  
+  int Ret = write_history(READLINE_HIST_FILE);
+  if (Ret != 0 ) printf("Error writing history file to '%s' (%s)\n", READLINE_HIST_FILE, strerror(Ret));
 }
Index: fact/BIASctrl/Crate.cc
===================================================================
--- fact/BIASctrl/Crate.cc	(revision 10068)
+++ fact/BIASctrl/Crate.cc	(revision 10070)
@@ -32,4 +32,5 @@
 	  Present[i][j] = false;
 	  Current[i][j] = 0;
+	  CurrentOffset[i][j] = 0;
 	}
   }
@@ -45,4 +46,6 @@
   NameService = new DimService ((SERVER_NAME"/NAME/ID"+ID.str()).c_str(), Name);
   BiasVolt = new DimService ((char *) (SERVER_NAME"/VOLT/ID"+ID.str()).c_str(), (char *) "D", Volt, MAX_NUM_BOARDS*NUM_CHANNELS*sizeof(double));
+  BiasDAC = new DimService ((char *) (SERVER_NAME"/DAC/ID"+ID.str()).c_str(), (char *) "I", DAC, MAX_NUM_BOARDS*NUM_CHANNELS*sizeof(int));
+  BiasCurrent = new DimService ((char *) (SERVER_NAME"/MICROAMP/ID"+ID.str()).c_str(), (char *) "F", Current, MAX_NUM_BOARDS*NUM_CHANNELS*sizeof(float));
 
   ClearVoltageArrays();
@@ -97,4 +100,6 @@
   delete NameService;
   delete BiasVolt;
+  delete BiasDAC;
+  delete BiasCurrent;
   delete[] Name;
 }
@@ -104,5 +109,5 @@
 //
 // Returns: 0 error, 1 success, -1 time-out exceeded
-vector<char> Crate::Communicate(string Buf) {
+vector<unsigned char> Crate::Communicate(string Buf) {
 
   int N;
@@ -110,5 +115,5 @@
   struct timeval WaitTime = {(long) m->fTimeOut, (long) ((m->fTimeOut-(long) m->fTimeOut)*1e6)};
   char Buffer[10000];
-  vector<char> Data;
+  vector<unsigned char> Data;
   
   // === Lock device ===
@@ -133,5 +138,4 @@
 	// Time-out expired?
 	if (!FD_ISSET(fDescriptor, &SelectDescriptor)) {
-  	  Data.push_back(-1);
 	  goto ExitCommunicate;
 	}
@@ -177,5 +181,5 @@
 int Crate::SystemReset() {
   
-  vector<char> Data = Communicate(string(3, 0));
+  vector<unsigned char> Data = Communicate(string(3, 0));
 
   if (Data.size() == 3) {
@@ -183,5 +187,5 @@
 	return 1;
   }
-  return Data[0];
+  return 0;
 }
 
@@ -201,12 +205,12 @@
   
   // Execute command
-  vector<char> Data = Communicate(Buf);
+  vector<unsigned char> Data = Communicate(Buf);
     
-  if (Data.size() != Buf.size()) return Data[0];
+  if (Data.size() != Buf.size()) return 0;
 
   // Evaluate data returned from crate
   int Count = 0;
   for (int i=0; i<MAX_NUM_BOARDS; i++) for (int j=0; j<NUM_CHANNELS; j++) {
-	Current[i][j] = Data[Count+1] + (Data[Count]&15)*256;
+	Current[i][j] = (Data[Count+1] + (Data[Count] & 0x0f)*256) * 1.22;
 	OC[i][j] = Data[Count] & 128;
 	Present[i][j] = Data[Count+2] & 0x70 ? false : true;
@@ -220,30 +224,27 @@
 
 // ***** Global set *****
-int Crate::GlobalSet(unsigned int SetPoint) {
-
-  // Check limit
-  if (SetPoint > 0x0FFF) {
-    m->PrintMessage("Error: Voltage DAC value above 0x0FFF\n"); 
-    return 0;
-  }
-
+int Crate::GlobalSet(double Voltage) {
+
+  unsigned int SetPoint = (unsigned int) (Voltage/90.0*0x0fff);
+  
   // Execute command
   string Buf;
   Buf = (((Buf + char(1<<6)) + char(SetPoint>>8)) + char(SetPoint));
-  vector<char> Data = Communicate(Buf);
+  vector<unsigned char> Data = Communicate(Buf);
 
   if (Data.size() == 3) {
 	for (int i=0; i<MAX_NUM_BOARDS; i++) for (int j=0; j<NUM_CHANNELS; j++) {
 	  DAC[i][j] = SetPoint;
-	  Volt[i][j] = (double) SetPoint / 0xfff * 90;
+	  Volt[i][j] = Voltage;
+	  RefVolt[i][j] = Voltage;
 	}
 	return 1;
   }
-  return Data[0];
+  return 0;
 }
 
 
 // ***** Set channel voltages *****
-int Crate::SetChannels(map<unsigned int, unsigned int> V) {
+int Crate::SetChannels(map<unsigned int, double> V) {
   
   string Buf;
@@ -252,20 +253,25 @@
 
   // Build and execute commands
-  for (map<unsigned int, unsigned int>::const_iterator it = V.begin(); it != V.end(); ++it) {
+  for (map<unsigned int, double>::const_iterator it = V.begin(); it != V.end(); ++it) {
+    // If DAC value unchanged, do not send command
+	if (DAC[it->first/NUM_CHANNELS][it->first%NUM_CHANNELS] == it->second/90.0*0x0fff) continue;
+
+	// Add command to buffer
 	Buf += char(3<<5) |  char(it->first/NUM_CHANNELS<<1 & 0x0f) | char((it->first%NUM_CHANNELS&16)>>4 & 1);
-	Buf += char(it->first%NUM_CHANNELS<<4) | ((it->second>>8) & 0x0f);
-	Buf += char(it->second);
-  }
-  vector<char> Data = Communicate(Buf);
+	Buf += char(it->first%NUM_CHANNELS<<4) | ((((unsigned int) (it->second/90.0*0x0fff))>>8) & 0x0f);
+	Buf += char(it->second/90.0*0x0fff);
+  }
+  vector<unsigned char> Data = Communicate(Buf);
 
   // Store new voltage values of successful
   if (Data.size() == Buf.size()) {
-	for (map<unsigned int, unsigned int>::const_iterator it = V.begin(); it != V.end(); ++it) {
-	  DAC[it->first/NUM_CHANNELS][it->first%NUM_CHANNELS] = it->second;
-	  Volt[it->first/NUM_CHANNELS][it->first%NUM_CHANNELS] = 90.0*it->second/0x0fff;
+	for (map<unsigned int, double>::const_iterator it = V.begin(); it != V.end(); ++it) {
+	  DAC[it->first/NUM_CHANNELS][it->first%NUM_CHANNELS] = (unsigned int) (it->second/90.0*0x0fff);
+	  Volt[it->first/NUM_CHANNELS][it->first%NUM_CHANNELS] = it->second;
+	  RefVolt[it->first/NUM_CHANNELS][it->first%NUM_CHANNELS] = it->second;
 	}
 	return 1;
   }
-  return Data[0];  
+  return 0;  
 }
 
@@ -275,10 +281,9 @@
   
   int Trial = 0;
-  vector<char> Data;
+  vector<unsigned char> Data;
 
   while(++Trial <= 3) {
     Data = Communicate(string(1, 0));
     if (Data.size() == 3) return true;
-    if (Data[0] == 0) break;
   }
   return false;
@@ -306,11 +311,71 @@
 void Crate::ClearVoltageArrays() {
 
-  for (int i=0; i<MAX_NUM_BOARDS; i++) {
-    for (int j=0; j<NUM_CHANNELS; j++){
-      DAC[i][j] = 0;
-      Volt[i][j] = 0.0;      
-    }
-  }
-  // Update DIM services
+  for (int i=0; i<MAX_NUM_BOARDS; i++) for (int j=0; j<NUM_CHANNELS; j++) {
+	DAC[i][j] = 0;
+	Volt[i][j] = 0;  
+	RefVolt[i][j] = 0;  
+  }
+
+  UpdateDIM();
+}
+
+
+// ***** Return calibrated voltage of given channel *****
+double Crate::GetVoltage(unsigned int Channel) {
+
+  if (Channel >= MAX_NUM_BOARDS*NUM_CHANNELS) return 0;
+  else return Volt[Channel/NUM_CHANNELS][Channel%NUM_CHANNELS]; 
+}
+
+
+// ***** Return DAC value of given channel *****
+unsigned int Crate::GetDAC(unsigned int Channel) {
+
+  if (Channel >= MAX_NUM_BOARDS*NUM_CHANNELS) return 0;
+  else return DAC[Channel/NUM_CHANNELS][Channel%NUM_CHANNELS]; 
+}
+
+
+// ***** Return current of given channel *****
+float Crate::GetCurrent(unsigned int Channel) {
+
+  if (Channel >= MAX_NUM_BOARDS*NUM_CHANNELS) return 0;
+  else return Current[Channel/NUM_CHANNELS][Channel%NUM_CHANNELS]-CurrentOffset[Channel/NUM_CHANNELS][Channel%NUM_CHANNELS]; 
+}
+
+
+// ***** Update DIM services *****
+void Crate::UpdateDIM() {
+
   BiasVolt->updateService();
-}
+  BiasDAC->updateService();
+}
+
+
+// ***** Set reference current for dynamic mode *****
+void Crate::SetRefCurrent() {
+
+  for (int i=0; i<MAX_NUM_BOARDS; i++) for (int j=0; j<NUM_CHANNELS; j++) {
+	RefCurrent[i][j] = Current[i][j];  
+  }
+}
+
+
+// ***** Correct voltages according to current *****
+void Crate::AdaptVoltages() {
+
+  static int LastUpdate = 0;
+   
+  map<unsigned int, double> Voltages;
+
+  for (int i=0; i<MAX_NUM_BOARDS; i++) for (int j=0; j<NUM_CHANNELS; j++) {
+    if (RefVolt[i][j] == 0) continue;
+	Voltages[i*NUM_CHANNELS+j] = RefVolt[i][j] + (RefCurrent[i][j]-Current[i][j])*RESISTOR/1e6;  
+  }  
+  SetChannels(Voltages);
+  
+  if (time(NULL)-LastUpdate > 5) {
+    LastUpdate = time(NULL);
+	UpdateDIM();
+  }
+}
Index: fact/BIASctrl/Crate.h
===================================================================
--- fact/BIASctrl/Crate.h	(revision 10068)
+++ fact/BIASctrl/Crate.h	(revision 10070)
@@ -17,4 +17,5 @@
 #define NUM_CHANNELS 32		// Channels per bias board
 #define BAUDRATE B115200
+const float RESISTOR = 1000;		// Resistance in Ohm for voltage correction
 
 class User;
@@ -27,6 +28,14 @@
 	FILE *File;
 	DimService *NameService;
+	DimService *BiasVolt;
+	DimService *BiasDAC;
+	DimService *BiasCurrent;
 
-	std::vector<char> Communicate(std::string);
+	int DAC[MAX_NUM_BOARDS][NUM_CHANNELS];		// Voltage in DAC units
+	double Volt[MAX_NUM_BOARDS][NUM_CHANNELS];	// Voltage in Volt
+	float Current[MAX_NUM_BOARDS][NUM_CHANNELS];
+	float CurrentOffset[MAX_NUM_BOARDS][NUM_CHANNELS]; // Offset for current measurement
+
+	std::vector<unsigned char> Communicate(std::string);
 	void ClearVoltageArrays();
    
@@ -36,7 +45,5 @@
 
     char *Name;
-	DimService *BiasVolt;
 
-	int Current[MAX_NUM_BOARDS][NUM_CHANNELS];
 	bool OC[MAX_NUM_BOARDS][NUM_CHANNELS];
 	bool Present[MAX_NUM_BOARDS][NUM_CHANNELS];
@@ -46,16 +53,21 @@
 	int ErrorCount;
 
-	unsigned int DAC[MAX_NUM_BOARDS][NUM_CHANNELS];      // Voltage in DAC units
-	double Volt[MAX_NUM_BOARDS][NUM_CHANNELS];  // Voltage in Volt
-	int CurrentOffset[MAX_NUM_BOARDS][NUM_CHANNELS]; // Offset for current measurement
+	float RefCurrent[MAX_NUM_BOARDS][NUM_CHANNELS];
+	double RefVolt[MAX_NUM_BOARDS][NUM_CHANNELS];
 
 	bool InitOK;
 
-	int SetChannels(std::map<unsigned int, unsigned int>);
+	int SetChannels(std::map<unsigned int, double>);
 	int ReadAll();
 	int SystemReset();
-	int GlobalSet(unsigned int);
+	int GlobalSet(double);
 	bool Synch();
 	bool CurrentCalib(double);
+	double GetVoltage(unsigned int);
+	unsigned int GetDAC(unsigned int);
+	float GetCurrent(unsigned int);
+	void UpdateDIM();
+	void SetRefCurrent();
+	void AdaptVoltages();
 };
 
Index: fact/BIASctrl/History.txt
===================================================================
--- fact/BIASctrl/History.txt	(revision 10068)
+++ fact/BIASctrl/History.txt	(revision 10070)
@@ -4,2 +4,3 @@
 17/11/2010	Added possibility for bulk transfers (ReadAll(), SetChannels())
 24/11/2010	Ramping for many channels possible with bulk transfers
+7/12/2010	Added dynamic mode.
Index: fact/BIASctrl/User.cc
===================================================================
--- fact/BIASctrl/User.cc	(revision 10068)
+++ fact/BIASctrl/User.cc	(revision 10070)
@@ -20,4 +20,5 @@
 	{"status", &User::cmd_status, 0, "[dac|current]", "Show status information (DAC values if requested)"},
 	{"ccal", &User::cmd_ccal, 1, "<volt>", "Calibrate current measurement at given voltage"},
+	{"mode", &User::cmd_mode, 1, "<static|dynamic>", "Set voltage stabilization mode"},
 	{"load", &User::cmd_load, 1, "<file>", "Load and set bias settings from file"},
 	{"save", &User::cmd_save, 1, "<file>", "Save current bias settings to file"},
@@ -43,5 +44,5 @@
   fTimeOut = atof(GetConfig("TimeOut").c_str());
   fStatusRefreshRate = atof(GetConfig("StatusRefreshRate").c_str());
-  fMaxDiff = atoi(GetConfig("HVMaxDiff").c_str());
+  fMaxDiff = atof(GetConfig("HVMaxDiffNew").c_str());
 
   if (fStatusRefreshRate < MIN_RATE || fStatusRefreshRate > MAX_RATE)  fStatusRefreshRate = 1;
@@ -158,8 +159,8 @@
 void User::cmd_hv() {
 
-  unsigned int DACValue, Errors=0, B, C;
+  unsigned int Errors=0;
   double Double;
   struct Range Crt, Chan;
-  vector< map<unsigned int, unsigned int> > Voltages (Crates.size());
+  vector< map<unsigned int, double> > Voltages (Crates.size());
 
   // Loop over all parameters
@@ -178,4 +179,6 @@
 	  Chan.Max = MAX_NUM_BOARDS*NUM_CHANNELS-1;
 	  
+	  if (Parameter[n] == "-") continue;
+
 	  if (T.size() == 2) {
 		if(!ConvertToRange(T[0], Crt) || !ConvertToRange(T[1], Chan)) {
@@ -201,16 +204,10 @@
 	// Loop over given crates and channels
 	for (int i=Crt.Min; i<=Crt.Max; i++) for (int j=Chan.Min; j<=Chan.Max; j++) {
-	  // Board and channel number
-	  B = j / NUM_CHANNELS;
-	  C = j % NUM_CHANNELS;
-
 	  // Voltage change (number starts with + oder -) ignored if current DAC value is zero
-	  if (isdigit(Parameter[n+1][0])==0 && Crates[i]->DAC[B][C] == 0) continue;
+	  if (isdigit(Parameter[n+1][0])==0 && Crates[i]->GetDAC(j) == 0) continue;
 
 	  // Relative or absolute change?
-	  if (isdigit(Parameter[n+1][0]) == 0) DACValue = Crates[i]->DAC[B][C] + (unsigned int) (Double/90*0x0fff);
-	  else DACValue = (unsigned int) (Double/90*0x0fff);
-
-	  Voltages[i][j] = DACValue;
+	  if (isdigit(Parameter[n+1][0]) == 0) Voltages[i][j] = Crates[i]->GetVoltage(j) + Double;
+	  else Voltages[i][j] = Double;
 	} // Channels
   } // Loop over command argument
@@ -219,5 +216,5 @@
   for (unsigned int i=0; i<Voltages.size(); i++) {
 	Errors += RampVoltages(i, Voltages[i]);
-    Crates[i]->BiasVolt->updateService();
+    Crates[i]->UpdateDIM();
   }
 
@@ -231,8 +228,9 @@
 
   char Buffer[MAX_COM_SIZE];
-  int Errors = 0, Board, Channel;
-  unsigned int DACValue, NBoards = 0;
+  int Errors = 0, Channel;
+  unsigned int NBoards = 0;
+  double Value;
   FILE *File;
-  map<unsigned int, unsigned int> Voltages;
+  map<unsigned int, double> Voltages;
 
   // Open file
@@ -249,22 +247,7 @@
 
 	  Voltages.clear();
-	  Board = 0;  Channel = 0;
-	  while (fscanf(File, "%u", &DACValue)==1 && Board<MAX_NUM_BOARDS) {
-		Voltages[Board*NUM_CHANNELS+Channel] = DACValue;
-
-	    // Ramp channel to new voltage
-    	/*if (!RampVoltage(DACValue, Crate, Board, Channel)) {
-	      Errors++;
-	      PrintMessage("Error: Could not ramp board %d, channel %d\n", Board, Channel);
-    	}
-		else {
-	      PrintMessage("Ramped board %d, channel %d to %u (%.2f V)                         \r",
-	    	 Board, Channel, DACValue, (double) DACValue/0x0fff*90);
-		}*/
-
-		if(++Channel == NUM_CHANNELS) {
-	      Board++;
-	      Channel = 0;
-		}
+	  Channel = 0;
+	  while (fscanf(File, "%lf", &Value)==1 && Channel<MAX_NUM_BOARDS*NUM_CHANNELS) {
+		Voltages[Channel++] = Value;
 	  }
 
@@ -273,5 +256,5 @@
 
       // Update DIM service
-	  Crates[Crate]->BiasVolt->updateService();
+	  Crates[Crate]->UpdateDIM();
 
 	  if (ferror(File) != 0) {
@@ -342,5 +325,5 @@
   if (!ConvertToDouble(Parameter[1], &Voltage)) return;
 
-  if (Crates[0]->GlobalSet((int) (Voltage/90*0xfff)) != 1) {
+  if (Crates[0]->GlobalSet(Voltage) != 1) {
     PrintMessage("Error: Could not global set board %d\n", 0);
   }    
@@ -386,7 +369,5 @@
     fprintf(File, "%s\n\n", Crates[i]->Name);
 
-    for (int j=0; j<MAX_NUM_BOARDS; j++) {
-	  for (int k=0; k<NUM_CHANNELS; k++) fprintf(File,"%5d ",Crates[i]->DAC[j][k]);
-    }
+    for (int j=0; j<MAX_NUM_BOARDS*NUM_CHANNELS; j++) fprintf(File,"%.3f ",Crates[i]->GetVoltage(j));
     fprintf(File, "\n");
   }
@@ -396,4 +377,18 @@
   }
 }
+
+//
+// Set operation mode
+//
+void User::cmd_mode() {
+
+  if (Match(Parameter[1], "static")) Mode = mode_static;
+  else {
+    Mode = mode_dynamic;
+	for (unsigned int i=0; i<Crates.size(); i++) {
+	  Crates[i]->SetRefCurrent();
+	}
+  }
+} 
 
 //
@@ -419,7 +414,7 @@
 	  if (j%12 == 0) PrintMessage("\n%3.1d:  ", j);
 	  if (!Crates[i]->Present[j/NUM_CHANNELS][j%NUM_CHANNELS]) PrintMessage("  -   ");
-      else if (Parameter.size() == 1) PrintMessage("%#5.2f ",Crates[i]->Volt[j/NUM_CHANNELS][j%NUM_CHANNELS]);
-	  else if (Match(Parameter[1], "dac")) PrintMessage("%5d ", Crates[i]->DAC[j/NUM_CHANNELS][j%NUM_CHANNELS]);
-	  else PrintMessage("%#5.2f %s ", (Crates[i]->Current[j/NUM_CHANNELS][j%NUM_CHANNELS]-Crates[i]->CurrentOffset[j/NUM_CHANNELS][j%NUM_CHANNELS])*1.2, Crates[i]->OC[j/NUM_CHANNELS][j%NUM_CHANNELS] ? "OC":"");
+      else if (Parameter.size() == 1) PrintMessage("%#5.2f ",Crates[i]->GetVoltage(j));
+	  else if (Match(Parameter[1], "dac")) PrintMessage("%5d ", Crates[i]->GetDAC(j));
+	  else PrintMessage("%#5.2f %s ", Crates[i]->GetCurrent(j), Crates[i]->OC[j/NUM_CHANNELS][j%NUM_CHANNELS] ? "OC":"");
     }
 	PrintMessage("\n");
@@ -449,6 +444,5 @@
 
   ExitRequest = true;
-  //pthread_kill(Thread, SIGUSR1); 
-  //pthread_cancel(Thread); 
+  pthread_kill(Thread, SIGUSR1);  // Make tjread return from usleep()
 }
   
@@ -484,21 +478,22 @@
 // Ramp to new voltage with maximum step size given in fMaxDiff
 // No ramping when decreasing voltage
-unsigned int User::RampVoltages(int Crate, map<unsigned int, unsigned int> Voltages) {
-
-  map<unsigned int, unsigned int> Target;
+unsigned int User::RampVoltages(int Crate, map<unsigned int, double> Voltages) {
+
+  map<unsigned int, double> Target;
   unsigned int Errors = 0;
 
   // Ramp until all channels at desired value
   while (!Voltages.empty()) {
-    // Remove channels already at target
-	for (map<unsigned int, unsigned int>::iterator it = Voltages.begin(); it != Voltages.end(); ++it) {
-	  if (Crates[Crate]->DAC[it->first/NUM_CHANNELS][it->first%NUM_CHANNELS] == it->second) Voltages.erase(it);
+    // Remove channels already at target (check for DAC, not for floating-point voltage)
+	for (map<unsigned int, double>::iterator it = Voltages.begin(); it != Voltages.end(); ++it) {
+	  //if (Crates[Crate]->GetDAC(it->first) == (unsigned int ) (it->second/90.0*0x0fff)) Voltages.erase(it);
+	  if (fabs(Crates[Crate]->GetVoltage(it->first)-it->second) < 0.001) Voltages.erase(it);
 	}
 	
 	// Limit voltage changes to fMaxDiff
 	Target = Voltages;
-	for (map<unsigned int, unsigned int>::iterator it = Target.begin(); it != Target.end(); ++it) {
-	  if (Crates[Crate]->DAC[it->first/NUM_CHANNELS][it->first%NUM_CHANNELS] + fMaxDiff/2 < it->second) {
-		it->second = Crates[Crate]->DAC[it->first/NUM_CHANNELS][it->first%NUM_CHANNELS] + fMaxDiff/2;
+	for (map<unsigned int, double>::iterator it = Target.begin(); it != Target.end(); ++it) {
+	  if (Crates[Crate]->GetVoltage(it->first) + fMaxDiff < it->second) {
+		it->second = Crates[Crate]->GetVoltage(it->first) + fMaxDiff;
 	  }
 	}	
@@ -545,5 +540,5 @@
       }
 
-	  map<unsigned int, unsigned int> Voltages;
+	  map<unsigned int, double> Voltages;
 	  
       for (int j=0; j<MAX_NUM_BOARDS*NUM_CHANNELS; j++) {
@@ -551,5 +546,4 @@
 		  Message(WARN, "Overcurrent on crate %d, board %d, channel %d, setting voltage to zero", i, j/NUM_CHANNELS, j%NUM_CHANNELS);
 		  Voltages[j] = 0;
-		  //Crates[i]->ChannelSet(j/NUM_CHANNELS, j%NUM_CHANNELS, 0);
     	}
       }
@@ -558,4 +552,6 @@
 		Crates[i]->SystemReset();
 	  }
+	  
+	  if (Mode == mode_dynamic) Crates[i]->AdaptVoltages();
 	} // for
 
Index: fact/BIASctrl/User.h
===================================================================
--- fact/BIASctrl/User.h	(revision 10068)
+++ fact/BIASctrl/User.h	(revision 10070)
@@ -24,4 +24,6 @@
 class User: public EvidenceServer {
 
+	enum RunMode {mode_static, mode_dynamic};
+
 	PixelMap *pm;
 	DimCommand *DIMCommand;
@@ -30,4 +32,5 @@
 	pthread_t Thread;
 	std::vector<std::string> Parameter;
+	RunMode Mode;
 
 	std::vector<class Crate *> Crates;
@@ -48,5 +51,5 @@
 	double fTimeOut;
 	float fStatusRefreshRate;
-	unsigned int fMaxDiff;
+	double fMaxDiff;
 
 	User();
@@ -54,5 +57,5 @@
 
 	void PrintMessage(const char *, ...);
-	unsigned int RampVoltages(int, std::map<unsigned int, unsigned int>);
+	unsigned int RampVoltages(int, std::map<unsigned int, double>);
 	void Monitor();
 	static void LaunchMonitor(User *);
@@ -64,4 +67,5 @@
 	void cmd_timeout();	void cmd_reset();
 	void cmd_help();	void cmd_ccal();
+	void cmd_mode();
 };
 
