Index: hvcontrol/src/CCCommand.cc
===================================================================
--- hvcontrol/src/CCCommand.cc	(revision 80)
+++ 	(revision )
@@ -1,125 +1,0 @@
-
-/********************************************************************\
-
-  Name:         CCCommand.cc
-
-  Created by:   Oliver Grimm, Sebastian Commichau, January 2009
-                oliver.grimm@phys.ethz.ch, commichau@phys.ethz.ch
-
-  Actions:      Listen to commands from Central Control (CC)
-
-\********************************************************************/
-
-#include "CCCommand.h"
-
-
-void CCCommand(ProcessIO *m) {
-
-  siginterrupt(SIGUSR1, true);
-
-  int ServerSocket,ConnectionSocket,ReadResult;
-  struct sockaddr_in SocketAddress, ClientAddress;
-  socklen_t SizeClientAddress=sizeof(ClientAddress);
-  char comline[MAX_COM_SIZE], str[MAX_COM_SIZE];
-  
-  // Set up server socket
-  if ((ServerSocket = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
-    sprintf(str,"error: could not open server socket, no remote connection possible");
-    m->PrintMessage(str);
-    return;
-  }
-
-// Allows immediate reuse of socket after closing (circumvents TIME_WAIT)
-  int Value=1;
-  if (setsockopt(ServerSocket, SOL_SOCKET, SO_REUSEADDR, (char *) &Value, sizeof (Value)) == -1) {
-    sprintf(str,"Warning: Could not set server socket option SO_REUSEADDR (%s).\n",strerror(errno));
-    m->PrintMessage(str);
-  }
-
-  SocketAddress.sin_family = PF_INET;
-  SocketAddress.sin_port = htons((unsigned short) m->config->fCCPort);
-  SocketAddress.sin_addr.s_addr = INADDR_ANY;
-
-  if (bind(ServerSocket, (struct sockaddr *) &SocketAddress, sizeof(SocketAddress)) == -1) {
-    sprintf(str,"error: could not bind port to socket");
-    m->PrintMessage(str);
-    close(ServerSocket);
-    return;
-  }
-  if (listen(ServerSocket, 0) == -1) {
-    sprintf(str,"error: could not set socket to listening");
-    m->PrintMessage(str);
-    close(ServerSocket);
-    return;
-  }
-  
-  while (!m->status->Exit) { // Looping to wait for incoming connection
-
-    if ((ConnectionSocket = accept(ServerSocket, (struct sockaddr *) &ClientAddress, &SizeClientAddress)) == -1) {
-      if (errno!=EINTR) {
-	sprintf(str,"error: failed to accept incoming connection");
-	m->PrintMessage(str);
-      }
-      close(ServerSocket);
-      return;
-    }
-
-    pthread_mutex_lock(&m->control_mutex);
-    m->status->Socket = ConnectionSocket;
-    m->status->cc_state = connected;
-    sprintf(str,"connected to client (%s)",inet_ntoa(ClientAddress.sin_addr));
-    m->PrintMessage(str);
-    pthread_mutex_unlock(&m->control_mutex);
-
-    while (!m->status->Exit) {  // Looping as long as client exists
-      bzero(comline,sizeof(comline));
-      ReadResult = read(ConnectionSocket, comline, MAX_COM_SIZE);
-      if (ReadResult==0) break; // Client does not exist anymore
-      if (ReadResult==-1) {
-	if (errno!=EINTR) {
-	  sprintf(str,"error: socket read failed");
-	  m->PrintMessage(str);
-	}
-	break;
-      }
-            
-      m->status->Pc = comline;      
-                 
-      ParseInput(m->status->Pc,&(m->status->NParam),m->status->Param);
-      
-      if (!(Match(m->status->Param[0], "exit") || Match(m->status->Param[0], "quit"))) {
-	
-	sprintf(str,"CC> %s",m->status->Pc);
-	m->log->LogWrite(str);
-	
-	sprintf(str,"%s",m->status->Pc);
-	printf(str);
-
-	pthread_mutex_lock(&m->control_mutex);
-	// Process CC command
-	if (m->CommandControl()==0)
-	  pthread_cond_broadcast(&m->control_cond);
-	pthread_mutex_unlock(&m->control_mutex);
-	
-      }
-      else
-	printf("remote exit|quit forbidden\n");
-           
-      m->PrintMessage(NULL);
-            
-    }
-
-    if (!(m->status->Exit)) {
-      sprintf(str,"disconnected from client (%s)",inet_ntoa(ClientAddress.sin_addr));
-      m->PrintMessage(str);
-    }
-    m->status->Socket = -1;
-    pthread_mutex_lock(&m->control_mutex);
-    m->status->cc_state = disconnected;
-    pthread_mutex_unlock(&m->control_mutex);
-    close(ConnectionSocket);
-
-  } 
-  close(ServerSocket);
-    
-}
Index: hvcontrol/src/CCCommand.h
===================================================================
--- hvcontrol/src/CCCommand.h	(revision 80)
+++ 	(revision )
@@ -1,17 +1,0 @@
-#ifndef CCCommand_H_SEEN
-#define CCCommand_H_SEEN
-
-#include <stdio.h>
-#include <unistd.h>
-#include <signal.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#include <arpa/inet.h>
-
-#include "ProcessIO.h"
-#include "Types.h"
-#include "Utilities.h"
-
-void CCCommand(ProcessIO *m);
-
-#endif
Index: hvcontrol/src/ConsoleCommand.cc
===================================================================
--- hvcontrol/src/ConsoleCommand.cc	(revision 80)
+++ 	(revision )
@@ -1,60 +1,0 @@
-
-/********************************************************************\
-
-  Name:         ConsoleCommand.cc
-
-  Created by:   Sebastian Commichau, March 2008
-                commichau@phys.ethz.ch
-
-  Actions:      Handle console input
-
-\********************************************************************/
- 
-
-#include "ConsoleCommand.h"
-
-
-void ConsoleCommand(ProcessIO *m) {
-
-  siginterrupt(SIGUSR1, true);
-
-  char comline[MAX_COM_SIZE];
-
-  char str[MAX_COM_SIZE];
-  char *c;
-
-  do {
-        
-    fprintf(stdout,m->status->Prompt);
-    c = fgets(comline, MAX_COM_SIZE, stdin);
-
-    m->status->Pc = comline;
-    //      sprintf(str,"Test in ConsoleCommand: %s",m->status->Pc);
-    //  printf(str);
-    /*
-    if (strlen(m->status->Pc) < 2 )  // Ignore commands with only '\n'
-      continue;
-    m->status->Pc[strlen(m->status->Pc)-1]='\0';  // Remove '\n'
-    */
-    //if(m->status->Pc[0]=='.') {   // Shell command
-    //  system(&(m->status->Pc[1]));
-    //  continue;
-    //}
-
-    
-    sprintf(str,"USER> %s",m->status->Pc);
-    m->log->LogWrite(str);
-
-    ParseInput(m->status->Pc,&(m->status->NParam),m->status->Param);
-     
-    pthread_mutex_lock(&m->control_mutex);
-
-    if (m->CommandControl()==0) 
-      pthread_cond_broadcast(&m->control_cond);
-
-    pthread_mutex_unlock(&m->control_mutex);      
-      
-  } while ((c != NULL) && (!m->status->Exit));
-
-}
-
Index: hvcontrol/src/ConsoleCommand.h
===================================================================
--- hvcontrol/src/ConsoleCommand.h	(revision 80)
+++ 	(revision )
@@ -1,14 +1,0 @@
-#ifndef CONSOLECOMMAND_H_SEEN
-#define CONSOLECOMMAND_H_SEEN
-
-#include <string.h>
-#include <stdio.h>
-#include <unistd.h> 
-#include <pthread.h>
-
-#include "ProcessIO.h"
-#include "Utilities.h"
-
-void ConsoleCommand(ProcessIO *m);
-
-#endif
Index: hvcontrol/src/HV.cc
===================================================================
--- hvcontrol/src/HV.cc	(revision 80)
+++ hvcontrol/src/HV.cc	(revision 90)
@@ -8,368 +8,157 @@
 
   Contents:     Main class for HV supply
-
-  Requirements: Both libftdi and libusb are required for the 
-                communication - see manual for more details.
-
-                libftdi: library for talking with FTDI USB <-> Serial 
-                converter, UM245R.
-                http://www.intra2net.com/de/produkte/opensource/ftdi/
-                
-                libusb: library for talking to USB devices from 
-                user-space. Also needed by libftdi. 
-                http://libusb.wiki.sourceforge.net/
                 
 \********************************************************************/
 
-
 #include "HV.h"
 
 
-HV::HV(char** usbdevice, int* usbdevicenumber, FILE* f,bool TestMode): fNumberOfBoards(0) {
-  
-  fTestMode = TestMode;
-
-  int i = 0, j = 0, ret = 0;
-
-  char manufacturer[STR_LENGTH], type[STR_LENGTH], serial[STR_LENGTH];
-
-  bzero(manufacturer, sizeof(manufacturer));
-  bzero(type, sizeof(type));
-  bzero(serial, sizeof(serial));
-
-  fprintf(stdout,"Scan: ");
-
-  // Search for FTDI devices
-  for (i = 0;i<MAX_NUM_HVBOARDS;i++)
-    ftdi_init(&ftdic[i]);
-
-  ftdi_init(&ftdic_dummy);
-
-  if ((i = ftdi_usb_find_all(&ftdic_dummy, &devlist, USB_VENDOR, USB_PRODUCT)) < 0)
-    fprintf(stderr,"error: ftdi_usb_find_all failed: %d (%s)\n", i, ftdi_get_error_string(&ftdic_dummy));
-    
-  fprintf(stdout,"found %d FTDI device(s)\n", i);
-  i = 0;
- 
-  if(fTestMode){
-    fprintf(stdout,"Test mode: One HVBoard initialized as dummy.\n");
-    fHVBoard[fNumberOfBoards] = new HVBoard("dummy", 0, &ftdic[fNumberOfBoards],fTestMode);
-    fNumberOfBoards++;
-    return;
-  }
-  // Obtain information on FTDI devices
-  for (curdev = devlist; (curdev != NULL && i<MAX_NUM_HVBOARDS); i++) {
-    
-    fprintf(stdout,"Device %d:\n", i);
-    
-    if ((ret = ftdi_usb_get_strings(&ftdic_dummy, curdev->dev, manufacturer, STR_LENGTH, type, STR_LENGTH, serial, STR_LENGTH)) < 0) {
-      fprintf(stderr," Error: ftdi_usb_get_strings failed: %d (%s)\n", ret, ftdi_get_error_string(&ftdic_dummy));
-      break;
-    }
-
-    fprintf(stdout," Manufacturer: %s - Type: %s - Serial: %s\n", manufacturer, type, serial);
-
-    // Fixme: the following code should be revised!
-    while (j<MAX_NUM_HVBOARDS) {
-      if (strcmp(serial,usbdevice[j])==0)
-	break;
-      j++;
-    }
-
-    if (j<MAX_NUM_HVBOARDS) {
-      ret = ftdi_usb_open_desc(&ftdic[fNumberOfBoards], USB_VENDOR, USB_PRODUCT, type, serial);
-      
-      // Fixme: this function does not work properly if there is more than one device???!!!
-      // ret = ftdi_usb_open(&ftdic[fNumberOfBoards], USB_VENDOR, USB_PRODUCT);
-      
-      if (ret < 0 && ret != -5)
-	fprintf(stderr," Error: unable to open FTDI device: %d (%s)\n", i, ftdi_get_error_string(&ftdic[fNumberOfBoards]));
-      else {
-	
-	ftdi_set_baudrate(&ftdic[fNumberOfBoards], USB_BAUDRATE);
-	ftdi_usb_reset(&ftdic[fNumberOfBoards]);
-	ftdi_usb_purge_buffers(&ftdic[fNumberOfBoards]);
-	/*
-	  The FTDI chip keeps data in the internal buffer for a specific
-	  amount of time if the buffer is not full yet to decrease load on the usb bus.
-	*/
-	ftdi_set_latency_timer(&ftdic[fNumberOfBoards], USB_LATENCY_TIMER);
-	
-	fHVBoard[fNumberOfBoards] = new HVBoard(serial, usbdevicenumber[j], &ftdic[fNumberOfBoards],fTestMode);
-	fNumberOfBoards++;
-	/*
-	  fprintf(stdout," FTDI open succeeded\n");
-	  fprintf(stdout," Baudrate: %d\n", ftdic[i].baudrate);
-	  fprintf(stdout," USB_read_timeout: %d\n", ftdic[i].usb_read_timeout);
-	  fprintf(stdout," USB_write_timeout: %d\n", ftdic[i].usb_write_timeout);
-	*/
-      }
-      
-    }
-    else
-      fprintf(stdout," Warning: found new USB device - check configuration file!\n");
-
-    j=0;    
-
-    curdev = curdev->next;
-  }
-
-  // Re-order board numbering otherwise it is determined by the connection sequence
-  ArrangeHVBoards(fHVBoard,fNumberOfBoards);
-
-}
-
-
-// Bubble-sort HV boards according to board number 
-void HV::ArrangeHVBoards(HVBoard** fHVBoard, int size) {
-
-  if(fTestMode){
-    return;
-  }
-
-  HVBoard* tmp;
-
-  for (int i=size-1;i>0;--i)
-    for (int pos=0;pos<i;++pos)            
-      if (fHVBoard[pos]->GetBoardNumber()>fHVBoard[pos+1]->GetBoardNumber()) {
-	tmp             = fHVBoard[pos];
-	fHVBoard[pos]   = fHVBoard[pos+1];
-	fHVBoard[pos+1] = tmp;
-      }
-  
-}
-
-
-HV::~HV() {
-
-  if(fTestMode){
-    fprintf(stdout,"Test mode: No FTDI device has to be closed.\n");
-    return;
-  }
- 
-  int i, ret = 0;
-  
-  for (i=0;i<fNumberOfBoards;i++) {
-    fprintf(stdout,"Device %d: ",i);
-    
-    ret = ftdi_usb_close(&ftdic[i]);
-
-    if (ret < 0)
-      fprintf(stderr, "Unable to close FTDI device: %d (%s)\n", i, ftdi_get_error_string(&ftdic[i]));
-    else 
-      fprintf(stdout, "FTDI close succeeded\n");
-
-    delete fHVBoard[i];
-  }
-  
-  fprintf(stdout,"FTDI list free\n");
-  ftdi_list_free(&devlist);
-
-  for (i=0;i<MAX_NUM_HVBOARDS;i++)
-    ftdi_deinit(&ftdic[i]);
-
-  ftdi_deinit(&ftdic_dummy);
-
-}
-
-
-HVBoard::HVBoard(char* serial, int number, struct ftdi_context* ftdic,bool TestMode) : fTimeOut(.5) 
-{
+// Constructor
+HVBoard::HVBoard(int DeviceNumber, char *DeviceName, bool TestMode, float TimeOut, bool verbose) {
+   
+  char Buffer[BUFFER_LENGTH];
+  struct termios tio;
  
   fTestMode = TestMode;
   fTestModeWrap = 0;
-  FTDI_C = ftdic;
-  sprintf(Serial,"%s",serial);
-  BoardNumber = number;
-     
-}
-
-
+
+  SetTimeOut(TimeOut);
+  BoardNumber = DeviceNumber;
+  BoardName = DeviceName;
+  
+  for (int i=0; i<NUM_CHAINS; i++) Overcurrent[i] = false;
+  ResetButton = false;
+  WrapOK = true;
+  LastWrapCount = -1;
+  
+  if (fTestMode) {
+    fDescriptor = 99;
+    return;
+  }
+
+  ClearVoltageArrays();
+
+  // Open device (do not warn on non-existing device)
+  snprintf(Buffer, BUFFER_LENGTH, "/dev/%s",DeviceName);
+  if ((fDescriptor = open(Buffer, O_RDWR|O_NOCTTY|O_NDELAY)) == -1) {
+    if(errno != 2) printf("Error: Could not open device %d/%s (%s)\n", DeviceNumber,DeviceName, strerror(errno));
+    return;
+  }
+
+  // Get current serial port settings
+  if (tcgetattr(fDescriptor, &tio) == -1) {
+    printf("tcgetattr(...) failed (%d/%s)\n", errno, strerror(errno));
+    return;   
+  }
+
+  // Set baudrate and raw mode
+  if (cfsetspeed(&tio, BAUDRATE) == -1) printf("Error: Could not set baud rate (%s)\n", strerror(errno));
+  cfmakeraw(&tio);
+  if (tcsetattr(fDescriptor, TCSANOW, &tio ) == -1) printf("Errsor with tcsetattr(...) (%s)\n", strerror(errno));
+
+  //  Synchronize HV board (if fails, closes device and sets fDescriptor to -2) 
+  unsigned char wbuf = REG_STATUS;
+  int trial = 0, ret;
+  
+  while(++trial<=3) {
+    if((ret = Communicate(stdout, &wbuf, 1, verbose)) == 1) {
+      Reset(stdout, verbose);
+      return;
+    }
+    if (ret==0) break;
+    wbuf = 0;
+  }
+  close(fDescriptor);
+  fDescriptor = -2;
+  return;
+}
+
+// Destructor (Resetting board)
 HVBoard::~HVBoard() {
- 
-}
-
-
-/* For test purposes only - never use this function with a real HV board!!! */
-void HVBoard::TestIO() {
-
-  int ret = 0, werrors = 0, rerrors = 0, mismatches = 0;
-
-  unsigned char wbuf[BUFFER_LENGTH], rbuf[BUFFER_LENGTH];
-
-  for (int i=0;i<=0XFF;i++) {
-    
-    wbuf[0] = (unsigned char)i;
-
-#ifdef DO_CAST
-    ret = ftdi_write_data(FTDI_C,(char*)wbuf,1);
-#endif
-    ret = ftdi_write_data(FTDI_C,wbuf,1);
-
-    if (ret < 0)
-      werrors++;
-    
-#ifdef DO_CAST
-    ret = ftdi_read_data(FTDI_C,(char*)rbuf,1);
-#endif    
-    ret = ftdi_write_data(FTDI_C,wbuf,1);   
-
-    if (ret < 0)
-      rerrors++;
-    
-    if (rbuf[0]!=wbuf[0]) {
-      mismatches++;
-      fprintf(stdout,"Mismatch - written: 0X%.2X read: 0X%.2X\n",wbuf[0],rbuf[0]);
-    }
-  }
-  fprintf(stdout, "Result: %d write errors, %d read errors, %d mismatches\n",werrors,rerrors,mismatches);
-}
-
-
-int HVBoard::Write(unsigned char* data, int size) {
-  if (fTestMode)
-    return 3;  // implying that 3 bytes are written
-
-#ifdef DO_CAST
-  return ftdi_write_data(FTDI_C, (char*)data, size);
-#endif
-  return ftdi_write_data(FTDI_C, data, size);
-}
-
-
-int HVBoard::Read(unsigned char* data, int size) {
-  if (fTestMode) {
-    data[0] = fTestModeWrap;
-    //    fprintf(stdout," Read Data 0X%.2X\n",data[0]);
-    fTestModeWrap++;
-    fTestModeWrap = fTestModeWrap%8;
-    return 1;  // one byte read
-  }
-#ifdef DO_CAST
-  return ftdi_read_data(FTDI_C, (char*)data, size);
-#endif
-  return ftdi_read_data(FTDI_C, data, size);
-}
-
-
-/*
- TRead: read from HV Board until fTimeOut has been reached 
-
- Returns:
-     0 if a read error has occured
-     1 on success
-    -1 if fTimeOut [s] has been exceeded
-*/
-int HVBoard::TRead(FILE* fptr, unsigned char* rbuf, bool verbose) {
-
-  if (fTestMode) {
-    Read(rbuf,BUFFER_LENGTH);
-    return 1;  // rbuf read
-  }
-
-  char str[STR_LENGTH];
-
-  long int t1, t2;
-  int ret = 0;
-
-  t1 = GetMicroSeconds();
-  
-  do {
-    
-    if ((ret = Read(rbuf,BUFFER_LENGTH)) < 1) {
-      if (verbose) 
-	if (ret < 0) {
-	  fprintf(stderr, " Read error: %d (%s)\n", ret, ftdi_get_error_string(FTDI_C));
-	  return 0;
-	}
-    }
-    else {
-
-      if (verbose)
-	fprintf(fptr," %d byte(s) read:\n",ret);
-      
-      for (int i=0;i<ret;i++) {
-	sPrintByteBin(rbuf[i],str);
-	if (verbose)
-	  fprintf(fptr," Byte %d: %s| 0X%.2X\n",i,str,rbuf[i]);
-      }
-      return 1;
-    }
-
-    t2 = GetMicroSeconds();
-
-    if ((t2-t1)/1000000. >= fTimeOut) {
-      fprintf(fptr," Warning: timeout exceeded\n");
-      return -1;
-    }
-
-  } while(1);
-  
+  if(fDescriptor >= 0 && !fTestMode) {
+    Reset(stdout, false);
+    close(fDescriptor);
+  }
+}
+
+
+// Communicate: Write and read from HV Board until fTimeOut has been reached 
+//
+// Returns: 0 read error, 1 success, -1 fTimeOut exceeded
+int HVBoard::Communicate(FILE* fptr, unsigned char* wbuf, int Bytes, bool verbose) {
+
+  unsigned char rbuf;
+  int ret;
+  fd_set SelectDescriptor;
+  
+  // === Write data ===
+  if (write(fDescriptor, wbuf, Bytes) < Bytes) {
+    fprintf(fptr," Error: could not write (all) data to HV board\n");
+    return 0;
+  }
+  if (verbose) {
+    fprintf(fptr,"%d bytes written:\n", Bytes);
+    for (int i=0; i<Bytes; i++) fprintf(fptr," Byte %d: %#.2x\n",i,wbuf[i]);
+  }
+
+  // === Try to read until time-out ===
+  FD_ZERO(&SelectDescriptor);   FD_SET(fDescriptor, &SelectDescriptor);
+  struct timeval WaitTime = {(long) fTimeOut, (long) ((fTimeOut-(long) fTimeOut)*1e6)};
+  if (select(fDescriptor+1, &SelectDescriptor, NULL, NULL, &WaitTime)==-1) {
+    printf("Error with select() (%d/%s)\n", errno,strerror(errno));
+    return 0;
+  }
+  // Time-out expired?
+  if (!FD_ISSET(fDescriptor, &SelectDescriptor)) {
+    if (verbose) printf("Time-out of %.2f seconds expired while reading\n", fTimeOut);
+    return -1;
+  }
+  // Read error?    
+  if ((ret = read(fDescriptor, &rbuf, 1)) == -1) {
+    fprintf(stderr, " Read error (%s)\n", strerror(errno));
+    return 0;
+  }
+
+  // === Update status information ===
+  if (LastWrapCount != -1) {
+    if ((LastWrapCount+1)%8 == (rbuf & 0X07)) WrapOK = true;
+    else WrapOK = false;
+  }
+  LastWrapCount = rbuf & 0X07;  
+  for (int i=0; i<NUM_CHAINS; i++) Overcurrent[i]=(rbuf & (0X08 << i));
+  ResetButton = (bool) (rbuf & 0X80);
+
+  if (verbose && ret==1) fprintf(fptr," 1 byte read: %#.2x\n", rbuf);  
+  
+  return 1;
 }
 
 
 /* Reset HV board - uses TRead() and has same return values */
-int HVBoard::Reset(FILE* fptr, unsigned char* rbuf, bool verbose) {
-
-  if (fTestMode)
-    return 1; 
-
-  char str[STR_LENGTH];
+int HVBoard::Reset(FILE* fptr, bool verbose) {
+  
+  if (fTestMode) return 1; 
 
   unsigned char wbuf[] = {REG_RESET,0,0};
-  
-  if (Write(wbuf,3) < 1) {
-    fprintf(fptr," Error: could not write to HV board\n");
-    return 0;
-  }
-  
-  if (verbose)
-    fprintf(fptr," 3 bytes written:\n");
-  
-  for (int i=0;i<3;i++) {
-    sPrintByteBin(wbuf[i],str);
-    if (verbose)
-      fprintf(fptr," Byte %d: %s| 0X%.2X\n",i,str,wbuf[i]);
-  }
-
-  return TRead(fptr,rbuf,verbose);
-
+  int ret;
+  
+  if((ret = Communicate(fptr, wbuf, 3, verbose)) == 1) ClearVoltageArrays();  
+  return ret;
 }
 
 
 /* Read status register - uses TRead() and has same return values */
-int HVBoard::GetStatus(FILE* fptr, unsigned char* rbuf, bool verbose) {
-  if (fTestMode){
-    //    printf("Test mode. (Get Status) \n");
-    return TRead(fptr,rbuf,verbose);
-    return 1;
-  }
-
-  char str[STR_LENGTH];
+int HVBoard::GetStatus(FILE* fptr, bool verbose) {
+
+  if (fTestMode) return 1;
 
   unsigned char wbuf[] = {REG_STATUS,0,0};
   
-  if (Write(wbuf,3) < 1) {
-    if (verbose)
-      fprintf(fptr," Error: could not write to HV board\n");
-    return 0;
-  }
-
-  if (verbose)
-    fprintf(fptr," 3 bytes written:\n");
-  
-  for (int i=0;i<3;i++) {
-    sPrintByteBin(wbuf[i],str);
-    if (verbose)
-      fprintf(fptr," Byte %d: %s| 0X%.2X\n",i,str,wbuf[i]);
-  }
-  
-  return TRead(fptr,rbuf,verbose);
-
+  return Communicate(fptr, wbuf, 3, verbose);
 }
 
 
 /* Set high voltage - uses TRead() and has same return values */
-int HVBoard::SetHV(FILE* fptr, int chain, unsigned int channel, unsigned int hv, unsigned char* rbuf, bool verbose) {
+int HVBoard::SetHV(FILE* fptr, int chain, unsigned int channel, unsigned int hv, bool verbose) {
 
   if (fTestMode){
@@ -377,25 +166,19 @@
     return 1;
   }
-
-  
-  char str[STR_LENGTH];
-
+  
   unsigned char wbuf[] = {0,0,0};
 
-  if (!(hv>=0.0 && hv<=0X3FFF)) {
+  if (!(hv>=0 && hv<=0x3FFF)) {
     fprintf(fptr," Error: HV beyond limits [0 - 0x3FFF]\n"); 
     return 0;
   }
   
-
   switch (chain) {
-    
-  case 0: wbuf[0] = REG_HV0; break;
-  case 1: wbuf[0] = REG_HV1; break;
-  case 2: wbuf[0] = REG_HV2; break;
-  case 3: wbuf[0] = REG_HV3; break;
-
-  default : fprintf(fptr," Error: chain %d does not exist\n",chain); return 0;
-
+    case 0: wbuf[0] = REG_HV0; break;
+    case 1: wbuf[0] = REG_HV1; break;
+    case 2: wbuf[0] = REG_HV2; break;
+    case 3: wbuf[0] = REG_HV3; break;
+
+    default : fprintf(fptr," Error: chain %d does not exist\n",chain); return 0;
   }
  
@@ -406,336 +189,24 @@
   wbuf[2] |= (unsigned char)(hv & 0X000000FF);              // Add [D7-D0]
    
-
-  if (Write(wbuf,3) < 1) {
-    fprintf(fptr," Error: could not write to HV board\n");
-    return 0;
-  }
-
-  if (verbose)
-    fprintf(fptr," 3 bytes written:\n");
-
-  for (int i=0;i<3;i++) {
-    sPrintByteBin(wbuf[i],str);
-    if (verbose)
-      fprintf(fptr," Byte %d: %s| 0X%.2X\n",i,str,wbuf[i]);
-  }
-
-  return TRead(fptr,rbuf,verbose);
-  
-}
-
-
-/* Set reference voltage - uses TRead() and has same return values */
-int HVBoard::SetVRef(FILE* fptr, int chain, unsigned int vref, unsigned char* rbuf, bool verbose) {
-
-    if (fTestMode){
-    printf("Test mode. Nothing to be done.\n");
-    return 1;
-  }
-
-  char str[STR_LENGTH];
-
-  unsigned char wbuf[] = {0,0,0};
-  
-  if (!(vref>=0 && vref<=0X3FFF)) {
-    if (verbose)
-      fprintf(fptr," Error: vref beyond limits\n"); 
-    return 0;
-  }
-
-  switch (chain) {
-
-  case 0: wbuf[0] = REG_VREF0; break;
-  case 1: wbuf[0] = REG_VREF1; break;
-  case 2: wbuf[0] = REG_VREF2; break;
-  case 3: wbuf[0] = REG_VREF3; break;
-
-  default : fprintf(fptr," Error: chain %d does not exist\n",chain); return 0;
-
-  }
- 
-  // Assemble bytes
-  wbuf[0] |= (unsigned char)((vref >> 13) & 0X0000000F); // Add [D13]
-  wbuf[1] |= (unsigned char)((vref >> 5)  & 0X000000FF); // Add [D12-D5]
-  wbuf[2] |= (unsigned char)((vref << 3)  & 0X000000FF); // Add [D4-D0]
-   
-  // PD bits (device clear) are not used
-  wbuf[0] &= ~REG_PD1; 
-  wbuf[0] &= ~REG_PD2;
-
-  if (Write(wbuf,3) < 1) {
-    fprintf(fptr," Error: could not write to HV board\n");
-    return 0;
-  }
-
-  if (verbose)
-    fprintf(fptr," 3 bytes written:\n");
-
-  for (int i=0;i<3;i++) {
-    sPrintByteBin(wbuf[i],str);
-    if (verbose)
-      fprintf(fptr," Byte %d: %s| 0X%.2X\n",i,str,wbuf[i]);
-  }
-
-  return TRead(fptr,rbuf,verbose);
-  
-}
-
-
-/* 
- Init: initialize (synchronize) HV board - to be used before any other access! 
-
- Returns 0 if an error has occured, 1 on success.
-
- Before any other access the HV board communication has to be synchronized.
- Each write access requires three bytes to be sent from the computer to the
- HV board. The HV board sends back one byte containing status information.
-
- The normal initialization procedure would be the following:
-
- 1.   send one byte (0X80 = REG_STATUS).
- 1.1. try reading as long as fTimeOut is not exceeded.
-
- 2.   send again one byte (0X00).
- 2.1. try reading as long as fTimeOut is not exceeded.
-
- 3.   send again one byte (0X00).
- 3.1. try reading again as long as fTimeOut is not exceeded.
- 
- Note: from time to time there are problems when performing only 3 trials! Reason:
- the first byte written by libftdi can get lost somewhere between 
- libusb <-> kernel <-> FTDI chip. I haven't found yet any solution to this.
- To solve the issue, another byte is sent to assure a proper synchronization,
- even though the first byte was lost:
-
- 4.   send again one byte (0X00).
- 4.1. try reading again as long as fTimeOut is not exceeded; if fTimeOut
-      has been exceeded return.
-
- See also: http://lists.omnipotent.net/pipermail/lcdproc/2008-June/012235.html
-*/
-int HVBoard::Init(bool verbose) {
-
-
-  unsigned char wbuf = REG_STATUS;
-  unsigned char rbuf[STR_LENGTH];
-  
-  int trial = 1;
-  int ret = 0;
-
-  long int t1, t2;
-
-
-  // First send 0X80
-  if (Write(&wbuf,1) < 1) {
-    if (verbose)
-      fprintf(stdout," Error: could not write to HV board\n");
-    return 0;
-  }
-  else
-    if (verbose)
-      fprintf(stdout," 1 byte written: 0X%.2X\n",wbuf);
-  
-
-  t1 = GetMicroSeconds();
-
-
-  // Read - first trial
-  do {
-
-    t2 = GetMicroSeconds();
-    
-    if ((ret = Read(rbuf,BUFFER_LENGTH)) < 1) {
-      if (verbose) 
-	if (ret < 0) {
-	  fprintf(stderr, " Read error: %d (%s)\n",ret,ftdi_get_error_string(FTDI_C));
-	  return 0;
-	}
+  return Communicate(fptr, wbuf, 3, verbose);
+}
+
+
+// Set all voltages of board to zero
+void HVBoard::ClearVoltageArrays() {
+
+  for (int j=0; j<NUM_CHAINS; j++) {
+    for (int k=0; k<NUM_CHANNELS; k++){
+      HV[j][k] = 0;
+      HVV[j][k] = 0.0;
     }
-    else {
-      if (verbose)
-	fprintf(stdout," %d byte(s) read:",ret);
-      for (int i=0;i<ret;i++)
-	if (verbose)
-	  fprintf(stdout," 0X%.2X",rbuf[i]);
-      if (verbose)
-	fprintf(stdout,"\n");
-      fprintf(stdout," Success: initialization done (%d trial)\n",trial);
-      return 1;
-    }
-    
-    if ((t2-t1)/1000000. > fTimeOut) {
-      if (verbose)
-	fprintf(stdout," Warning: timeout exceeded\n");
-      trial++;
-      
-      // Second write
-      wbuf = 0;
-      if (Write(&wbuf,1) < 1) {
-	if (verbose)
-	  fprintf(stdout," Error: could not write to HV board\n");
-	return 0;
-      }
-      else
-	if (verbose)
-	  fprintf(stdout," 1 byte written: 0X%.2X\n",wbuf);
-      
-      t1 = GetMicroSeconds();
-      
-      // Read - second trial
-      do {
-
-	t2 = GetMicroSeconds();
-    
-	if ((ret = Read(rbuf,BUFFER_LENGTH)) < 1) {
-	  if (verbose) 
-	    if (ret < 0) {
-	      fprintf(stderr, " Read error: %d (%s)\n",ret,ftdi_get_error_string(FTDI_C));
-	      return 0;
-	    }
-	}
-	else {
-	  if (verbose)
-	    fprintf(stdout," %d byte(s) read:",ret);
-	  for (int i=0;i<ret;i++)
-	    if (verbose)
-	      fprintf(stdout," 0X%.2X",rbuf[i]);
-	  if (verbose)
-	    fprintf(stdout,"\n");
-	  fprintf(stdout," Success: initialization done (%d trials)\n",trial);
-	  return 1;
-	}
-
-	if ((t2-t1)/1000000. > fTimeOut) {
-	  if (verbose)
-	    fprintf(stdout," Warning: timeout exceeded\n");
-	  trial++;
-	  
-	  // Third write
-	  wbuf = 0;
-	  if (Write(&wbuf,1) < 1) {
-	    if (verbose)
-	      fprintf(stdout," Error: could not write to HV board\n");
-	    return 0;
-	  }
-	  else
-	    if (verbose)
-	      fprintf(stdout," 1 byte written: 0X%.2X\n",wbuf);
-
-
-	  // Read - third trial
-	  do {
-	    
-	    t2 = GetMicroSeconds();
-	    
-	    if ((ret = Read(rbuf,BUFFER_LENGTH)) < 1) {
-	      if (verbose) 
-		if (ret < 0) {
-		  fprintf(stderr, " Read error: %d (%s)\n",ret,ftdi_get_error_string(FTDI_C));
-		  return 0;
-		}
-	    }
-	    else {
-	      if (verbose)
-		fprintf(stdout," %d byte(s) read:",ret);
-	      for (int i=0;i<ret;i++)
-		if (verbose)
-		  fprintf(stdout," 0X%.2X",rbuf[i]);
-	      if (verbose)
-		fprintf(stdout,"\n");
-	      fprintf(stdout," Success: initialization done (%d trials)\n",trial);
-	      return 1;
-	    }
-	    
-	    
-	    if ((t2-t1)/1000000. > fTimeOut) {
-	      if (verbose)
-		fprintf(stdout," Warning: timeout exceeded\n");
-	      trial++;
-	      
-	      // Fourth write
-	      wbuf = 0;
-	      if (Write(&wbuf,1) < 1) {
-		if (verbose)
-		  fprintf(stdout," Error: could not write to HV board\n");
-		return 0;
-	      }
-	      else
-		if (verbose)
-		  fprintf(stdout," 1 byte written: 0X%.2X\n",wbuf);
-	   
-	      
-	      // Read - fourth and last trial
-	      do {
-		
-		t2 = GetMicroSeconds();
-		
-		if ((ret = Read(rbuf,BUFFER_LENGTH)) < 1) {
-		  if (verbose) 
-		    if (ret < 0) {
-		      fprintf(stderr, " Read error: %d (%s)\n",ret,ftdi_get_error_string(FTDI_C));
-		      return 0;
-		    }
-		}
-		else {
-		  if (verbose)
-		    fprintf(stdout," %d byte(s) read:",ret);
-		  for (int i=0;i<ret;i++)
-		    if (verbose)
-		      fprintf(stdout," 0X%.2X",rbuf[i]);
-		  if (verbose)
-		    fprintf(stdout,"\n");
-		  fprintf(stdout," Success: initialization done (%d trials)\n",trial);
-		  return 1;
-		}
-				
-		if ((t2-t1)/1000000. > fTimeOut) {
-		  if (verbose)
-		    fprintf(stdout," Error: timeout exceeded - initialization failed (%d trials)\n",trial);
-		  return 0;
-		 
-		}
-		
-	      } while (1);
-	      	      
-	    }
-	   	    
-	  } while (1);
-
-	}
-
-      } while (1);
-            
-    }
-
-  } while (1);
-
-
-  return 0;
-}
-
-
-/* Decode wrap counter */
-int HVBoard::DecodeWrap(unsigned char* rbuf) {
-
-  return (*rbuf & 0X07);
-
-}
-
-
-/* Decode over current bits */
-void HVBoard::DecodeOC(bool OC[], unsigned char* rbuf) {
-
-  for (int i=0;i<MAX_NUM_CHAINS;i++)
-    OC[i]=(*rbuf & (0X08 << i));
-}
-
-
-/* Decode bit indicating manual reset */
-bool HVBoard::DecodeReset(unsigned char* rbuf) {
-
-  return (bool)(*rbuf & 0X80);
-
-}
-
-
+  }
+}
+
+
+// Set time-out to wait for read
+void HVBoard::SetTimeOut(double t) {
+
+  if (t >= MIN_TIMEOUT && t <= MAX_TIMEOUT) fTimeOut  = t;
+  else fTimeOut  = 1.0;
+}
Index: hvcontrol/src/HV.h
===================================================================
--- hvcontrol/src/HV.h	(revision 80)
+++ hvcontrol/src/HV.h	(revision 90)
@@ -2,37 +2,16 @@
 #define HV_H_SEEN
 
-#include "Types.h"
-#include "Utilities.h"
-
-#include <ftdi.h>
+#include <termios.h>		// POSIX terminal control definitions
+#include <fcntl.h>		// File control definitions => fcntl() in fcn OpenPort()
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
 #include <sys/ioctl.h>
 
+#include <HVConfig.h>
 
-#ifndef NULL
-#ifdef __cplusplus
-#define NULL 0
-#else
-#define NULL ((void *)0)
-#endif
-#endif 
-
-
-// Have a look at http://www.linux-usb.org/usb.ids
-// Vendor: Future Technology Devices International, Ltd (FTDI)
-#define USB_VENDOR  0X0403 
-// Product: FT232 USB-Serial (UART) IC (USB <-> Serial converter, UM245R)
-#define USB_PRODUCT 0X6001 
-
-
-#define USB_BAUDRATE 115000
-#define USB_LATENCY_TIMER 1
-
+#define BAUDRATE B115200
 
 // HV board control registers
-#define REG_VREF0   0X00
-#define REG_VREF1   0X08
-#define REG_VREF2   0X10
-#define REG_VREF3   0X18
-
 #define REG_HV0     0X20
 #define REG_HV1     0X28
@@ -42,8 +21,4 @@
 #define REG_RESET   0XF8
 #define REG_STATUS  0X80
-
-#define REG_PD1     0X04
-#define REG_PD2     0X02
-
 
 // HV board status bits
@@ -58,65 +33,31 @@
 class HVBoard {
   
- public:
-  
-  HVBoard(char* serial, int number, struct ftdi_context* ftdic, bool TestMode);
-  ~HVBoard();
-
-  bool fTestMode;
-
-  int Init(bool verbose);
-  int Reset(FILE* fptr, unsigned char* rbuf, bool verbose);
-  int GetStatus(FILE* fptr, unsigned char* rbuf, bool verbose);
-  int SetVRef(FILE* fptr, int chain, unsigned int vref, unsigned char* rbuf, bool verbose);
-  int SetHV(FILE* fptr, int chain, unsigned int channel, unsigned int hv, unsigned char* rbuf, bool verbose);
-  struct ftdi_context* GetFTDI_C() {return FTDI_C;}
-  char* GetSerial() {return Serial;}
-  int GetBoardNumber() {return BoardNumber;}
-  int Write(unsigned char* data, int size);
-  int Read(unsigned char* data, int size);
-  int TRead(FILE* fptr, unsigned char* rbuf, bool verbose);
-  void SetTimeOut(float t) {fTimeOut = t;}
-  float GetTimeOut() {return fTimeOut;}
-  void TestIO();       // Warning: NEVER use this function with a real HV board!!!
-  int DecodeWrap(unsigned char* rbuf);
-  void DecodeOC(bool OC[], unsigned char* rbuf);
-  bool DecodeReset(unsigned char* rbuf);
-
-  struct ftdi_context* FTDI_C;
-  char Serial[STR_LENGTH];
-  int  BoardNumber;
-  float fTimeOut;      // [s] timeout to return from read 
-  int fTestModeWrap;
-  
-};
-
-
-
-class HV {
+   int BoardNumber;
+   int fTestModeWrap;
+   bool fTestMode;
 
  public:
   
-  HV(char** usbdevice, int* usbdevicenumber, FILE* f,bool TestMode);
-  ~HV();
+   HVBoard(int, char *, bool, float, bool);
+   ~HVBoard();
 
-  int fNumberOfBoards;
-  int fMaxNumberOfBoards;
+   int fDescriptor; 
+   bool Overcurrent[NUM_CHAINS];
+   bool ResetButton;
+   bool WrapOK;
+   int LastWrapCount;
+   double fTimeOut;      // [s] timeout to return from read 
+  
+   char *BoardName; 
+   int HV[NUM_CHAINS][NUM_CHANNELS];      // HV value in DAC units
+   double HVV[NUM_CHAINS][NUM_CHANNELS];  // HV value in volts
 
-  bool fTestMode;
-
-  HVBoard* fHVBoard[MAX_NUM_HVBOARDS];
-  int GetNumberOfBoards() {return fNumberOfBoards;} 
-  void SetNumberOfBoards(int i) {fNumberOfBoards = i;}
-  HVBoard* GetHVBoard(int i) {return fHVBoard[i];}
-  
- protected:
-
-  // For FTDI USB <-> serial converter 
-  struct ftdi_context ftdic[MAX_NUM_HVBOARDS];
-  struct ftdi_context ftdic_dummy;
-  struct ftdi_device_list *devlist, *curdev;
-  
-  void ArrangeHVBoards(HVBoard** fHVBoard, int size);
- 
+   void ClearVoltageArrays();
+   int Reset(FILE*, bool);
+   int GetStatus(FILE*, bool);
+   int SetHV(FILE*, int, unsigned int, unsigned int, bool);
+   int GetBoardNumber() {return BoardNumber;}
+   int Communicate(FILE*, unsigned char*, int, bool);
+   void SetTimeOut(double);
 };
 
Index: hvcontrol/src/HVCalib.cc
===================================================================
--- hvcontrol/src/HVCalib.cc	(revision 80)
+++ hvcontrol/src/HVCalib.cc	(revision 90)
@@ -12,13 +12,12 @@
 
 
-#include "HVCalib.h"
 #include <stdio.h>
 #include <iostream>
 #include <fstream>
 #include <math.h>
+
+#include "HVCalib.h"
+
 using namespace std;
-
-
-
 
 
@@ -39,11 +38,11 @@
 
 
-  HVArray = new float***[hvConfig->NumHVBoards];
+  HVArray = new double***[hvConfig->NumHVBoards];
   for(int i=0; i<hvConfig->NumHVBoards; i++) {
-    HVArray[i] = new float**[NCHAIN];
-    for(int j=0; j<NCHAIN; j++) {
-      HVArray[i][j] = new float*[NCHANNEL];
-      for(int k=0; k<NCHANNEL; k++) {
-	HVArray[i][j][k] = new float[NDACValues];
+    HVArray[i] = new double**[NUM_CHAINS];
+    for(int j=0; j<NUM_CHAINS; j++) {
+      HVArray[i][j] = new double*[NUM_CHANNELS];
+      for(int k=0; k<NUM_CHANNELS; k++) {
+	HVArray[i][j][k] = new double[NDACValues];
       }
     }
@@ -52,8 +51,8 @@
   DACArray = new int***[hvConfig->NumHVBoards];
   for(int i=0; i<hvConfig->NumHVBoards; i++) {
-    DACArray[i] = new int**[NCHAIN];
-    for(int j=0; j<NCHAIN; j++) {
-      DACArray[i][j] = new int*[NCHANNEL];
-      for(int k=0; k<NCHANNEL; k++) {
+    DACArray[i] = new int**[NUM_CHAINS];
+    for(int j=0; j<NUM_CHAINS; j++) {
+      DACArray[i][j] = new int*[NUM_CHANNELS];
+      for(int k=0; k<NUM_CHANNELS; k++) {
 	DACArray[i][j][k] = new int[NHVValues];
       }
@@ -61,12 +60,7 @@
   }
 
-
-
   for(int i=0; i<hvConfig->NumHVBoards; i++){
-  //  for(int i=0; i<1; i++){
-    for(int j=0;j<NCHAIN;j++){
-      //for(int j=0;j<1;j++){
+    for(int j=0; j<NUM_CHAINS; j++){
       sprintf(calibfile,"Calib/%s_%c%d.txt",hvConfig->fUSBDevice[i],65+j,1); 
-      //      printf("Calibration tabel 0: %s\n", calibfile);
       ifstream fin(calibfile);
 
@@ -74,12 +68,12 @@
 	fin >> dac;
 	idacOld = 0;
-	if ((int)dac >= hvConfig->DACMin) {
+	if ((int) dac >= hvConfig->DACMin) {
 	  if (first){
-	    iDACMin = (int)dac;
+	    iDACMin = (int) dac;
 	    first = false;
 	  }
 	  idac = (int)dac - iDACMin;
 	  istep = idac - idacOld;
-	  for(int k=0;k<NCHANNEL;k++){
+	  for(int k=0; k<NUM_CHANNELS; k++){
 	    fin>>HVArray[i][j][k][idac];
 	    for (int l=1; l<istep;l++){
@@ -100,9 +94,6 @@
 
   for(int i=0; i<hvConfig->NumHVBoards; i++){
-    //  for(int i=0; i<1; i++){
-    for(int j=0;j<NCHAIN;j++){
-      //  for(int j=0;j<1;j++){
-      for(int k=0;k<NCHANNEL;k++){
-	//for(int k=0;k<1;k++){
+    for(int j=0;j<NUM_CHAINS;j++){
+      for(int k=0;k<NUM_CHANNELS;k++){
 	ihvOld = 0;
 	first = true;
@@ -117,12 +108,9 @@
 	    ihv1000 = (int)((hv1000>=0)?ceil(hv1000):floor(hv1000));
 	  }
-	  else {
-	    ihv1000 = (int)((hv1000<0)?ceil(hv1000):floor(hv1000));
-	  }
-	  if (ihv1000 <= ihvOld){
-	    continue;
-	  }
+	  else ihv1000 = (int)((hv1000<0)?ceil(hv1000):floor(hv1000));
+
+	  if (ihv1000 <= ihvOld) continue;
 	  else if (ihv1000 > ihvOld){
-	    for (int m=0; m<(ihv1000-ihvOld);m++){
+	    for (int m=0; m<(ihv1000-ihvOld); m++){
 	      DACArray[i][j][k][ihvOld+m] = l+iDACMin;
 	      //printf("HV = %d, HVArr = %f, DACArray = %d, m = %d. \n",ihvOld+m,HVArray[i][j][k][l],DACArray[i][j][k][ihvOld+m],m);
@@ -143,6 +131,6 @@
 
   for (int i=0; i<MAX_NUM_HVBOARDS; i++){
-    for (int j=0; j<NCHAIN;j++){
-      for (int k=0; k<NCHANNEL;k++){
+    for (int j=0; j<NUM_CHAINS;j++){
+      for (int k=0; k<NUM_CHANNELS;k++){
 	delete [] HVArray[i][j][k];
 	delete [] HVArray;
@@ -152,6 +140,6 @@
 
   for (int i=0; i<MAX_NUM_HVBOARDS; i++){
-    for (int j=0; j<NCHAIN;j++){
-      for (int k=0; k<NCHANNEL;k++){
+    for (int j=0; j<NUM_CHAINS;j++){
+      for (int k=0; k<NUM_CHANNELS;k++){
 	delete [] DACArray[i][j][k];
 	delete [] DACArray;
@@ -163,5 +151,5 @@
 /////////////////////////////////////////////////////////////////////////
 
-float HVCalib::DACToHV(int dac, int board, int chain, int channel) {
+double HVCalib::DACToHV(int dac, int board, int chain, int channel) {
   if (dac < iDACMin){
     return HVArray[board][chain][channel][0] + (dac - iDACMin)*fHVCalibSlope;
@@ -173,5 +161,5 @@
 /////////////////////////////////////////////////////////////////////////
 
-int HVCalib::HVToDAC(float hv, int board, int chain, int channel) {
+int HVCalib::HVToDAC(double hv, int board, int chain, int channel) {
   if (hv < HVArray[board][chain][channel][0]){
         return iDACMin + (int)((hv - HVArray[board][chain][channel][0])/fHVCalibSlope);
@@ -180,10 +168,10 @@
     int ihv = 0;
     double intpart;
-    float hv1000 = (hv-HVArray[board][chain][channel][0])*1000.;
+    double hv1000 = (hv-HVArray[board][chain][channel][0])*1000.;
     if (modf(hv1000,&intpart) >= 0.5){
-      ihv = (int)((hv1000>=0)?ceil(hv1000):floor(hv1000));
+      ihv = (int) (hv1000>=0 ? ceil(hv1000) : floor(hv1000));
     }
     else {
-      ihv = (int)((hv1000<0)?ceil(hv1000):floor(hv1000));
+      ihv = (int) (hv1000<0 ? ceil(hv1000) : floor(hv1000));
     }
     return DACArray[board][chain][channel][ihv];
Index: hvcontrol/src/HVCalib.h
===================================================================
--- hvcontrol/src/HVCalib.h	(revision 80)
+++ hvcontrol/src/HVCalib.h	(revision 90)
@@ -1,21 +1,16 @@
-
 #ifndef HVCALIB_H_SEEN
 #define HVCALIB_H_SEEN
 
+#include <string.h>
 
-#include <string.h>
-#include <HVConfig.h>
-#include "Types.h"
-
-#define NCHAIN 4
-#define NCHANNEL 32
+#include "HVConfig.h"
 
 
 class HVCalib {
 
-  // privat:
-  float ****HVArray;
+ private:
+ 
+  double ****HVArray;
   int ****DACArray;
-
   
   int NDACValues;
@@ -24,15 +19,12 @@
  public:
 
-
   HVCalib(HVConfig *hvConfig);
   ~HVCalib();
 
   int iDACMin;
-  float fHVCalibSlope;
+  double fHVCalibSlope;
 
-  int HVToDAC(float hv, int board, int chain, int channel);
-  float DACToHV(int dac, int board, int chain, int channel);
-
-
+  int HVToDAC(double hv, int board, int chain, int channel);
+  double DACToHV(int dac, int board, int chain, int channel);
 };
 
Index: hvcontrol/src/HVConfig.cc
===================================================================
--- hvcontrol/src/HVConfig.cc	(revision 80)
+++ hvcontrol/src/HVConfig.cc	(revision 90)
@@ -11,6 +11,4 @@
 \********************************************************************/
 
-
-#include "ReadCard.h"
 #include "HVConfig.h"
 
@@ -18,17 +16,16 @@
 HVConfig::HVConfig(FILE* fptr, char *configfile) {
 
-  fLogPath   = new char[FILENAME_MAX_SIZE];
+  fLogFile   = new char[BUFFER_LENGTH];
   fUSBDevice = new char*[MAX_NUM_HVBOARDS];
-  fCCClient  = new char[FILENAME_MAX_SIZE];
 
-  fPixMapTable = new char[FILENAME_MAX_SIZE];
+  fPixMapTable = new char[BUFFER_LENGTH];
     
   for (int i=0; i<MAX_NUM_HVBOARDS; i++) {
-    fUSBDevice[i]      = new char[FILENAME_MAX_SIZE];
+    fUSBDevice[i]      = new char[BUFFER_LENGTH];
     USBDeviceNumber[i] = 0;
 
-    for (int j=0; j<MAX_NUM_CHAINS; j++)
-      for (int k=0; k<2; k++)
-	Coef[i][j][k] = 0.;
+    for (int j=0; j<NUM_CHAINS; j++) {
+      for (int k=0; k<2; k++) Coef[i][j][k] = 0.;
+    }
   }
 
@@ -38,12 +35,9 @@
   fStatusRefreshRate = 1.;
   fTimeOut           = 1.;
-  IsDAC              = true;
   DACMin             = 11008;
   DACMax             = 12496;
-  HVMin              = 67.0;
-  HVMax              = 76.0;
   fHVCalibOffset      = -.8;
   fHVCalibSlope       = 0.0064;
-  fHVMaxDiff          = 1.0;  
+  fHVMaxDiff          = 1;  
 
   if (configfile != NULL) {
@@ -58,11 +52,7 @@
 HVConfig::~HVConfig() {
 
-  delete [] fLogPath;
-  delete [] fPixMapTable;
-
-  for (int i=0; i<MAX_NUM_HVBOARDS; i++)
-    delete [] fUSBDevice[i];
+  delete [] fLogFile;	delete [] fPixMapTable;
+  for (int i=0; i<MAX_NUM_HVBOARDS; i++) delete [] fUSBDevice[i];
   delete [] fUSBDevice;
-
 }
 
@@ -78,21 +68,15 @@
     return 0;
   }
-  else {
-    fprintf(fptr,"Opening configuration file: %s\n", configfile);
-  }
+  else fprintf(fptr,"Opening configuration file: %s\n", configfile);
  
-  ReadCard("LogPath",    fLogPath,    's',f);
+  ReadCard("LogFile",    fLogFile,    's',f);
+  ReadCard("PixMapTable",fPixMapTable,'s',f);
+  ReadCard("TestMode",   &str,        's',f);
+  if (!strcmp(str,"TRUE")) TestMode = true;
 
-  ReadCard("PixMapTable",fPixMapTable,'s',f);
-
-  ReadCard("TestMode",   &str,        's',f);
-  if (!strcmp(str,"TRUE"))
-    TestMode = true;
-
-
-  for (int i=0;i<MAX_NUM_HVBOARDS;i++) {
+  for (int i=0; i<MAX_NUM_HVBOARDS; i++) {
     sprintf(str,"Board%d",i);
 
-    if (ReadCard(str, dev, 's', f)==0) {
+    if (ReadCard(str, dev, 's', f)) {
       USBDeviceNumber[j] = i;
       sprintf(fUSBDevice[j++],"%s",dev);
@@ -104,17 +88,10 @@
   ReadCard("StatusRefreshRate", &fStatusRefreshRate, 'f', f);
   ReadCard("CCPort",            &fCCPort,            'I', f);
-  ReadCard("CCClient",           fCCClient,          's', f);
-  ReadCard("IsDAC",             &str,                's', f);
   ReadCard("DACMin",            &DACMin,             'I', f);
   ReadCard("DACMax",            &DACMax,             'I', f);
-  ReadCard("HVMin",             &HVMin,              'f', f);
-  ReadCard("HVMax",             &HVMax,              'f', f);
   ReadCard("HVCalibOffset",     &fHVCalibOffset,     'f', f);
   ReadCard("HVCalibSlope",      &fHVCalibSlope,      'f', f);
-  ReadCard("HVMaxDiff",         &fHVMaxDiff,         'f', f);
+  ReadCard("HVMaxDiff",         &fHVMaxDiff,         'U', f);
 
-  if (strcmp(str,"TRUE"))
-    IsDAC = false;
-  
   fclose(f);
   return 1;
@@ -124,12 +101,9 @@
 int HVConfig::PrintHVConfig(FILE *fptr) {
   
-  fprintf(fptr,"\n");                                   
-  fprintf(fptr,"********************************************* CONFIG ********************************************\n\n"); 
-  
-  fprintf(fptr," HV control configuration (%s):\n\n", FileName);
-  fprintf(fptr," Log path:          %s\n\n", fLogPath);
-  fprintf(fptr," Pixel map table:   %s\n\n", fPixMapTable);
-  fprintf(fptr," Test mode:         %s\n\n", TestMode ? "yes" : "no");
-  fprintf(fptr," %.2d USB devices:\n\n", NumHVBoards);
+  fprintf(fptr," \n HV control configuration (%s):\n\n", FileName);
+  fprintf(fptr," Log file:          %s\n", fLogFile);
+  fprintf(fptr," Pixel map table:   %s\n", fPixMapTable);
+  fprintf(fptr," Test mode:         %s\n", TestMode ? "yes" : "no");
+  fprintf(fptr," %d USB devices:\n", NumHVBoards);
   
   for (int i=0;i<NumHVBoards;i++) 
@@ -138,79 +112,56 @@
   fprintf(fptr,"\n");
   fprintf(fptr," TimeOut:           %.2f s\n",   fTimeOut);
-  fprintf(fptr," StatusRefreshRate: %.2f Hz\n\n",fStatusRefreshRate);
+  fprintf(fptr," StatusRefreshRate: %.2f Hz\n",fStatusRefreshRate);
   fprintf(fptr," CCPort:            %d\n",       fCCPort);
-  fprintf(fptr," CCClient:          %s\n\n",     fCCClient);
-  fprintf(fptr," Set DAC values:    %s\n\n",     IsDAC ? "yes" : "no");
-  fprintf(fptr," DACMin value:      %d\n\n",     DACMin);
-  fprintf(fptr," DACMax value:      %d\n\n",     DACMax);
-  fprintf(fptr," HVMin value:       %f\n\n",     HVMin);
-  fprintf(fptr," HVMax value:       %f\n\n",     HVMax);
-  fprintf(fptr," HVCalibOffset :    %f\n\n",     fHVCalibOffset);
-  fprintf(fptr," HVCalibSlope :     %f\n\n",     fHVCalibSlope);
-  fprintf(fptr," HVMaxDiff :        %f\n\n",     fHVMaxDiff);
+  fprintf(fptr," DACMin value:      %d\n",     DACMin);
+  fprintf(fptr," DACMax value:      %d\n",     DACMax);
+  fprintf(fptr," HVCalibOffset :    %f\n",     fHVCalibOffset);
+  fprintf(fptr," HVCalibSlope :     %f\n",     fHVCalibSlope);
+  fprintf(fptr," HVMaxDiff :        %u\n",     fHVMaxDiff);
  
-  fprintf(fptr,"*************************************************************************************************\n\n");
-
   return 1;
 }
 
+// ReadCard function (original version by F. Goebel)
+// Data is read into an array if MaxNum is larger than 1
+bool ReadCard(const char *card_flag, void *store, char Type, FILE *File, unsigned int MaxNum) {
+  
+  char *card_name, *card_val, Buffer[MAX_COM_SIZE];
+  unsigned int Count=0;
+  
+  rewind(File);
 
-int HVConfig::WriteHVConfig(FILE* fptr, char *configfile) {
+  while (fgets(Buffer, sizeof(Buffer), File) != NULL) {    // Read line by line
+    card_name = strtok(Buffer," \t\n");
+    
+     // Ignore empty lines, comments, and skip if card name does not match
+    if (card_name==NULL || card_name[0]=='#' || strcmp(card_name, card_flag)!=0) continue;
 
-  FILE *f;
-
-  time_t time_now_secs;
-  struct tm *time_now;
-
-  time(&time_now_secs);
-  time_now = localtime(&time_now_secs);
-
-  if ((f = fopen(configfile,"w")) == NULL) {
-    fprintf(fptr,"Could not open file: %s\n", configfile);
-    return 0;
+    // Read numbers of given type (if MaxNum>1 read array)
+    while ((card_val=strtok(NULL," \t\n")) != NULL && Count++<MaxNum) {
+      switch (Type) {
+	case 'I': *(((int *&) store)++) = (int) strtol(card_val, NULL, 10);
+	      	  break;
+	case 'i': *(((short *&) store)++) = (short) strtol(card_val, NULL, 10);
+	      	  break;
+	case 'U': *(((unsigned int *&) store)++) = (unsigned int) strtoul(card_val, NULL, 10);
+	      	  break;
+	case 'u': *(((unsigned short *&) store)++) = (unsigned short) strtoul(card_val, NULL, 10);
+	      	  break;
+	case 'f': *(((float *&) store)++) = atof(card_val);
+	      	  break;
+	case 'd': *(((double *&) store)++) = atof(card_val);
+	      	  break;
+	case 's': sprintf((char *) store, "%s", card_val);
+	      	  break;
+	case 'c': *((char *) store) = card_val[0];
+	      	  break;
+	default:  fprintf(stderr,"Warning: Unknown type '%c' for reading of configuration file\n", Type);
+	      	  return false;
+      }
+    }
+    return true;  // Finished reading data for card name  
   }
-  
-  fprintf(f,"# Main configuration file for the HV control program %s, %04d %02d %02d, %02d:%02d:%02d\n",
-	  HV_CONTROL_VERSION, 
-	  1900 + time_now->tm_year, 
-	  1 + time_now->tm_mon,
-	  time_now->tm_mday,
-	  time_now->tm_hour,
-	  time_now->tm_min,
-	  time_now->tm_sec);
-
-  fprintf(f,"# Note: this file will be updated at program exit\n\n");
-
-  fprintf(f,"LogPath            %s\n\n",   fLogPath);
-  fprintf(f,"PixMapTable        %s\n\n",   fPixMapTable);
-
-  fprintf(f,"TestMode           %s       #Test Mode: if no HV boards are connected, the test mode can be used.",((TestMode) ? "TRUE" : "FALSE"));
-
-  fprintf(f,"TimeOut            %.2f s   # Timeout to return from read (%.2f,...%.2f) s\n\n",fTimeOut,MIN_TIMEOUT,MAX_TIMEOUT);
-
-  fprintf(f,"StatusRefreshRate  %.2f Hz   # Status update rate (%.2f,...%.2f) Hz\n\n",fStatusRefreshRate,MIN_RATE,MAX_RATE);
-
-  fprintf(f,"CCPort             %d   # Port used to look for commands from the Central Control\n",fCCPort);
-  fprintf(f,"CCClient           %s   # Central Control client name\n\n",fCCClient);
-  fprintf(f,"IsDAC              %s   # Define here if user input is interpreted as DAC value or voltage\n\n",((IsDAC) ? "TRUE" : "FALSE"));
-  fprintf(f,"DACMin             %d   # Starting point for calibration of DAC to voltage values\n",DACMin);
-  fprintf(f,"DACMax             %d   # End point for calibration of DAC to voltage values\n",DACMax);
-  fprintf(f,"HVMin              %f   # Starting point for calibration of voltage to DAC values\n",HVMin);
-  fprintf(f,"HVMax              %f   # End point for calibration of voltage to DAC values\n",HVMax);
-  fprintf(f,"HVCalibOffset      %f   # Calibration of DAC to voltage values\n",fHVCalibOffset);
-  fprintf(f,"HVCalibSlope       %f   # Calibration of DAC to voltage values\n\n",fHVCalibSlope);
-  fprintf(f,"HVMaxDiff          %f   # Speed for HV changes limited to 1V/ms\n",fHVMaxDiff);
-
-  fprintf(f,"# List of HV boards (at most %d HV boards will be recognized):\n",MAX_NUM_HVBOARDS);
-
-  for (int i=0;i<NumHVBoards;i++) 
-    fprintf(f,"Board%d             %s\n",USBDeviceNumber[i],fUSBDevice[i]);
-  
-  fprintf(fptr,"Configuration file successfully updated\n");
-  
-  fclose(f);
-  return 1;
-
+  return false;
 }
 
-
Index: hvcontrol/src/HVConfig.h
===================================================================
--- hvcontrol/src/HVConfig.h	(revision 80)
+++ hvcontrol/src/HVConfig.h	(revision 90)
@@ -4,8 +4,20 @@
 
 #include <time.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
 
-#include <string.h>
+#define MAX_COM_SIZE 1000
+#define MAX_NUM_HVBOARDS 20
+#define NUM_CHAINS 4
+#define NUM_CHANNELS 32
+#define BUFFER_LENGTH 256
 
-#include "Types.h"
+#define MIN_TIMEOUT 0.01
+#define MAX_TIMEOUT 5.0
+
+#define MIN_RATE 0.01
+#define MAX_RATE 50.0
+
 
 class HVConfig {
@@ -18,5 +30,4 @@
   int ReadHVConfig(FILE* fptr, char *configfile);
   int PrintHVConfig(FILE* fptr);
-  int WriteHVConfig(FILE* fptr, char *configfile);
 
   int NumHVBoards;
@@ -24,13 +35,11 @@
 
   int fCCPort;
-  char *fCCClient;
 
   bool TestMode;
 
-  bool IsDAC;
-  float Coef[MAX_NUM_HVBOARDS][MAX_NUM_CHAINS][2];
+  float Coef[MAX_NUM_HVBOARDS][NUM_CHAINS][2];
  
   char*  FileName;
-  char*  fLogPath;
+  char*  fLogFile;
   char** fUSBDevice;
 
@@ -42,12 +51,13 @@
   int DACMin;
   int DACMax;
-  float HVMin;
-  float HVMax;
 
   float  fHVCalibOffset;
   float  fHVCalibSlope;
-  float  fHVMaxDiff;
+  
+  unsigned int  fHVMaxDiff;
 
 };
 
+bool ReadCard(const char *, void *, char, FILE *, unsigned int=1);
+
 #endif
Index: hvcontrol/src/HVMonitor.cc
===================================================================
--- hvcontrol/src/HVMonitor.cc	(revision 80)
+++ 	(revision )
@@ -1,28 +1,0 @@
-
-/********************************************************************\
-
-  Name:         HVMonitor.cc
-
-  Created by:   Sebastian Commichau, November 2008
-                commichau@phys.ethz.ch
-
-  Actions:      Monitor HV board status
-
-\********************************************************************/
-
-#include "HVMonitor.h"
-
-
-void HVMonitor(ProcessIO *m) {
-  
-  siginterrupt(SIGUSR1, true);
- 
-  while (!m->status->Exit) {
-
-    if (!m->status->Stop)
-      m->Monitor();
-
-    usleep((unsigned long)floor(1000000./(m->hv->GetNumberOfBoards()*m->status->fStatusRefreshRate)));
-  }
-
-}
Index: hvcontrol/src/HVMonitor.h
===================================================================
--- hvcontrol/src/HVMonitor.h	(revision 80)
+++ 	(revision )
@@ -1,14 +1,0 @@
-#ifndef HVMonitor_H_SEEN
-#define HVMonitor_H_SEEN
-
-#include <stdio.h>
-#include <unistd.h>
-#include <signal.h>
-
-#include "ProcessIO.h"
-#include "Types.h"
-#include "Utilities.h"
-
-void HVMonitor(ProcessIO *m);
-
-#endif
Index: hvcontrol/src/HVStatus.cc
===================================================================
--- hvcontrol/src/HVStatus.cc	(revision 80)
+++ 	(revision )
@@ -1,175 +1,0 @@
-
-/********************************************************************\
-
-  Name:         HVStatus.cc
-
-  Created by:   Sebastian Commichau, November 2008
-                commichau@phys.ethz.ch
-
-  Contents:     Store HV supply status information
-
-\********************************************************************/
-
-#include "HVStatus.h"
-
-static char* state_str[]    = {"active", "stopped", "n.a."}; 
-static char* isok_str[]     = {"error", "ok"};
-static char* cc_state_str[] = {"disconnected", "connected"};
-
-void InitStatus(Status* status, HVConfig* config) {
-
-  status->state     = active;
-  status->cc_state  = disconnected;
-  status->Exit      = FALSE;
-  status->Stop      = FALSE;
-  status->Log       = TRUE;
-  status->Verbose   = FALSE;
-  status->CCCommand = FALSE;
-
-  status->Socket    = -1;
-  sprintf(status->CCClient,"%s", config->fCCClient);
-  status->CCPort    = config->fCCPort;
-
-
-  status->fUSBDevice = new char*[MAX_NUM_HVBOARDS];
-  
-  for (int i=0; i<MAX_NUM_HVBOARDS; i++) {
-    status->fUSBDevice[i]      = new char[FILENAME_MAX_SIZE];
-    status->USBDeviceNumber[i] = USB_MAX_DEVICE_NUMBER+1;
-  }
-
-  status->USBMinDeviceNumber = USB_MAX_DEVICE_NUMBER;
-  status->USBMaxDeviceNumber = USB_MIN_DEVICE_NUMBER;
-
-  for (int i=0;i<MAX_NUM_HVBOARDS;i++) {
-    status->IsUpdated[i] = FALSE;
-    status->isok[i]      = TRUE;
-    status->MR[i]        = FALSE;
-    status->WC[0][i]     = 0;
-    status->WC[1][i]     = 1;
-
-    for (int j=0;j<MAX_NUM_CHAINS;j++) {
-      status->VRef[i][j] = 0;
-      status->OC[i][j]   = FALSE;
-
-      for (int k=0;k<MAX_NUM_CHANNELS;k++){
-	status->HV[i][j][k] = 0;
-	status->HVV[i][j][k] = 0.0;
-      }
-    }
-  }
-
-  status->NumHVBoards = 0;
-  status->FirstBoard  = 0;
-  status->LastBoard   = -1;
-
-  status->FirstChain  = 0;
-  status->LastChain   = 3;
-  
-
-  if (config->fTimeOut >= (float)MIN_TIMEOUT && config->fTimeOut <= (float)MAX_TIMEOUT)
-    status->fTimeOut  = config->fTimeOut;
-  else
-    status->fTimeOut  = 1.;
-
-  if (config->fStatusRefreshRate >= (float)MIN_RATE && config->fStatusRefreshRate <= (float)MAX_RATE) 
-    status->fStatusRefreshRate = config->fStatusRefreshRate;
-  else
-    status->fStatusRefreshRate = 1.;
-} 
-
-
-void ReInitStatus(Status* status) {
-
-  for (int i=0;i<MAX_NUM_HVBOARDS;i++) {
-    status->IsUpdated[i] = FALSE;
-    for (int j=0;j<MAX_NUM_CHAINS;j++) {
-      status->VRef[i][j] = 0;
-      for (int k=0;k<MAX_NUM_CHANNELS;k++)
-	status->HV[i][j][k] = 0;
-    }
-  }
-  
-} 
-
-
-void ReInitStatusOneBoard(Status* status, int board) {
-
-  status->IsUpdated[board] = FALSE;
-  for (int j=0;j<MAX_NUM_CHAINS;j++) {
-    status->VRef[board][j] = 0;
-    for (int k=0;k<MAX_NUM_CHANNELS;k++)
-      status->HV[board][j][k] = 0;
-  }
-    
-} 
-
-
-void PrintStatus(Status* status, HVConfig* config, FILE* fptr) {
-
-  fprintf(fptr,"\n");
-  fprintf(fptr,"********************************************* STATUS ********************************************\n\n");
-  fprintf(fptr," Status monitor: %s\n",state_str[status->state]);
-  fprintf(fptr," Logging: %s\n", ((status->Log) ? "on" : "off"));
-  fprintf(fptr," Verbose: %s\n", ((status->Verbose) ? "on" : "off"));
-  fprintf(fptr," Timeout [s]: %.2f\n",status->fTimeOut);
-  fprintf(fptr," Status refresh rate [Hz]: %.2f\n",status->fStatusRefreshRate);
-  fprintf(fptr," CC state: %s\n",                     cc_state_str[status->cc_state]);
-  fprintf(fptr," CC client: %s\n",                    status->CCClient);
-  fprintf(fptr," CC port: %d\n",                      status->CCPort);
-  fprintf(fptr," Total number of HV boards: %d\n",   status->NumHVBoards);
-  if (!status->NumHVBoards)
-    fprintf(fptr," Active HV boards: 0\n\n");
-  else if (status->NumHVBoards == ((status->LastBoard - status->FirstBoard) + 1))
-    fprintf(fptr," Active HV boards: all\n\n");
-  else
-    fprintf(fptr," Active HV boards: %d\n\n",            (status->LastBoard - status->FirstBoard) + 1);
-
-  for (int i=status->FirstBoard;i<=status->LastBoard;i++) {
-    fprintf(fptr," BOARD %d (%s):\n",status->USBDeviceNumber[i],status->fUSBDevice[i]);
-    fprintf(fptr,"  Wrap counter: %s (%d)\n",isok_str[status->isok[i]], status->WC[1][i]);
-    fprintf(fptr,"  Manual reset: %s\n\n",((status->MR[i]) ? "yes" : "no"));
-
-    for (int j=status->FirstChain;j<=status->LastChain;j++) {
-      fprintf(fptr,"  CHAIN %d:\n",j);
-      fprintf(fptr,"   Over-current: %s\n",((status->OC[i][j]) ? "yes" : "no"));
-      fprintf(fptr,"   Reference voltage: %d\n",status->VRef[i][j]);
-      fprintf(fptr,"   High voltage:\n");
-      for (int k=0;k<4;k++) {
-	fprintf(fptr,"    Channels %.2d-%.2d: ",k*8,k*8+7);
-	for (int l=0;l<8;l++) 
-	  fprintf(fptr," %5d ",status->HV[i][j][k*8+l]);
-	fprintf(fptr,"\n");
-      }
-	fprintf(fptr,"\n");
-    }
-  }
-
-
-  fprintf(fptr,"*************************************************************************************************\n\n");
-
-}
-
-
-void sPrintStatus(Status* status, char* str, int i) {
-
-  sprintf(str,"status board %d (%s): MR %s OC0 %s OC1 %s OC2 %s OC3 %s WC %s (%d)\n",status->USBDeviceNumber[i],status->fUSBDevice[i],
-	  ((status->MR[i]) ? "yes" : "no"),
-	  ((status->OC[i][0]) ? "yes" : "no"),
-	  ((status->OC[i][1]) ? "yes" : "no"),
-	  ((status->OC[i][2]) ? "yes" : "no"),
-	  ((status->OC[i][3]) ? "yes" : "no"),
-	  isok_str[status->isok[i]],
-	  status->WC[1][i]);
- 
-  //  if (status->Socket != -1) // Print status string to socket if open
-  //    write(status->Socket,str,strlen(str)+1);
-
-}
-
-
-char* GetStateStr(Status* status) {
-
-  return state_str[status->state];
-
-}
Index: hvcontrol/src/HVStatus.h
===================================================================
--- hvcontrol/src/HVStatus.h	(revision 80)
+++ 	(revision )
@@ -1,82 +1,0 @@
-
-#ifndef HVSTATUS_H_SEEN
-#define HVSTATUS_H_SEEN
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <sys/socket.h>
-#include <unistd.h>
-#include <pthread.h>
-
-#include "Types.h"
-#include "HVConfig.h"
-
-typedef enum stateenum { active, stopped, na } state_enum;
-typedef enum connection  { disconnected, connected } connect_enum;
-
-typedef struct status_str {
-  
-  pthread_t HVMonitor;
-
-  char Prompt[MAX_COM_SIZE];
-  
-  bool Log;
-  bool Verbose;
-
-  char Param[10][MAX_COM_SIZE], *Pc; // For parser
-  int NParam;
-  
-  connect_enum cc_state;
-
-  int Socket;                   // PrintMessage() uses this socket, -1 if not connected
-  pthread_t SocketThread;       // exit function sends signal to this thread
-
-  int CCPort;
-  char CCClient[STR_LENGTH];
-  
-  char** fUSBDevice;
-  int USBDeviceNumber[MAX_NUM_HVBOARDS];
-  int USBMinDeviceNumber;
-  int USBMaxDeviceNumber;
-
-  int NumHVBoards;
-  int FirstBoard;
-  int LastBoard;
-
-  int FirstChain;
-  int LastChain;
-  
-  unsigned int VRef[MAX_NUM_HVBOARDS][MAX_NUM_CHAINS];     
-  unsigned int HV[MAX_NUM_HVBOARDS][MAX_NUM_CHAINS][MAX_NUM_CHANNELS];      // HV value in DAC
-  float HVV[MAX_NUM_HVBOARDS][MAX_NUM_CHAINS][MAX_NUM_CHANNELS];            // HV value in volts
-
-  float fTimeOut;
-  float fStatusRefreshRate;
-
-  bool OC[MAX_NUM_HVBOARDS][MAX_NUM_CHAINS]; // Overcurrent flag
-  bool MR[MAX_NUM_HVBOARDS];                 // Manual reset
-  
-  bool isok[MAX_NUM_HVBOARDS];
-  state_enum   state;
-
-  bool IsUpdated[MAX_NUM_HVBOARDS];
-
-  int WC[2][MAX_NUM_HVBOARDS];
-  
-  int CCCommand;
-  int Exit;
-  int Stop;
-
-} Status;
-
-
-void InitStatus(Status* status, HVConfig* config);
-void ReInitStatus(Status* status);
-void ReInitStatusOneBoard(Status* status, int board);
-void PrintStatus(Status* status, HVConfig* config, FILE* fptr);
-void sPrintStatus(Status* status, char* str, int i);
-char* GetStateStr(Status* status);
-
-#endif
Index: hvcontrol/src/Log.cc
===================================================================
--- hvcontrol/src/Log.cc	(revision 80)
+++ 	(revision )
@@ -1,56 +1,0 @@
-
-#include "Log.h"
-
-Log::Log(char logpath[]) {
-
-  char logfile[FILENAME_MAX_SIZE];
-  time_t time_now_secs;
-  struct tm *time_now;
-
-  time(&time_now_secs);
-  time_now = localtime(&time_now_secs);
-
-  // Open log file
-  sprintf(logfile, "%s/hvutil_%04d_%02d_%02d_%02d_%02d_%02d.log", 
-	  logpath,
-	  1900 + time_now->tm_year,
-	  1 + time_now->tm_mon,
-	  time_now->tm_mday,
-	  time_now->tm_hour,
-	  time_now->tm_min,
-	  time_now->tm_sec);
-  if ((logptr = fopen(logfile, "w")) == NULL) {
-    fprintf(stderr,"Log::Log: could not open file %s => check DAQ config file\n", logfile);
-    exit(1);
-  }  
-
-  LogWrite("start logfile\n");
-}
-
-
-Log::~Log() {
-  LogWrite("end logfile\n");
-  fclose(logptr);
-  printf("Logfile closed\n");
-}
-
-
-int Log::LogWrite(char logtext[]) {
-  time_t time_now_secs;
-  struct tm *time_now;
-
-  time(&time_now_secs);
-  time_now = localtime(&time_now_secs);
-
-  fprintf(logptr, "[%04d:%02d:%02d:%02d:%02d:%02d] %s",
-	  1900 + time_now->tm_year,
-	  1 + time_now->tm_mon,
-	  time_now->tm_mday,
-	  time_now->tm_hour,
-	  time_now->tm_min,
-	  time_now->tm_sec,
-	  logtext);
-  fflush(logptr);
-
-  return 0;
-}
Index: hvcontrol/src/Log.h
===================================================================
--- hvcontrol/src/Log.h	(revision 80)
+++ 	(revision )
@@ -1,25 +1,0 @@
-#ifndef LOG_H_SEEN
-#define LOG_H_SEEN
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <time.h>
-
-#include "Types.h"
-
-#define MAX_LOG_SIZE 220
-
-class Log {
-
- public:
-  Log(char logpath[]);
-  ~Log();
-  
-  int LogWrite(char logtext[]);
-  
- public:
-  FILE *logptr;
-  char logtext[MAX_LOG_SIZE];
-};
-
-#endif
Index: hvcontrol/src/Makefile
===================================================================
--- hvcontrol/src/Makefile	(revision 80)
+++ 	(revision )
@@ -1,33 +1,0 @@
-#
-#  Makefile 
-#
-
-include ../Makefile.general
-
-INCDIRS = -I. -I/usr/local/include
-
-CC_SOURCES =  $(shell ls *.cc)
-CC_SOURCES := $(notdir $(CC_SOURCES))
-CC_OBJECTS =  $(CC_SOURCES:%.cc=%.o)
-
-C_SOURCES  =  $(shell ls *.c)
-C_SOURCES  := $(notdir $(C_SOURCES))
-C_OBJECTS  =  $(C_SOURCES:%.c=%.o)
-
-OBJECTS = $(CC_OBJECTS)  $(C_OBJECTS) 
-SOURCES = $(CC_SOURCES)  $(C_SOURCES) 
-
-all: $(OBJECTS) 
-
-include ../Makefile.rules
-
-clean: rmobj rmdep
-
-mrproper: clean rmbak
-
-
-
-
-
-
-
Index: hvcontrol/src/ProcessIO.cc
===================================================================
--- hvcontrol/src/ProcessIO.cc	(revision 80)
+++ hvcontrol/src/ProcessIO.cc	(revision 90)
@@ -2,1813 +2,743 @@
 /********************************************************************\
 
-  Name:         ProcessIO.cc
-
-  Created by:   Sebastian Commichau, November 2008
-                commichau@phys.ethz.ch
-
-  Contents:     Main class processing user input
+  ProcessIO.cc
+
+  Main class processing user input
+ 
+  Sebastian Commichau, Sabrina Stark-Schneebeli, Oliver Grimm
 
 \********************************************************************/
 
-
 #include "ProcessIO.h"
 
+static char* state_str[]    = {"active", "stopped", "n.a."};
 
 ProcessIO::ProcessIO(char *ConfigFile) {
 
-  // Get program start time - only needed for uptime command
+  // Get program start time
   time (&StartTime);
 
-  status  = new Status;
-  config  = new HVConfig(stdout,ConfigFile);
+  // Create instances
+  config = new HVConfig(stdout,ConfigFile);
   calib  = new HVCalib(config);
-  log     = new Log(config->fLogPath);
-  hv      = new HV(config->fUSBDevice,config->USBDeviceNumber,stdout,config->TestMode);
- 
-  pm = new PixelMap(config->fPixMapTable);
-
-  // Initialize status structure (HVStatus.cc/h)
-  InitStatus(status,config);    
-
-  // Print HV control configuration to the log file
-  config->PrintHVConfig(log->logptr);
-
-  // The following loop was added to allow for an arbitrary numeration of the HV boards
-  for (int i=0;i<hv->GetNumberOfBoards();i++) {
-    
-    sprintf(status->fUSBDevice[i],"%s",(hv->GetHVBoard(i))->GetSerial());
-    status->USBDeviceNumber[i] = (hv->GetHVBoard(i))->GetBoardNumber();
-
-    if ((hv->GetHVBoard(i))->GetBoardNumber() > status->USBMaxDeviceNumber)
-      status->USBMaxDeviceNumber = (hv->GetHVBoard(i))->GetBoardNumber();
-
-    if ((hv->GetHVBoard(i))->GetBoardNumber() < status->USBMinDeviceNumber)
-      status->USBMinDeviceNumber = (hv->GetHVBoard(i))->GetBoardNumber();
-
-    (hv->GetHVBoard(i))->SetTimeOut(config->fTimeOut);
-  }
-
-  // Initialize HV boards (see below)
-  InitializeHV();
-
-  status->FirstBoard  = 0;
-  status->NumHVBoards = hv->GetNumberOfBoards();
-  status->LastBoard   = hv->GetNumberOfBoards()-1;
-
-  // Print status information to the log file
-  PrintStatus(status,config,log->logptr);
-
-  // Send reset command to all boards
-  ResetAllBoards();
-
-  // Print some information
-  sprintf(str,"status monitor: %s\n", GetStateStr(status));
-  if (hv->GetNumberOfBoards()>0) DoPrompt(str);
-  
-  sprintf(str,"type (h)elp to get a list of available commands\n");
-  DoPrompt(str);
-
-  // Print empty prompt
-  DoPrompt(NULL);
-  
-  // Initialize mutex variable for thread synchronization
-  pthread_mutex_init (&control_mutex, NULL);
-  pthread_cond_init  (&control_cond,  NULL);
-  
-  sprintf(str,"**************** End of constructor ProcessIO ************\n");
-  DoPrompt(str);
-  
-}
-
-
-ProcessIO::~ProcessIO() {
-  
-  pthread_mutex_destroy (&control_mutex);
-  pthread_cond_destroy  (&control_cond);
-  
-  config->fStatusRefreshRate = status->fStatusRefreshRate;
-  config->fTimeOut           = status->fTimeOut;
-  config->WriteHVConfig(stdout,config->FileName);
-
-  delete hv;
-  delete status;
-  delete config;
-  delete log;
-  delete pm;
-  
-}
-
-
-// Print list of all commands 
-void ProcessIO::PrintHelp() {
-
-  puts("");
-  puts("********************************************** HELP *********************************************\n");
-  puts(" board <i>|<i> <j>|<all>           Address board i, boards i-j or all boards");
-  puts(" chain <i>|<i> <j>|<all>           Address chain i, chains i-j or all chains");
-  puts(" clear                             Clear screen");
-  puts(" config                            Print configuration");
-  puts(" help                              Print help");
-  puts(" hv <ch>|<all> [b][x]<v>           Set chan. <ch>|<all> chan. of active chain(s)/board(s) to <v>");
-  //  puts(" hvdiff <ch>|<all> [b][x]<diff>    Set chan. <ch>|<all> chan. of active chain(s)/board(s) to <diff>");
-  puts(" hvdiff <PXL id> <diff>            Set HV difference of pixel PXL id to <diff>");
-  puts(" list                              List all HV boards");
-  puts(" load <file>                       Load HV settings from <file>");
-  puts(" log <on>|<off>                    Enable|disable logging");
-  puts(" quit|exit                         Exit program");
-  puts(" rate <rate>                       Set status refresh rate to <rate> [Hz]");
-  puts(" reset                             Reset active HV board");
-  puts(" save [file]                       Save current HV settings to [file]");
-  puts(" start                             Start HV status monitor");
-  puts(" status                            Show status information");
-  puts(" stop                              Stop HV status monitor - not recommended!");
-  puts(" time                              Print current date and time");
-  puts(" timeout <time>                    Set timeout to return from read to <time> [s]");
-  puts(" uptime                            Get program uptime [h:m:s]");
-  puts(" verbose <on>|<off>                Enable|disable verbosity");
-  puts(" vref [b][x]<v>                    Set reference voltage of active chain(s)/board(s) to <v>\n");
-  puts("*************************************************************************************************\n");
-
-}
-
-
-// Process user input
-int ProcessIO::CommandControl() {
-
-
-  // Adress HV board
-  if (Match(status->Param[0], "board")) {
-    
-    if (!NBoards())
-      return 0;
-    else {
-  
-      // Select all boards
-      if (status->Param[1][0] == 'a' && !status->Param[2][0]) {
-	
-	status->FirstBoard = 0;
-	status->LastBoard = hv->GetNumberOfBoards()-1;
-	
-      }
-      // Wrong type of argument
-      else if (!IsNoDigit(status->Param[1]) || !IsNoDigit(status->Param[2]) || status->Param[3][0] || !status->Param[1][0]) {
-	sprintf(str,"ERROR - usage: <board> <i>|<i> <j>|<all>\n");
-	DoPrompt(str);	
-	return 0;
-      } 
-      // Check if board(s) exist(s)
-      else if (status->Param[1][0] || status->Param[2][0]) {
-
-	if (!IsBoard(atoi(status->Param[1]))) {
-	  sprintf(str,"ERROR -board #%d does not exist\n", atoi(status->Param[1]));
-	  DoPrompt(str);
-	  return 0;
-	}
-	
-	if (status->Param[2][0])
-	  if (!IsBoard(atoi(status->Param[2]))) {
-	    sprintf(str,"ERROR -board #%d does not exist\n", atoi(status->Param[2]));
-	    DoPrompt(str);
-	    return 0;
-	  }
-
-	if (status->Param[1][0] && status->Param[2][0]) {
-	  
-	  status->FirstBoard = GetBoardIdx(atoi(status->Param[1]));
-	  status->LastBoard  = GetBoardIdx(atoi(status->Param[2]));
-
-	}
-	else if (status->Param[1][0]) {
-
-	  status->FirstBoard = GetBoardIdx(atoi(status->Param[1]));
-	  status->LastBoard = status->FirstBoard;
-	  
-	}
-      }
-    
-      //DoPrompt(NULL);
-    }
-    
-    DoPrompt(NULL);
-    return 0;
-  } 
-
-
-  // Adress chains
-  else if (Match(status->Param[0], "chain")) {
-    
-    if (!NBoards())
-      return 0;
-    else {
-      
-      if (status->Param[1][0] == 'a') {
-	
-	status->FirstChain = 0;
-	status->LastChain  = 3;
-	
-      } 
-      else if (!IsNoDigit(status->Param[1]) || !status->Param[1][0]) {
-	sprintf(str,"ERROR -usage: <chain> <i>|<i> <j>|<all>\n");
-	DoPrompt(str);	
-	return 0;
-      }
-      else if (status->Param[1][0] >= 0 && atoi(status->Param[1]) >= 0 && atoi(status->Param[1]) < 4 && !status->Param[2][0]) {
-	
-	status->FirstChain = atoi(status->Param[1]);
-	status->LastChain = status->FirstChain;
-	
-      }
-      else if ((status->Param[1][0] >= 0 && atoi(status->Param[1]) >= 0 && atoi(status->Param[1]) < 4) && 
-	       (status->Param[2][0] > 0 && atoi(status->Param[2]) > 0 && atoi(status->Param[2]) < 4)) {
-	
-	status->FirstChain = atoi(status->Param[1]);
-	status->LastChain = atoi(status->Param[2]);
-	
+  pm 	 = new PixelMap(config->fPixMapTable);
+
+  // Initialize status variables
+  state     = active;
+  Exit      = false;
+  Verbose   = false;
+  CmdFromSocket = false;
+  Socket    = -1;
+  
+  NumHVBoards = 0;
+  FirstBoard  = 0;
+  LastBoard   = -1;
+  FirstChain  = 0;
+  LastChain   = 3;
+  
+  if (config->fStatusRefreshRate >= MIN_RATE && config->fStatusRefreshRate <= MAX_RATE) 
+    fStatusRefreshRate = config->fStatusRefreshRate;
+  else fStatusRefreshRate = 1.;
+    
+  // Open HV devices
+  if(config->TestMode){
+    fprintf(stdout,"Test mode: One HVBoard initialized as dummy.\n");
+    fHVBoard[NumHVBoards] = new HVBoard(0, 0, config->TestMode, config->fTimeOut, Verbose);
+    NumHVBoards++;
+  }
+  else {
+    for (int i=0; i<config->NumHVBoards; i++) {
+      fHVBoard[NumHVBoards] = new HVBoard(config->USBDeviceNumber[i], config->fUSBDevice[i], config->TestMode, config->fTimeOut, Verbose);
+      if(fHVBoard[NumHVBoards]->fDescriptor >= 0) {
+         printf("Synchronized and reset HV board %d (%s)\n",i,config->fUSBDevice[i]);
+         NumHVBoards++;
       }
       else {
-	
-	if (atoi(status->Param[1]) < 0 || atoi(status->Param[1]) > 3) {
-	  sprintf(str,"ERROR -chain #%d does not exist\n", atoi(status->Param[1]));
-	  DoPrompt(str);
-	}
-	
-	
-	if ((atoi(status->Param[2]) < 0 || atoi(status->Param[2]) > 3) && (atoi(status->Param[1]) != atoi(status->Param[2]))) {
-	  sprintf(str,"ERROR -chain #%d does not exist\n", atoi(status->Param[2]));
-	  DoPrompt(str);
-	}
-	
-	return 0;
-	
+        printf("Failed to synchronize to HV board %d (%s)\n",i,config->fUSBDevice[i]);
+	delete fHVBoard[NumHVBoards];
       }
-
-      DoPrompt(NULL);
-    }
-    
-    return 0;
+    }
   } 
-
-
-  // Clear screen
-  else if (Match(status->Param[0], "clear") || Match(status->Param[0], "cls")) {
-
-  system("clear");
-  DoPrompt(NULL);
-
-  return 0;
-  
-  }
+  LastBoard = NumHVBoards-1;
+
+  // Open log file
+  if ((Logfile = fopen(config->fLogFile, "a")) == NULL) printf("Warning: Could not open log file '%s'\n", config->fLogFile);
+  PrintMessage(MsgToLog,"********** Logging started **********\n");
+
+  // Print configuration to log file
+  if(Logfile) config->PrintHVConfig(Logfile);
+}
+
+
+ProcessIO::~ProcessIO() {
+  
+  for (int i=0; i<NumHVBoards; i++) delete fHVBoard[i];
+
+  delete config;    delete pm;
+  
+  if(Logfile != NULL) {
+    if(!fclose(Logfile)) printf("Closing logfile\n");
+    else perror("Error closing logfile");
+  }
+}
+
+
+// Process user input
+void ProcessIO::CommandControl(char *Command) {
+
+  if (strlen(Command)==0) return;  // Ignore empty commands
+
+  if(Command[0]=='.') {   // Shell command
+    system(&(Command[1]));
+    return;
+  }
+
+  for(int i=0; i<MAX_NUM_TOKEN; i++) Param[i] = "";  // All pointers point initially to empty string
+    NParam = ParseInput(Command, Param);
+
+  // Adress HV board
+  if (Match(Param[0], "board")) {
+    
+    if (!NumHVBoards) return;
+
+    // Print list of boards
+    if (NParam == 1) {
+      for (int i=0; i<NumHVBoards; i++) {
+        PrintMessage("Board %d: %s\n", fHVBoard[i]->GetBoardNumber(), fHVBoard[i]->BoardName);
+      }
+      return;
+    }
+
+    //Select board(s)
+    if (Match(Param[1],"all")) {
+      FirstBoard = 0;
+      LastBoard = NumHVBoards-1;
+    } 
+    else if (NParam==2 && atoi(Param[1])>=0 && atoi(Param[1])<NumHVBoards) {
+      FirstBoard = atoi(Param[1]);
+      LastBoard = FirstBoard;
+    }
+    else if (NParam==3 && atoi(Param[1])>=0 && atoi(Param[1])<NumHVBoards && 
+           atoi(Param[2])>0 && atoi(Param[2])<NumHVBoards) {
+      FirstBoard = atoi(Param[1]);
+      LastBoard = atoi(Param[2]);
+    }
+    else PrintMessage("Cannot address board(s), out of range.\n");
+
+    return;
+  } 
+
+
+  // Adress chains
+  else if (Match(Param[0], "chain")) {
+    
+    if (!NumHVBoards) return;
+    
+    if (Match(Param[1],"all")) {
+      FirstChain = 0;
+      LastChain = 3;
+    } 
+    else if (NParam==2 && atoi(Param[1])>=0 && atoi(Param[1])<4) {
+      FirstChain = atoi(Param[1]);
+      LastChain = FirstChain;
+    }
+    else if (NParam==3 && atoi(Param[1])>=0 && atoi(Param[1])<4 && 
+           atoi(Param[2])>0 && atoi(Param[2])<4) {
+      FirstChain = atoi(Param[1]);
+      LastChain = atoi(Param[2]);
+    }
+    else PrintMessage("Cannot address chain(s), out of range.\n");
+        
+    return;
+  } 
 
 
   // Print HV utility configuration
-  else if (Match(status->Param[0], "config")) {
+  else if (Match(Param[0], "config")) {
 
     config->PrintHVConfig(stdout);
     
-    return 0;
+    return;
   }
 
 
   // Print help
-  if (Match(status->Param[0], "help")) {
-
-    PrintHelp();
-    DoPrompt(NULL);
-   
-    return 0;
+  if (Match(Param[0], "help")) {
+    puts(" board <i>|<i> <j>|<all>           Address board i, boards i-j or all boards or list boards");
+    puts(" chain <i>|<i> <j>|<all>           Address chain i, chains i-j or all chains");
+    puts(" hv <PXL id>|<ch>|<all> <v>        Set HV of pixel ID, ch. or all ch. of active chain(s)/board(s)");
+    puts(" hvdiff <PXL id>|<ch>|<all> <diff> Change HV by <diff>");
+    puts(" status [dac]                      Show status information (DAC values if requested)");
+    puts(" config                            Print configuration");
+    puts(" load <file>                       Load HV settings from <file>");
+    puts(" save <file>                       Save current HV settings to [file]");
+    puts(" exit                              Exit program");
+    puts(" rate <rate>                       Set status refresh rate to <rate> [Hz]");
+    puts(" timeout <time>                    Set timeout to return from read to <time> [s]");
+    puts(" reset                             Reset active HV board");
+    puts(" start                             Start HV status monitor");
+    puts(" stop                              Stop HV status monitor - not recommended!");
+    puts(" uptime                            Get program uptime [h:m:s]");
+    puts(" verbose <on|off>|                 Enable|disable verbosity");
+    puts(" help                              Print help");
+    puts(" .<cmd>                   	     Execute shell command <cmd>");
+
+    return;
   } 
 
 
-  // Write high voltage -----------------------------------------------------------------------------------------
-  if (Match(status->Param[0], "hv")) {
-
-    if (!NBoards())
-      return 0;
-
-    int errors = 0;
-    unsigned int hvoltage = 0, hvAll = 0;
-    float hvoltageV = 0.0;
-    int channel = 0, hvdiff = 0;
-    bool allchannels = FALSE;
-
-    if (status->Param[1][0]>0 && status->Param[2][0]>0) {
-
-      // Set channel
-      if (IsNoDigit(status->Param[1]))
-	channel = atoi(status->Param[1]);
-      else if(status->Param[1][0] == 'a')
-	allchannels = TRUE;
-      else {
-	DoPrompt("ERROR - wrong input format - usage: hv <channel>|<all> <voltage>\n");
-	return 0;
-      }
-          
-      // Binary input
-      if (tolower(status->Param[2][0])=='x' && strlen(status->Param[2])>2) {
-	if (sPrintHex2Dec(Chop(status->Param[2]+1),&hvoltage)!=0) {
-	  DoPrompt("ERROR - wrong input format - usage: hv <channel>|<all> <voltage>\n");
-	  return 0;
-	}
-      }
-      // Hexadecimal input
-      else if (tolower(status->Param[2][0])=='b' && strlen(status->Param[2])>2) {
-	if (sPrintBin2Dec(Chop(status->Param[2]+1),&hvoltage)!=0) {
-	  DoPrompt("ERROR - wrong input format - usage: hv <channel>|<all> <voltage>\n");
-	  return 0;
-	}
-      }
-      // Decimal input
-      else if (IsNoDigit(status->Param[2])&&config->IsDAC)
-	hvoltage = atoi(status->Param[2]);
-      else if (IsNoDigit(status->Param[2])&&(!(config->IsDAC)))
-	hvoltageV = atof(status->Param[2]);
-      // Wrong input format
-      else {
-	DoPrompt("ERROR - wrong input format - usage: hv <channel>|<all> <voltage>\n");
-	return 0;
-      }
-
-      // Check limits
-      if (channel>31 || channel <0) {
-	DoPrompt("ERROR - channel out of range (0...31)!\n");
-	return 0;
-      }
-      else if ((hvoltage>0X3FFF || hvoltage <0)&&config->IsDAC) {
-	DoPrompt("ERROR - high voltage out of range (Vmin: 0, Vmax: 16383)!\n");
-	return 0;
-      }
-      else if ((hvoltage>78.0 || hvoltage <0)&&(!(config->IsDAC))) {
-	DoPrompt("ERROR - high voltage out of range (Vmin: 0, Vmax: 78.)!\n");
-	return 0;
-      }
-
-      StopMonitor();
-
-      
-      for (int i=status->FirstBoard;i<=status->LastBoard;i++) {
-
-	for (int j=status->FirstChain;j<=status->LastChain;j++) {
-	  if (!allchannels) {
- // Convert from HV to DAC values
-	    if (!(config->IsDAC)){
-	      status->HVV[i][j][channel]=hvoltageV;
-	      hvoltage = calib->HVToDAC(hvoltageV,i,j,channel);
-	    }
-	    hvdiff = hvoltage - status->HV[i][j][channel];
-	    for (int k=0;k<=abs((int)(hvdiff/config->fHVMaxDiff));k++){
-	      if (k<abs((int)(hvdiff/config->fHVMaxDiff))){
-		hvoltage=(unsigned int)(status->HV[i][j][channel] + config->fHVMaxDiff*hvdiff/abs(hvdiff));
-	      }
-	      if (k==(abs((int)(hvdiff/config->fHVMaxDiff)))){
-		hvoltage=(unsigned int)(status->HV[i][j][channel] + (hvdiff%(int)config->fHVMaxDiff));
-	      }
-	     
-	      if ((hv->GetHVBoard(i))->SetHV(stdout,j,channel,hvoltage,rbuf,status->Verbose)==1){
-		status->HV[i][j][channel]=hvoltage;
-		UpdateStatus(i,rbuf);
-		
-		sprintf(str,"OK - board %d: high voltage of chain %d channel %d set to %d | 0X%.4X | %f V\n",hv->GetHVBoard(i)->GetBoardNumber(),j,channel,hvoltage,hvoltage,calib->DACToHV(hvoltage,hv->GetHVBoard(i)->GetBoardNumber(),j,channel));
-		//		DoPrompt(str);
-		if (status->Verbose) {
-		  sPrintStatus(status,str,i);
-		  DoPrompt(str);
-		}
-		sPrintStatus(status,str,i); // Print status only to socket 
-	      }
-	      else {
-		sprintf(str,"ERROR - board %d error: could not set hv - check timeout and try again\n",hv->GetHVBoard(i)->GetBoardNumber());
-		DoPrompt(str);
-		errors++;
-	      }
-	    }
+  // Set new high voltage --------------------------------------------------------------------------------------
+  if (Match(Param[0], "hv") || Match(Param[0], "hvdiff")) {
+
+    if (!NumHVBoards) return;
+
+    int hvoltage, DACValue, Errors=0, Board, Chain=0, Channel=0;
+    double hvoltageV;
+    bool allchannels = false, SetDac = false;
+    
+    // Need two parameters or three if last is 'dac'
+    if (NParam<3 || NParam>4) {
+      PrintMessage("ERROR - usage: hv <channel>|<all> <voltage> [dac]\n");
+      return;
+    }
+
+    if (NParam==4 && Match(Param[3], "dac")) SetDac = true;
+    
+    // Evaluate pixel or channel parameter    
+    if((Board = pm->Pixel_to_HVboard(Param[1])) != 999999999) {
+      Chain = pm->Pixel_to_HVchain(Param[1]);
+      Channel = pm->Pixel_to_HVchannel(Param[1]);
+    }
+    else if (Match(Param[1], "all")) allchannels = true;
+    else if (ConvertToInt(Param[1], &Channel)) {
+      Board = -1;
+      Chain = -1;
+    } 
+    else {
+      PrintMessage("ERROR - wrong input format - usage: hv <channel>|<all> <voltage>\n");
+      return;
+    }
+    // Check channel limits (voltage limit is only checked in SetHV())
+    if (Channel<0 || Channel>31) {
+      PrintMessage("ERROR - channel out of range (0...31)!\n");
+      return;
+    }
+
+    if (SetDac && !ConvertToInt(Param[2], &hvoltage)) {
+      PrintMessage("ERROR - wrong number format for DAC voltage setting\n");
+      return;
+    } 
+    if (!SetDac && !ConvertToDouble(Param[2], &hvoltageV)) {
+      PrintMessage("ERROR - wrong number format for voltage setting\n");
+      return;
+    } 
+
+    for (int i=FirstBoard; i<=LastBoard; i++) {
+      if (!allchannels && Board != 999999999 && i != Board && Board!=-1) continue;
+
+      for (int j=FirstChain; j<=LastChain; j++) {
+        if (!allchannels && Chain != 999999999 && j != Chain && Chain!=-1) continue;
+
+	for (int k=0; k<NUM_CHANNELS; k++) {
+	  if (!allchannels && k!= Channel) continue;
+
+    	  // Convert from HV to DAC values
+	  if (!SetDac){
+	    if(strlen(Param[0]) > 2) fHVBoard[i]->HVV[j][k] += hvoltageV; // hvdiff
+	    else fHVBoard[i]->HVV[j][k] = hvoltageV;
+	    DACValue = calib->HVToDAC(fHVBoard[i]->HVV[j][k], i, j, k);
 	  }
 	  else {
-	    sprintf(str,"OK - updating board %d chain %d\n",hv->GetHVBoard(i)->GetBoardNumber(),j);
-	    DoPrompt(str);
+	    if(strlen(Param[0]) > 2) DACValue = fHVBoard[i]->HV[j][k] + hvoltage; // hvdiff
+	    else DACValue = hvoltage;
+	  }
 	  
-	    for (int k=0;k<MAX_NUM_CHANNELS;k++) {
- // Convert from HV to DAC values
-	      if (!(config->IsDAC)){
-		status->HVV[i][j][k]=hvoltageV;
-		hvoltage = calib->HVToDAC(hvoltageV,i,j,k);
-	      }
-	      hvAll = hvoltage;
-	      hvdiff = hvAll - status->HV[i][j][k];
-	      for (int l=0;l<=abs((int)(hvdiff/config->fHVMaxDiff));l++){
-		if (l<abs((int)(hvdiff/config->fHVMaxDiff))){
-		  hvoltage=(unsigned int)(status->HV[i][j][k] + config->fHVMaxDiff*hvdiff/abs(hvdiff));
-		}
-		if (l==(abs((int)(hvdiff/config->fHVMaxDiff)))){
-		  hvoltage=(unsigned int)(status->HV[i][j][k] + (hvdiff%(int)config->fHVMaxDiff));
-		}
-		if ((hv->GetHVBoard(i))->SetHV(stdout,j,k,hvoltage,rbuf,status->Verbose)==1) {
-		  status->HV[i][j][k]=hvoltage;
-		  UpdateStatus(i,rbuf);
-		  
-		  if (status->Verbose) {
-		    sprintf(str,"OK - board %d: high voltage of chain %d channel %d set to %d | 0X%.4X | %f V\n",hv->GetHVBoard(i)->GetBoardNumber(),j,channel,hvoltage,hvoltage,calib->DACToHV(hvoltage,hv->GetHVBoard(i)->GetBoardNumber(),j,channel));
-		    //sprintf(str,"board %d: high voltage of chain %d channel %d set to %d | 0X%.4X\n",hv->GetHVBoard(i)->GetBoardNumber(),j,k,hvoltage,hvoltage);
-		    //   DoPrompt(str);
-		    sPrintStatus(status,str,i);
-		    DoPrompt(str);
-		  }
-		  sPrintStatus(status,str,i); // Print status only to socket 
-		}
-		
-		else {
-		  sprintf(str,"ERROR - board %d error: could not set HV - check timeout and try again\n",hv->GetHVBoard(i)->GetBoardNumber());
-		  DoPrompt(str);
-		  errors++;
-		}
-	      }
+	  // Set new voltage (if DAC value, update calilbrated value)
+	  if(!RampVoltage(DACValue, i, j, k)) Errors++;
+	  else if(SetDac) fHVBoard[i]->HVV[j][k] = calib->DACToHV(fHVBoard[i]->HV[j][k], i, j, k);
+
+	} // Channels	
+      } // Chains
+    } // Boards
+
+    if (Errors > 0) PrintMessage("Warning: Errors on %d channel(s) occurred\n", Errors);
+    else PrintMessage("OK - no error(s)\n");
+    
+    return;
+  }
+
+
+  // Load HV settings from file
+  else if (Match(Param[0], "load")) {
+
+    char Buffer[MAX_COM_SIZE];
+    int NBoards = 0, Errors = 0, Chain;
+    unsigned int DACValue;
+    FILE *File;
+    
+    if (NParam != 2) {
+      PrintMessage("Usage: load <file>\n");
+      return;
+    }
+    
+    if ((File=fopen(Param[1], "r")) == NULL) {
+      PrintMessage("Error: Could not open file '%s' (%s)\n", Param[1], strerror(errno));
+      return;
+    }
+	
+    StopMonitor();
+
+    while (fgets(Buffer, sizeof(Buffer), File) != NULL) {
+      for (int Board=0; Board<NumHVBoards; Board++) {
+	if (Match(fHVBoard[Board]->BoardName, Buffer)) {
+
+	  PrintMessage("Found HV settings for board %d (%s)\n",fHVBoard[Board]->GetBoardNumber(), fHVBoard[Board]->BoardName);
+
+	  Chain = 0;
+	  while (fgets(Buffer, sizeof(Buffer), File) && Chain<NUM_CHAINS) {
+    	    if (strlen(Buffer) == 1) continue;  // Ignore if only newline character
+
+    	    for (int Channel=0; Channel<NUM_CHANNELS; Channel++) {
+	      if (sscanf(Buffer, "%u", &DACValue) != 1) {
+    	    	PrintMessage("Error reading DAC values from file, terminating\n");
+		return;
+	      }	      
+	      if (!RampVoltage(DACValue, Board, Chain, Channel)) Errors++;
 	    }
+	    Chain++;
 	  }
+	  PrintMessage("Finished updating board.\n");
+    	  NBoards++;
 	}
-      }
-
-      
-
-      StartMonitor();
-
-      if (errors) {
-	sprintf(str,"ERROR - warning %d error(s) => check timeout and try again\n",errors);
-	DoPrompt(str);
-      }
-      else {
-	sprintf(str,"OK - no error(s)... success!\n");
-	DoPrompt(str);
-      }
-
-    }
-    else {
-      sprintf(str,"ERROR - usage: hv <channel>|<all> <voltage>\n");
-      DoPrompt(str);
-    }
-
-    return 0;
-  }  // End: Write high voltage  ----------------------------------------------------------------------------------------
-
-
-
-  // Write difference of high voltage ------------------------------------------------------------------------------------
-  if (Match(status->Param[0], "hvdiff")) {
-
-    if (!NBoards())
-      return 0;
-
-    int errors = 0;
-    int hvdiff = 0;
-    unsigned int hvoltage = 0;
-    float hvoltageV = 0.0;
-    float hvdiffV = 0.0;
-    std::string pixelname(status->Param[1]);
-    unsigned int board = 0;
-    unsigned int chain = 0;
-    unsigned int channel = 0;
-
-
-    if (status->Param[1][0]>0 && status->Param[2][0]>0) {
-
-
-      // Set board
-      board = pm->Pixel_to_HVboard(pixelname);
-      //      std::cout << "Board: " << board << std::endl;
-      // Set chain
-      chain = pm->Pixel_to_HVchain(status->Param[1]);
-      //      std::cout << "Chain: " << chain << std::endl;
-      // Set channel
-      channel = pm->Pixel_to_HVchannel(status->Param[1]);
-      //      std::cout << "Channel: " << channel << std::endl;
-
-      // Binary input
-      if (tolower(status->Param[2][0])=='x' && strlen(status->Param[2])>2) {
-	if (sPrintHex2Dec(Chop(status->Param[2]+1),(unsigned int *)hvdiff)!=0) {
-	  DoPrompt("ERROR - wrong input format - usage: hvdiff <channel>|<all> <hv difference>\n");
-	  return 0;
-	}
-      }
-      // Hexadecimal input
-      else if (tolower(status->Param[2][0])=='b' && strlen(status->Param[2])>2) {
-	if (sPrintBin2Dec(Chop(status->Param[2]+1),(unsigned int *)hvdiff)!=0) {
-	  DoPrompt("ERROR - wrong input format - usage: hvdiff <channel>|<all> <hv difference>\n");
-	  return 0;
-	}
-      }
-      // Decimal input
-      else if (IsNoDigit(status->Param[2])&&(config->IsDAC))
-	hvdiff = atoi(status->Param[2]);
-      else if (IsNoDigit(status->Param[2])&&(!(config->IsDAC)))
-	hvdiffV = atof(status->Param[2]);
-      // Wrong input format
-      else {
-	DoPrompt("ERROR - wrong input format - usage: hvdiff <channel>|<all> <hv difference>\n");
-	return 0;
-      }
-      // Check limits
-      if (channel>31 || channel <0) {
-	sprintf(str,"ERROR - channel out of range (0...31)!\n");
-	DoPrompt(str);
-	return 0;
-      }
-      else if (hvdiff>config->DACMax || hvdiff <(-(config->DACMax))) {
-	sprintf(str,"ERROR - difference of high voltage [hvdiff:%d] out of range (Vmin: 0.0, Vmax: %d)!\n", hvdiff,config->DACMax);
-	DoPrompt(str);
-	return 0;
-      }
-      else if (hvdiffV>(calib->DACToHV(config->DACMax,0,0,0))|| hvdiffV<-(calib->DACToHV(config->DACMax,0,0,0))) {
-	sprintf(str,"ERROR - difference of high voltage [hvdiff:%f] out of range (Vmin: 0.0, Vmax: %f)!\n",hvdiffV,calib->DACToHV(config->DACMax,0,0,0));
-	DoPrompt(str);
-	return 0;
-      }
-      
-
-
-      //Convert from HV to DAC values
-      if (!(config->IsDAC)){
-	hvoltageV = status->HVV[board][chain][channel]+hvdiffV;
-	status->HVV[board][chain][channel] = hvoltageV;
-	//	printf("hv+diff = %f .\n",hvoltageV);
-	hvdiff = calib->HVToDAC(hvoltageV,board,chain,channel) - status->HV[board][chain][channel];
-	//	printf("dac new = %d, dac old = %d.\n",calib->HVToDAC(hvoltageV,board,chain,channel),status->HV[board][chain][channel]);
-	//	printf("dac diff = %d .\n",hvdiff);
-      }
-      StopMonitor();
-
-   
-      
-      hvoltage = status->HV[board][chain][channel];
-      //      printf("dac hv = %d .\n",hvoltage);
-      for (int k=0;k<=abs((int)(hvdiff/config->fHVMaxDiff));k++){
-	if (k<abs((int)(hvdiff/config->fHVMaxDiff))){
-	  hvoltage=(unsigned int)(hvoltage + config->fHVMaxDiff*hvdiff/abs(hvdiff));
-	}
-	if (k==(int)(abs((int)(hvdiff/config->fHVMaxDiff)))){
-	  hvoltage=(unsigned int)(hvoltage + (hvdiff%(int)config->fHVMaxDiff));
-	}
-	
-	
-	status->HV[board][chain][channel]=hvoltage;
-	//	printf("dac hv rampingup= %d .\n",hvoltage);
-	if ((hv->GetHVBoard(board))->SetHV(stdout,chain,channel,hvoltage,rbuf,status->Verbose)==1) {
-	  UpdateStatus(board,rbuf);
-	  if (k==(abs((int)(hvdiff/config->fHVMaxDiff)))){
-	    sprintf(str,"OK - board %d: high voltage of chain %d channel %d set to %d | 0X%.4X | %f V\n",hv->GetHVBoard(board)->GetBoardNumber(),chain,channel,hvoltage,hvoltage,calib->DACToHV(hvoltage,hv->GetHVBoard(board)->GetBoardNumber(),chain,channel));
-	    //sprintf(str,"board %d: high voltage of chain %d channel %d set to %d | 0X%.4X\n",hv->GetHVBoard(board)->GetBoardNumber(),chain,channel,hvoltage,hvoltage);
-	    DoPrompt(str);
-	    sPrintStatus(status,str,board); // Print status only to socket 
-	  }
-	}
-	else {
-	  sprintf(str,"ERROR - board %d chain %d channel %d error: could not set hv - check timeout and try again\n",hv->GetHVBoard(board)->GetBoardNumber(), chain, channel);
-	  DoPrompt(str);
-	  errors++;
-	}
-      }          // for loop over k
-      if (status->Verbose) {
-	sPrintStatus(status,str,board);
-	DoPrompt(str);
-      }
-   
-    
-      StartMonitor();
-
-      if (errors) {
-	sprintf(str,"ERROR - warning %d error(s)\n",errors);
-	DoPrompt(str);
-      }
-      else {
-	sprintf(str,"OK - no error(s)... success!\n");
-	DoPrompt(str);
-      }
-    }
-    else {
-      sprintf(str,"ERROR - usage: hvdiff <PXL id> <hv difference>\n");
-      DoPrompt(str);
-    }
-    return 0;
-
-  }
-
-      // End: Write difference of high voltage --------------------------------------------------------------------
-  
-
-
-  // List HV boards
-  else if (Match(status->Param[0], "list")) {
-    
-    sprintf(str,"OK - %d HV board(s) active:\n",hv->GetNumberOfBoards());
-    DoPrompt(str);
-
-    for (int i=0;i<hv->GetNumberOfBoards();i++) {
-      sprintf(str,"OK - board %d (%s)\n",(hv->GetHVBoard(i))->GetBoardNumber(),(hv->GetHVBoard(i))->GetSerial());
-      DoPrompt(str);
-    }
-    
-    return 0;
-  }
-
-
-  // Load HV settings from file
-  else if (Match(status->Param[0], "load")) {
-
-    char param[20][MAX_COM_SIZE];
-    char buffer[128];
-
-    int nparam  = 0;
-    int nrows   = 0;
-    int board   = 0;
-    int chain   = 0;
-    int channel = 0;
-    int nboards = 0;
-    int errors  = 0;
-    unsigned int hvoltage = 0;
-
-    FILE *file;
-    
-    if (status->Param[1][0] && !status->Param[2][0]) {
-      
-      if ((file=fopen((char *)Chop(status->Param[1]),"r"))!=NULL) {
-	
-	if (status->Verbose) {
-	  sprintf(str,"OK - file \"%s\" opened\n",Chop(status->Param[1]));
-	  DoPrompt(str);
-	}
-	
-	StopMonitor();
-
-	while (fgets(buffer,100,file)) {
-	  
-	  ParseInput(buffer,&nparam,param);
-	  
-	  if (nparam==2 && Match(param[0],"Device:")) {
-	    	    
-	    for (int j=0;j<hv->GetNumberOfBoards();j++)
-	      if (Match(Chop(status->fUSBDevice[j]),Chop(param[1]))) {
-
-		board = j;
-		
-		sprintf(str,"OK - found HV settings for board %d (%s)\n",hv->GetHVBoard(board)->GetBoardNumber(),Chop(param[1]));
-		DoPrompt(str);
-		
-		nboards++;
-		nrows = 0;
-	      
-		while (fgets(buffer,100,file)) {
-		  
-		  ParseInput(buffer,&nparam,param);
-		  
-		  if (nparam==8) { 
-
-		    chain = nrows/4;
-
-		    if (!((nrows)%4)) {
-		      sprintf(str,"OK - updating board %d chain %d\n",hv->GetHVBoard(board)->GetBoardNumber(),chain);
-		      DoPrompt(str);
-		    }
-
-		    
-		    for (int i=0;i<nparam;i++) {
-		      
-		      hvoltage = atoi(param[i]);
-		      channel  = (i+8*nrows)%32;
-		      
-		      // Submit HV values
-		      if ((hv->GetHVBoard(board))->SetHV(stdout,chain,channel,hvoltage,rbuf,status->Verbose)==1) {
-			
-			status->HV[board][chain][channel]=hvoltage;
-			UpdateStatus(board,rbuf);
-			
-			if (status->Verbose) {
-			  sprintf(str,"OK - board %d: high voltage of chain %d channel %d set to %d | 0X%.4X\n",
-				  hv->GetHVBoard(board)->GetBoardNumber(),chain,channel,hvoltage,hvoltage);
-			  DoPrompt(str);
-			  sPrintStatus(status,str,board);
-			  DoPrompt(str);
-			}
-		      }
-		      else {
-			sprintf(str,"ERROR - board %d error: could not set HV - check timeout and try again\n",hv->GetHVBoard(board)->GetBoardNumber());
-			DoPrompt(str);
-			errors++;
-		      }
-		      
-		    }
-		    
-		    nrows++;
-		    
-		  }
-		  else if (nparam==2)
-		    break;
-		}
-	      }
-	  } 
-	}
-	
-	if (fclose (file)) {
-	  sprintf(str,"ERROR - could not close file \"%s\"\n",Chop(status->Param[1]));
-	  DoPrompt(str);
-	} 
-	else {
-	  if (status->Verbose) {
-	    sprintf(str,"OK - file \"%s\" closed\n",Chop(status->Param[1]));
-	    DoPrompt(str);
-	  }
-	}
-
-	if (nboards!=hv->GetNumberOfBoards()) {
-	  sprintf(str,"ERROR - warning: could not load HV settings for all connected HV boards\n");
-	  DoPrompt(str);
-	}
-	else {
-	  sprintf(str,"OK - success: read HV settings for all connected HV boards\n");
-	  DoPrompt(str);
-	}
-
-	if (errors) {
-	  sprintf(str,"ERROR - warning %d error(s) => check timeout and try again\n",errors);
-	  DoPrompt(str);
-	}
-	else {
-	  sprintf(str,"OK - no error(s)... success!\n");
-	  DoPrompt(str);
-	}
-	
-      }
-      else {
-	sprintf(str,"ERROR - could not open file \"%s\"\n",Chop(status->Param[1]));
-	DoPrompt(str);
-      }
-      
-    }
-    else
-      DoPrompt("ERROR - usage: load <file>\n");
-
+      } // Loop over boards
+    } // while()
+    	    
     StartMonitor();
-
-    return 0;
-    
+    	
+    if (NBoards != NumHVBoards) {
+      PrintMessage("Warning: Could not load HV settings for all connected HV boards\n");
+    }
+    else if (Errors == 0) PrintMessage("Success: Read HV settings for all connected HV boards\n");
+    if (Errors != 0) PrintMessage("Warning: Errors on %d channel(s) occurred\n", Errors);
+    
+    if (fclose(File) != 0) PrintMessage("Error: Could not close file '%s'\n",Param[1]);
+
+    return;    
   }
 	   
 
-  // Enable/disable logging
-  else if (Match(status->Param[0], "log")) {
-
-    if (Match(status->Param[1], "on") && status->Param[1][0]) {
-      status->Log = TRUE;
-      sprintf(str,"OK - logging enabled\n");
-      DoPrompt(str);
-    }
-    
-    else if (Match(status->Param[1], "off") && status->Param[1][0]) {
-      status->Log = FALSE;
-      sprintf(str,"OK -logging disabled\n");
-      DoPrompt(str);
-    }
-    
-    else
-      DoPrompt("ERROR - usage: log <on>|<off>\n");
-  
-    return 0;
-  }
-
-
   // Set status refresh rate
-  if (Match(status->Param[0], "rate")) {
-
-    if (!NBoards())
-      return 0;
-
-    if (status->Param[1][0]>0) {
-
-      if (!IsNoDigit(status->Param[1])) {
-	DoPrompt("ERROR - wrong input format - usage: rate <rate>\n");
-	return 0;
-      }
-      // Check limits
-      else if (atof(status->Param[1]) < MIN_RATE || atof(status->Param[1]) > MAX_RATE) {
-	sprintf(str,"ERROR - refresh rate out of range (min: %.2f Hz, max: %.2f Hz)!\n",MIN_RATE,MAX_RATE);
-	DoPrompt(str);
-	return 0;
-      }
-      else {
-	StopMonitor();
-	status->fStatusRefreshRate=atof(status->Param[1]);
-	sprintf(str,"OK - status refresh rate set to %.2f Hz\n",status->fStatusRefreshRate);
-	DoPrompt(str);
-      }
-      StartMonitor();
-      return 0;
-      
-    }
-    else {
-      sprintf(str,"ERROR - usage: rate <rate>\n");
-      DoPrompt(str);
-    }
-    
-    return 0;
-  }
-
-  /*
-  // Read from device - NEVER use this function with a real HV board!!!
-  if (Match(status->Param[0], "read")) {
-
-    if (!NBoards())
-      return 0;
-
-    if (status->state==active) {
-      StopMonitor();
-      sprintf(str,"warning: status monitoring deactivated\n");
-      DoPrompt(str);
-    }
-    
-    for (int i=status->FirstBoard;i<=status->LastBoard;i++) {
-      if (1 == ((hv->GetHVBoard(i))->Read(rbuf,1))) {
-	sPrintByteBin(rbuf[0],bdata);
-	sprintf(str,"%d byte(s) read (board %d): %d | 0X%.2X | B%s\n",1,i,rbuf[0],rbuf[0],bdata);
-      }
-      else
-	sprintf(str,"error: could not read from board %d\n",i);
-
-      usleep(1000);
-
-      DoPrompt(str);
-    }
-
-    return 0;
-  } 
-  */
+  if (Match(Param[0], "rate")) {
+
+    double Rate;
+    
+    if (!NumHVBoards) return;
+
+    if (NParam != 2) {
+      PrintMessage("Usage: rate <Hz>\n");
+      return;
+    }
+    
+    if (!ConvertToDouble(Param[1], &Rate)) {
+       PrintMessage("Error: Wrong number format\n");
+       return;   
+    }
+
+    // Check limits
+    if (Rate<MIN_RATE || Rate>MAX_RATE) {
+      PrintMessage("Refresh rate out of range (min: %.2f Hz, max: %.2f Hz)\n", MIN_RATE, MAX_RATE);
+      return;
+    }
+
+    StopMonitor();
+    fStatusRefreshRate = Rate;
+    PrintMessage("Refresh rate set to %.2f Hz\n", fStatusRefreshRate);
+    StartMonitor();
+
+    return;
+  }
   
   // Reset
-  if (Match(status->Param[0], "reset")) {
-
-    if (!NBoards())
-      return 0;
+  if (Match(Param[0], "reset")) {
+
+    if (!NumHVBoards) return;
 
     StopMonitor();
     ResetActiveBoards();
-    ReInitStatus(status);
     StartMonitor();
-    return 0;
-  }
-
-
-  // Start ROOT
-  else if (Match(status->Param[0], "root")) {
-    
-    sprintf(str,"OK - starting ROOT... type '.q' to return\n");
-    DoPrompt(str);
-    system ("root");
-
-  return 0;
-  
+    return;
   }
 
 
   // Save HV settings of all boards
-  else if (Match(status->Param[0], "save")) {
-
-    if (status->Param[1][0] && !status->Param[2][0]) {
-      
-      if (SaveHVSettings(Chop(status->Param[1]))) {
-	sprintf(str,"OK - HV settings written to \"%s\"\n",Chop(status->Param[1]));
-	DoPrompt(str);
+  else if (Match(Param[0], "save")) {
+
+    FILE *File;
+    time_t time_now_secs;
+    struct tm *Time;
+
+    if (NParam != 2) {
+      PrintMessage("Usage: save <Filename>\n");
+      return;
+    }
+  
+    time(&time_now_secs);
+    Time = localtime(&time_now_secs);
+
+    if ((File = fopen(Param[1], "w")) == NULL) {
+      PrintMessage("Error: Could not open file '%s' (%s)\n", Param[1], strerror(errno));
+      return;
+    }
+  
+    fprintf(File,"********** HV settings, %04d %02d %02d, %02d:%02d:%02d **********\n\n",
+	    1900 + Time->tm_year, 1 + Time->tm_mon,
+	    Time->tm_mday, Time->tm_hour, Time->tm_min, Time->tm_sec);
+  
+    for (int i=0; i<NumHVBoards; i++) {
+      fprintf(File, "%s\n\n", fHVBoard[i]->BoardName);
+
+      for (int j=0; j<NUM_CHAINS; j++) {
+	for (int k=0; k<NUM_CHANNELS; k++) fprintf(File,"%5d ",fHVBoard[i]->HV[j][k]);
+	fprintf(File, "\n");
       }
-      
-    }
-    else {
-      
-      char buffer[MAX_COM_SIZE];
-      
-      time_t time_now_secs;
-      struct tm *time_now;
-      
-      time(&time_now_secs);
-      time_now = localtime(&time_now_secs);
-      
-      sprintf(buffer,"OK - hvsettings/HV_%04d-%02d-%02d_%02d-%02d-%02d.txt",
-	      1900 + time_now->tm_year, 
-	      1 + time_now->tm_mon,
-	      time_now->tm_mday,
-	      time_now->tm_hour,
-	      time_now->tm_min,
-	      time_now->tm_sec);
-
-      //sprintf(str,"warning: HV settings will be written to \"%s\"\n",buffer);
-      //DoPrompt(str);
-      
-      if (SaveHVSettings(buffer)) {
-	sprintf(str,"OK - HV settings successfully written to \"%s\"\n",buffer);
-	DoPrompt(str);
-      }
-    }
-
-    return 0;
-   
+      fprintf(File, "\n");
+    }
+
+    if (fclose(File) != 0) {
+      PrintMessage("Error: Could not close file '%s' (%s)\n", Param[1], strerror(errno));  
+    }
+
+    return;
   }
 
 
   // Start monitoring
-  else if (Match(status->Param[0], "start")) {
-
-    if (!NBoards())
-      return 0;
-    
-    if (status->state==active) {
-      sprintf(str,"OK - status monitoring is already active\n");
-      DoPrompt(str);
-      return 0;
-    }
-
+  else if (Match(Param[0], "start")) {
+
+    if (!NumHVBoards) return;
+    
     StartMonitor();
-
-    sprintf(str,"OK - status monitoring activated\n");
-    DoPrompt(str);
-
-    return 0;
-  
+    PrintMessage("OK - status monitoring activated\n");
+
+    return;  
   }
 
  
   // Print status
-  else if (Match(status->Param[0], "status") || Match(status->Param[0], "info")) {
-    
-    if (!NBoards())
-      return 0;
-
-    PrintStatus(status,config,stdout);
-    PrintStatus(status,config,log->logptr);
-
-    return 0;
+  else if (Match(Param[0], "status")) {
+    
+    PrintMessage("\n Status monitor: %s\n", state_str[state]);
+    PrintMessage(" Verbose: %s\n", Verbose ? "on" : "off");
+    PrintMessage(" Status refresh rate [Hz]: %.2f\n", fStatusRefreshRate);
+    PrintMessage(" Socket state: %s\n", Socket==-1 ? "disconnected":"connected");
+    PrintMessage(" Total number of HV boards: %d\n", NumHVBoards);
+    PrintMessage(" Active HV boards: %d\n\n ", LastBoard - FirstBoard + 1);
+
+    for (int i=FirstBoard; i<=LastBoard; i++) {
+      PrintMessage(" BOARD %d (%s)   Wrap counter: %s (%d)  Manual reset: %s  Time-out: %.2f s\n\n",
+	fHVBoard[i]->GetBoardNumber(), fHVBoard[i]->BoardName,
+	fHVBoard[i]->WrapOK ? "ok":"error",
+	fHVBoard[i]->LastWrapCount, 
+	fHVBoard[i]->ResetButton ? "yes" : "no",
+	fHVBoard[i]->fTimeOut);
+
+      for (int j=FirstChain; j<=LastChain; j++) {
+	PrintMessage("  CHAIN %d     Over-current: %s\n ", j, fHVBoard[i]->Overcurrent[j] ? "yes" : "no");
+	for (int k=0;k<4;k++) {
+	  for (int l=0;l<8;l++) {
+	    if(NParam == 2) PrintMessage("%5d ",fHVBoard[i]->HV[j][k*8+l]);
+    	    else PrintMessage("%#5.2f ",fHVBoard[i]->HVV[j][k*8+l]);
+    	  }
+	  PrintMessage("\n ");
+	}
+	  PrintMessage("\n ");
+      }
+    }
+
+    return;
   } 
 
 
   // Stop monitoring
-  else if (Match(status->Param[0], "stop")) {
-
-    if (!NBoards())
-      return 0;
-    
-    if (status->state!=active) {
-      sprintf(str,"OK - status monitoring is already deactivated\n");
-      DoPrompt(str);
-      return 0;
-    }
-
-    StopMonitor();
-    
-    sprintf(str,"ERROR - warning: status monitoring deactivated\n");
-    DoPrompt(str);
-
-    return 0;
-  
-  }
-
-  /*
-  // Sweep HV
-  else if (Match(status->Param[0], "sweep")) {
-
-    if (!NBoards())
-      return 0;
-
-    int errors = 0;
-    int channel = 0;
-
-    unsigned int hv1 = 0;
-    unsigned int hv2 = 0;
-    unsigned int dv  = 10;
-
-    bool allchannels = FALSE;
-
-    float delay = 1.;
-
-    if (status->Param[1][0]>0 && status->Param[2][0]>0 && status->Param[3][0]>0 && status->Param[4][0]>0){
-      
-      if (status->Param[1][0] == 'a' )
-	allchannels = TRUE;
-      else if (IsNoDigit(status->Param[1])) {
-	channel = atoi(status->Param[1]);
-	// Check limits
-	if (channel>31 || channel <0) {
-	  DoPrompt("channel out of range (0...31)!\n");
-	  return 0;
-	}
+  else if (Match(Param[0], "stop")) {
+
+    if (!NumHVBoards) return;
+    
+    StopMonitor();    
+    PrintMessage("Status monitor stopped\n");
+
+    return;
+  }
+
+
+  // Set timeout to return from read
+  if (Match(Param[0], "timeout")) {
+
+    double Timeout;
+    
+    if (!NumHVBoards) return;
+
+    if (NParam != 2) {
+      PrintMessage("Usage: timeout <secs>\n");
+      return;
+    }
+    
+    if (!ConvertToDouble(Param[1], &Timeout)) {
+       PrintMessage("Error: Wrong number format\n");
+       return;   
+    }
+
+    for (int i=0; i<NumHVBoards; i++) fHVBoard[i]->SetTimeOut(Timeout);
+    PrintMessage("Timeout set to %.2f s for all boards\n", Timeout);
+    
+    return;
+  }
+
+    
+  // Print uptime
+  if (Match(Param[0], "uptime")) {
+    time_t ActualT;
+    time (&ActualT);
+
+    PrintMessage("%d:%02d:%02d\n", (int) difftime(ActualT, StartTime)/3600, ((int) difftime(ActualT, StartTime)/60)%60, (int) difftime(ActualT, StartTime)%60);
+
+    return;
+  } 
+
+
+  // Enable/disable verbosity
+  else if (Match(Param[0], "verbose")) {
+
+    if (Match(Param[1], "on")) {
+      Verbose = true;
+      PrintMessage("Verbosity enabled\n");
+    }    
+    else if (Match(Param[1], "off")) {
+      Verbose = false;
+      PrintMessage("Verbosity disabled\n");
+    }
+    else PrintMessage("Usage: verbose <on>|<off>\n");
+  
+    return;
+  }
+  
+  
+  // Exit program
+  else if(Match(Param[0], "exit")) {
+
+    if (CmdFromSocket) {
+      PrintMessage("Exit command not allowed over socket.\n");
+      return;
+    }  	
+
+    Exit = true;
+    pthread_kill(HVMonitor, SIGUSR1);
+    pthread_kill(SocketThread, SIGUSR1);
+ 
+    return;
+  }
+  
+  PrintMessage("Unknown command '%s'\n", Param[0]);
+ 
+  return;
+}
+
+
+// Print message to selected target
+void ProcessIO::PrintMessage(int Target, const char *Format, ...) {
+  va_list ArgumentPointer;
+  va_start(ArgumentPointer, Format); 
+  PrintMessage(Target, Format, ArgumentPointer);
+  va_end(ArgumentPointer);
+}
+
+// Print message to log file, and screen or socket (depending on command origin)
+void ProcessIO::PrintMessage(const char *Format, ...) {
+  va_list ArgumentPointer;
+  va_start(ArgumentPointer, Format);
+  if (CmdFromSocket) PrintMessage(MsgToSocket|MsgToLog, Format, ArgumentPointer);
+  else PrintMessage(MsgToConsole|MsgToLog, Format, ArgumentPointer);
+  va_end(ArgumentPointer);
+}
+
+// Function doing the actual printing work
+void ProcessIO::PrintMessage(int Target, const char *Format, va_list ArgumentPointer) {
+
+  char Textbuffer[MAX_COM_SIZE];
+
+  memset(Textbuffer, 0, sizeof(Textbuffer));  
+  vsnprintf(Textbuffer, sizeof(Textbuffer), Format, ArgumentPointer);
+  
+  // Print to console
+  if(Target & MsgToConsole) {
+    if(strlen(Textbuffer)>0 && Textbuffer[strlen(Textbuffer)-1]=='\n') {
+      printf("\r%s%s", Textbuffer, Prompt);   // New prompt
+      fflush(stdout);
+    }
+    else printf("%s", Textbuffer);
+  }
+  // Print to log file
+  if((Target & MsgToLog) && Logfile!=NULL) {
+    fprintf(Logfile, "%s", Textbuffer);
+    fflush(Logfile);
+  }
+  // Print to socket
+  if((Target & MsgToSocket) && Socket!=-1) {
+    write(Socket, Textbuffer, strlen(Textbuffer));
+  }
+}
+
+
+// Ramp to new voltage with maximum step size given in config->fHVMaxDiff
+// No ramping when decreasing voltage
+bool ProcessIO::RampVoltage(unsigned int Target, int Board, int Chain, int Channel) {
+
+  int Diff;
+  
+  while (fHVBoard[Board]->HV[Chain][Channel] != (int) Target) {	  
+    Diff = Target - fHVBoard[Board]->HV[Chain][Channel];
+    if (Diff > (int) config->fHVMaxDiff) Diff = config->fHVMaxDiff;
+
+    if (fHVBoard[Board]->SetHV(stdout, Chain, Channel, fHVBoard[Board]->HV[Chain][Channel]+Diff, Verbose)==1) {
+      fHVBoard[Board]->HV[Chain][Channel] += Diff;
+
+      if (Verbose) {
+	PrintMessage("OK - board %d: high voltage of chain %d channel %d set to %d | 0X%.4X | %f V\n",fHVBoard[Board]->GetBoardNumber(),Chain, Channel, Target, Target, calib->DACToHV(Target,fHVBoard[Board]->GetBoardNumber(),Chain,Channel));
+	PrintBoardStatus(Board);
       }
-      
-      if (IsNoDigit(status->Param[2]) && IsNoDigit(status->Param[3]) && IsNoDigit(status->Param[4])) {
-	
-	hv1 = atoi(status->Param[2]);
-	hv2 = atoi(status->Param[3]);
-	dv  = atoi(status->Param[4]);
-	
-	if ((hv1>0X3FFF || hv1 <0) || (hv2>0X3FFF || hv2 <0)) {
-	  DoPrompt("high voltage out of range (Vmin: 0, Vmax: 16383)!\n");
-	  return 0;
-	}
-
-	if (hv1 > hv2) {
-	  DoPrompt("wrong limits (Vmin < Vmax)!\n");
-	  return 0;
-	}
-
-	if (dv < 1 || dv > abs(hv2-hv1)) {
-	  DoPrompt("step size out of range (dVmin: 1, dVmax: |hv2-hv1|)!\n");
-	  return 0;
-	}
-	
-	if (status->Param[5][0]>0 && IsNoDigit(status->Param[5])) {
-	  if (atof(status->Param[5])<MIN_SWEEP_RATE || atof(status->Param[5])>MAX_SWEEP_RATE) {
-	    sprintf(str,"rate out of range (min: %.2f Hz, max: %.2f Hz)!\n",MIN_SWEEP_RATE,MAX_SWEEP_RATE);	    
-	    DoPrompt(str);
-	    return 0;
-	  }
-	  else 
-	    delay = 1./atof(status->Param[5]);
-	}
+    }
+    else {
+      PrintMessage("ERROR - Could not set HV of board %d, chain %d, channel %d. Skipping channel\n",fHVBoard[Board]->GetBoardNumber(),Chain,Channel);
+      return false;
+    }
+  }
+  return true;
+}
+
+void ProcessIO::StartMonitor() {
+
+  state = active;
+  pthread_kill(HVMonitor, SIGUSR1);
+}
+
+
+void ProcessIO::StopMonitor() {
+
+  state = stopped;
+  pthread_kill(HVMonitor, SIGUSR1);
+}
+
+
+void ProcessIO::Monitor() {
+
+  for (int i=0; i<NumHVBoards; i++) {
+
+    if (fHVBoard[i]->GetStatus(stdout,false)!=1) {
+      PrintMessage("Error: Monitor, could not read status of board %d\n", fHVBoard[i]->GetBoardNumber());
+    }
+    
+    if (fHVBoard[i]->ResetButton) {
+      PrintMessage("Manual reset of board %d\n",fHVBoard[i]->GetBoardNumber());
+      ResetBoard(i);
+    }
+    
+    if (!fHVBoard[i]->WrapOK) {
+      PrintMessage("Error: Wrap counter mismatch board %d\n",fHVBoard[i]->GetBoardNumber());
+    }
+
+    for (int j=0; j<NUM_CHAINS; j++) {
+      if (fHVBoard[i]->Overcurrent[j]) {
+	PrintMessage("Warning: Overcurrent in chain %d of board %d\n",j,fHVBoard[i]->GetBoardNumber());
+	ResetBoard(i);
       }
-      else {
-	DoPrompt("error: wrong input format - usage: sweep <channel>|<all> <v1> <v2> <dv> [rate]\n");
-	return 0;
-      }
-
-
-      StopMonitor();
-      
-      for (int i=status->FirstBoard;i<=status->LastBoard;i++) 
-	for (int j=status->FirstChain;j<=status->LastChain;j++) {
-	  if (!allchannels) {
-	    
-	    for (unsigned int v = hv1; v<=hv2; v+=dv) {
-	      if ((hv->GetHVBoard(i))->SetHV(stdout,j,channel,v,rbuf,status->Verbose)==1) {
-		sprintf(str,"board %d: high voltage of chain %d channel %d set to %d | 0X%.4X\n",i,j,channel,v,v);
-		status->HV[i][j][channel]=v;
-		DoPrompt(str);
-		UpdateStatus(i,rbuf);
-		sPrintStatus(status,str,i);
-		DoPrompt(str);
-	      }
-	      else {
-		sprintf(str,"board %d error: could not set hv - check timeout and try again\n",i);
-		DoPrompt(str);
-		errors++;
-	      }
-
-	      usleep((unsigned long)floor(delay*1000000.));
-	    }
-
-	  }
-	  else {
-	    for (int k=0;k<MAX_NUM_CHANNELS;k++) {
-
-	      for (unsigned int v = hv1; v<=hv2; v+=dv) {
-		
-		if ((hv->GetHVBoard(i))->SetHV(stdout,j,k,v,rbuf,status->Verbose)==1) {
-		  sprintf(str,"board %d: high voltage of chain %d channel %d set to %d | 0X%.4X\n",i,j,k,v,v);
-		  status->HV[i][j][k]=v;
-		  DoPrompt(str);
-		  UpdateStatus(i,rbuf);
-		  sPrintStatus(status,str,i);
-		  DoPrompt(str);
-		}
-		else {
-		  sprintf(str,"board %d error: could not set hv - check timeout and try again\n",i);
-		  DoPrompt(str);
-		  errors++;
-		}
-		
-		usleep((unsigned long)floor(delay*1000000.));
-
-	      }
-	    }
-	  }
-	}
-
-      StartMonitor();
-
-      if (errors) {
-	sprintf(str,"warning %d error(s) => check timeout and try again\n",errors);
-	DoPrompt(str);
-      }
-      else {
-	sprintf(str,"no error(s)... success!\n");
-	DoPrompt(str);
-      }
+    }
+  }
+}
+
+
+void ProcessIO::ResetActiveBoards() {
+  
+  for (int i=FirstBoard; i<=LastBoard; i++) ResetBoard(i);
+}
+
+
+void ProcessIO::ResetBoard(int i) {
+    
+  if (fHVBoard[i]->Reset(stdout,Verbose) == 1) {
+    PrintMessage("Reset of board %d\n", fHVBoard[i]->GetBoardNumber());
+    PrintBoardStatus(i);
+  }
+  else PrintMessage("Error: Could not reset board %d\n",fHVBoard[i]->GetBoardNumber());
+}
+
+
+int ProcessIO::GetBoardIdx(int board) {
+
+  for (int i=0; i<MAX_NUM_HVBOARDS; i++) {
+    if (board == fHVBoard[i]->GetBoardNumber()) return i;
+  }
+  return -1;
+}
+
+
+void ProcessIO::PrintBoardStatus(int i) {
+
+  PrintMessage("Status board %d (%s): MR %s OC0 %s OC1 %s OC2 %s OC3 %s WC %s (%d)\n",
+    	  fHVBoard[i]->GetBoardNumber(), fHVBoard[i]->BoardName,
+	  fHVBoard[i]->ResetButton ? "yes" : "no",
+	  fHVBoard[i]->Overcurrent[0] ? "yes" : "no",
+	  fHVBoard[i]->Overcurrent[1] ? "yes" : "no",
+	  fHVBoard[i]->Overcurrent[2] ? "yes" : "no",
+	  fHVBoard[i]->Overcurrent[3] ? "yes" : "no",
+	  fHVBoard[i]->WrapOK ? "ok":"error", fHVBoard[i]->LastWrapCount);
+}
+
+
+// Parse command line for white space and double-quote separated tokens 
+int ProcessIO::ParseInput(char* Command, const char *Param[]) {
+  int Count=0;
+   
+  while(Count<MAX_NUM_TOKEN) {
+    while (isspace(*Command)) Command++; // Ignore initial white spaces
+    if(*Command=='\0') break;
+    if (*Command == '\"') {
+      Param[Count] = ++Command;
+      while(*Command!='\"' && *Command!='\0') Command++;
     }
     else {
-      DoPrompt("usage: sweep <channel>|<all> <v1> <v2> <dv> [rate]\n");
-      return 0;
-    }
-    
-    return 0;
-  
-  }
-  */
-
-  // Print time and date
-  else if (Match(status->Param[0], "date") || Match(status->Param[0], "time")) {
-
-    PrintDateAndTime();
-   
-    return 0;
-  } 
-
-
-  /*
-  // Test I/O - NEVER use this function with a real HV board!!!
-  else if (Match(status->Param[0], "testio")) {
-
-    for (int i=status->FirstBoard;i<=status->LastBoard;i++) 
-      (hv->GetHVBoard(i))->TestIO();
-
-    return 0;
-  } 
-  */
-
-
-  // Set timeout to return from read
-  if (Match(status->Param[0], "timeout")) {
-
-    if (!NBoards())
-      return 0;
-
-    if (status->Param[1][0]>0) {
-
-      if (!IsNoDigit(status->Param[1])) {
-	DoPrompt("ERROR - wrong input format - usage: timeout <time>\n");
-	return 0;
-      }
-      // Check limits
-      else if (atof(status->Param[1]) < MIN_TIMEOUT || atof(status->Param[1]) > MAX_TIMEOUT) {
-	sprintf(str,"ERROR -timeout out of range (min: %.2f s, max: %.2f s)!\n",MIN_TIMEOUT,MAX_TIMEOUT);
-	DoPrompt(str);
-	return 0;
-      }
-      else {
-	StopMonitor();  
-	for (int i=0;i<hv->GetNumberOfBoards();i++) 
-	  (hv->GetHVBoard(i))->SetTimeOut((float)atof(status->Param[1]));
-	status->fTimeOut = atof(status->Param[1]);	
-	sprintf(str,"OK - timeout set to %.2f s\n",status->fTimeOut);
-
-	DoPrompt(str);
-	
-	StartMonitor();
-	return 0;
-      }
-    }
-    else {
-      sprintf(str,"ERROR - usage: timeout <time>\n");
-      DoPrompt(str);
-    }
-    
-    return 0;
-  }
-
-    
-  // Print uptime
-  if (Match(status->Param[0], "uptime")) {
-
-    double difftime = GetDiffTime(&StartTime);
-
-    sprintf(str,"OK - %d:%02d:%02d\n",(int)difftime/SECONDS_HOUR,((int)difftime/SECONDS_MINUTE)%SECONDS_MINUTE,(int)difftime%SECONDS_MINUTE);
-    DoPrompt(str);
-
-    return 0;
-  } 
-
-
-  // Enable/disable verbosity
-  else if (Match(status->Param[0], "verbose")) {
-
-    if (Match(status->Param[1], "on") && status->Param[1][0]) {
-      if (status->Verbose == TRUE) {
-	sprintf(str,"OK - verbosity is already enabled\n");
-	DoPrompt(str);
-      }
-      else {
-	status->Verbose = TRUE;
-	sprintf(str,"OK - verbosity enabled\n");
-	DoPrompt(str);
-      }
-    }
-    
-    else if (Match(status->Param[1], "off") && status->Param[1][0]) {
-      if (status->Verbose == FALSE) {
-	sprintf(str,"OK - verbosity is already disabled\n");
-	DoPrompt(str);
-      }
-      else {
-	status->Verbose = FALSE;
-	sprintf(str,"OK - verbosity disabled\n");
-	DoPrompt(str);
-      }
-    }
-    
-    else
-      DoPrompt("ERROR - usage: verbose <on>|<off>\n");
-  
-    return 0;
-  }
-  
-  
-  // Write reference voltage
-  if (Match(status->Param[0], "vref")) {
-
-    if (!NBoards())
-      return 0;
-
-    unsigned int voltage = 0;
-
-    if (status->Param[1][0]>0) {
-      
-      // Binary input
-      if (tolower(status->Param[1][0])=='x' && strlen(status->Param[1])>2) {
-	if (sPrintHex2Dec(Chop(status->Param[1]+1),&voltage)!=0) {
-	    DoPrompt("ERROR - wrong input format - usage: vref <voltage>\n");
-	    return 0;
-	}
-      }
-      // Hexadecimal input
-      else if (tolower(status->Param[1][0])=='b' && strlen(status->Param[1])>2) {
-	if (sPrintBin2Dec(Chop(status->Param[1]+1),&voltage)!=0) {
-	  DoPrompt("ERROR - wrong input format - usage: vref <voltage>\n");
-	  return 0;
-	}
-      }
-      // Decimal input
-      else if (IsNoDigit(status->Param[1]))
-	voltage = atoi(status->Param[1]);
-      // Wrong input format
-      else {
-	DoPrompt("ERROR - wrong input format - usage: vref <voltage>\n");
-	return 0;
-      }
-
-      // Check limits
-      if (voltage>0X3FFF || voltage <0) {
-	DoPrompt("ERROR - reference voltage out of range (Vmin: 0, Vmax: 16383)!\n");
-	return 0;
-      }
-
-
-      StopMonitor();
-          
-      for (int i=status->FirstBoard;i<=status->LastBoard;i++) 
-	for (int j=status->FirstChain;j<=status->LastChain;j++) {
-	  if (((hv->GetHVBoard(i))->SetVRef(stdout,j,voltage,rbuf,status->Verbose)==1)) {
-	    sprintf(str,"OK - board %d: reference voltage of chain %d set to %d | 0X%.4X\n",hv->GetHVBoard(i)->GetBoardNumber(),j,voltage,voltage);
-	    status->VRef[i][j]=voltage;
-	    DoPrompt(str);
-	    UpdateStatus(i,rbuf);
-	    sPrintStatus(status,str,i);
-	    DoPrompt(str);
-	  } else {
-	    sprintf(str,"ERROR - board %d error: could not set vref - check timeout and try again\n",hv->GetHVBoard(i)->GetBoardNumber());
-	    DoPrompt(str);
-	  }
-	}
-      
-      StartMonitor();
-    }
-    else {
-      sprintf(str,"ERROR - usage: vref <voltage>\n");
-      DoPrompt(str);
-    }
-
-    return 0;
-  }
-
-  /*
-  // Write to device - NEVER use this function with a real HV board!!!
-  if (Match(status->Param[0], "write")) {
-    
-    if (!NBoards())
-      return 0;
-
-    if (status->Param[1][0]>0) {
-      
-      // Binary input
-      if (tolower(status->Param[1][0])=='x' && strlen(status->Param[1])>2) {
-	if (sPrintHex2Dec(Chop(status->Param[1]+1),(unsigned int*)wbuf)!=0) {
-	  DoPrompt("wrong input format or value out of range!\n");
-	  return 0;
-	}
-      }
-      // Hexadecimal input
-      else if (tolower(status->Param[1][0])=='b' && strlen(status->Param[1])>2) {
-	if (sPrintBin2Dec(Chop(status->Param[1]+1),(unsigned int*)wbuf)!=0) {
-	  DoPrompt("wrong input format or value out of range!\n");
-	  return 0;
-	}
-      }
-      // Decimal input
-      else if (atoi(status->Param[1])>=0 && atoi(status->Param[1])<=255 && IsNoDigit(status->Param[1]))
-	wbuf[0] = (unsigned char)atoi(status->Param[1]);
-      // Wrong input
-      else {
-	DoPrompt("wrong input format or value out of range!\n");
-	return 0;
-      }
-      
-      if (status->state==active) {
-	StopMonitor();
-	sprintf(str,"warning: status monitoring deactivated\n");
-	DoPrompt(str);
-      }
-      
-      for (int i=status->FirstBoard;i<=status->LastBoard;i++) 
-        if ((hv->GetHVBoard(i))->Write(wbuf,1) == 1) {
-	  sPrintByteBin(wbuf[0],bdata);
-	  sprintf(str,"%d byte(s) written (board %d): %d | 0X%.2X | B%s\n",1,i,wbuf[0],wbuf[0],bdata);
-	  DoPrompt(str);
-	}
-	else {
-	  sprintf(str,"error: could not write to board %d\n",i);
-	  DoPrompt(str);
-	}
-
-    }
-    else {
-      sprintf(str,"error: no input\n");
-      DoPrompt(str);
-    }
-    return 0;
-  }
-  */
-
-  // Exit program
-  else if(Match(status->Param[0], "exit") || Match(status->Param[0], "quit")) {
-
-    StopMonitor();
-    
-    ResetAllBoards();
-
-    status->Exit = TRUE;
-
-    pthread_kill(status->HVMonitor, SIGUSR1);
-    pthread_kill(status->SocketThread, SIGUSR1);
- 
-    return 0;
-  }
-  
-  else if (strchr(status->Param[0],'\n')-status->Param[0]==0) {
-    return 0;
-  }
-
-  else {
-    
-    if (strchr(status->Param[0],'\n') == 0)
-      sprintf(str,"ERROR - unknown command: %s\n",status->Param[0]);
-    else
-      sprintf(str,"ERROR - unknown command: %s",status->Param[0]);
-    
-    DoPrompt(str);
-    
-    return 0;
-
-  }
- 
-  return 0;
-}
-
-
-void ProcessIO::PrintDateAndTime() {
-
-  char str[MAX_COM_SIZE];
-
-  time_t rawtime;
-  struct tm * timeinfo;
-  
-  time(&rawtime);
-  timeinfo = localtime(&rawtime); // Get local time
-  fflush(stdout);
-  sprintf(str,"OK - current date/time is: %s",asctime(timeinfo));
-  DoPrompt(str);
-
-}
-
-void ProcessIO::DoPrompt(char* str) {
-  if (str!=NULL) {
-    if (status->Socket != -1) // Print status string to socket if open
-      write(status->Socket,str,strlen(str)+1);
-  }
-  else {
-    if (status->Socket != -1) // Print status string to socket if open
-      write(status->Socket,"OK\n",3);
-  }
-  if (str!=NULL) {
-    if (status->NumHVBoards == 0) {
-      sprintf(status->Prompt,"HV> %s",str);
-      printf(status->Prompt);
-      if (status->Log)
-	log->LogWrite(status->Prompt);
-      sprintf(status->Prompt,"HV> ");
-    }
-    else if (status->FirstBoard == status->LastBoard) {
-
-      int board = hv->GetHVBoard(status->FirstBoard)->GetBoardNumber();
-
-      if (status->FirstChain == status->LastChain) {
-	sprintf(status->Prompt,"HV|C%d|B%d> %s",status->FirstChain,board,str);
-	printf(status->Prompt);
-	if (status->Log)
-	  log->LogWrite(status->Prompt);
-	sprintf(status->Prompt,"HV|C%d|B%d> ",status->FirstChain,board);
-      }
-      else {
-	sprintf(status->Prompt,"HV|C%d-%d|B%d> %s",status->FirstChain,status->LastChain,board,str);
-	printf(status->Prompt);
-	if (status->Log)
-	  log->LogWrite(status->Prompt);
-	sprintf(status->Prompt,"HV|C%d-%d|B%d> ",status->FirstChain,status->LastChain,board);
-      }
-
-    }
-    else {
-     
-      int firstboard = (hv->GetHVBoard(status->FirstBoard)->GetBoardNumber() > hv->GetHVBoard(status->LastBoard)->GetBoardNumber()) ?
-	hv->GetHVBoard(status->LastBoard)->GetBoardNumber() : hv->GetHVBoard(status->FirstBoard)->GetBoardNumber();
-
-      int lastboard = (hv->GetHVBoard(status->FirstBoard)->GetBoardNumber() > hv->GetHVBoard(status->LastBoard)->GetBoardNumber()) ?
-	hv->GetHVBoard(status->FirstBoard)->GetBoardNumber() : hv->GetHVBoard(status->LastBoard)->GetBoardNumber();
-
-      if (status->FirstChain == status->LastChain) {
-	sprintf(status->Prompt,"HV|C%d|B%d-%d> %s",status->FirstChain,firstboard,lastboard,str);
-	printf(status->Prompt);
-	if (status->Log)
-	  log->LogWrite(status->Prompt);
-	sprintf(status->Prompt,"HV|C%d|B%d-%d> ",status->FirstChain,firstboard,lastboard);
-      }
-      else {
-	sprintf(status->Prompt,"HV|C%d-%d|B%d-%d> %s",status->FirstChain,status->LastChain,firstboard,lastboard,str);
-	printf(status->Prompt);
-	if (status->Log)
-	  log->LogWrite(status->Prompt);
-	sprintf(status->Prompt,"HV|C%d-%d|B%d-%d> ",status->FirstChain,status->LastChain,firstboard,lastboard);
-      }
-    }
-  }
-  else {
-    if (status->NumHVBoards == 0)
-      sprintf(status->Prompt,"HV> ");
-    else if (status->FirstBoard == status->LastBoard) {
-      
-      int board = hv->GetHVBoard(status->FirstBoard)->GetBoardNumber();
-
-      if (status->FirstChain == status->LastChain)
-	sprintf(status->Prompt,"HV|C%d|B%d> ",status->FirstChain,board);
-      else
-	sprintf(status->Prompt,"HV|C%d-%d|B%d> ",status->FirstChain,status->LastChain,board);
-    }
-    else {
-
-      int firstboard = (hv->GetHVBoard(status->FirstBoard)->GetBoardNumber() > hv->GetHVBoard(status->LastBoard)->GetBoardNumber()) ?
-	hv->GetHVBoard(status->LastBoard)->GetBoardNumber() : hv->GetHVBoard(status->FirstBoard)->GetBoardNumber();
-
-      int lastboard = (hv->GetHVBoard(status->FirstBoard)->GetBoardNumber() > hv->GetHVBoard(status->LastBoard)->GetBoardNumber()) ?
-	hv->GetHVBoard(status->FirstBoard)->GetBoardNumber() : hv->GetHVBoard(status->LastBoard)->GetBoardNumber();
-
-     if (status->FirstChain == status->LastChain)
-       sprintf(status->Prompt,"HV|C%d|B%d-%d> ",status->FirstChain,firstboard,lastboard);
-     else 
-       sprintf(status->Prompt,"HV|C%d-%d|B%d-%d> ",status->FirstChain,status->LastChain,firstboard,lastboard);
-     }
-  }
-}
-
-
-void ProcessIO::PrintMessage(char *str) {
-
-  char outstr[MAX_COM_SIZE];
-  
-  fflush(stdout);
-  if (str!=NULL) {
-
-    if (status->NumHVBoards == 0) 
-      sprintf(outstr,"%s\nHV> ",str); 
-    else if (status->FirstBoard == status->LastBoard) {
-      
-      int board = hv->GetHVBoard(status->FirstBoard)->GetBoardNumber();
-      
-      if (status->FirstChain == status->LastChain) 
-	sprintf(outstr,"%s\nHV|C%d|B%d> ",str,status->FirstChain,board); 
-      else 
-	sprintf(outstr,"%s\nHV|C%d-%d|B%d> ",str,status->FirstChain,status->LastChain,board); 
-    }
-    else {
-      
-      int firstboard = (hv->GetHVBoard(status->FirstBoard)->GetBoardNumber() > hv->GetHVBoard(status->LastBoard)->GetBoardNumber()) ?
-	hv->GetHVBoard(status->LastBoard)->GetBoardNumber() : hv->GetHVBoard(status->FirstBoard)->GetBoardNumber();
-      
-      int lastboard = (hv->GetHVBoard(status->FirstBoard)->GetBoardNumber() > hv->GetHVBoard(status->LastBoard)->GetBoardNumber()) ?
-	hv->GetHVBoard(status->FirstBoard)->GetBoardNumber() : hv->GetHVBoard(status->LastBoard)->GetBoardNumber();
-      
-      if (status->FirstChain == status->LastChain)
-	sprintf(outstr,"%s\nHV|C%d|B%d-%d> ",str,status->FirstChain,firstboard,lastboard);
-      else 
-	sprintf(outstr,"%s\nHV|C%d-%d|B%d-%d> ",str,status->FirstChain,status->LastChain,firstboard,lastboard); 
-    }
-  }
-  else {
-
-    if (status->NumHVBoards == 0) 
-      sprintf(outstr,"HV> "); 
-    else if (status->FirstBoard == status->LastBoard) {
-      
-      int board = hv->GetHVBoard(status->FirstBoard)->GetBoardNumber();
-      
-      if (status->FirstChain == status->LastChain) 
-	sprintf(outstr,"HV|C%d|B%d> ",status->FirstChain,board); 
-      else 
-	sprintf(outstr,"HV|C%d-%d|B%d> ",status->FirstChain,status->LastChain,board); 
-    }
-    else {
-      
-      int firstboard = (hv->GetHVBoard(status->FirstBoard)->GetBoardNumber() > hv->GetHVBoard(status->LastBoard)->GetBoardNumber()) ?
-	hv->GetHVBoard(status->LastBoard)->GetBoardNumber() : hv->GetHVBoard(status->FirstBoard)->GetBoardNumber();
-      
-      int lastboard = (hv->GetHVBoard(status->FirstBoard)->GetBoardNumber() > hv->GetHVBoard(status->LastBoard)->GetBoardNumber()) ?
-	hv->GetHVBoard(status->FirstBoard)->GetBoardNumber() : hv->GetHVBoard(status->LastBoard)->GetBoardNumber();
-      
-      if (status->FirstChain == status->LastChain)
-	sprintf(outstr,"HV|C%d|B%d-%d> ",status->FirstChain,firstboard,lastboard);
-      else 
-	sprintf(outstr,"HV|C%d-%d|B%d-%d> ",status->FirstChain,status->LastChain,firstboard,lastboard);
-    }
-
-
-  }
-
-  fflush(stdout);
-  fputs(outstr, stdout);
-  fflush(stdout);
-
-}
-
-
-void ProcessIO::PrintMessageToLog(char *str) {
-
-  char outstr[MAX_COM_SIZE];
-
-  if (status->NumHVBoards == 0) {
-    sprintf(outstr,"HV|B> %s\n",str);
-    log->LogWrite(outstr);
-  }
-  else if (status->FirstBoard == status->LastBoard) {
-    
-    int board = hv->GetHVBoard(status->FirstBoard)->GetBoardNumber();
-    
-    sprintf(outstr,"HV|B%d> %s\n",board,str);
-    log->LogWrite(outstr);
-  }
-  else {
-    
-    int firstboard = (hv->GetHVBoard(status->FirstBoard)->GetBoardNumber() > hv->GetHVBoard(status->LastBoard)->GetBoardNumber()) ?
-      hv->GetHVBoard(status->LastBoard)->GetBoardNumber() : hv->GetHVBoard(status->FirstBoard)->GetBoardNumber();
-    
-    int lastboard = (hv->GetHVBoard(status->FirstBoard)->GetBoardNumber() > hv->GetHVBoard(status->LastBoard)->GetBoardNumber()) ?
-      hv->GetHVBoard(status->FirstBoard)->GetBoardNumber() : hv->GetHVBoard(status->LastBoard)->GetBoardNumber();
-
-    sprintf(outstr,"HV|B%d-%d> %s\n",firstboard,lastboard,str);
-   log->LogWrite(outstr);
-  }
-
-}
-
-
-// Print message to screen, log file and socket
-void ProcessIO::PrintMessageO(char *Format, ...) {
-
-  char Textbuffer[MAX_COM_SIZE];
-
-  va_list ArgumentPointer;  va_start(ArgumentPointer, Format);
-  vsprintf(Textbuffer, Format, ArgumentPointer);
-
-  fputs(Textbuffer, stdout);   fflush(stdout);  // Print to console
-  
-  if(status->Socket != -1)                      // Print to socket if open
-    write(status->Socket,Textbuffer,strlen(Textbuffer)+1); // +1 to transmit '\0'
-}
-
-
-int ProcessIO::NBoards() {
-
-  if (status->NumHVBoards==0)
-    DoPrompt("ERROR - no HV boards available!\n");
-
-  return status->NumHVBoards;
-}
-
-
-int ProcessIO::InitializeHV() {
-
-  int nb = 0;
-
-  if (hv->GetNumberOfBoards())
-    printf("OK - Initialization:\n");
-
-  for (int i=0;i<hv->GetNumberOfBoards();i++) {
-    printf("OK - HV board %d (%s):\n",hv->GetHVBoard(i)->GetBoardNumber(),hv->GetHVBoard(i)->GetSerial());
-    nb+=hv->GetHVBoard(i)->Init(status->Verbose);
-  }
-
-  return nb;
-}
-
-
-void ProcessIO::UpdateStatus(int i, unsigned char* rbuf) {
-
-  if (status->IsUpdated[i])
-    status->WC[0][i] = status->WC[1][i];
-  else {
-    status->WC[0][i] = hv->GetHVBoard(i)->DecodeWrap(rbuf)-1;
-    status->IsUpdated[i] = TRUE;
-  }
-  
-  status->WC[1][i] = hv->GetHVBoard(i)->DecodeWrap(rbuf);
-
-  int d = (int)abs(status->WC[0][i]-status->WC[1][i]);
-
-  status->isok[i] = (d==1 || d==7) ? 1 : 0;
-
-  hv->GetHVBoard(i)->DecodeOC(status->OC[i], rbuf);
-  status->MR[i] = hv->GetHVBoard(i)->DecodeReset(rbuf);
-
-}
-
-
-void ProcessIO::StartMonitor() {
-
-  status->state = active;
-  status->Stop  = FALSE;
-
-  pthread_kill(status->HVMonitor, SIGUSR1);
-
-}
-
-
-void ProcessIO::StopMonitor() {
-
-  status->state = stopped;
-  status->Stop  = TRUE;
-
-  pthread_kill(status->HVMonitor, SIGUSR1);
-
-}
-
-
-void ProcessIO::Monitor() {
-
-  char str[MAX_COM_SIZE];
-
-  for (int i=0;i<hv->GetNumberOfBoards() ;i++) {
-
-    if ((hv->GetHVBoard(i))->GetStatus(stdout,rbuf,FALSE)!=1) {
-      sprintf(str,"ERROR - board %d error: could not read status - check timeout and status refresh rate...",hv->GetHVBoard(i)->GetBoardNumber());
-      PrintMessage(str);      
-    }
-    else
-      UpdateStatus(i,rbuf);
-    
-    if (status->MR[i]) {
-      sprintf(str,"ERROR - warning: manual reset of board %d!",hv->GetHVBoard(i)->GetBoardNumber());
-      PrintMessage(str);      
-      StopMonitor();
-      ResetBoard(i);
-      ReInitStatusOneBoard(status,i);
-      StartMonitor();
-    }
-    
-    if (!status->isok[i]) {
-      sprintf(str,"ERROR - wrap counter mismatch board %d (%d,%d)!",hv->GetHVBoard(i)->GetBoardNumber(),status->WC[0][i],status->WC[1][i]);
-      PrintMessage(str);      
-    }
-
-    for (int j=0;j<MAX_NUM_CHAINS;j++) 
-      if (status->OC[i][j]) {
-	sprintf(str,"ERROR - warning: overcurrent in chain %d of board %d!",j,hv->GetHVBoard(i)->GetBoardNumber());
-	PrintMessage(str);      
-	ResetBoard(i);
-	ReInitStatusOneBoard(status,i);
-      }
-  }
-}
-
-
-void ProcessIO::ResetActiveBoards() {
-  
-  for (int i=status->FirstBoard;i<=status->LastBoard;i++) {
-    if ((hv->GetHVBoard(i))->Reset(stdout,rbuf,status->Verbose)==1) {
-      sprintf(str,"OK - software reset done board %d\n",hv->GetHVBoard(i)->GetBoardNumber());
-      DoPrompt(str);
-      UpdateStatus(i,rbuf);
-      sPrintStatus(status,str,i);
-      DoPrompt(str);
-    }
-    else {
-      sprintf(str,"ERROR - board %d error: could not reset - check timeout and try again\n",hv->GetHVBoard(i)->GetBoardNumber());
-	DoPrompt(str);
-    }    
-  }
-  
-}
-
-
-void ProcessIO::ResetAllBoards() {
-  
-  for (int i=0;i<hv->GetNumberOfBoards();i++) {
-    if ((hv->GetHVBoard(i))->Reset(stdout,rbuf,status->Verbose)==1) {
-      sprintf(str,"OK - software reset done board %d\n",hv->GetHVBoard(i)->GetBoardNumber());
-      DoPrompt(str);
-      UpdateStatus(i,rbuf);
-      sPrintStatus(status,str,i);
-      DoPrompt(str);
-    }
-    else {
-      sprintf(str,"ERROR - board %d error: could not reset - check timeout and try again\n",hv->GetHVBoard(i)->GetBoardNumber());
-      DoPrompt(str);
-    }    
-  }
-  
-}
-
-
-void ProcessIO::ResetBoard(int i) {
-    
-  if ((hv->GetHVBoard(i))->Reset(stdout,rbuf,status->Verbose)==1) {
-    sprintf(str,"OK - software reset done board %d",hv->GetHVBoard(i)->GetBoardNumber());
-    PrintMessage(str);
-    UpdateStatus(i,rbuf);
-    sPrintStatus(status,str,i);
-    PrintMessage(Chop(str));
-  }
-  else {
-    sprintf(str,"ERROR - board %d error: could not reset - check timeout and try again",hv->GetHVBoard(i)->GetBoardNumber());
-    PrintMessage(str);
-  }    
-  
-}
-
-
-int ProcessIO::SaveHVSettings(char* filename) {
-
-  char str[MAX_COM_SIZE];
-
-  FILE *fptr;
-
-  time_t time_now_secs;
-  struct tm *time_now;
-  
-  time(&time_now_secs);
-  time_now = localtime(&time_now_secs);
-
-  if ((fptr = fopen(filename,"w")) == NULL) {
-    sprintf(str,"ERROR - could not open file \"%s\"\n", filename);
-    return 0;
-  }
-  
-  fprintf(fptr,"\n********** HV settings written by hvutil %s, %04d %02d %02d, %02d:%02d:%02d **********\n\n",
-	  HV_CONTROL_VERSION, 
-	  1900 + time_now->tm_year, 
-	  1 + time_now->tm_mon,
-	  time_now->tm_mday,
-	  time_now->tm_hour,
-	  time_now->tm_min,
-	  time_now->tm_sec);
-  
-  for (int i=0;i<status->NumHVBoards;i++) {
-    fprintf(fptr,"Device: %s\n\n",status->fUSBDevice[i]);
-    
-    for (int j=0;j<MAX_NUM_CHAINS;j++) {
-      for (int k=0;k<4;k++) {
-	for (int l=0;l<8;l++) 
-	  fprintf(fptr,"%5d ",status->HV[i][j][k*8+l]);
-	fprintf(fptr,"\n");
-      }
-      fprintf(fptr,"\n");
-    }
-  }
-   
-  fclose(fptr);
-
-  return 1;
-}
-
-
-int ProcessIO::IsBoard(int board) {
-
-  for (int i=0;i<MAX_NUM_HVBOARDS;i++)
-    if (board == status->USBDeviceNumber[i])
-      return 1;
-
-  return 0;
-}
-
-
-int ProcessIO::GetBoardIdx(int board) {
-
-  for (int i=0;i<MAX_NUM_HVBOARDS;i++)
-    if (board == status->USBDeviceNumber[i])
-      return i;
-
-  return -1;
-}
+      Param[Count] = Command;
+      while(!isspace(*Command) && *Command!='\0') Command++;
+    }
+    if(*Command != '\0') *Command++ = '\0';
+    Count++;
+  }
+  return Count;
+}
+
+// Check if two strings match (min 1 character must match)
+bool Match(const char *str, const char *cmd) {
+  return strncasecmp(str,cmd,strlen(str)==0 ? 1:strlen(str)) ? false:true;
+}
+
+// Convert string to double
+// Returns false if conversion did not stop on whitespace or EOL character
+bool ConvertToDouble(const char *String, double *Result) {
+
+  char *EndPointer;
+  
+  *Result = strtod(String, &EndPointer);
+  if(!isspace(*EndPointer) && *EndPointer!='\0') return false;
+  return true;
+}
+
+
+// Convert string to int
+// Returns false if conversion did not stop on whitespace or EOL character
+bool ConvertToInt(const char *String, int *Result) {
+
+  char *EndPointer;
+  
+  *Result = (int) strtol(String, &EndPointer, 0);
+  if(!isspace(*EndPointer) && *EndPointer!='\0') return false;
+  return true;
+}
Index: hvcontrol/src/ProcessIO.h
===================================================================
--- hvcontrol/src/ProcessIO.h	(revision 80)
+++ hvcontrol/src/ProcessIO.h	(revision 90)
@@ -3,92 +3,82 @@
 #define PROCESSIO_H_SEEN
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
 #include <stdarg.h>
-#include <limits.h>
-#include <time.h>
 #include <errno.h>
-#include <unistd.h>
 #include <math.h>
-#include <pthread.h>
-#include <termios.h>
-#include <fcntl.h>
-#include <assert.h>
-#include <dirent.h>
-#include <sys/time.h>  
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <sys/select.h>
 #include <signal.h>
 
-#include "Types.h"
-#include "HVStatus.h"
-#include "Log.h"
 #include "HVConfig.h"
 #include "HVCalib.h"
-#include "Utilities.h"
 #include "HV.h"
+#include "../pixelmap/PixelMap.h"
 
-#include <iostream>
-#include "../../fact_repos.svn/pixelmap/PixelMap.h"
+#define MAX_NUM_TOKEN 10
 
+#define MsgToConsole 1
+#define MsgToLog 2
+#define MsgToSocket 4
+
+typedef enum stateenum { active, stopped, na } state_enum;
 
 class ProcessIO {
 
- private:
-  
   time_t StartTime;
-
-  char str[MAX_COM_SIZE];
-
-  unsigned char wbuf[BUFFER_LENGTH];
-  unsigned char rbuf[BUFFER_LENGTH];
-
-  char bdata[16];
-
+  FILE *Logfile;
   PixelMap *pm;
 
  public:
   
-  HVConfig*    config;
-  HVCalib*     calib;
-  Status*      status;
-  Log*         log;
+  HVConfig    *config;
+  HVCalib     *calib;
+  HVBoard* fHVBoard[MAX_NUM_HVBOARDS];
 
   pthread_mutex_t control_mutex;
-  pthread_cond_t  control_cond;
 
+  char Prompt[MAX_COM_SIZE];
+  const char *Param[MAX_NUM_TOKEN]; // For parser
+  int NParam;
+  bool CmdFromSocket;
   
-  HV *hv;
-  HVBoard *hvboard;
+  // Status variables  
+  pthread_t HVMonitor;       // exit function sends signal to these threads
+  pthread_t SocketThread;
+
+  bool Verbose;  
+  int Socket;                // -1 if not connected
+
+  int NumHVBoards;
+  int FirstBoard;
+  int LastBoard;
+  int FirstChain;
+  int LastChain;
   
-
-  ProcessIO(char *config_file);
+  float fStatusRefreshRate;
+  state_enum   state;
+  bool Exit;
+    
+  // Methods
+  ProcessIO(char *);
   ~ProcessIO();
 
-  void Scan();
-  void PrintHelp();
-  void PrintDateAndTime();
-  void DoPrompt(char* str);
-  void PrintMessage(char* str);
-  void PrintMessageToLog(char *str);
-  void PrintMessageO(char *Format, ...);
-  int CommandControl();
-  int NBoards(); 
-  int InitializeHV();
-  void UpdateStatus(int i, unsigned char* rbuf);
+  void PrintMessage(int, const char *, ...);
+  void PrintMessage(const char *, ...);
+  void PrintMessage(int, const char *, va_list);
+  void CommandControl(char*);
+  bool RampVoltage(unsigned int, int, int, int);
   void StartMonitor();
   void StopMonitor();
   void Monitor();
   void ResetActiveBoards();
-  void ResetAllBoards();
-  void ResetBoard(int i);
-  int SaveHVSettings(char* filename);
-  int IsBoard(int i);
-  int GetBoardIdx(int board);
+  void ResetBoard(int);
+  int GetBoardIdx(int);
 
+  void PrintBoardStatus(int);
+
+  int ParseInput(char*, const char *Param[]);
 };
 
+bool Match(const char *, const char *);
+bool ConvertToDouble(const char *, double *);
+bool ConvertToInt(const char *, int *);
+
 #endif
Index: hvcontrol/src/ReadCard.cc
===================================================================
--- hvcontrol/src/ReadCard.cc	(revision 80)
+++ 	(revision )
@@ -1,151 +1,0 @@
-
-/********************************************************************\
-
-  Name:         ReadCard.cc
-
-  Created by:   F. Goebel
-
-  Contents:     Read input card
-
-\********************************************************************/
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include "ReadCard.h"
-
-int ReadCard(char *card_flag, void *store, char type, FILE *fptr, int id) {
-  char id_flag[100];
-  sprintf(id_flag, "%d", id);
-  return ReadCard(card_flag, store, type, fptr, id_flag);
-}
-
-
-int ReadCard(char *card_flag, void *store, char type, FILE *fptr, char *id_flag) {
-  char *card_name, *card_val, *card_id=NULL;
-  char  line[160];
-
-  rewind(fptr);
-
-  while (fgets(line, 160, fptr) != NULL) {    // Read line by line
-    card_name = strtok(line," \t\n");
-    if (id_flag!=NULL) {
-      card_id = strtok(NULL," \t\n");
-    }
-    card_val  = strtok(NULL," \t\n");
-    
-    if (card_name != NULL && card_val != NULL   // Comment or empty line?
-        && card_name[0] != '*' && card_name[0] != '#') {
-      
-      if (strcmp(card_name, card_flag)!=0) {   // Is this the card name we are looking for?
-	continue;  
-      }
-      if ((id_flag!=NULL) &&                // Is id_flag required
-	  (strcmp(card_id, id_flag)!=0)) {  // Is it the correct id_flag
-	continue;  
-      }
-
-      switch (type) {
-      case 'I':
-	*((int *) store) = (int) strtol(card_val, (char**)NULL, 10);
-	break;
-      case 'i':
-	*((short *) store) = (short) strtol(card_val, (char**)NULL, 10);
-	break;
-      case 'U':
-	*((unsigned int *) store)   
-	  = (unsigned int) strtoul(card_val, (char**)NULL, 10);
-	break;
-      case 'u':
-	*((unsigned short *) store) 
-	  = (unsigned short) strtoul(card_val, (char**)NULL, 10);
-	break;
-      case 'f' :
-	*((float *) store) = atof(card_val);
-	break;
-      case 'd' :
-	*((double *) store) = atof(card_val);
-	break;
-      case 's' :
-	sprintf((char *) store,"%s",card_val);
-	break;
-      case 'c' :
-	*((char *) store) = card_val[0];
-	break;
-      default :
-	fprintf(stderr,"WARNING: ReadCard: unknown type: %c\n", type);
-	return -2;
-      }
-
-      return 0; // Found card name
-    }
-  }
-
-  //fprintf(stderr,"WARNING: ReadCard: card: %s not found\n", card_flag);
-  return -1;
-}
-
-
-int ReadCardExt(char *card_flag, void *store, char type, FILE *fptr, char *id_flag) {
-  char *card_name, *card_val, *card_id=NULL;
-  char  line[160];
-
-  rewind(fptr);
-
-  while (fgets(line, 160, fptr) != NULL) {    // Read line by line
-    card_name = strtok(line," \t\n");
-    if (id_flag!=NULL) {
-      card_id = strtok(NULL," \t\n");
-    }
-    card_val  = strtok(NULL," \t\n");
-    
-    if (card_name != NULL && card_val != NULL   // Comment or empty line?
-        && card_name[0] != '*' && card_name[0] != '#') {
-      
-      if (strcmp(card_name, card_flag)!=0) {   // Is this the card name we are looking for?
-	continue;  
-      }
-      if ((id_flag!=NULL) &&                // Is id_flag required
-	  (strcmp(card_id, id_flag)!=0)) {  // Is it the correct id_flag
-	continue;  
-      }
-
-      switch (type) {
-      case 'I':
-	*((int *) store) = (int) strtol(card_val, (char**)NULL, 10);
-	break;
-      case 'i':
-	*((short *) store) = (short) strtol(card_val, (char**)NULL, 10);
-	break;
-      case 'U':
-	*((unsigned int *) store)   
-	  = (unsigned int) strtoul(card_val, (char**)NULL, 10);
-	break;
-      case 'u':
-	*((unsigned short *) store) 
-	  = (unsigned short) strtoul(card_val, (char**)NULL, 10);
-	break;
-      case 'f' :
-	*((float *) store) = atof(card_val);
-	break;
-      case 'd' :
-	*((double *) store) = atof(card_val);
-	break;
-      case 's' :
-	sprintf((char *) store,"%s",card_val);
-	break;
-      case 'c' :
-	*((char *) store) = card_val[0];
-	break;
-      default :
-	fprintf(stderr,"WARNING: ReadCard: unknown type: %c\n", type);
-	return -2;
-      }
-
-      return 0; // Found card name
-    }
-  }
-
-  //fprintf(stderr,"WARNING: ReadCard: card: %s not found\n", card_flag);
-  return -1;
-}
Index: hvcontrol/src/ReadCard.h
===================================================================
--- hvcontrol/src/ReadCard.h	(revision 80)
+++ 	(revision )
@@ -1,10 +1,0 @@
-#ifndef READCARD_H_SEEN
-#define READCARD_H_SEEN
-
-#include <stdio.h>
-
-int ReadCard(char *card_flag, void *store, char type, FILE *fptr, char *id_flag=NULL);
-int ReadCardExt(char *card_flag, void *store, char type, FILE *fptr, char *id_flag=NULL);
-int ReadCard(char *card_flag, void *store, char type, FILE *fptr, int id);
-
-#endif
Index: hvcontrol/src/Types.h
===================================================================
--- hvcontrol/src/Types.h	(revision 80)
+++ 	(revision )
@@ -1,42 +1,0 @@
-#ifndef CTXTYPES_H_SEEN
-#define CTXTYPES_H_SEEN
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#define HV_CONTROL_VERSION "V1.0"
-
-#define I8      char
-#define U8      unsigned char
-#define I16     short
-#define U16     unsigned short
-#define I32     int
-#define U32     unsigned int
-#define F32     float
-#define F64     double
-#define Boolean char
-
-#define TRUE 1
-#define FALSE 0
-
-#define FILENAME_MAX_SIZE 256
-#define MAX_COM_SIZE 1000
-#define MAX_NUM_HVBOARDS 20
-#define MAX_NUM_CHAINS 4
-#define MAX_NUM_CHANNELS 32
-#define MAX_PATH 256
-#define STR_LENGTH 256
-#define BUFFER_LENGTH 256
-
-#define USB_MAX_DEVICE_NUMBER 65000
-#define USB_MIN_DEVICE_NUMBER 0
-
-#define MIN_TIMEOUT 0.01
-#define MAX_TIMEOUT 5.0
-
-#define MIN_RATE 0.01
-#define MAX_RATE 50.0
-
-#endif
-
-
Index: hvcontrol/src/Utilities.cc
===================================================================
--- hvcontrol/src/Utilities.cc	(revision 80)
+++ 	(revision )
@@ -1,437 +1,0 @@
-
-
-/********************************************************************\
-
-  Name:         Utilities.cc
-
-  Created by:   Sebastian Commichau, July 2008
-                commichau@phys.ethz.ch
-
-  Content:      Provides numerous utilities
-
-\********************************************************************/
- 
-
-#include "Utilities.h"
-
-
-// Parse user input 
-void ParseInput(char* Pc, int* NParam, char Param[][MAX_COM_SIZE])
-{
-  int i;
-  *NParam = 0;
-
-  for (i = 0; i<10; i++)
-    Param[i][MAX_COM_SIZE] = 0;
-
-  while (*Pc == ' ') // Ignore leading blanks
-    Pc++;
-  
-  do {
-    if (*Pc == '"') {
-      Pc++;
-      for (i = 0; *Pc && *Pc != '"'; i++)
-	Param[*NParam][i] = *Pc++;
-      if (*Pc)
-	Pc++;
-    } else if (*Pc == '\'') {
-      Pc++;
-      for (i = 0; *Pc && *Pc != '\''; i++)
-	Param[*NParam][i] = *Pc++;
-      if (*Pc)
-	Pc++;
-    } else if (*Pc == '`') {
-      Pc++;
-      for (i = 0; *Pc && *Pc != '`'; i++)
-	Param[*NParam][i] = *Pc++;
-      if (*Pc)
-	Pc++;
-    } else
-      for (i = 0; *Pc && *Pc != ' '; i++)
-	Param[*NParam][i] = *Pc++;
-    Param[*NParam][i] = 0;
-    while (*Pc == ' ' || *Pc == '\r' || *Pc == '\n')
-      Pc++;
-    (*NParam)++;
-  } while (*Pc);
-
-}
-
-
-// Check if two strings match
-int Match(char *str, char *cmd)
-{
-   int i;
-
-   if(str[0] == '\r' || str[0] == '\n')
-     return 0;
-
-   for(i = 0; i < (int) strlen(str); i++) 
-     {
-       if(toupper(str[i]) != toupper(cmd[i]) && str[i] != '\r' && str[i] != '\n')
-         return 0;
-     }
-
-   return 1;
-}
-
-
-// Remove newline from string
-char* Chop(char str[]) {
-
-  char *ptr;
-
-  if ((ptr = strchr(str, '\n')) != NULL)
-    *ptr = '\0';
-
-  return str;
-
-}
-
-
-int MakeDir(char *Dir, char *RunDate) {
-
-   char str[MAX_COM_SIZE];
-
-   sprintf(str,"%s/%s",Dir,RunDate);
-
-   struct stat buf;
-
-   if (stat(str, &buf)) 
-     return mkdir(str, 0711);
-   
-   return 0;
-}
-
-
-
-void GetUTCSecondsOfDay(double* t) {
-  
-  struct tm * timeinfo;
-  time_t rawtime;
-  
-  struct timezone tz;
-  struct timeval actual_time;   // Actual time 
-  
-  gettimeofday(&actual_time, &tz);
-  
-  time(&rawtime);
-  
-  timeinfo = gmtime(&rawtime);      // Get UTC (or GMT timezone).
-  
-  *t = (timeinfo->tm_hour*3600 + timeinfo->tm_min*60 + timeinfo->tm_sec) + actual_time.tv_usec/1000000.;
-  
-}
-
-
-void GetLocalSecondsOfDay(double* t) {
-  
-  struct tm * timeinfo;
-  time_t rawtime;
-  
-  struct timezone tz;
-  struct timeval actual_time;   // Actual time 
-  
-  gettimeofday(&actual_time, &tz);
-  
-  time(&rawtime);
-  
-  timeinfo = localtime(&rawtime); // Get local time
-  
-  *t = (timeinfo->tm_hour*3600 + timeinfo->tm_min*60 + timeinfo->tm_sec) + actual_time.tv_usec/1000000.;
-  
-}
-
-
-void GetLocalDay(int* t) {
-  
-  struct tm * timeinfo;
-  time_t rawtime;
-  
-  time(&rawtime);
-  
-  timeinfo = localtime(&rawtime); // Get local time
-  
-  *t = (timeinfo->tm_yday);
-  
-}
-
-
-double GetDiffTime(time_t* StartT) {
-
-  time_t ActualT;
-
-  time (&ActualT);
-
-  return difftime (ActualT,*StartT);
-
-}
-
-
-long int GetMicroSeconds() {
-
-  struct tm * timeinfo;
-  time_t rawtime;
-  
-  struct timezone tz;
-  struct timeval actual_time;   // Actual time
-  
-  gettimeofday(&actual_time, &tz);
-  
-  time(&rawtime);
-  
-  timeinfo = gmtime(&rawtime);  // Get UTC (or GMT timezone).
-  
-  return (timeinfo->tm_hour*3600 + timeinfo->tm_min*60 + timeinfo->tm_sec)*1000000 + actual_time.tv_usec;
-
-}
-
-
-/* Prints the binary representation of a 1 byte-integer to stdout */
-void PrintByteBin(unsigned char i) {
-
-  for (int k=7;k>=0;k--)
-    if ((i & (1 << k)) !=0) {
-        if ((k)%8)
-        printf("1");
-        else
-        printf("1 ");
-    }
-    else {
-        if ((k)%8)
-        printf("0");
-        else
-        printf("0 ");
-    }
-  printf("\n");
-}
-
-
-/* Prints the binary representation of a 1-byte integer to str */
-void sPrintByteBin(unsigned char i, char* str) {
-
-  bzero(str,sizeof(str));
-
-  for (int k=7;k>=0;k--)
-    if ((i & (1 << k)) !=0) {
-      if ((k)%8)
-        strcat(str,"1");
-      else
-        strcat(str,"1 ");
-    }
-    else {
-      if ((k)%8)
-	strcat(str,"0");
-      else
-	strcat(str,"0 ");
-    }
-}
-
-
-/* Prints the binary representation of a 2-byte integer to stdout */
-void PrintWordBin(unsigned short i) {
-
-  for (int k=15;k>=0;k--)
-    if ((i & (1 << k)) !=0) {
-        if ((k)%8)
-        printf("1");
-        else
-        printf("1 ");
-    }
-    else {
-        if ((k)%8)
-        printf("0");
-        else
-        printf("0 ");
-    }
-  printf("\n");
-
-}
-
-
-/* Prints the binary representation of a 2-byte integer to str */
-void sPrintWordBin(unsigned short i, char* str) {
-
-  bzero(str,sizeof(str));
-
-  for (int k=15;k>=0;k--)
-    if ((i & (1 << k)) !=0) {
-      if ((k)%8)
-	strcat(str,"1");
-      else
-	strcat(str,"1 ");
-    }
-    else {
-      if ((k)%8)
-	strcat(str,"0");
-      else
-	strcat(str,"0 ");
-    }
-}
-
-
-/* 
-  Converts a hexadecimal string to integer - returns
- -1    - Conversion was abnormally terminated by
-         occurrence of an illegal character
-  0    - Conversion was successful 
-  1    - String is empty
-  2    - String has more than 2 characters
-*/
-int sPrintHex2Dec(const char* xs, unsigned int* result) {
-
-  size_t szlen = strlen(xs);
-  int xv, fact;
-  
-  if (szlen>0) {
-    // Converting more than 32 bit hexadecimal value?
-    if (szlen>4) return 4; 
-    
-    // Begin conversion here
-    *result = 0;
-    fact = 1;
-    
-    // Run until no more character to convert
-    for (int i=szlen-1; i>=0; i--) {
-      if (isxdigit(*(xs+i))) {
-	if (*(xs+i)>=97) {
-	  xv = ( *(xs+i) - 97) + 10;
-	}
-	else if ( *(xs+i) >= 65) {
-	  xv = (*(xs+i) - 65) + 10;
-	}
-	else {
-	    xv = *(xs+i) - 48;
-	}
-	*result += (xv * fact);
-	fact *= 16;
-      }
-      else {
-	// Conversion was abnormally terminated
-	// by non hexadecimal digit, hence
-	// returning only the converted with
-	// an error value 0 (illegal hex character)
-	return -1;
-      }
-    }
-    return 0;
-  }
-
-  // Nothing to convert - string is empty
-  return 1;
-}
-
-
-/* An integer is interpreted as binary number and converted to an integer */
-int Bin2Dec(int bin)
-{
-  int power = 0;
-  int decimal = 0;
-  int num;
-  
-  while (bin > 0) {
-
-    num = bin % 10;
-    decimal = decimal + num * (int) pow(num * 2, power++);
-    bin = bin / 10;
-  }
-  
-  return decimal;
-}
-
-
-/* 
-  Converts a binary string to integer - returns
- -1    - Conversion was abnormally terminated by
-         occurrence of an illegal character
-  0    - Conversion was successful 
-  1    - String is empty
-  8    - String has more than 8 characters
-*/
-int sPrintBin2Dec(const char* bs, unsigned int* result) {
-
-  size_t szlen = strlen(bs);
-
-  *result = 0;
-
-  int p=0;
-
-  if (szlen>0) {
-
-    // Converting more than 32 bit value?
-    if (szlen>32) return 32; 
-
-    // Begin conversion here    
-    for (int i=szlen-1; i>=0; i--) {
-
-      if (*(bs+i)=='1' || *(bs+i)=='0') {
-
-	if (*(bs+i)=='1') 
-	  *result += (int)pow(2.,(double)p);
-	
-	p++;
-      }
-      else return -1;
-    }
-    return 0;
-
-  }
-  // Nothing to convert - string is empty
-  return 1;   
-}
-
-
-
-/* Converts a binary string to a decimal number, returns decimal value */
-int Bin2Dec(const char *bs) {
-
-  int b, /*m,*/ n;
-  int len, sum = 0;
-  
-  len = strlen(bs) - 1;
-  
-  for (int k = 0; k <= len; k++) {
-        
-    b = 1;
-
-    n = (bs[k] - '0'); // Char to numeric value
-    
-    if ((n > 1) || (n < 0))
-      return 0;
-    
-    
-    b = b << (len-k);
-    
-    //for (b = 1, m = len; m > k; m--) 
-    //b *= 2; // 1 2 4 8 16 32 64 ... place-values, reversed here
-        
-    // Sum it up
-    sum = sum + n * b;
-    
-    //printf("%d*%d + ",n,b);
-  }
-  return sum;
-}
-
-
-int IsNoDigit(const char* str) {
-
-  size_t szlen = strlen(str); 
-
-  if (szlen>0) {
-
-    for (int i=szlen-1; i>=0; i--) {
-      if (isalpha((int)*(str+i)))
-	return 0;
-    }
-    // Okay, no alphabetic character found
-    return 1;
-  }
-  // String is empty
-  return -1;
-}
-
-
-void SignalHandler(int Signal) {
-  return;          
-}
Index: hvcontrol/src/Utilities.h
===================================================================
--- hvcontrol/src/Utilities.h	(revision 80)
+++ 	(revision )
@@ -1,40 +1,0 @@
-
-#ifndef UTILITIES_H_SEEN
-#define UTILITIES_H_SEEN
-
-#define SECONDS_DAY  86400
-#define SECONDS_HOUR  3600
-#define SECONDS_MINUTE  60
-
-#include <string.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <sys/stat.h>
-#include <time.h>
-#include <sys/time.h>  
-#include <math.h>
-
-#include "Types.h"
-
-void ParseInput(char* Pc, int* Nparam, char Param[][MAX_COM_SIZE]);
-int Match(char *str, char *cmd);
-char* Chop(char str[]);
-int MakeDir(char *Dir, char *RunDate);
-void GetUTCSecondsOfDay(double* t);
-void GetLocalSecondsOfDay(double* t);
-void GetLocalDay(int* t);
-double GetDiffTime(time_t* StartT);
-long int GetMicroSeconds();
-
-void PrintByteBin(unsigned char i);
-void sPrintByteBin(unsigned char i, char* str);
-void PrintWordBin(unsigned short i);
-void sPrintWordBin(unsigned short i, char* str);
-int sPrintBin2Dec(const char* bs, unsigned int* result);
-int Bin2Dec(int bin);
-int Bin2Dec(const char *bs);
-int sPrintHex2Dec(const char* xs, unsigned int* result);
-int IsNoDigit(const char* str);
-void SignalHandler(int Signal);
-
-#endif
