Issues Configuring AD7746 with Arduino - Registers Not Updating

Hello Arduino Community,

I'm working with the AD7746 capacitance-to-digital converter using an Arduino. Despite following the setup, the register values are not updating correctly.

Details:

  1. Connections:
  • I2C address: 0x48
  • Confirmed connection with I2C scanner.
  1. Setup:
  • Using AD7746.cpp and AD7746.h files from an I2Cdev library.
  • Sketch writes to configuration registers but reads back incorrect values (0x07).

Observations:

  • I2C communication confirmed: Scanner detects device at 0x48.
  • Writing Registers: Commands sent to write configuration registers (0x07, 0x09, 0x0A, 0x0B).
  • Reading Registers: Values read back are always 0x07.

Sample Code:

#include <Wire.h>
#include "AD7746.h"

AD7746 capSensor;

void setup() {
    Serial.begin(115200);
    while (!Serial);
    Wire.begin();
    capSensor.initialize();

    if (capSensor.testConnection()) {
        Serial.println("AD7746 connection successful.");
    } else {
        Serial.println("AD7746 connection failed.");
        while (1);
    }

    capSensor.writeCapSetupRegister(0x81);  // Example configuration
    capSensor.writeExcSetupRegister(0x0B);  // Example excitation setup
    capSensor.writeConfigurationRegister(0x31);
    capSensor.writeCapDacARegister(0x80);  // Example DAC setup

    readRegister(AD7746_RA_CAP_SETUP);
    readRegister(AD7746_RA_EXC_SETUP);
    readRegister(AD7746_RA_CONFIGURATION);
    readRegister(AD7746_RA_CAP_DAC_A);
}

void loop() {
    uint8_t status = capSensor.getStatus();
    if (status & 0x01) { // Capacitance data ready
        uint32_t capacitance = capSensor.getCapacitance();
        Serial.print("Capacitance: ");
        Serial.println(capacitance);
    }
    if (status & 0x02) { // Voltage/Temperature data ready
        uint32_t vtData = capSensor.getVTData();
        Serial.print("VT Data: ");
        Serial.println(vtData);
    }
    delay(1000);
}

void readRegister(uint8_t reg) {
    uint8_t value;
    I2Cdev::readByte(AD7746_ADDRESS, reg, &value);
    Serial.print("Read 0x");
    Serial.print(value, HEX);
    Serial.print(" from register 0x");
    Serial.println(reg, HEX);
}

Questions:

  1. Initialization Sequence: Are there specific steps for initializing the AD7746 that I might be missing?
  2. Timing Issues: Could this be related to delays or timing in the I2C communication?
  3. Power Supply: Any known issues with power requirements for the AD7746 that could cause such behavior?

Any insights or suggestions would be greatly appreciated!

Thank you!

Have you put 4k7 pull up resistors on each I2C line?

Hello @Grumpy_Mike
yes, I have tried it with both 10k and 4.7k resistors. I am using this board which uses Ad7746, based on the documentation regular configuration for Ad7746 should also work for this one. But I don't know where I am going wrong that nothing happens. ( I get a constant value as output and thats it.)

Can you show the console output.

It is interesting that you are getting back 0x07 each time which is the address used in the first command capSensor.writeCapSetupRegister()

You could try commenting this out capSensor.writeCapSetupRegister(0x81); and see if you then get back 0x09 instead.

Probably the next step is to abandon that library ( #include "AD7746.h") you are using and use Wire (I2C) command directly.

Thanks for that. I see you need

Two 2pF ceramic capacitors

Did you use those? I must say there are rather small, and the leads must be as short as possible.

It would be good to see the exact circuit you used. Is it soldered up or is it on solderless bread board? Because solderless bread board is going to give you a lot more than 2pF stray capacitance. Have you got a schematic of what you actually wired up? And also a photograph would help.

And yes the console output would be good to see.

Hello @6v6gt

I omitted the command capSensor.writeCapSetupRegister() and nothing happened; the register values remained 0x07. I then switched to using Wire.h directly for configuration. Here is the code:

#include <Wire.h>

#define AD7745_ADDRESS 0x48 // Default I2C address for AD7745/AD7746

// AD7745/AD7746 Register addresses
#define STATUS_REG 0x00
#define CAP_DATA_HIGH 0x01
#define CAP_DATA_MIDDLE 0x02
#define CAP_DATA_LOW 0x03
#define CAP_SETUP_REG 0x07
#define VT_SETUP_REG 0x08
#define EXC_SETUP_REG 0x09
#define CONFIG_REG 0x0A

void setup() {
  Serial.begin(115200);
  while (!Serial) { }

  Wire.begin();

  // Initialize the AD7745/AD7746
  initializeAD7745();

  // Check if AD7745/AD7746 is connected
  Wire.beginTransmission(AD7745_ADDRESS);
  if (Wire.endTransmission() == 0) {
    Serial.println("AD7745/AD7746 connected.");
  } else {
    Serial.println("AD7745/AD7746 not connected!");
    while (1);
  }
  
  // Print initial register values
  printRegisterValues();
}

void loop() {
  // Read capacitance data
  long capacitance = readCapacitance();

  // Print capacitance value
  Serial.print("Capacitance: ");
  Serial.print(capacitance);
  Serial.println(" aF");

  delay(1000);
}

void initializeAD7745() {
  // Reset the device to ensure it starts from a known state
  Wire.beginTransmission(AD7745_ADDRESS);
  Wire.write(0xBF); // Reset command
  Wire.endTransmission();
  delay(200); // Wait for the reset to complete

  // Enable capacitive input, continuous conversion mode
  Wire.beginTransmission(AD7745_ADDRESS);
  Wire.write(CAP_SETUP_REG); // Point to Cap Setup Register
  Wire.write(0x30); // Enable capacitive input
  Wire.endTransmission();

  // Set default configuration
  Wire.beginTransmission(AD7745_ADDRESS);
  Wire.write(CONFIG_REG); // Point to Configuration Register
  Wire.write(0x10); // Set to default configuration
  Wire.endTransmission();

  // Setup excitation source
  Wire.beginTransmission(AD7745_ADDRESS);
  Wire.write(EXC_SETUP_REG); // Point to Excitation Setup Register
  Wire.write(0x04); // Set excitation voltage
  Wire.endTransmission();
}

long readCapacitance() {
  Wire.beginTransmission(AD7745_ADDRESS);
  Wire.write(CAP_DATA_HIGH); // Point to the high byte of capacitance data
  Wire.endTransmission();

  Wire.requestFrom(AD7745_ADDRESS, 3); // Request 3 bytes of data
  while (Wire.available() < 3);

  byte capHigh = Wire.read();
  byte capMiddle = Wire.read();
  byte capLow = Wire.read();

  // Combine the three bytes to form the capacitance value
  long capacitance = ((long)capHigh << 16) | ((long)capMiddle << 8) | capLow;

  return capacitance;
}

void printRegisterValues() {
  // Read and print Cap Setup Register
  Wire.beginTransmission(AD7745_ADDRESS);
  Wire.write(CAP_SETUP_REG);
  Wire.endTransmission();
  Wire.requestFrom(AD7745_ADDRESS, 1);
  while (Wire.available()) {
    byte regValue = Wire.read();
    Serial.print("Cap Setup Register: 0x");
    Serial.println(regValue, HEX);
  }

  // Read and print Configuration Register
  Wire.beginTransmission(AD7745_ADDRESS);
  Wire.write(CONFIG_REG);
  Wire.endTransmission();
  Wire.requestFrom(AD7745_ADDRESS, 1);
  while (Wire.available()) {
    byte regValue = Wire.read();
    Serial.print("Configuration Register: 0x");
    Serial.println(regValue, HEX);
  }

  // Read and print Excitation Setup Register
  Wire.beginTransmission(AD7745_ADDRESS);
  Wire.write(EXC_SETUP_REG);
  Wire.endTransmission();
  Wire.requestFrom(AD7745_ADDRESS, 1);
  while (Wire.available()) {
    byte regValue = Wire.read();
    Serial.print("Excitation Setup Register: 0x");
    Serial.println(regValue, HEX);
  }

  // Read and print Status Register
  Wire.beginTransmission(AD7745_ADDRESS);
  Wire.write(STATUS_REG);
  Wire.endTransmission();
  Wire.requestFrom(AD7745_ADDRESS, 1);
  while (Wire.available()) {
    byte regValue = Wire.read();
    Serial.print("Status Register: 0x");
    Serial.println(regValue, HEX);
  }
}

Despite these changes, I still receive 0x07 for all register values.

Serial Monitor output:

11:46:58.176 -> AD7745/AD7746 connected.
11:46:58.176 -> Cap Setup Register: 0x7
11:46:58.176 -> Configuration Register: 0x7
11:46:58.176 -> Excitation Setup Register: 0x7
11:46:58.176 -> Status Register: 0x7
11:46:58.176 -> Capacitance: 458752 aF
11:46:59.175 -> Capacitance: 458752 aF
11:47:00.145 -> Capacitance: 458752 aF
11:47:01.146 -> Capacitance: 458752 aF
11:47:02.192 -> Capacitance: 458752 aF
11:47:03.190 -> Capacitance: 458752 aF

I am not using 2pF ceramic capacitor. At the moment I am just trying to drive this sensor and test it with standard capacitors. So the setup is very simple and you can see it in the attached photo:
note : I tried 10k, 4.7k resistors as pull-up resistors. Also I tried direct connection of I2C from the board to the Arduino.

I am testing different capacitors that won't effect the output in general!

This program should return A0 HEX
If not, then you have a hardware problem.
If yes then your software is wrong

Power cycle the AD7746 first

// FOR TEST

/*
   Error codes for Wire.endTransmission
    0: success
    1: data too long to fit in transmit buffer (32 byte max)
    2: received NACK on transmit of address
    3: received NACK on transmit of data
    4: other error (???)
*/

#include <Wire.h>

byte reg_pointer, data;
byte I2CError;

void setup()
{
  Wire.begin();
  Wire.setClock(100000);  // Make sure SCL is 100kHz
  Serial.begin(9600);
  I2CError = 0;
  reg_pointer = 0x0A;
}

void loop()
{
  Wire.beginTransmission(0x48);
  Wire.write(reg_pointer);

  I2CError = Wire.endTransmission(true); // Send the data
  if (I2CError == 0)
    Serial.println ("OK ");
  else
  {
    Serial.print ("Error      ");
    Serial.println (I2CError);
  }
  //while (I2CError != 0);


  Wire.requestFrom(0x48, 1, true);
  while (Wire.available() == 0) {delay(5);}
  data = Wire.read();
  Serial.print(reg_pointer, HEX); Serial.print("\t");
  Serial.print(data, HEX); Serial.print("\t");
  Serial.println();

  delay (3000); // Wait 3
}

Hi @jim-p
Thank you for your test script.

This is what I get:

14:22:21.653 -> OK 
14:22:21.653 -> A	7

so reg_pointer = A and data = 7
I would like to point that I have 3 of these sensors and I get the same value for all of them.

It's a hardware issue but not sure what?

@jim-p Thanks for your time and help.

I am using this board and I don't know if it adds a layer of complexity for configuration or not. since based on the schematic I2C PMOD connectors are directly connected to the AD7746's related pins

That board already has pull-ups, so I would remove the pull-up on you breadboard and try again.

I see what's wrong.
It needs a repeated start.
Try this code

// FOR TEST

/*
   Error codes for Wire.endTransmission
    0: success
    1: data too long to fit in transmit buffer (32 byte max)
    2: received NACK on transmit of address
    3: received NACK on transmit of data
    4: other error (???)
*/

#include <Wire.h>

byte reg_pointer, data;
byte I2CError;

void setup()
{
  Wire.begin();
  Wire.setClock(100000);  // Make sure SCL is 100kHz
  Serial.begin(9600);
  I2CError = 0;
  reg_pointer = 0x0A;
}

void loop()
{
  Wire.beginTransmission(0x48);
  Wire.write(reg_pointer);

  I2CError = Wire.endTransmission(false); //repeated start
  if (I2CError == 0)
    Serial.println ("OK ");
  else
  {
    Serial.print ("Error      ");
    Serial.println (I2CError);
  }
  //while (I2CError != 0);


  Wire.requestFrom(0x48, 1, true);
  while (Wire.available() == 0) {delay(5);}
  data = Wire.read();
  Serial.print(reg_pointer, HEX); Serial.print("\t");
  Serial.print(data, HEX); Serial.print("\t");
  Serial.println();

  delay (3000); // Wait 3
}
1 Like

YES, finally a response from the device.
I received A0
Now I know the hardware works.

Apparently the library you are using does not send a repeated start, so obviously that library was never tested with a real device
I would look for a different library.

Don't forget you can remove the pull-ups

1 Like

Thank you so much sir. You saved me from giving up this sensor.

I don't see any libraries so I guess you will have to write your own code.
Glad it worked