Post Go back to editing

# Problem in measuring impedance at lower frequency from 10 Hz to 1k Hz using AD5933

Hello everyone, I am developing an impedance measurement system using AD5933 with a microcontroller. I can measure impedance from 47 ohms to several mega ohms from frequency range 5k to 100k Hz. Now I want to measure impedance from frequency range 10 Hz to 4k Hz. I have uploaded my AFE picture. I know there are many threads related to lower frequency excitation, I have gone through them but I did not get an appropriate idea.

I have uploaded a picture below. According to my understanding after going through this table, we can measure impedance at a low-frequencies by simply giving an external clock to AD5933 pin. I have tried but it's just working for 16Mhz and 4Mhz external oscillator clock. For lower frequencies from 10Hz to 1K Hz how can we measure impedance, do we need any calculation for settling cycle register?

Parents
• Quite an elaborate AFE you got there... The suspect would be the circuit R8R9R10C3 that acts as a low-pass filter with a time constant (R8||R9||R10)*C3 = 1.41630901288kOhm*1μF = 1.4 ms, so operating frequencies lower than a few KHz start noticeably leaking through. The suggestion would be to increase the resistors R8, R9, R10 (and, of course, R13 to keep R13/R10 ratio the same) or C3 or all the above. And prepare for long sweep duration.

If your current number of settling cycles works for your measurements at high MCLK, there should be not need to change it at lower MCLK.

• Thank you for your reply, I got this circuit from chabowski paper [1],  In this paper page num. 16 it is discussed that (ICA and ICB are for DC bias canceller. the voltage detectors are averaged on R8 and R9 and its correspond to DC bias voltage.

I think it's not an AFE problem because now I am trying to measure lower frequencies without AFE. I have measured 20kohm resistor with RFB 10kohm, it gives correct measurement from frequency sweep (5k-100k) by using 16Mhz external clock (settling cycle 0x64) and from 1khz to 5khz by using the 4Mhz external clock (settling cycle=0x0F), but when I am connecting 2Mhz external clock it acts as I have shown in video (running infinitely). but if I change the settling cycle from 0x0x0F to 0x05 it gives the result that I have shown in the image (not correct), I have measured 20kohm with 10kohm RFB.

1SIMPLE WIDE FREQUENCY RANGE IMPEDANCE METER BASED ON AD5933 INTEGRATED CIRCUIT

Konrad Chabowski, Tomasz Piasecki, Andrzej Dzierka, Karol Nitsch

Metrology & Measurement System, Vol. XXII (2015), No. 1, pp. 13–24.

• I have uploaded my circuit and external oscillator output. It's working for  16Mhz or 4Mhz, but for lower frequencies, it's not working. Now I am giving 2Mhz frequency, I want to take measurement from 300 Hz to 5000 Hz.

• This circuit should work fine if Vexc is set at maximum and gain is set at 1x.
Do you have control over I2C speed of your microcontroller? Something similar to, say, Arduino's Wire.setClock() function that could reduce the I2C clock below 100KHz?

• Thanks for your reply, I am using Teensy3.2 and Arduino IDE for programming. yes, I can control the i2c speed, I have mentioned the function below. now I am using 400Khz. but minimum speed will be 100kHz,

Vexc = 1.98Vp-p;

gain= X1;

Wire.begin(I2C_MASTER, 0x00, I2C_PINS_18_19, I2C_PULLUP_EXT, 400000);

• I have tried with Arduino UNO with 50kHz i2c frequency, but I am facing the same problem.

• AFAIK with Wire library you can go as low as 31KHz if you call Wire.setClock(31000L) after Wire.begin(). Maybe that would resolve your operation issues at low MCLK.

• Snorlax, I think I am doing some mistake in my code, I saw the post as you mentioned above, can you please tell what is L in the picture below that must be an integer as gennyelectro said, I am using the function for frequency code I mentioned below

```byte getFrequency(float freq, int n){
long val = long((freq/(MCLK/4)) * pow(2,27));
byte code;

switch (n) {
case 1:
code = (val & 0xFF0000) >> 0x10;
break;

case 2:
code = (val & 0x00FF00) >> 0x08;
break;

case 3:
code = (val & 0x0000FF);
break;

default:
code = 0;
}

return code;
}```

• Your function should work just fine as long as you change your global MCLK value in accordance with the clock frequency you feed the AD5933 chip.
As to the "L" gennyelectro discussed - it is the integer number of full cycles encompassed by the 1024-long sampled sequence to eliminate the effects of the DFT artifacts. Not sure if it is directly related to your problem.

• sorry for the late reply. I have solved my problem, Actually i was not waiting between reads.

• Great, best of luck with the rest of your endeavor!

• Hi   and  , may I know if you have added any additional circuitry between Out1 (DS1077L-66) and MCLK (AD5933). I have tried to generate 2MHz using DS1077L-40. I notice that the overshoots on the rising and falling edges of the clock waveform are very high. I have checked the generated waveform using an oscilloscope. The max and min voltage of the clock waveform are 6.72V and -1.68V respectively as shown in the picture below, which is way beyond the absolute maximum rating indicated in the datasheet (-0.3V to Vdd+0.3V).

I have added a 500pF shunt capacitor to filter out the spikes to ensure the waveform is within the absolute maximum rating as shown in the attached picture below. However, it seems like my AD5933 IC cannot detect the clock signal as my calibration keeps failing (calibration works on evaluation board with signal generator using the same source code, so it is definitely not the coding problem).

• Hi   and  , may I know if you have added any additional circuitry between Out1 (DS1077L-66) and MCLK (AD5933). I have tried to generate 2MHz using DS1077L-40. I notice that the overshoots on the rising and falling edges of the clock waveform are very high. I have checked the generated waveform using an oscilloscope. The max and min voltage of the clock waveform are 6.72V and -1.68V respectively as shown in the picture below, which is way beyond the absolute maximum rating indicated in the datasheet (-0.3V to Vdd+0.3V).

I have added a 500pF shunt capacitor to filter out the spikes to ensure the waveform is within the absolute maximum rating as shown in the attached picture below. However, it seems like my AD5933 IC cannot detect the clock signal as my calibration keeps failing (calibration works on evaluation board with signal generator using the same source code, so it is definitely not the coding problem).

Children
• Not sure I can be of help without seeing the setup. The AD5933 in my experience worked fine with just about any source of MCLK from general-purpose lab generators to chip oscillators of various kinds including programmable ones, just not the the DS1077L-40 specifically. Whenever chip oscillators were used they shared power supply with the AD5933, so the levels were automatically within working range. Also the wires/traces between the oscillator output and the MCLK input were typically under 10cm in length, so excessive over/undershoots were never observed.
How do you conclude that the calibration is failing? Does the problem occur when the output signal from the DS1077L-40 is fed to the evaluation board? If so, would it be possible to supply power to the DS1077L-40 from the evaluation board so that it would be the same as the AD5933 receives?
500 pF is probably too much, the DS1077L-40 datasheet seems to suggest that 50pF is the max load. To reduce the spikes while preserving reasonably sharp transitions people tend to use 10-30Ω resistors between the oscillator output and MCLK input.

• Hi  , thanks for replying. Please see below for the schematic of my setup:

I have posted my question in  Using DS1077L as External Clock for AD5933 MCLK as well. More pictures of waveforms from DS1077L-40 for different frequencies before and after filtering using a shunt capacitor can be found in this post. Would really appreciate if you could give me some comments over there.

Actually DS1077L has been used quite commonly for AD5933 IC. Basically I have not seen anyone who has added any external circuitry/filter between the MCLK and OUT1. Besides, as my DS1077L-40 is powered using STM32 Blue Pill 3.3V pin, I really have no clue why the overshoot spike can go up to 6.72V. As you mentioned about the wires/trace length, I am thinking if it is possible that the spikes are due to the probe connecting the DS1077L-40 and oscilloscope as the probe is more than 10cm? (I have set 10x on both the probe and oscilloscope as the bandwidth of 1x is too low so the overshoot cannot be detected.)

Regarding the calibration fail, I am using the AD5933 library from https://github.com/mjmeli/arduino-ad5933 , where there is a if-case that determines if the calibration is successful or failed.

I haven't tried to feed the output signal from DS1077L-40 directly to the EVAL-AD5933EBZ evaluation board yet. Will try and update here. Regarding if it is possible to power up DS1077L-40 using the evaluation board, I will try to short the 3 pins on LK6 (Datasheet pg39) and output the 3.3V to the DS1077L-40 via VDD-EXT on J2. Will update soon regarding this. Thank you for your suggestion.

Regarding the 50 pF max load, I believe what it means on the datasheet is the combined capacitive effect on the output pin instead of the maximum capacitance allowed to be connected externally at the output. Please see the link below for more info (although crystal oscillator is used as the example (Ctrl F: "Understanding Load Capacitance")):-

Moreover, thanks for recommending the 10-33ohm resistor. I have connected a 10ohm resistor onto the route between OUT1 and MCLK along with the shunt capacitor, which forms a low pass filter with cutoff frequency of 31.83MHz. The rising edge and falling edge of the waveform looks even better now. I am still trying out with different values of shunt capacitor. Will update some pictures here soon as well. Unfortunately, the calibration fail problem still persists. Is there any chance that my MCLK pin had been damaged so that it could not detect any external signal?

Apologies for the long reply. Would really appreciate if you could give me any suggestion for debugging please. Thanks in advance.

.

• Per your schematic both AD5933 and the  DS1077L-40 are powered from the same 3.3V source coming from the STM32, so there should be no issues with the clock and no need for any additional elements between the OUT1 and MCLK. It looks like the chps are physically close to each other, which makes your scope probe a suspect. Assuming the probe is properly compensated and the ground trace on your board between the chips is of a very low inductance, perhaps it has too long a ground wire to the alligator clip contacting the ground of your circuit. You might consider using spring-loaded ground pin instead.
Still it does not explain the software reporting failing calibration. The suspect would be the high value - 10uF - of the capacitor at Vout causing long transition, which the software in the library does not take into account. I would try making this capacitor about the same as on evaluation board, generate typical excitation frequency and see if the failure goes away.

• Hi  , I had tried to power up the DS1077L-40 using the 3.3V source on the EVAL-AD5933EBZ (via LK6) and connect it to the MLCK pin (via LK4) with and without the RC filter. My system did not respond at all when the RC filter was placed between MCLK and OUT1. Fortunately, after removing the RC filter and connect OUT1 directly to MCLK, the system works although the results are not perfect as shown below:

Hence, since the system works without filter, I believe that the overshoot spike is most likely due to the probe as you advised. However, I do not have any cable with the spring-loaded ground pin with me at the moment so I can't really dig further into this. No matter how, since the DS1077L-40 is working now, although it only works with the evaluation board currently, I will proceed to try with the AD5933 IC and my designed AFE and update again.

Regarding the 10uF capacitor, I do not think it is an issue. The reason I chose 10uF is to ensure that the cutoff frequency is lower than 1Hz (Freq_cutoff=1/(10uF||25kohm)=0.637Hz). I remember that I saw someone chose this value in some other posts in the forum as well. Besides, the calibration has no problem when I used the internal clock to sweep from 5kHz to 10kHz so I think the calibration fail is most likely due to the RC filter again. Will try and update soon.

Thank you so much for your help. I really appreciate it.

*Btw, I wonder how you are going add a 10uF capacitor on the evaluation board? I thought there is already a 47nF capacitor on the board? Sorry for my silly question.

• My system did not respond at all when the RC filter was placed between MCLK and OUT1.

Yes, to be expected, as most digital systems require sharp transitions at the front and trailing edges of the clock meander. Whenever you have spikes at the edges, more often than not there is some parasitic inductance involved in the sircuit, primary suspect would be the ground lead on the scope probe, less likely inductance of the wire carrying the clock signal, even less likely the inductance of power and ground traces (usually taken care of by the power bypassing capacitors, which you do have in your circuit). So, the MCLK signal is not likely the issue, no need to worry about amending the scope probe, etc. Perhaps using clock signal without any filteris should be fine.

Regarding the 10uF capacitor, I do not think it is an issue.

If the software did not report calibration failure when the chip was running on the internal oscillator then it is not an issue. Just for the future consideration, the low cut-off frequency comes at a price of a lengthy transition when the INITIALIZE WITH START FREQUENCY COMMAND takes the chip out of standby mode, see Figure 28. Frequency Sweep Flow Chart on p.22 of the datasheet. On the diagram it says: "AFTER A SUFFICIENT AMOUNT OF SETTLING TIME HAS ELAPSED...", but the third-party software you are using might not be waiting long enough when this capacitor is much larger than the one assumed by the software developer. With 10 uF the software should wait 5-7 sec for the circuit to reasonably settle.

Btw, I wonder how you are going add a 10uF capacitor on the evaluation board?

Could be a bit challenging if you do not have soldering/repair equipment for SMD components. The easiest thing would be to add whatever capacitor you need in parallel to C7 on the board by soldering the leads to the exposed pins using a very small soldering iron tip. Alternatively, perhaps you can find a ceramic 10uF SMD capacitor of the same footprint as C7 and glue its pads on top of the corresponding C7 pads using conductive adhesive (aka Silver Adhesive, etc.). Will require steady hands and sharp eyes or/and a decent magnifying glass.

although the results are not perfect as shown below

I think your setup is functional and what you see is the result of the chip introducing its own, the so-called "system phase" into the measurements. It is possible to account for it and other potential issues through proper calibration. Can help you with that once you have settled with the hardware.

• Looked at the library you are using - indeed calibration success or failure reported by the software has nothing to do whether the calibration was correct or not. Function "calibrate" simply calls function "frequencySweep". Here is the relevant section of the code from the AD5933.cpp:

```bool AD5933::frequencySweep(int real[], int imag[], int n) {
// Begin by issuing a sequence of commands
// If the commands aren't taking hold, add a brief delay
if (!(setPowerMode(POWER_STANDBY) &&         // place in standby
setControlMode(CTRL_INIT_START_FREQ) && // init start freq
setControlMode(CTRL_START_FREQ_SWEEP))) // begin frequency sweep
{
return false;
}```

Basically if any of these three functions return False the software reports calibration failed, although it was some low-level function such as reading or writing byte over the I2C bus that failed. If you drill down a bit from here you can see that the failure comes from functions getByte and sendByte, which query the results of Arduino's Wire functions, so, if an error occurs in some byte operation by one of the Wire functions, it is reported as calibration failure.
There is a bit cryptic comment in the code regarding the delay, but the code itself does not provide any means of letting the circuit settle after exiting standby mode, initiates outputting the excitation voltage and starts sweeping immediately. Also not every compiler can guarantee that the three function inside the "if" boolean expression are going to be called in the same sequential order they are listed in the statement. So, watch out.

• With 10 uF the software should wait 5-7 sec for the circuit to reasonably settle.

I have found one function called "bool AD5933::setSettlingCycles(int time)" in the cpp file of the library. It seems like it can be used to control the settling time cycle. I will look further into it. However, I was wondering how you came out with the 5-7 sec setting time. Is there any formula to calculate the number of settling time cycles required, e.g. the system time constant? Btw I did not change the settling time cycles for any of my test, so I believe it is working on the default now although I have no idea what the default number of settling time cycles is as I could not find it in the datasheet.

If you drill down a bit from here you can see that the failure comes from functions getByte and sendByte, which query the results of Arduino's Wire functions, so, if an error occurs in some byte operation by one of the Wire functions, it is reported as calibration failure.

No wonder I had gotten this error so frequently. Initially I thought it's the problem of the pull up resistor for my I2C bus. Really thanks a lot for pointing this out.

Btw, I have rebuilt the whole system on a breadboard. As you expected, the system works with both the internal and external oscillator (for the latter, the calibration error's gone after I removed the RC filter. Really thanks a lot for your advice). I have experimented on both 47nF and 10uF capacitor as well. The picture below is the comparison between the ideal value and result from evaluation board, breadboard with 47nF cap and breadboard with 10uF cap.

I did not change the default number of settling time cycle (Again, I am still unsure how to modify it using this library. Will check and update). However, I believe that my hardware is working now, with either both 47nF and 10uF cap. I guess that the large gap between the breadboards' results and the evaluation board's results might be due to the connection problem as I used a lot of jumper wires as shown in the picture below.

Will proceed to the rebuild the whole system on a veroboard and see if the error gap is smaller. Please let me know if you have any suggestions to reduce the error gap. Besides, could you share me some refs regarding the "proper calibration" so that I can try out myself first please (Btw I am currently using multipoint calibration)?

Thank you very much.

• I was wondering how you came out with the 5-7 sec setting time.

This was just a guess. The reason is the high-pass filter that is produced by the DC-blocking capacitor and the voltage divider resistors, you have estimated the cut-off frequency at 0.637 Hz. The thing is that in the stand-by mode the VOUT pin of the AD5933 is connected to ground and, once the command to output excitation voltage is received by the chip, VOUT goes to the Vdcoffset and the node voltage where the capacitor is connected to both the divider resistors jumps from Vdd/2 to Vdd/2 + Vdcoffset and slowly goes back down to Vdd/2. As the result, the Vpk sinewave is sitting on the DC baseline that is exponentially sloping down to Vdd/2. The chip does not have any means to check the voltage it mindlessly samples and processes, so if this settling process is not waited out the results coming out of AD5933 are substantially distorted. The time constant for this exponential voltage settling is R*C = 10uF*25k = 0.25s, so for the voltage to settle to 99% it takes 5 times this time constant or1.25s, but to make sure that there is no slope influence on the data it is a good idea to wait at least 7-10 time constants, so 2 -2.5 sec should be sufficient.

it can be used to control the settling time cycle

Number of settling cycles is a different matter - it is wait time between frequency increment and start of the data acquisition at each frequency step in the sweep. What we discussed above happens prior to initiation of the sweep. The DC level in the excitation voltage does not change between the frequency points within the sweep, so this waiting is useful mostly when dealing with resonant circuits, which take time to assume new frequency when excitation changes. The only limitation is that this Number of Settling Cycles cannot be programmed in as zero (from personal experience, this is the undocumented behaviour of the chip)

Will proceed to the rebuild the whole system on a veroboard and see if the error gap is smaller.

I think more work can be done with the breadboards as they are - everything seem to be functional. I would try keeping those two boards as close to each other as possible and have multiple jumper wires between corresponding grounds and Vdd-s to reduce parasitic inductance and would use as short wires as possible along the critical signal pass, specially the node where Rfb meets the Z and "-" input of A2.

Btw I am currently using multipoint calibration

When sweeping wide frequency ranges covering a decade or more, calibrating at every frequency pint is the way to go. Can you tell a bit more as to how you do it with your breadboard setup? Using Arduino library you mentioned? When you do it with the evaluation board - are you using the ADI demo software? It would be useful if you could post the raw Re and Im data in text or CSV format here, it should be possible by using Insert->Image, video, file.

could you share me some refs regarding the "proper calibration"

You might be very well already doing it, hard to tell without knowing your excitation, PGA gain, Rfb, Rcal  value and other parameters. The calibration in official documentation is not clear and aiming at getting absolute value of the impedance under test, which kinda defeats the purpose of the chip capable of measuring complex values. I had a few of calibration discussions in this forum, but after ADI re-designed it, having hard time finding relevant ones, here is one that might help.

• Hi  , thank you for the suggestions. I have spent the last few days replacing all the long jumper wires in my circuit with shorter wires and adding more connections for the ground. The results look better now but still not as good as the evaluation board. I will proceed to modify my code and include the "settling process" before performing frequency sweep.

By the way, I am confused with the "Default" number of settling time cycles, as I could not find it in the datasheet. Do you have any idea regarding this? Besides, may I know if the way of calculating the required number of settling time cycles is also similar to the "settling process" you mentioned above, i.e. calculate the required settling time of the unknown impedance?

When sweeping wide frequency ranges covering a decade or more, calibrating at every frequency pint is the way to go. Can you tell a bit more as to how you do it with your breadboard setup? Using Arduino library you mentioned? When you do it with the evaluation board - are you using the ADI demo software? It would be useful if you could post the raw Re and Im data in text or CSV format here, it should be possible by using Insert->Image, video, file.

In my case, I am trying to measure the impedance of a R||C circuit, where R=1000ohm and C=0.1uF, from 10Hz to 10kHz. This system will be further used for electrochemical biosensor application. I am currently setting up the whole system on breadboards, where all the ICs were soldered on the corresponding DIP adapter following the schematic I shared in the post above. I am not using the ADI demo software and my system is driven using the library I shared before https://github.com/mjmeli/arduino-ad5933 on Arduino IDE with a STM32 Blue Pill microcontroller. As I am sweeping across wide frequency, I have made a few partitions following the recommended MCLKs as shown below:

Desired Results (Derived Mathematically for1000ohm||0.1uF):

 f R I MCLK min|Z| max|Z| RFB_DESIRED RCAL_DESIRED RFB_DESIRED RCAL_DESIRED 10 999.9605 6.282937 25KHz 999.9803 999.9803 1461.763901 998.0319045 1450 950 100 996.0677 62.58478 250kHz 992.1966 998.0319 1453.217265 992.1966154 1450 950 200 984.4541 123.7102 400 940.5874 236.3954 2MHz 314.7234 969.8388 460.9585228 314.7234052 460 300 600 875.563 330.0795 800 798.3 401.2694 1000 716.9568 450.4772 1200 637.5562 480.706 1400 563.7687 495.9169 1600 497.3522 499.993 1800 438.7695 496.2367 2000 387.7266 487.2317 2200 343.5534 474.8942 2400 305.4408 460.5939 2600 272.5731 445.283 2800 244.1938 429.6082 3000 219.6326 413.9977 3200 198.3108 398.7275 3400 179.7363 383.9677 3600 163.4948 369.8165 3800 149.2385 356.3234 4000 136.6765 343.5055 4200 125.5652 331.3586 4400 115.7003 319.8652 4600 106.9103 308.9992 4800 99.05082 298.7302 5000 91.99967 289.0255 16MHz 157.1767 303.3145 230.2083356 157.1767257 230 150 5200 85.65337 279.8515 5400 79.92387 271.1753 5600 74.736 262.9649 5800 70.02536 255.1898 6000 65.73658 247.8211 6200 61.82188 240.8318 6400 58.2399 234.1965 6600 54.95472 227.8919 6800 51.93505 221.8959 7000 49.15352 216.1885 7200 46.58614 210.7507 7400 44.21183 205.5654 7600 42.01198 200.6165 7800 39.97015 195.8891 8000 38.07176 191.3695 8200 36.30385 187.0451 8400 34.65487 182.9041 8600 33.11452 178.9356 8800 31.67355 175.1295 9000 30.32369 171.4764 9200 29.05749 167.9677 9400 27.86825 164.5953 9600 26.74991 161.3516 9800 25.69698 158.2297 10000 24.70452 155.2231

Collected Results:

 Setup Evaluation Board Breadboard with 47nF C_Filter Breadboard with 0.1uF C_Filter f R I R I R I 10 100 200 400 134.16 2.2 223.7 4.76 220.76 86.76 600 933.12 530.76 1009.65 550.84 1039.54 213.06 800 872.92 392.41 970.18 410.91 975.55 290.33 1000 756.63 442.62 867.66 476.63 881.23 430.64 1200 680.98 478.84 776.46 520.44 802.37 488.59 1400 602.19 495.47 682.24 548.4 700.59 517.08 1600 517.68 494.57 594.55 559.91 609.44 543.07 1800 451.97 492.54 521.17 556.25 531.09 543.06 2000 398.4 485.91 457.34 547.21 460.43 540.25 2200 347.62 472.97 396.83 528.27 398.32 524.07 2400 303.37 452.8 346.54 512.43 353.43 511.85 2600 267.57 433.04 305.96 494.71 310.33 493.16 2800 233.93 411.43 271.51 474.01 274.06 475.26 3000 208.28 393.55 242.12 454.29 241.39 454.08 3200 187.37 376.35 217.73 436.17 217.52 434.86 3400 168.69 359.44 195.01 418.02 196.3 416.88 3600 152.42 342.79 178.45 397.25 176.93 400.81 3800 137.79 328.4 162.43 388.38 157.71 385.15 4000 126.4 314.29 146.6 372.07 146 368.61 4200 115.75 301.26 133.79 357.58 132.01 355.73 4400 104.95 285.76 119.74 350.33 122.44 344.94 4600 101.15 273.31 117.46 339.39 111.97 330.09 4800 94.08 263.58 107.79 326.59 104.97 320.4 5000 88.05 254.5 99.15 313.91 98.57 309.71 5200 91.94 287.47 98.01 288.75 91.66 286.25 5400 87.57 278.13 88.54 280.72 88.9 280.44 5600 83.18 270.76 83.15 273.95 83.85 273.83 5800 77.53 264.3 78.73 267.35 77.61 265.53 6000 71.71 256.52 74.27 257.64 72.82 258.76 6200 67.42 248.08 87.56 292.77 68.41 250.44 6400 64.44 240.93 88.2 297.9 66.07 242.88 6600 61.81 235.05 63.36 237.65 62.8 237.09 6800 58.19 229.64 59.47 232.18 59.29 231.62 7000 54.58 223.84 55.24 226.03 54.93 225.91 7200 51.61 217.75 52.4 220.44 52.79 219.33 7400 49.45 211.98 83.22 294.44 50.63 213.89 7600 47.37 207.03 48.31 209.1 48.34 208.89 7800 45.19 202.34 77.17 278.63 46.22 204.03 8000 43.08 197.72 76.47 277.43 44 199.48 8200 41.17 193.02 41.89 194.99 42.44 194.5 8400 39.55 188.64 40.44 190.58 40.96 190.28 8600 38.15 184.64 73.5 268.49 39.32 186.1 8800 36.6 181.06 73.79 269.77 37.94 182.13 9000 34.9 177.07 72.62 267.3 35.57 178.38 9200 33.7 173.37 72.39 265.41 34.87 174.93 9400 32.45 169.82 71.93 263.06 33.73 171.41 9600 31.37 166.54 68.95 253.77 32.47 167.97 9800 30.28 163.38 68.91 252.77 31.43 165.19 10000 29.15 160.37 67.19 247.38 31.2 162.22

You might be very well already doing it, hard to tell without knowing your excitation, PGA gain, Rfb, Rcal  value and other parameters. The calibration in official documentation is not clear and aiming at getting absolute value of the impedance under test, which kinda defeats the purpose of the chip capable of measuring complex values. I had a few of calibration discussions in this forum, but after ADI re-designed it, having hard time finding relevant ones, here is one that might help.

I am using the Range 1 where DC=1.48V and AC=1.98Vpp. As AFE is used in my setup, the DC is rebiased to Vdd/2. My PGA is x1 for all case. The Rfb is calculated based on the formula provided in the tech note as well as our previous discussion in How to correctly calculate the Rfb value in AD5933 . Rcal is simply the Zmin for each partition as you mentioned in other posts that the formula Rcal = 1/3 * (Zmin + Zmax) is not practical. I am not sure about the number of settling cycles used as I still don't understand this part very well. I did not modify it at all so everything about the number of settling cycle remains default. I am only able to sweep down to 400Hz at the moment. Will try to go for lower frequency and update you soon. I will also try to implement the calibration procedures you shared in the link above. Hopefully it can help reduce the error gap between the spectrums collected using my system and the ideal values. Really thank you so much for your help.

• the formula Rcal = 1/3 * (Zmin + Zmax) is not practical

If you are not using demo software, are you controlling the Demo board from your Arduino Blue Pill?

I am confused with the "Default" number of settling time cycles

There is no default number of settling cycles, the demo software defaults it to be 15, but there is no particular reason for that. This is simply the number of excitation voltage sine wave periods the chip outputs after switching to the next frequency in the course of sweep before it starts sampling the Vadc. As long as it is not zero, it should not matter much for your experiments with non-resonant circuits, which most biosensors are. Setting Number of Settling Cycles at 1 should be OK for your measurements and would keep your sweep time short.
If your Z is a resonant circuit, shifting from one frequency to the next causes beating in the current passing through between the resonant frequency ωand the excitation frequency. This beating takes time to pass for the current sine wave at the new excitation frequency no longer be distorted. If the quality factor of Z is Q, the settling time constant can be estimated as τ =2 Q / ω0 and, similarly to the settling we discussed, it is good idea to wait 7-10 times this time constant to make sure the beatings do not affect the measurements.

my system is driven using the library I shared before https://github.com/mjmeli/arduino-ad5933

The AD5933.cpp contains the method "bool AD5933::setSettlingCycles(int time)", but it is not called from the ad5933-test.ino, so this Number of Settling Cycles is not initialised. Datasheet does not specify what value the registers assume upon the chip power-up. When using this library it would make sense to stick with the diagram on Fig. 28, p. 22 of the datasheet, which does require for the Number of Settling Cycles to be initialized.

Collected Results

Big swings in the data at 3-4 points at the lower frequency end are likely from the systematic error from the built-in "DFT" - will require even lower MCLK to eliminate. At the higher frequencies, something is happening at 5KHz, is this the frequency where you are switching from 16MHz to 2MHz MCLK? Not yet clear what it is, but it causes a noticeable step in the data from evaluation board as well as from the setup with two different capacitor values, as if the control binary words for the frequency with the new MCLK are not calculated quite correctly. Could be a number of other issues - we will need to look at it further.
It sounds like you use different Rfb and Rcal for each frequency range (partition), how do you switch Rfb as you sweep across entire frequency range over several partitions? Just to see if the switching between the ranges causes discontinuities in the data, could you connect the Rfb and Rcal you are using above 5KHz (230 and 150 Ohm), perform the entire sweep same way as you did collecting this data and post raw Re and Im values you are getting from the registers? And then the same raw Re and Im values with your R||C network?

the formula Rcal = 1/3 * (Zmin + Zmax) is not practical

Not only it is not practical, it can lead to wrong calibration. For example, if someone is trying to measure an impedance, which does not change much, so that Zmax ≈ Zmin, this formula would suggest to use Rcal = 2/3 * Zmin, which would guarantee the Vadc clipping, faulty calibration and the user endlessly puzzling over incorrect measurement results.