Post Go back to editing

Ad5933 analog front end - 4 electrode measuring

Hey everyone,

I need to implement a four electrode measuring circuit to interface with the Ad5933.

Ive used the suggested analog front end in the attached link, which is very popular throughout the references:

www.instructables.com/.../

My problem:

Im able to calibrate a 1k resistor but whenever I change the load after calibration it shows very little difference, for instance an avg of 1040 ohm instead of 1000 ohm when I plug a 2k resistor.

Sometimes it shows even a lower avg value.

My setup:

For the opamps I ised TL072 and for the inamp I used INA118P. both are have suitable specs for the job.

I used 1M resistor for R current and R protect and used Rin of 2k and Rfb of 1k.

Ive fed the inamp and opamps with v+ of 10v and v- of negative 10v.

Ive attached all grounds in the system.

I short circuited all the ad5933 vdd pins and have them 5v vdd from an arduino, and did the same for the ground pins and attached to the common ground.

The ad5934 is controlled via the arduino by attaching a4 and a5 pins to scl and sda pins.

Finally ive attached a 1k resistor as the load between the four electrodes. Each pole of the resistor gets two parallel electrodes.

Ive checked my wiring a hundred times and Ive tried to add Rg to the inamp.

Ive tried to play with rfb and r in.

Ive chexked with a scope in every point to see that the signal is what its supposed to be. Im sure its good until the inamps input, where im not quite sure because I get very low voltage different across the input pins (20mv).

I would cery much appreciate guidance

Ben

Parents
  • It is had to suggest much without seeing the exact schematic with all connections and component values. Referring to a general sketch in your link, first suspect to check would be the DC working point for the entire schematic as the AD5933, generally speaking, requires the AC signals to have zero line at Vdd/2 = 2.5V in your case. Can you check if the DC voltage is 2.5V at:
    1. The left pin of Rcurrent resistor
    2. The output of the Vref Generator
    3. The right pin of Rprotect
    4. The left pin of Rin
    5. The RF pin of the AD5933
    ?
    If all is well, can you check that the AC voltage at the RFB pin of the AD5933 is a well-formed sinewave without any distortion or clipping at 0V or Vdd or both?
    Also, what settings are you programming into the AD5933? Excitation voltage, PGA gain, frequency range, number of settling cycles, etc.? 

  • Hey  Snorlax, Thanks for your reply!

    Im attaching an image of the schematics to make it more clear.

    regarding your questions, I have checked for vdc of 2.5v at all the points you suggested and it is indeed 2.5v.

    I do see some kind of clipping at the rfb pib and I cant seem to understand why it happens. it clips the lower part of the wave.

     my settings:

    supply voltage 5v

    Excitation voltage: 2.24v dc offset with vpp of 3v

    PGA gain=1

    frequency range 50Khz-52Khz

    default number of settling cycles 

  • and if I may, I'd like to add the Arduino code for the full picture:

    /*
    ad5933-test
        Reads impedance values from the AD5933 over I2C and prints them serially.
    */
    
    #include <Wire.h>
    #include "AD5933.h"
    
    #define START_FREQ  (50000)
    #define FREQ_INCR   (100)
    #define NUM_INCR    (20)
    #define REF_RESIST  (1000)
    
    double gain[NUM_INCR+1];
    int phase[NUM_INCR+1];
    
    void setup(void)
    {
      // Begin I2C
      Wire.begin();
    
      // Begin serial at 9600 baud for output
      Serial.begin(9600);
      Serial.println("AD5933 Test Started!");
    
      // Perform initial configuration. Fail if any one of these fail.
      if (!(AD5933::reset() &&
            AD5933::setInternalClock(true) &&
            AD5933::setStartFrequency(START_FREQ) &&
            AD5933::setIncrementFrequency(FREQ_INCR) &&
            AD5933::setNumberIncrements(NUM_INCR) &&
            AD5933::setPGAGain(PGA_GAIN_X1)))
            {
                Serial.println("FAILED in initialization!");
                while (true) ;
            }
    
      // Perform calibration sweep
      if (AD5933::calibrate(gain, phase, REF_RESIST, NUM_INCR+1))
        Serial.println("Calibrated!");
      else
        Serial.println("Calibration failed...");
    }
    
    void loop(void)
    {
    
      // Complex but more robust method for frequency sweep
      frequencySweepRaw();
    
      // Delay
      delay(5000);
    }
    
    
    void frequencySweepRaw() {
        // Create variables to hold the impedance data and track frequency
        int real, imag, i = 0, cfreq = START_FREQ/1000;
    
        // Initialize the frequency sweep
        if (!(AD5933::setPowerMode(POWER_STANDBY) &&          // place in standby
              AD5933::setControlMode(CTRL_INIT_START_FREQ) && // init start freq
              AD5933::setControlMode(CTRL_START_FREQ_SWEEP))) // begin frequency sweep
             {
                 Serial.println("Could not initialize frequency sweep...");
             }
    
        // Perform the actual sweep
        while ((AD5933::readStatusRegister() & STATUS_SWEEP_DONE) != STATUS_SWEEP_DONE) {
            // Get the frequency data for this frequency point
            if (!AD5933::getComplexData(&real, &imag)) {
                Serial.println("Could not get raw frequency data...");
            }
    
            // Print out the frequency data
            Serial.print(cfreq);
            Serial.print(": R=");
            Serial.print(real);
            Serial.print("/I=");
            Serial.print(imag);
    
            // Compute impedance
            double magnitude = sqrt(pow(real, 2) + pow(imag, 2));
            double impedance = 1/(magnitude*gain[i]);
            Serial.print("  |Z|=");
            Serial.println(impedance);
    
            // Increment the frequency
            i++;
            cfreq += FREQ_INCR/1000;
            AD5933::setControlMode(CTRL_INCREMENT_FREQ);
        }
    
        Serial.println("Frequency sweep complete!");
    
        // Set AD5933 power mode to standby when finished
        if (!AD5933::setPowerMode(POWER_STANDBY))
            Serial.println("Could not set to standby...");
    }

    I think I have a problem calculating the real gain in the circuit and how to take into account the different resistor values in the final gain calculation.

    I would probably also need to incorporate it in the calibration process but since I use a library for the ad5933 I assume I'd have to make my own calibration function?

Reply
  • and if I may, I'd like to add the Arduino code for the full picture:

    /*
    ad5933-test
        Reads impedance values from the AD5933 over I2C and prints them serially.
    */
    
    #include <Wire.h>
    #include "AD5933.h"
    
    #define START_FREQ  (50000)
    #define FREQ_INCR   (100)
    #define NUM_INCR    (20)
    #define REF_RESIST  (1000)
    
    double gain[NUM_INCR+1];
    int phase[NUM_INCR+1];
    
    void setup(void)
    {
      // Begin I2C
      Wire.begin();
    
      // Begin serial at 9600 baud for output
      Serial.begin(9600);
      Serial.println("AD5933 Test Started!");
    
      // Perform initial configuration. Fail if any one of these fail.
      if (!(AD5933::reset() &&
            AD5933::setInternalClock(true) &&
            AD5933::setStartFrequency(START_FREQ) &&
            AD5933::setIncrementFrequency(FREQ_INCR) &&
            AD5933::setNumberIncrements(NUM_INCR) &&
            AD5933::setPGAGain(PGA_GAIN_X1)))
            {
                Serial.println("FAILED in initialization!");
                while (true) ;
            }
    
      // Perform calibration sweep
      if (AD5933::calibrate(gain, phase, REF_RESIST, NUM_INCR+1))
        Serial.println("Calibrated!");
      else
        Serial.println("Calibration failed...");
    }
    
    void loop(void)
    {
    
      // Complex but more robust method for frequency sweep
      frequencySweepRaw();
    
      // Delay
      delay(5000);
    }
    
    
    void frequencySweepRaw() {
        // Create variables to hold the impedance data and track frequency
        int real, imag, i = 0, cfreq = START_FREQ/1000;
    
        // Initialize the frequency sweep
        if (!(AD5933::setPowerMode(POWER_STANDBY) &&          // place in standby
              AD5933::setControlMode(CTRL_INIT_START_FREQ) && // init start freq
              AD5933::setControlMode(CTRL_START_FREQ_SWEEP))) // begin frequency sweep
             {
                 Serial.println("Could not initialize frequency sweep...");
             }
    
        // Perform the actual sweep
        while ((AD5933::readStatusRegister() & STATUS_SWEEP_DONE) != STATUS_SWEEP_DONE) {
            // Get the frequency data for this frequency point
            if (!AD5933::getComplexData(&real, &imag)) {
                Serial.println("Could not get raw frequency data...");
            }
    
            // Print out the frequency data
            Serial.print(cfreq);
            Serial.print(": R=");
            Serial.print(real);
            Serial.print("/I=");
            Serial.print(imag);
    
            // Compute impedance
            double magnitude = sqrt(pow(real, 2) + pow(imag, 2));
            double impedance = 1/(magnitude*gain[i]);
            Serial.print("  |Z|=");
            Serial.println(impedance);
    
            // Increment the frequency
            i++;
            cfreq += FREQ_INCR/1000;
            AD5933::setControlMode(CTRL_INCREMENT_FREQ);
        }
    
        Serial.println("Frequency sweep complete!");
    
        // Set AD5933 power mode to standby when finished
        if (!AD5933::setPowerMode(POWER_STANDBY))
            Serial.println("Could not set to standby...");
    }

    I think I have a problem calculating the real gain in the circuit and how to take into account the different resistor values in the final gain calculation.

    I would probably also need to incorporate it in the calibration process but since I use a library for the ad5933 I assume I'd have to make my own calibration function?

Children
No Data