Adafruit Nau7802 calibration with deep sleep

Hello,

I hooked up a adafruit Nau_7802 24 bit ADC via STEMMA to my esp32 board. I want my esp32 board to go to deepsleep for 15 mins or so and then wake up without doing the calibration routine in the setup. Mostly the offset calibration because that would destroy the reading of the strain gauge attached to the Nau7802. My idea is to only do the offset calibration routine when a button is being pressed. The calibrated offset value is then stored in the eeprom of the esp32 since there it survives the deep sleep and deducted from the reading the Nau_7802 will perform once it wakes up from deep sleep. I just didnt find where in the .cpp and .h file in the library that offset value is being calculated and how to access it.

This is the the calibration part of the .cpp file

/**************************************************************************/
/*!
    @brief  Perform the internal calibration procedure
    @param mode The calibration mode to perform: NAU7802_CALMOD_INTERNAL,
    NAU7802_CALMOD_OFFSET or NAU7802_CALMOD_GAIN
    @returns True on calibrations success
*/
/**************************************************************************/
bool Adafruit_NAU7802::calibrate(NAU7802_Calibration mode) {
  Adafruit_I2CRegister ctrl2_reg = Adafruit_I2CRegister(i2c_dev, NAU7802_CTRL2);
  Adafruit_I2CRegisterBits cal_start =
      Adafruit_I2CRegisterBits(&ctrl2_reg, 1, 2); // # bits, bit_shift
  Adafruit_I2CRegisterBits cal_err =
      Adafruit_I2CRegisterBits(&ctrl2_reg, 1, 3); // # bits, bit_shift
  Adafruit_I2CRegisterBits cal_mod =
      Adafruit_I2CRegisterBits(&ctrl2_reg, 2, 0); // # bits, bit_shift

  if (!cal_mod.write(mode))
    return false;
  if (!cal_start.write(true))
    return false;
  while (!cal_start.read()) {
    delay(10);
  }

  return !cal_err.read();
}

and here is the calibration part of the .h file

/*! The possible calibration modes */
typedef enum _calib_mode {
  NAU7802_CALMOD_INTERNAL = 0,
  NAU7802_CALMOD_OFFSET = 2,
  NAU7802_CALMOD_GAIN = 3,
} NAU7802_Calibration;

/**************************************************************************/
/*!
    @brief  NAU7802 driver.
*/
/**************************************************************************/
class Adafruit_NAU7802 {
public:
  Adafruit_NAU7802();
  bool begin(TwoWire *theWire = &Wire);
  bool reset(void);
  bool enable(bool flag);
  bool available(void);
  int32_t read(void);

  bool setLDO(NAU7802_LDOVoltage voltage);
  NAU7802_LDOVoltage getLDO(void);
  bool setGain(NAU7802_Gain gain);
  NAU7802_Gain getGain(void);
  bool setRate(NAU7802_SampleRate gain);
  NAU7802_SampleRate getRate(void);
  bool calibrate(NAU7802_Calibration mode);

The github suppository of the breakout board

thank you very much for any hint

The calibration routine in the .cpp file triggers the calibration process, but the actual calculation of the offset value is not explicitly shown in the code snippet you provided. Typically, the offset value is calculated by taking a reading with a known weight and a reading with no weight, then calculating the difference.

// Function to read the offset value from the NAU7802
int32_t Adafruit_NAU7802::readOffset() {
// Assuming the offset is stored in a register, replace 'OFFSET_REGISTER' with the actual register address
return readRegister(OFFSET_REGISTER);
}

// Function to write the offset value to the NAU7802
bool Adafruit_NAU7802::writeOffset(int32_t offsetValue) {
// Write the offset value to the appropriate register
return writeRegister(OFFSET_REGISTER, offsetValue);
}

Thank you @robert2001b . You are right the offset is normally calculated with a known weight. The sparkfun qwiic scale break out board does it this way. But the NAU_7802 from adafruit removes the offset by doing something in the 'CTRL2' register. When the calibration process begins, the CAL_START bit is set. The calibrate() function continuously polls the CAL_START bit to determine when the calibration process has finished. It waits until the CAL_START bit becomes 0, indicating that the calibration is complete.

Once the CAL_START bit is cleared, the function proceeds to check the status of the CAL_ERR bit in the CTRL2 register. If the CAL_ERR bit is not set (i.e., it remains 0), it indicates that the calibration process was successful.

Once the calibration process finishes successfully, the ADC automatically clears this bit to signal that the calibration is complete. I am not a programmer so I don't really know how to gain access to whatever happens in the register.

My work around looks like this:
buttonfritzingSteckplatine.pdf (498.3 KB)

The internal offset calibration only starts when a button is being pressed during the setup rountine. The offset value is then stored in the preference

  if (buttonState == HIGH) {


      // Take 10 readings to flush out readings
  for (uint8_t i=0; i<10; i++) {
    while (! nau.available()) delay(1);
    nau.read();
  }
  calValuebefore=nau.getAverage(10);





      while (! nau.calibrate(NAU7802_CALMOD_OFFSET)) {
    Serial.println("Failed to calibrate system offset, retrying!");
    delay(1000);
  }
      Serial.println("Calibrated system offset");
      Serial.println("The button is pressed");
  calValueafter=nau.getAverage(10);
  offset=calValuebefore-calValueafter;
  preferences.putLong("offset", offset);    
      Serial.print("Offset: "); Serial.println(preferences.getLong("offset", 0));



  }

  else 
    Serial.println("The button is released");


offset2=preferences.getLong("offset", 0);
  preferences.end();

}

When it boots up again it takes that stored value as the offset.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.