Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
NovelecProtocol.cpp 28.41 KiB
// ============================================================================
//
// = CONTEXT
//    TANGO Project - NovelecProtocol Support Library
//
// = FILENAME
//    NovelecProtocol.cpp
//
// = AUTHOR
//    X. Elattaoui
//
// ============================================================================

/*
*  NOTE : WARNING !!!
*  ------
*   TO AVOID ANY COMMUNICATION BUG, DO NOT END STRINGSTREAMS BY AN 'END OF LINE'
*  (i.e. std::endl; ). THE MCCE2 returns bad formatted response !!!
*/

// ============================================================================
// DEPENDENCIES
// ============================================================================
#include <iostream>
#include <sstream>
#include <string>
#include <helpers/XString.h>
#include "NovelecProtocol.h"

//- commands numbers
static const short  STATUS_CMD_NUM              = 1;
static const short  ERRORS_CMD_NUM              = 2;
static const short  MODE_CMD_NUM                = 3;
static const short  ELECTROTYPE_CMD_NUM         = 4;
static const short  POLARITY_CMD_NUM            = 5;
static const short  FREQUENCY_CMD_NUM           = 6;
static const short  GAIN_CMD_NUM                = 7;
static const short  RANGE_CMD_NUM               = 8;
static const short  RESPONSE_LGTH_CMD_NUM       = 17;
static const short  CLEAR_ERRORS_CMD_NUM        = 18;
static const long   PILOTAGE_AND_PROG_RESP_LGTH = 10;
static const long   READ_DATA_RESP_LGTH         = 24;
//- the specific new line character
static const char END_OF_LINE[] = "\r\n";
//- modes allowed
static const std::string mode_str[] = {"ERR : UNKNOWN MODE","ZERO V/F","OFFSET","LEAKAGE","TEST","MEASURE"};
static const std::string range_str[5][8] = {
  {"1E-11AcC","3E-11AcC","1E-10AcC","3E-10AcC", "OUT OF RANGE","OUT OF RANGE","OUT OF RANGE","OUT OF RANGE"},
  {"1E-10AcC","3E-10AcC","1E-9AcC","3E-9AcC","1E-8AcC","3E-8AcC","1E-7AcC","3E-7AcC"},
  {"1E-8AcC","3E-8AcC","1E-7AcC","3E-7AcC","1E-6AcC","3E-6AcC","1E-5AcC","3E-5AcC"},
  {"1000MOhm","300MOhm","100MOhm","30MOhm","OUT OF RANGE","OUT OF RANGE","OUT OF RANGE","OUT OF RANGE"},
  {"1000KOhm","300KOhm","100KOhm","30KOhm","OUT OF RANGE","OUT OF RANGE","OUT OF RANGE","OUT OF RANGE"}
};
static const std::string frequency_str[]= {"3 Hz","10 Hz","100 Hz","1000 Hz"};
static const std::string gain_str[]   = {"1","10","100"};

/*
// ============================================================================
// NovelecProtocol::NovelecProtocol
// ============================================================================
NovelecProtocol::NovelecProtocol (std::string& serial_device_name, unsigned short devAddress, unsigned short novelecType)
  : ElectrometerProtocol(),
    _devAdd(devAddress),
    _novType(novelecType),
    _rangeParameterNum(0),
    _communication_link(0),
    _is_measure_mode_on(false),
    _is_explicite_resp_enabled(false)
{
  _commDevName = serial_device_name;
  _function = "Not updated";
}
*/
// ============================================================================
// NovelecProtocol::NovelecProtocol
// ============================================================================
NovelecProtocol::NovelecProtocol (std::string& serial_device_name, unsigned short devAddress)
  : ElectrometerProtocol(),
    _devAdd(devAddress),
    _novType(0),
    _rangeParameterNum(0),
    _communication_link(0),
    _is_measure_mode_on(false),
    _is_explicite_resp_enabled(false)
{
  _commDevName = serial_device_name;
  _function = "Not updated";
}

// ============================================================================
// NovelecProtocol::~NovelecProtocol
// ============================================================================
NovelecProtocol::~NovelecProtocol (void)
{
//  std::cout << "NovelecProtocol::~NovelecProtocol <-" << std::endl;
  if ( this->_communication_link )
  {
    delete _communication_link;
    this->_communication_link = 0;
  }
//  std::cout << "NovelecProtocol::~NovelecProtocol ->" << std::endl;
}

// ============================================================================
// NovelecProtocol::build_communicationLink
// ============================================================================
bool NovelecProtocol::build_communicationLink()
{
  if (_commDevName.empty())
    return false;

  _communication_link = new TangoSerialLink(_commDevName);

  if (!_communication_link)
    return false;

  //- find the connected electrometer type and its ranges
  std::string eType = this->check_electrotype();
  this->_novType = XString<short>::convertFromString(eType);
  this->_rangeParameterNum  = _novType + 2; // NOTE : +2 means => the range command number is the novelec type + 2 !

  return true;
}

// ============================================================================
// NovelecProtocol::NovelecProtocol
// ============================================================================
void NovelecProtocol::init_MCCE2_for_communication(void)
{
  std::stringstream explicite_resp;
  //- CMD to enable PROG cmds
  this->switch_MCCE2_OFF();  //- this command is now called in the MCCE2 device !

  //- Clear error registers
  this->clear_registers();

  //- send cmd to have an explicite response :
  explicite_resp << _devAdd << " PROG " << RESPONSE_LGTH_CMD_NUM << " 1" << END_OF_LINE;
  std::string tmp = this->_communication_link->write_read(explicite_resp.str(), PILOTAGE_AND_PROG_RESP_LGTH);
  //- check only the command response
  check_command(tmp);

  //- lock parameters modification
  this->switch_MCCE2_ON();

  //- if no error
  _is_explicite_resp_enabled = true;
}

// ============================================================================
// NovelecProtocol::check_electrotype
// ============================================================================
std::string NovelecProtocol::check_electrotype (void)
{
  std::stringstream cmd_to_send;
  std::string electroType("no data");
  std::string tmp("no data");

  //- send command to Novelec device
  cmd_to_send << _devAdd << " READ " << ELECTROTYPE_CMD_NUM << END_OF_LINE;
  tmp = this->_communication_link->write_read(cmd_to_send.str(), READ_DATA_RESP_LGTH);

  //- check and extract the response
  electroType = check_and_extract_data(tmp, ELECTROTYPE_CMD_NUM);

  //- check what is the response mode type
  if( _is_explicite_resp_enabled )
    electroType = electroType.substr(electroType.find(".")+1);

  return electroType;
}

// ============================================================================
// NovelecProtocol::get_mode
// ============================================================================
std::string NovelecProtocol::get_mode (void)
{
  std::stringstream cmd_to_send;
  std::string argout("no data");
  std::string tmp("no data");

  //- send command to Novelec device
  cmd_to_send << _devAdd << " READ " << MODE_CMD_NUM << END_OF_LINE;
  tmp = this->_communication_link->write_read(cmd_to_send.str(), READ_DATA_RESP_LGTH);

  //- check and extract the response
  argout = check_and_extract_data(tmp, MODE_CMD_NUM);

  //- check what is the response mode type
  if( !_is_explicite_resp_enabled )
  {
    short idx = XString<short>::convertFromString(argout);
    _function = mode_str[idx];
  }
  else
    _function = argout;

  return _function;
}

// ============================================================================
// NovelecProtocol::get_value
// ============================================================================
std::string NovelecProtocol::get_value (void)
{
  std::stringstream cmd_to_send;
  std::string tmp("no data");
  std::string value("-1");
  short cmd_num = 13;       //- default value for DEBUG !!!

  //- first get mode
  get_mode();

  if( (_function.find("OFFSET") != std::string::npos) || (_function.find("V1") != std::string::npos) )
  {
    cmd_num = 12;
  }
  else if( (_function.find("LEAKAGE") != std::string::npos) || (_function.find("V2") != std::string::npos) )
    cmd_num = 11;
  else
    std::cout << "\t\t***WARN : Current mode : \"" << get_mode() << "\" has no value available." << std::endl;

  cmd_to_send << _devAdd << " READ " << cmd_num << END_OF_LINE;
  tmp = this->_communication_link->write_read(cmd_to_send.str(), READ_DATA_RESP_LGTH);

  //- check only the command response
  value = check_and_extract_data(tmp, cmd_num);

  return value;
}

// ============================================================================
// NovelecProtocol::switch_MCCE2_ON
// ============================================================================
void NovelecProtocol::switch_MCCE2_ON (void)
{
  std::stringstream cmd_to_send;
  std::string tmp("no data");

  //- send cmd to have a explicite response :
  cmd_to_send << _devAdd << " MEASURE 1 " << END_OF_LINE;
  tmp = this->_communication_link->write_read(cmd_to_send.str(), PILOTAGE_AND_PROG_RESP_LGTH);

  //- check only the command response
  check_command(tmp);

  _is_measure_mode_on = true;
}

// ============================================================================
// NovelecProtocol::switch_MCCE2_OFF
// ============================================================================
void NovelecProtocol::switch_MCCE2_OFF (void)
{
  std::stringstream cmd_to_send;
  std::string tmp("no data");

  //- send cmd to have a explicite response :
  cmd_to_send << _devAdd << " MEASURE 0 " << END_OF_LINE;
  tmp = this->_communication_link->write_read(cmd_to_send.str(), PILOTAGE_AND_PROG_RESP_LGTH);

  //- check only the command response
  check_command(tmp);

  _is_measure_mode_on = false;
}

// ============================================================================
// NovelecProtocol::unable_zeroVF_func
// ============================================================================
void NovelecProtocol::unable_zeroVF_func (void)
{
  std::stringstream cmd_to_send;
  std::string cmdNumber(" 1");      //- PROG 1 -> = PROG FUNCTION
  std::string tmp("no data");

  //- allow parameters modification
  this->switch_MCCE2_OFF();
  //- send cmd to have a explicite response :
  cmd_to_send << _devAdd << " PROG 1 " << cmdNumber << END_OF_LINE;
  tmp = this->_communication_link->write_read(cmd_to_send.str(), PILOTAGE_AND_PROG_RESP_LGTH);

  //- check only the command response
  check_command(tmp);

  //- lock parameters modification
  this->switch_MCCE2_ON();
}

// ============================================================================
// NovelecProtocol::unable_offset_zeroV1_func
// ============================================================================
void NovelecProtocol::unable_offset_zeroV1_func (void)
{
  std::stringstream cmd_to_send;
  std::string cmdNumber(" 2");      //- PROG 1 -> = PROG FUNCTION
  std::string tmp("no data");

  //- allow parameters modification
  this->switch_MCCE2_OFF();

  //- send cmd to have a explicite response :
  cmd_to_send << _devAdd << " PROG 1 " << cmdNumber << END_OF_LINE;
  tmp = this->_communication_link->write_read(cmd_to_send.str(), PILOTAGE_AND_PROG_RESP_LGTH);

  //- check only the command response
  check_command(tmp);

  //- lock parameters modification
  this->switch_MCCE2_ON();
}

// ============================================================================
// NovelecProtocol::unable_leakage_zeroV2_func
// ============================================================================
void NovelecProtocol::unable_leakage_zeroV2_func (void)
{
  std::stringstream cmd_to_send;
  std::string cmdNumber(" 3");      //- PROG 1 -> = PROG FUNCTION
  std::string tmp("no data");

  //- allow parameters modification
  this->switch_MCCE2_OFF();

  //- send cmd to have a explicite response :
  cmd_to_send << _devAdd << " PROG 1 " << cmdNumber << END_OF_LINE;
  tmp = this->_communication_link->write_read(cmd_to_send.str(), PILOTAGE_AND_PROG_RESP_LGTH);

  //- check only the command response
  check_command(tmp);

  //- lock parameters modification
  this->switch_MCCE2_ON();
}

// ============================================================================
// NovelecProtocol::unable_test_func
// ============================================================================
void NovelecProtocol::unable_test_func (void)
{
  std::stringstream cmd_to_send;
  std::string cmdNumber(" 4");      //- PROG 1 -> = PROG FUNCTION
  std::string tmp("no data");

  //- allow parameters modification
  this->switch_MCCE2_OFF();

  //- send cmd to have a explicite response :
  cmd_to_send << _devAdd << " PROG 1 " << cmdNumber << END_OF_LINE;
  tmp = this->_communication_link->write_read(cmd_to_send.str(), PILOTAGE_AND_PROG_RESP_LGTH);

  //- check only the command response
  check_command(tmp);

  //- lock parameters modification
  this->switch_MCCE2_ON();
}

// ============================================================================
// NovelecProtocol::unable_measure_func
// ============================================================================
void NovelecProtocol::unable_measure_func (void)
{
  std::stringstream cmd_to_send;
  std::string cmdNumber(" 5");      //- PROG 1 -> = PROG FUNCTION
  std::string tmp("no data");

  //- allow parameters modification
  this->switch_MCCE2_OFF();

  //- send cmd to have a explicite response :
  cmd_to_send << _devAdd << " PROG 1 " << cmdNumber << END_OF_LINE;
  tmp = this->_communication_link->write_read(cmd_to_send.str(), PILOTAGE_AND_PROG_RESP_LGTH);

  //- check only the command response
  check_command(tmp);

  //- lock parameters modification
  this->switch_MCCE2_ON();
}

// ============================================================================
// NovelecProtocol::get_range
// ============================================================================
std::string NovelecProtocol::get_range (void)
{
  std::stringstream cmd_to_send;
  std::string argout("no data");
  std::string tmp("no data");

  //- send command to Novelec device
  cmd_to_send << _devAdd << " READ " << RANGE_CMD_NUM << END_OF_LINE;
  tmp = this->_communication_link->write_read(cmd_to_send.str(), READ_DATA_RESP_LGTH);

  //- check and extract the response
  argout = check_and_extract_data(tmp, RANGE_CMD_NUM);

  //- check what is the response mode type
  if( _is_explicite_resp_enabled == false )
  {
    short idx = XString<short>::convertFromString(argout);
    argout = range_str[_novType-1][idx];
  }

  return argout;
}

// ============================================================================
// NovelecProtocol::set_range
// ============================================================================
void NovelecProtocol::set_range (std::string value)
{
  std::stringstream cmd_to_send;
  std::string tmp("no data");

  //- allow parameters modification
  this->switch_MCCE2_OFF();
  //- send command to Novelec device
  cmd_to_send << _devAdd << " PROG " << _rangeParameterNum << " " << value << END_OF_LINE;
  tmp = this->_communication_link->write_read(cmd_to_send.str(), PILOTAGE_AND_PROG_RESP_LGTH);

  //- the novelec device send ACK/NAK response after a received command
  check_command(tmp);

  //- lock parameters modification
  this->switch_MCCE2_ON();
}

// ============================================================================
// NovelecProtocol::get_polarity
// ============================================================================
std::string NovelecProtocol::get_polarity (void)
{
  std::stringstream cmd_to_send;
  std::string argout("no data");
  std::string tmp("no data");

  //- send command to Novelec device
  cmd_to_send << _devAdd << " READ " << POLARITY_CMD_NUM << END_OF_LINE;
  tmp = this->_communication_link->write_read(cmd_to_send.str(), READ_DATA_RESP_LGTH);

  //- check and extract the response
  argout = check_and_extract_data(tmp, POLARITY_CMD_NUM);

  //- check what is the response mode type
  if( _is_explicite_resp_enabled == false )
  {
    short idx = XString<short>::convertFromString(argout);
    if(idx < 0)
      argout = "negative";
    else
      argout = "positive";
  }

  return argout;
}

// ============================================================================
// NovelecProtocol::set_polarity
// ============================================================================
void NovelecProtocol::set_polarity (std::string newPolarity)
{
  std::stringstream cmd_to_send;
  std::string tmp("no data");

  //- check if the MCCE2 is not in MEASURE mode to get/change any settings
  if ( newPolarity.find("POSIT") == std::string::npos && newPolarity.find("NEGAT") == std::string::npos )
  {
    throw electrometer::ElectrometerException("INVALID_PARAMETER",
        "Expected POSITIVE or NEGATIVE in UPPER case.",
        "NovelecProtocol::set_polarity( ).");
  }

  //- allow parameters modification
  this->switch_MCCE2_OFF();

  //- send command to Novelec device
  cmd_to_send << _devAdd << " PROG 2" << " " << newPolarity << END_OF_LINE;
  tmp = this->_communication_link->write_read(cmd_to_send.str(), PILOTAGE_AND_PROG_RESP_LGTH);

  //- the novelec device send ACK/NAK response after a received command
  check_command(tmp);

  //- lock parameters modification
  this->switch_MCCE2_ON();
}
// ============================================================================
// NovelecProtocol::get_frequency
// ============================================================================
std::string NovelecProtocol::get_frequency (void)
{
  std::stringstream cmd_to_send;
  std::string argout("no data");
  std::string tmp("");

  //- send command to Novelec device
  cmd_to_send << _devAdd << " READ " << FREQUENCY_CMD_NUM << END_OF_LINE;
  tmp = this->_communication_link->write_read(cmd_to_send.str(), READ_DATA_RESP_LGTH);

  //- check and extract the response
  argout = check_and_extract_data(tmp, FREQUENCY_CMD_NUM);

  //- check what is the response mode type
  if( _is_explicite_resp_enabled == false )
  {
    short idx = XString<short>::convertFromString(argout);
    argout    = frequency_str[idx];
  }

  return argout;
}

// ============================================================================
// NovelecProtocol::set_frequency
// ============================================================================
void NovelecProtocol::set_frequency (std::string newFrequency)
{
  std::stringstream cmd_to_send;
  std::string tmp("no data");

  //- allow parameters modification
  this->switch_MCCE2_OFF();

  //- send command to Novelec device
  cmd_to_send << _devAdd << " PROG 9" << " " << newFrequency << END_OF_LINE;
  tmp = this->_communication_link->write_read(cmd_to_send.str(), PILOTAGE_AND_PROG_RESP_LGTH);

  //- the novelec device send ACK/NAK response after a received command
  check_command(tmp);

  //- lock parameters modification
  this->switch_MCCE2_ON();
}

// ============================================================================
// NovelecProtocol::get_gain
// ============================================================================
std::string NovelecProtocol::get_gain (void)
{
  std::stringstream cmd_to_send;
  std::string argout("no data");
  std::string tmp("no data");

  //- send command to Novelec device
  cmd_to_send << _devAdd << " READ " << GAIN_CMD_NUM << END_OF_LINE;
  tmp = this->_communication_link->write_read(cmd_to_send.str(), READ_DATA_RESP_LGTH);

  //- check and extract the response
  argout = check_and_extract_data(tmp, GAIN_CMD_NUM);

  //- check what is the response mode type
  if( _is_explicite_resp_enabled == false )
  {
    short idx = XString<short>::convertFromString(argout);
    argout    = gain_str[idx];
  }
  else
    //- erase wildcard char : response received is as this "*10xx"
    argout    = argout.erase(argout.find('*'),1);

  return argout;
}

// ============================================================================
// NovelecProtocol::set_gain
// ============================================================================
void NovelecProtocol::set_gain (std::string newGain)
{
  std::stringstream cmd_to_send;
  std::string tmp("no data");

  //- allow parameters modification
  this->switch_MCCE2_OFF();
  //- send command to Novelec device
  cmd_to_send << _devAdd << " PROG 8" << " " << newGain << END_OF_LINE;
  tmp = this->_communication_link->write_read(cmd_to_send.str(), PILOTAGE_AND_PROG_RESP_LGTH);

  //- the novelec device send ACK/NAK response after a received command
  check_command(tmp);

  //- lock parameters modification
  this->switch_MCCE2_ON();
}

// ============================================================================
// NovelecProtocol::get_errors
// ============================================================================
std::string NovelecProtocol::get_errors (void)
{
  std::stringstream cmd_to_send;
  std::string argout("no data");
  std::string tmp("no data");

  //- send command to Novelec device
  cmd_to_send << _devAdd << " READ " << ERRORS_CMD_NUM << END_OF_LINE /*<< std::endl */;
  tmp = this->_communication_link->write_read(cmd_to_send.str(), READ_DATA_RESP_LGTH);

  //- check and extract the response
  argout = check_and_extract_data(tmp, ERRORS_CMD_NUM);

  return argout;
}

// ============================================================================
// NovelecProtocol::reset
// ============================================================================
void NovelecProtocol::reset (void)
{
  std::stringstream cmd_to_send;

  //- send command
  cmd_to_send << _devAdd << " RESET" << END_OF_LINE;
  _communication_link->write(cmd_to_send.str());
  //- there is no response from the device !!!
}

// ============================================================================
// NovelecProtocol::local
// ============================================================================
void NovelecProtocol::local (void)
{
  std::stringstream cmd_to_send;
  std::string tmp("no data");

  //- allow parameters modification
  this->switch_MCCE2_OFF();
  //- send command
  cmd_to_send << _devAdd << " LOCAL" << END_OF_LINE;
  tmp = this->_communication_link->write_read(cmd_to_send.str(), PILOTAGE_AND_PROG_RESP_LGTH);

  //- check the response
  check_command(tmp);

  //- lock parameters modification
  this->switch_MCCE2_ON();
}

// ============================================================================
// NovelecProtocol::remote
// ============================================================================
void NovelecProtocol::remote (void)
{
  std::stringstream cmd_to_send;
  std::string tmp("no data");

  //- allow parameters modification
  this->switch_MCCE2_OFF();

  //- send command
  cmd_to_send << _devAdd << " REMOTE" << END_OF_LINE;
  tmp = this->_communication_link->write_read(cmd_to_send.str(), PILOTAGE_AND_PROG_RESP_LGTH);

  //- check the response
  check_command(tmp);

  //- lock parameters modification
  this->switch_MCCE2_ON();
}

// ============================================================================
// NovelecProtocol::get_raw_status
// ============================================================================
std::string NovelecProtocol::get_raw_status (void)
{
  std::stringstream cmd_to_send;
  std::string argout("no data");
  std::string tmp("no data");

  //- send command to Novelec device
  cmd_to_send << _devAdd << " READ " << STATUS_CMD_NUM << END_OF_LINE;

  try
  {
    tmp = this->_communication_link->write_read(cmd_to_send.str(), READ_DATA_RESP_LGTH);
  }
  catch(Tango::DevFailed& df)
  {
    throw;
  }
  catch(...)
  {
    throw;
  }

  //- check and extract the response
  argout = check_and_extract_data(tmp, STATUS_CMD_NUM);

  return argout;
}

// ============================================================================
// NovelecProtocol::clear_registers
// ============================================================================
void NovelecProtocol::clear_registers (void)
{
  std::stringstream cmd_to_send;
  std::string tmp("no data");

  //- send command
  cmd_to_send << _devAdd << " PROG " << CLEAR_ERRORS_CMD_NUM << " 1 " << END_OF_LINE;
  tmp = this->_communication_link->write_read(cmd_to_send.str(), PILOTAGE_AND_PROG_RESP_LGTH);

  //- check the response
  check_command(tmp);
}

// ============================================================================
// NovelecProtocol::is_allowed
// ============================================================================
void NovelecProtocol::is_allowed (void)
{
  if(this-> _is_measure_mode_on)
    throw electrometer::ElectrometerException("COMMAND_NOT_ALLOWED",
        "Cannot change parameter(s) when MEASURE mode enabled : call MCCE2_OFF command.",
        "NovelecProtocol::check_command( ).");
}

// ============================================================================
// NovelecProtocol::check_command
//  This method read the device response and check and throw an
//  Electrometer Exception if the device response is a NAK.
//  Else, it returns the extracted response
// ============================================================================
void NovelecProtocol::check_command (std::string response)
{
  //- A correct response is :
  //      -> "address ACK " : if command well understood
  //- An invalid response is: "address NAK ..."
  if(response.find("NAK") != std::string::npos)
  {
    throw electrometer::ElectrometerException("COMMAND_NOT_UNDERSTOOD",
        "Bad formatted string command sent -> NAK received !",
        "NovelecProtocol::check_command( ).");
  }
  /*  else
      if(response.find("ACK") != std::string::npos)
        data = response;
      else //- must not exist !!!
        throw electrometer::ElectrometerException("INVALID_DATA",
                            "Invalid string received from Novelec device.",
                            "NovelecProtocol::check_command( ).");
  */

}

// ============================================================================
// NovelecProtocol::check_and_extract_data
//  This method read the device response and check and throw an
//  Electrometer Exception if the device response is a NAK.
//  Else, it returns the extracted response
// ============================================================================
std::string NovelecProtocol::check_and_extract_data (std::string response, short cmd_sent)
{
  std::string data;
  std::string cmd_sentStr;

  cmd_sentStr = XString<short>::convertToString(cmd_sent);

  //- A correct response is :
  //      -> "address AWR ReadNum = data " : if there is a returned value
  //- An invalid response is: "address NAK ..."

  if(response.find("NAK") != std::string::npos)
  {
    throw electrometer::ElectrometerException("COMMAND_NOT_UNDERSTOOD",
        "Bad formatted string command sent -> NAK received !",
        "NovelecProtocol::check_and_extract_data( ).");
  }
  else if(response.find("AWR") != std::string::npos)
  {
    //- check if it is the received answer of the command sent
    if(response.find(cmd_sentStr) != std::string::npos)
    {
      //- extract data in the device response
      data = response.substr(response.find("=")+1);

      /*
      * check if the response is a short or explicite response
      *
      * To do so, check if char at idx 18 is a space or a letter :
      *   if it is a space -> this is a short response
      *     and must be converted to return the explicite response
      *   else it is an explicite response it can be returned as this
      */
      //- extract char
      response = response.substr(18,1);

      //- check what is this char a 'space' or 'letter'
      if(response.find(" ") != std::string::npos)
        _is_explicite_resp_enabled = false;
      else
        _is_explicite_resp_enabled = true;

      //- erase first and last space char(s)
      data.erase(data.find_last_of(" "));
      size_t pos = data.find(" ");
      while ( pos != std::string::npos )
      {
        data.erase(pos, 1);
        pos = data.find(" ");
      }

      /*data.erase(data.find_first_of(" "),1);
      data.erase(data.find_last_of(" ")); */
    }
    else
      throw electrometer::ElectrometerException("SYNCHRONISATION_LOST",
          "The received response is not for the command previously sent.",
          "NovelecProtocol::check_and_extract_data( ).");
  }
  else //- must not exist !!!
    throw electrometer::ElectrometerException("INVALID_DATA",
        "Invalid string received from Novelec device.",
        "NovelecProtocol::check_and_extract_data( ).");

  return data;
}