AnsweredAssumed Answered

AD7193 - Incorrect gain after calibration

Question asked by estratos on Oct 3, 2017
Latest reply on Oct 5, 2017 by estratos

I'm working on a project based on the AD7193 ADC IC where I need to set the PGA dynamically depending on the type of probe being connected. I know that  setting the gain is working since I'm reading the CONFIG register just after writing it. This is the function created to write and confirm the gain:

 

 

bool AD7193::setPGAGain(uint8_t gain)
{
  uint32_t gainSetting;

  switch(gain)
  {
    case 1:
      gainSetting = 0x00;
      break;
    case 8:
      gainSetting = 0x03;
      break;
    case 16:
      gainSetting = 0x04;
      break;
    case 32:
      gainSetting = 0x05;
      break;
    case 64:
      gainSetting = 0x06;
      break;
    case 128:
      gainSetting = 0x07;
      break;
    default:
      return false;
  }

 

  digitalWrite(csPin, LOW);
  delay(10);

  uint32_t regValue = getRegisterValue(AD7193_REG_CONF, registerSize[AD7193_REG_CONF]);

  // No need to alter the register
  if ((AD7193_CONF_GAIN(regValue)) == gainSetting)
    return true;

 

  regValue &= ~AD7193_CONF_GAIN(0x7);
  regValue |= gainSetting;
  setRegisterValue(AD7193_REG_CONF, regValue, registerSize[AD7193_REG_CONF]);
 delay(100);

 

  uint32_t newValue = getRegisterValue(AD7193_REG_CONF, registerSize[AD7193_REG_CONF]);

 

  digitalWrite(csPin, HIGH);
  delay(10);

 

  return (newValue == regValue);
}

 

The above function seems to be working fine and it returns "true" most of the time, which means that the gain has been successfully set and modified.

 

Now the issue comes when I run the necessary calibration after changing the gain. whatever gain I decide to set with the above function, it reverts to 128 after calibrating the AD7193.

 

I'm actually running an internal zero-scale calibration followed by an internal full-scale calibration. finally, the mode is switched to IDLE:

 

 

/**
* calibrate
*
* Calibrate AD7193
*/
void AD7193::calibrate(void)
{
  uint32_t regValue;

  digitalWrite(csPin, LOW);
  delay(10);

 

  regValue = getRegisterValue(AD7193_REG_MODE, registerSize[AD7193_REG_MODE]);

 

  // Zero-scale calibration
  regValue &= ~AD7193_MODE_SEL(0x07); // keep all bit values except Mode select bits
  regValue |= AD7193_MODE_SEL(AD7193_MODE_CAL_INT_ZERO); // internal zero scale calibration
  setRegisterValue(AD7193_REG_MODE, regValue, registerSize[AD7193_REG_MODE]);

 

  waitForADC();

 

  // Full-scale calibration
  regValue &= ~AD7193_MODE_SEL(0x07); // keep all bit values except Mode select bits
  regValue |= AD7193_MODE_SEL(AD7193_MODE_CAL_INT_FULL); // internal full scale calibration
  setRegisterValue(AD7193_REG_MODE, regValue, registerSize[AD7193_REG_MODE]);

 

  waitForADC();

 

  // Full-scale calibration
  regValue &= ~AD7193_MODE_SEL(0x07); // keep all bit values except Mode select bits
  regValue |= AD7193_MODE_SEL(AD7193_MODE_IDLE); // back to idle state
  setRegisterValue(AD7193_REG_MODE, regValue, registerSize[AD7193_REG_MODE]);

 

  waitForADC();

 

  digitalWrite(csPin, HIGH);
  delay(10);
}

 

where waitForADC waits for AD7193_RDY_STATE to go low for a maximum of 5 seconds. I'm suspecting that the problem is in this calibration function and I've even trying with some additional delays here and there without success.

 

Thanks in advance for your help.

Outcomes