AnsweredAssumed Answered

AD5933 wrong values

Question asked by pegie on Dec 15, 2015
Latest reply on Aug 2, 2016 by Snorlax

Hi there!

For a few days I've been trying to cope with my AD5933 problem. For now I'm trying to measure resistance in a range of 40-90 kohm, with frequency values ranging 2k-75k . I use a decade resistor for tests. My Rcal is 47k, I chose one point calibration for every frequency increment. I don't need exact values, but what I get can't be considered as satisfying in any way.

 

So, I wrote a code for each frequency value to get the real and imaginary part of my Z which goes like this [I post just the main functions not to mess everything - for example the I2C functions, UART etc]:

 

 

int16_t pom_raw[8][2];

long int Z10k[8];

long int Z[8];

long int Z_wlasc[8];

long int gain_factor[8];

char buffer [55];

char buffer2 [55];

 

unsigned long int freq [8]  = {2000, 3000, 5000, 10000, 20000, 30000, 50000, 75000};

 

 

 

 

uint16_t AD5933_get_data(uint8_t from)

{                  

  uint8_t ret,ret1;

  ret1 =0;

 

  ret = i2c_start(AD5933ADR+I2C_WRITE);

  if (ret){

        i2c_stop();

  }else{

        i2c_write(0xb0); // address pointer                     

        i2c_write(from); // konkretny adres     

        i2c_stop();                   

    }

 

 

    ret = i2c_start( AD5933ADR+I2C_WRITE);     

    if (ret){

        i2c_stop();

    }else{

 

 

        i2c_write(0xa1); // block read                   

        i2c_write(0x02); // num_bytes                  

        i2c_rep_start(AD5933ADR + I2C_READ);

        ret = i2c_readAck();

        ret1 = i2c_readNak();

        i2c_stop();

    }

    return( (ret*256) + ret1);

}

 

void AD5933_single_raw(int16_t f) //,int16_t *re, int16_t *im)

{

    uint8_t status;

    int16_t real, imag;

    AD5933_reset();

    AD5933_startfreq(freq[f]);

    AD5933_freq_inc(1);

    AD5933_no_inc(255);

    AD5933_no_settlcyc(255);

 

    AD5933_reset();

 

    AD5933_single_write(0x80,0x10); //inicjalizacja, vpp =2, pga gain x5

    AD5933_single_write(0x80,0x20); //start, vpp =2, pga gain x5

 

    do

    {

        status = AD5933_get_status();

    }

    while((status & 0x02) == 0x00);

 

    real = AD5933_get_data(0x94);

    imag = AD5933_get_data(0x96);

 

    pom_raw[f][0] = real;

    pom_raw[f][1] = imag;

}

 

void calibration(void)

{

  for (unsigned int i=0; i<8; i++)

  {

  _delay_ms(500);

  AD5933_single_raw(i);

  signed int R = pom_raw[i][0];

  signed int I = pom_raw[i][1];

 

  if (R !=0)

  {

       Z10k[i]=hypot((double) R, (double) I);

       faza10k[i]=pow(tan((double)I/(double)R),-1);

       gain_factor[i] = ((Z10k[i])*(47000));

       sprintf(buffer2,"%ld\n",Z10k[i]);

       send_string("\n\r");

       _delay_ms(10);

       send_string(buffer2);

       PORTD &= ~(1<<LED2);

   }

  else

  {

       gain_factor[i]=0;

       sprintf(buffer2,"%ld\n",Z10k[i]);

       _delay_ms(10);

       send_string(buffer2);

       send_string("\n\r");

  }

  }

}

 

void meas(void)

{

  for (int i=0; i<8; i++)

  {

 

       AD5933_single_raw(i);

 

       signed int Rw = pom_raw[i][0];

       signed int Iw = pom_raw[i][1];

       if (Rw !=0)

       {

            Z[i]=hypot((double)Rw,(double)Iw);

            faza[i]=pow(tan(((double)Iw)/((double)Rw)),-1);

            if (Z[i] != 0)

            {

                 Z_wlasc[i]=(gain_factor[i]/(Z[i]));

            }

            else

            {

                 Z_wlasc[i]=0;

            }

       }
     }

}

 

Values of my frequency [they are stored in a table] are correct, because I checked it on the osciloscope.

I'm using ATmega8A (internal 8MHz RC) to control everything via SCL and SDA, internal clock for AD5933, 2Vpp, 5x PGA gain, supplying with 5V via UART-USB ft232rl integrated circuit...


My problem is that I get the right value just for a resistance equal to calibration. When I take 60k resistor - I get around 47,5k; for 40k I have 46,7k. Everything oscilates around 47k. I checked the content of R and I registers, and it turned out that without using gain factor, my raw |Z| is always somewhere around 20k, no matter if higher or lower resistance is taken. I'd like to know if I do anything wrong with calibration process or gaining the gain factor/magnitude. Maybe my variables are defined incorrectly? I will happily post other parts of my code if needed. I just didn't want to spam the forum with everything. Sorry if brackets are wrong - I tried to clearify whole program and could make a mistake. I'd love to know if my code could cause wrong measurements, or is it my hardware. So first I ask you for the code.

 

Regards

Outcomes