Uncategorized

AD5933 takes much longer to preform a frequency sweep than expected

Ask QuestionAsked todayActive todayViewed 18 times1

I’ve been trying to replicate a 2015 paper that uses Electrical Impedance Tomography to map a cross-section of a hand, and they use the AD5933 Bio-impedance analyzer. On page 3 of the paper, they say they could achieve a sample speed of 3ms per sample, but performing a simple, single frequency sweep with the same chip takes me over 90 ms on average.

I’m using modified code from a different project for the AD5933 and Arduino. I’ve included the parts I think are relevant (although I understand usually the code contained in a post isn’t always the offending segment, I’m shortening it to not make the question too long).

//ALL CAPS VARIABLES ARE SET TO THE HEX VALUES SPECIFIED IN THE DATASHEET (AFTER PAGE 23)
//PROGRAMS THE REGISTERS BEFORE A SWEEP. TAKES AROUND 25ms, BUT ONLY NEEDS TO BE PERFORMED ONCE PER FRAME
void programReg(){

  // Set Range 1, PGA gain 1
  writeData(CTRL_REG,0x01);
  // Set settling cycles
  writeData(NUM_SCYCLES_R1, 0x07);
  writeData(NUM_SCYCLES_R2, 0xFF);

  // Start frequency of 1kHz
  writeData(START_FREQ_R1, getFrequency(start_freq,1));
  writeData(START_FREQ_R2, getFrequency(start_freq,2));
  writeData(START_FREQ_R3, getFrequency(start_freq,3));

  // Increment by 1 kHz
  writeData(FREG_INCRE_R1, getFrequency(incre_freq,1));
  writeData(FREG_INCRE_R2, getFrequency(incre_freq,2));
  writeData(FREG_INCRE_R3, getFrequency(incre_freq,3));

  // Points in frequency sweep (100), max 511
  writeData(NUM_INCRE_R1, (incre_num & 0x001F00)>>0x08 );
  writeData(NUM_INCRE_R2, (incre_num & 0x0000FF));

}

//CODE WHERE THE ACTUAL SWEEP IS PERFORMED
void runSweep() {
            Serial.print("0: ");
          Serial.println(micros()-t);
    short re;
  short img;
  double freq;
  double mag;
  double phase;
  double gain;
  double impedance;
        double tot=0;
        double avg;
 double a, b, c;
  int i = 0;
  int j = 0;
  int flag = 0;
  boolean w_f;

  programReg();

  // 1. Standby '10110000' Mask D8-10 of avoid tampering with gains
  writeData(CTRL_REG,(readData(CTRL_REG) & 0x07) | 0xB0);

  // 2. Initialize sweep
  writeData(CTRL_REG,(readData(CTRL_REG) & 0x07) | 0x10);

  // 3. Start sweep
  writeData(CTRL_REG,(readData(CTRL_REG) & 0x07) | 0x20);
  w_f = (readData(STATUS_REG) & 0x07) < 4 ; //Checks if the frequency sweep is not complete
  Serial.print("1: ");
  Serial.println(micros()-t);
  while(w_f) {
        flag = readData(STATUS_REG)& 2; //This is true if there is valid data in the register (DS, pg. 26)
        Serial.print("2: "); 
        Serial.println(micros()-t);
        while(flag != 2){
        delay(3);
        flag = readData(STATUS_REG)& 2;
        Serial.print("2.1: ");
        Serial.println(micros()-t);
    if (flag == 2) {
      byte R1 = readData(RE_DATA_R1);
      byte R2 = readData(RE_DATA_R2);
      re = (R1 << 8) | R2;

      R1  = readData(IMG_DATA_R1);
      R2  = readData(IMG_DATA_R2);
      img = (R1 << 8) | R2;

      freq = start_freq + i*incre_freq;
      mag = sqrt(pow(double(re),2)+pow(double(img),2));
            Serial.print("3: ");
          Serial.println(micros()-t);


      Serial.print(" Resistance: ");
      Serial.print(re);
      Serial.print(",");

      Serial.print(" Reactance: ");
      Serial.print(img);


      // break;  //TODO: for single run, remove after debugging
      
      //Increment frequency
          w_f = (readData(STATUS_REG) & 0x07) < 4 ;
      if(w_f){
 
            writeData(CTRL_REG,(readData(CTRL_REG) & 0x07) | 0x30);

  
    }
                Serial.print("4: ");
          Serial.println(micros()-t);
      


      }
}
  //Power down
//  writeData(CTRL_REG,0xA0);
  }
  writeData(CTRL_REG,(readData(CTRL_REG) & 0x07) | 0xA0);

}

I have timing markers on the runSweep() function that return this:

1: 25096.00
2: 27900.00
2.1: 33724.00
2.1: 39572.00
2.1: 45412.00
2.1: 51256.00
2.1: 57104.00
2.1: 62944.00
2.1: 68792.00
2.1: 74644.00
2.1: 80488.00
3: 90012.00
 Resistance: -106, Reactance: 301, Impedence: 37267.40
4: 97448.00
2: 100260.00
2.1: 106132.00
2.1: 112020.00
2.1: 117912.00
2.1: 123808.00
2.1: 129712.00
2.1: 135600.00
2.1: 141468.00
2.1: 147340.00
2.1: 153212.00
3: 162772.00
Resistance: -146, Reactance: 418, Impedence: 26873.24
4: 166912.00
Last: 170948.00

My question is: How do I decrease the time it takes for a sweep to be performed?

I’ve tried: setting the speed of the Wire.h library to 400000Hz (the fastest timing), and skipping the flag check step after a 5 ms delay (led to useless data). On the hardware side, I tried replacing the chip, to no avail. I’ve run out of ideas, so any help is greatly appreciated.microcontrolleranalogi2cimpedanceshareedit  follow  flag asked 2 hours agoJonah11111 bronze badge New contributor

  • #Jonah, ah, let me see. The datasheet specifies typical sample rate of 1 Msps, or sample time 1 us. Your result of 90 ms comparing to the 2105 paper’s 3 ms of course is unreasonably slow. I would suggest the following troubleshooting methods: (1) set frequency sweep from 100 to 50 points, and see if sample time decreases from your 90 ms to something better. .(2) Your debugging “Serial.print()” statements of course slow things down quite a bit. Perhaps you can uncomment all the print statements and timestamp before and after testing to calculate average sample time lapse. – tlfong01 1 min ago    Edit   

add a comment

Categories: Uncategorized

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.