AD7747 capacitive to digital converters (i2c)

Hi guys,

Just wondering if any of you have tried using these Analogue devices CDC chips.

The datasheet is here:

http://www.analog.com/static/imported-files/data_sheets/AD7747.pdf

Basically it uses a sgima-delta modulator to measure single ended capacitance, quite sueful for proximity detection.

Anyway, it uses a i2c interface, you have to write to several registers first to set the device up for operation, followed by a sequential read of the 3 1 byte registers that store the converted digital data (adresses 0x01, 0x02 and 0x03). There is a pin on the chip, an active low output called RDY, when this goes low the conversion is complete and the master is free to read the device - another way of checking the status of the conversion may also be observed by reading the status register at adress 0x00

I thought using the arduino for this would be a neat and quick method. My code is below:

n.b. the datasheet gives the device adress as 0x90 for read and 0x91 for write, from what I understand from the arduino, I drop the last bit and shift to the left, giving an adress of 0x48.....

#include <Wire.h>
#define SLAVEWRT 0x48 // adress of device during write cycle
#define SLAVERD  0x48 // adress of device during read cycle

int flagpin = 2; //sets up an analogue pin


void setup()
{
  pinMode(flagpin, INPUT); // sets up analogue pin as input
  Wire.begin(); // sets up i2c for operation
  Serial.begin(115200); // set up baud rate for serial USB
  Wire.beginTransmission(SLAVEWRT); // begins write cycle 
  Wire.send(0x07); // sets memory pointer to CAP setup register
  Wire.send(0xA0); // sends data to cap setup enabling correct function of chip
  Wire.endTransmission(); // ends i2c cycle
  delay(4);
  Wire.beginTransmission(SLAVEWRT); // begin write cycle
  Wire.send(0x09); // sends memory pointer to excitation set up register
  Wire.send(0x06); // sends data to exc setup register
  Wire.endTransmission(); // ends cycle
}

void loop() // main program begins
{
  int ready = digitalRead(flagpin);// sets up integer 'ready' as data from pin 2
  
      while (ready ==HIGH)// until pin 2 transitions high to low, do nothing
      {
      };
      Wire.beginTransmission(SLAVERD); // begin read cycle
      Wire.send(0x01); // send memory pointer to first cap data register
      Wire.endTransmission(); // end cycle
      Wire.requestFrom(SLAVERD,3); // reads 3 bytes starting from 0x01
      while(Wire.available())
     {
      char c = Wire.receive();
      Serial.print(c, DEC); // reads the 3 bytes onto serial monitor in decimal form
      Serial.print(",");
     }
      Serial.println();
}

Now from what I can see, on my chip the data conversion never completes, i.e. there is no transtion form high to low on the RDY pin of the AD 7747 chip. Thus I never read anything on the serial monitor.

In terms of my own trouble shooting, I decided to modify the code, removing the while loop for the ready function and simply reading the first memory adress 0x00, to check on the conversion:

#include <Wire.h>
#define SLAVEWRT 0x48
#define SLAVERD  0x48

int flagpin = 2;


void setup()
{
  pinMode(flagpin, INPUT);
  Wire.begin();
  Serial.begin(115200);
  Wire.beginTransmission(SLAVEWRT);
  Wire.send(0x07);
  Wire.send(0xA0);
  Wire.endTransmission();
  delay(4);
  Wire.beginTransmission(SLAVEWRT);
  Wire.send(0x09);
  Wire.send(0x06);
  Wire.endTransmission();



  
     
      Wire.beginTransmission(SLAVERD);
      Wire.send(0x00);
      Wire.endTransmission(); 
      Wire.requestFrom(SLAVERD,4);
      while(Wire.available())
     {
      char c = Wire.receive();
      Serial.print(c, HEX);
      Serial.print(",");
     }
      Serial.println();
}

void loop()
{
}

When I did this the serial monitor showed up 4 values: 7,0,0,0. The first memory adress 0x00 (the status register) therefore shows that no conversion is ready and the next three adresses (i.e. the capacitive data registers) are all zero (as would be expected). Having said that, it would seem to prove to me that the master is reading the slave.

Anyone who read the other topic I started about interfacing the arduino to some i2c EEPROM will see that my overall aims are heavily involved with conquering the two wire bus, as such, with this device I would greatly appreciate any help in debugging my software in order to narrow down where the fault lies, i.e. is it my crap programming skills or is there something amiss with the chip itself...

To answer my own dumbass question.... there was a default value in one of the configuration registers, set as 0xA0 which should ahve been 0xA1 - the difference between sitting in idle and doing continuous conversion.

Kids: read your datasheets ;D

There is great confusion about the Wire library and address treatment. In this case you have the correcy 0x48 address, but the reasoning is off.

n.b. the datasheet gives the device adress as 0x90 for read and 0x91 for write,

Actually... the opposite
0x90 for Write
0x91 for Read

from what I understand from the arduino, I drop the last bit and shift to the left, giving an adress of 0x48.....

Actually just shift right one bit, and the LSB is dropped.
0x48 is in fact the correct result. B1001000

When twi gets 0x48 it shifts it to the left one bit:
B10010000 and adds the Read/Write LSB bit yielding B10010001 == 0x91 for a Read

twi code...

// build sla+w, slave device address + w bit
  twi_slarw = TW_READ;
      twi_slarw |= address << 1;

Your code should work (address wise).

Hope that helps.