using AD5933 to measure impedances
Dependencies: 4DGL-uLCD-SE mbed
AD5933.cpp
- Committer:
- mvaca3
- Date:
- 2016-12-13
- Revision:
- 71:91f99e81cd1c
- Parent:
- 69:cfee0a25ef44
File content as of revision 71:91f99e81cd1c:
#include <mbed.h> #include "AD5933.h" //#include <math.h> AD5933::AD5933(I2C*i2c, Serial *pc, Serial *bt) { //pass to private variables _i2c = i2c; _pc = pc; _bt = bt; } void AD5933::calibrate(double ref) { //store reference resistance _ref = ref; //perform frequency sweep sweep(); //for each step, calculate gain factor and phase for(int i=0; i <= 9; i+=1) { _gain[i] = (float)(1.0/ref)/sqrt((pow((double)_real[i],2)+pow((double)_imag[i],2)))*pow(10.0,11); _phase[i] = (float)atan((double)(_imag[i]/_real[i])); } for(int i = 0; i <=9; i++) { //_pc->printf("_gain[%i]: %f, _phase[%i]: %f\n\r", i, _gain[i], i, _phase[i]); } //take temperature _temp[0] = getTemp(); } void AD5933::configure() { _pga = 0x1; _range = 0x0; char buff[3]; char b[10]; _bt->putc('.'); //set lower control byte to all 0 for internal clock buff[0] = 0x00; //_pc->printf("buff is %x\n\r", buff[0]); _i2c->write(CTRL_LOW, buff, 1); _i2c->read(CTRL_LOW, buff, 1); //_pc->printf("buff is %x\n\r", buff[0]); //_pc->printf("_freq: %i\n\r", _freq); //_pc->printf("%f\n\r", (_freq/(16776000/4.0)) * pow(2.0,27)); float fModified = (_freq / (16776000/4.0)) * pow(2.0,27); sprintf(b, "%.0f", fModified); int fFinal = atoi(b); float iModified = (_inc / (16776000/4.0)) * pow(2.0,27); sprintf(b, "%.0f", iModified); int iFinal = atoi(b); //_pc->printf("fFinal: %i\n\riModified: %i\n\r", fFinal, iFinal); _bt->putc('.'); //_pc->printf("Entering start frequency into registers.\n\r"); buff[2] = fFinal & 0x0000FF; buff[1] = (fFinal & 0x00FF00) >> 8; buff[0] = (fFinal & 0xFF0000) >> 16; //_pc->printf("buff is %x%x%x\n\r", buff[0], buff[1], buff[2]); //set frequency sweep parameters _i2c->write(FREQ_HIGH, buff, 3); //start frequency _i2c->read(FREQ_HIGH, buff, 3); //start frequency //_pc->printf("buff is %x%x%x\n\r", buff[0], buff[1], buff[2]); //_pc->printf("Entering frequency increment into registers.\n\r"); buff[2] = iFinal & 0xFF; buff[1] = (iFinal & 0xFF00) >> 8; buff[0] = (iFinal & 0xFF0000) >> 16; //_pc->printf("buff is %x%x%x\n\r", buff[0], buff[1], buff[2]); _i2c->write(FINC_HIGH, buff, 3); //frequency increments _i2c->read(FINC_HIGH, buff, 3); //frequency increments //_pc->printf("buff is %x%x%x\n\r", buff[0], buff[1], buff[2]); _bt->putc('.'); //_pc->printf("Entering number of increments into registers.\n\r"); buff[1] = _n & 0xFF; buff[0] = (_n & 0xFF00) >> 8; //_pc->printf("buff is %x%x\n\r", buff[0], buff[1]); _i2c->write(NINC_HIGH, buff, 2); //number of increments _i2c->read(NINC_HIGH, buff, 2); //number of increments //_pc->printf("buff is %x%x\n\r", buff[0], buff[1]); //_pc->printf("Entering settling cycles into registers.\n\r"); buff[1] = 0xF4; buff[0] = 0x03; //_pc->printf("buff is %x%x\n\r", buff[0], buff[1]); _i2c->write(SET_CYCLE, buff, 2); //number of settling cycles is 1000 _i2c->read(SET_CYCLE, buff, 2); //number of settling cycles is 1000 //_pc->printf("buff is %x%x\n\r", buff[0], buff[1]); // _pc->printf("Standing by.\n\r"); _bt->putc('.'); //set to standby via reset command buff[0] = (0xB << 4) | (_range << 1) | _pga; //_pc->printf("buff is %x\n\r", buff[0]); _i2c->write(CTRL_HIGH, buff, 1); _i2c->read(CTRL_HIGH, buff, 1); //_pc->printf("buff is %x\n\r", buff[0]); _bt->putc('.'); _pc->printf("Initialize with start frequency command.\n\r"); //start frequency command buff[0] = (0x1 << 4) | (_range << 1) | _pga; //_pc->printf("buff is %x\n\r", buff[0]); _i2c->write(CTRL_HIGH, buff, 1); _i2c->read(CTRL_HIGH, buff, 1); //_pc->printf("buff is %x\n\r", buff[0]); //_pc->printf("Beginning frequency sweep.\n\r"); for(int i = 0; i < 999; i++) { if (fmod((double)i,200.0) ==0) _bt->putc('.'); } //after sufficient time, sweep command buff[0] = (0x2 << 4) | (_range << 1) | _pga; //_pc->printf("buff is %x\n\r", buff[0]); _i2c->write(CTRL_HIGH, buff, 1); _i2c->read(CTRL_HIGH, buff, 1); //_pc->printf("buff is %x\n\r", buff[0]); //repeat initial frequency to remove error buff[0] = (0x4 << 4) | (_range << 1) | _pga; //_pc->printf("buff is %x\n\r", buff[0]); _i2c->write(CTRL_HIGH, buff, 1); _i2c->read(CTRL_HIGH, buff, 1); //_pc->printf("buff is %x\n\r", buff[0]); } void AD5933::sweep() { _bt->putc('.'); _pc->printf("Entering sweep\n\r"); _freq = 100000; _inc = 100000; _n = 9; int i = 0; char buff; configure(); read(i); _i2c->read(STATUS, &buff, 1); while(i < 9) { _bt->putc('.'); i++; buff = (0x3 << 4) | (_range << 1) | _pga; _i2c->write(CTRL_HIGH, &buff, 1); read(i); _i2c->read(STATUS, &buff, 1); } } void AD5933::sweep1() { _n = 0; int i = -2; _bt->putc('.'); configure(); _bt->putc('.'); read(i); _bt->putc('.'); i++; char buff = (0x3 << 4) | (_range << 1) | _pga; _i2c->write(CTRL_HIGH, &buff, 1); read(i); } void AD5933::read(int i) { _bt->putc('.'); char buff; //repeat initial frequency to remove error buff = (0x4 << 4) | (_range << 1) | _pga; //_pc->printf("buff is %x\n\r", &buff); _i2c->write(CTRL_HIGH, &buff, 1); _i2c->read(CTRL_HIGH, &buff, 1); //_pc->printf("buff is %x\n\r", &buff); //update impedance _i2c->read(STATUS, &buff, 1); //while(!(buff & 0x2)&&!(i==0)) { _i2c->read(STATUS, &buff, 1); } char temp[2]; _bt->putc('.'); if(i > -1){ _i2c->read((int) REAL_HIGH, temp, 2); _real[i] = (int)temp[0] << 8 + (int)temp[1]; _i2c->read((int) IMAG_HIGH, temp, 2); _imag[i] = (int)temp[0] << 8 + (int)temp[1]; } else if(i > -2) { _i2c->read((int) REAL_HIGH, &temp[0], 2); _r = (int)temp[0] << 8 + temp[1]; _i2c->read((int) IMAG_HIGH, &temp[0], 2); _i = (int)temp[0] << 8 + temp[1]; } } float AD5933::getTemp() { double result = 0; char buff[2]; //measure temperature for correction buff[0] = (0x9 << 4) | (_range << 1) | _pga; _i2c->write(CTRL_HIGH, &buff[0], 1); _i2c->read(STATUS, &buff[0], 1); _bt->putc('.'); //while(!(buff[0] & 0x1)) //{ _i2c->read(STATUS, &buff[0], 1); //} if (!_i2c->read((int) TEMP_HIGH, &buff[0], 2)) { result += (buff[1] & 0x1); result += (buff[1] & 0x2)*2; result += (buff[1] & 0x4)*4; result += (buff[1] & 0x8)*8; result += (buff[1] & 0x16)*16; result += (buff[1] & 0x32)*32; result += (buff[1] & 0x64)*64; result += (buff[1] & 0x128)*128; _bt->putc('.'); result += (buff[0] & 0x1)*256; result += (buff[0] & 0x2)*512; result += (buff[0] & 0x4)*1024; result += (buff[0] & 0x8)*2048; result += (buff[0] & 0x16)*4096; result += (buff[0] & 0x32)* -8192; } return result/32; } void AD5933::findZ(int f) { _bt->putc('.'); //set frequency for sweep _freq = f*100000; //sweep sweep1(); //_pc->printf("Got values for _r: %i, _i: %i\n\r", _r, _i); //get temperature _temp[1] = getTemp(); //perform gain/phase correction //_pc->printf("_gain[%i]: %f, _gain[%i] corrected: %le", f-1, _gain[f-1], f-1, _gain[f-1] * pow(10.0,-11)); _z = (1.0/((_gain[f-1] * pow(10.0,-11))*sqrt((double)(pow((double)_r, 2)+pow((double)_i,2 ))))); _phs = (float)atan((double)(_i/_r)); _phs = _phs - _phase[f-1]; //perform temperature correction _z = _z + (_temp[1]-_temp[0])*0.00003*_z; _bt->putc('.'); } float AD5933::getZ() { return _z; } float AD5933::getPhase() { return _phs; }