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
Categories: Uncategorized