Changeset 11919


Ignore:
Timestamp:
08/30/11 15:16:47 (13 years ago)
Author:
ogrimm
Message:
Added simple bias current calibration
Location:
fact/BIASctrl
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • fact/BIASctrl/Crate.cc

    r11915 r11919  
    182182  funlockfile(File);
    183183
    184   if (ErrorCount > MAX_ERR_COUNT) Disabled = true;
     184  if (ErrorCount > MAX_ERR_COUNT) {
     185        m->Message(m->ERROR, "Crate %s has more than %d errors, disabled", Name, MAX_ERR_COUNT);   
     186        Disabled = true;
     187  }
    185188
    186189  return Data;
     
    224227  if (Data.size() != Buf.size()) return false;
    225228
    226   // Evaluate data returned from crate
     229  // Evaluate data returned from crate (1 count for current -> 1.22 uA)
    227230  int Count = 0;
    228231  for (unsigned int i=0; i<MAX_NUM_BOARDS*NUM_CHANNELS; i++) {
  • fact/BIASctrl/History.txt

    r11915 r11919  
    202026/8/2011       Removed support for multiple crates. Crate name can be given as
    2121                        command line argument.
     2230/8/2011       Added basic calibration for current measurement.
  • fact/BIASctrl/User.cc

    r11915 r11919  
    2121        {"reset", &User::cmd_reset, 0, true, "", "Reset active crate"},
    2222        {"synch", &User::cmd_synch, 0, true, "", "Synchronize active crate"},
    23         {"status", &User::cmd_status, 0, false, "[dac|current]", "Show status information (DAC values if requested)"},
     23        {"voltage", &User::cmd_status, 0, false, "[dac]", "Show voltage setpoints"},
     24        {"current", &User::cmd_status, 0, false, "", "Show currents"},
     25        {"status", &User::cmd_status, 0, false, "[R|I0]", "Show status information"},   
     26        {"calib", &User::cmd_calib, 1, true, "<V1 V2 Num|invalidate>", "Calibrate current measurement (linear fit between V1 and V2)"},
    2427        {"mode", &User::cmd_mode, 1, true, "<static|dynamic>", "Set voltage stabilization mode (experimental)"},
    2528        {"load", &User::cmd_load, 1, true, "<file>", "Load and set bias settings from file"},
     
    3437User::User(string Board): EvidenceServer(SERVER_NAME) {
    3538
     39  vector<string> Text;
     40
    3641  MainThread = pthread_self();
    3742
     
    3944  ConsoleText = NULL;
    4045  ConsoleOut = new DimService(SERVER_NAME"/ConsoleOut", (char *) "");
     46
     47  // Initialize current calibration constants
     48  R.resize(MAX_NUM_BOARDS*NUM_CHANNELS, numeric_limits<double>::infinity());
     49  I0.resize(MAX_NUM_BOARDS*NUM_CHANNELS, 0);
    4150
    4251  // Get/initialize configuration data
     
    4756  GetConfig("RampSpeed");
    4857  GetConfig("UpdatePeriod");
    49   vector<string> Text = Tokenize(GetConfig("DefaultVoltage", ""), " \t");
    50  
     58
     59  Text = Tokenize(GetConfig("DefaultVoltage", ""), " \t");
    5160  for (unsigned int i=0; i<Text.size(); i++) {
    5261        DefaultVoltage.push_back(atof(Text[i].c_str()));
     62  }   
     63
     64  Text = Tokenize(GetConfig("Calibration_R"), " \t");
     65  for (unsigned int i=0; i<Text.size() && i<R.size(); i++) {
     66        R[i] = atof(Text[i].c_str())/1000.0;
     67  }
     68
     69  Text = Tokenize(GetConfig("Calibration_I0"), " \t");
     70  for (unsigned int i=0; i<Text.size() && i<I0.size(); i++) {
     71        I0[i] = atof(Text[i].c_str());
    5372  }
    5473
     
    389408
    390409//
     410// Calibrate current measurement
     411//
     412void User::cmd_calib() {
     413
     414  map<unsigned int, double> Voltages, Initial, Current[2];
     415  int Errors, Num;
     416  double Volt[2];
     417
     418  // Clear current calibration values?
     419  if (Match(Parameter[1], "invalidate")) {
     420        PrintMessage("Current calibration invalidated\n");
     421        R.assign(MAX_NUM_BOARDS*NUM_CHANNELS, numeric_limits<double>::infinity());
     422        I0.assign(MAX_NUM_BOARDS*NUM_CHANNELS, 0);
     423        return;
     424  }
     425
     426  // Check number of parameters and convert
     427  if (Parameter.size() != 4) {
     428        PrintMessage("Error: Number of parameters incorrect\n");
     429        return;
     430  }
     431
     432  if (!ConvertToDouble(Parameter[1], &Volt[0]) || !ConvertToDouble(Parameter[2], &Volt[1])) {
     433    PrintMessage("Error: Wrong number format for voltages\n");
     434        return;
     435  }
     436
     437  if (!ConvertToInt(Parameter[3], &Num)) {
     438    PrintMessage("Error: Wrong number format for number of iterations\n");
     439        return;
     440  }
     441
     442  // Check if infinity can be represented for double
     443  if (!numeric_limits<double>::has_infinity) {
     444        PrintMessage("Cannot perform calibration, double cannot represent infinity\n");
     445        return;
     446  }
     447
     448  // Save initial voltages
     449  for (unsigned int i=0; i<MAX_NUM_BOARDS*NUM_CHANNELS; i++) Initial[i] = Dev->GetVoltage(i);
     450
     451  // Make current measurements at given voltages
     452  for (unsigned int Round=0; Round<2; Round++) {
     453        // Set voltage
     454        for (unsigned int i=0; i<MAX_NUM_BOARDS*NUM_CHANNELS; i++) Voltages[i] = Volt[Round];
     455
     456        if ((Errors = RampVoltages(Voltages)) != 0) {
     457          PrintMessage("%d errors occurred while ramping to %.2f V\n", Errors, Volt[Round]);
     458          return;
     459        }
     460        else PrintMessage("Ramped all channels to %.2f V\n", Volt[Round]);
     461
     462        // Read currenty repeatably
     463        for (int Count=0; Count<Num; Count++) {
     464          if (Count % 20 == 0) PrintMessage("Reading current iteration %d   \r", Count);
     465          if (!Dev->ReadAll()) {
     466                PrintMessage("\nError from ReadAll()\n");
     467                return;
     468          }
     469          for (unsigned int i=0; i<MAX_NUM_BOARDS*NUM_CHANNELS; i++) {
     470                Current[Round][i] += Dev->GetCurrent(i)/Num;
     471          }
     472        }
     473  } // for()
     474
     475
     476  // Set initial voltages
     477  if ((Errors = RampVoltages(Initial)) != 0) {
     478        PrintMessage("%d errors occurred while ramping back to inital voltages\n", Errors);
     479        return;
     480  }
     481  else PrintMessage("Ramped all channels back to inital voltages\n");
     482
     483  // Calculate calibration constants (R in MOhm)
     484  for (unsigned int i=0; i<MAX_NUM_BOARDS*NUM_CHANNELS; i++) {
     485    R[i] = (Volt[1] - Volt[0]) / (Current[1][i]-Current[0][i]);
     486        I0[i] = Current[0][i] - Volt[0]/R[i];
     487  }
     488}
     489
     490//
    391491// Print status
    392492//
    393493void User::cmd_status() {
     494
     495  enum {M_V,M_DAC,M_I,M_R,M_I0,M_notset} M = M_notset;
    394496
    395497  // Overview information
     
    414516
    415517  // Voltage or current list
    416   if (Parameter.size() == 1) PrintMessage("Channel voltages (in V)");
    417   else if (Match(Parameter[1], "dac")) PrintMessage("Channel voltages (in DAC values)");
    418   else PrintMessage("Channel currents (in uA)");
     518  if (Match(Parameter[0], "voltage")) {
     519        if (Parameter.size() == 1) M = M_V;
     520        else M = M_DAC;
     521  }
     522  else if (Match(Parameter[0], "current")) M = M_I;
     523  else if (Parameter.size() == 2) {
     524        if (Match(Parameter[1], "R")) M = M_R;
     525        if (Match(Parameter[1], "I0")) M = M_I0;
     526  }
     527
     528  if (M == M_notset) return;
     529  if (M == M_V) PrintMessage("Channel voltages (in V)");
     530  if (M == M_DAC) PrintMessage("Channel voltages (in DAC values)");
     531  if (M == M_R) PrintMessage("Channel internal resistance  (in kOhm)");
     532  if (M == M_I0) PrintMessage("Channel current offset (in uA)");
     533  if (M == M_I) PrintMessage("Channel currents (in uA)");
    419534
    420535  for (unsigned int j=0; j<MAX_NUM_BOARDS*NUM_CHANNELS; j++) {
    421536        if (j%12 == 0) PrintMessage("\n%3.1d:  ", j);
    422         if (!Dev->Present[j]) PrintMessage("  -   ");
    423     else if (Parameter.size() == 1) PrintMessage("%#5.2f", Dev->GetVoltage(j));
    424         else if (Match(Parameter[1], "dac")) PrintMessage("%5d", Dev->GetDAC(j));
    425         else PrintMessage("%#5.2f", Dev->GetCurrent(j));
     537        if (!Dev->Present[j]) PrintMessage("    -");
     538    else if (M == M_V) PrintMessage("%#5.2f", Dev->GetVoltage(j));
     539        else if (M == M_DAC) PrintMessage("%5d", Dev->GetDAC(j));
     540        else if (M == M_R) PrintMessage("%#5.2f", R[j]*1000);
     541        else if (M == M_I0) PrintMessage("%#5.2f", I0[j]);
     542        else if (M == M_I) PrintMessage("%#5.1f", Dev->GetCurrent(j) - Dev->GetVoltage(j)/R[j] - I0[j]);
     543
    426544        // Print overcurrent marker
    427545        PrintMessage("%s ", Dev->OC[j] ? "*":" ");
  • fact/BIASctrl/User.h

    r11915 r11919  
    3333        class Crate *Dev;
    3434        std::vector<double> DefaultVoltage;
    35 
     35        std::vector<double> R, I0;
     36       
    3637        void commandHandler();
    3738
     
    6061        void cmd_exit();        void cmd_reset();
    6162        void cmd_help();        void cmd_mode();
    62         void cmd_shell();
     63        void cmd_shell();       void cmd_calib();
    6364};
    6465
Note: See TracChangeset for help on using the changeset viewer.