0

I'm trying to read a block of bytes from an AD5934 Impedance converter (PDF) using I2C.

This is my code so far

Preamble:

#define AD5934_Address                    0xD
#define AD5934_Start_Frequency            0x82
#define AD5934_Block_Read                 0b10100001
#define AD5934_Address_Pointer            0b10110000

Loop:

void loop() {
  readAD5934(AD5934_Start_Frequency, test, 3);
}

Read Function:

byte readAD5934 (int address, long int  data, int len) {
  byte err = 0, counter;

  if (len > 32)
    return 0xFF;

  else if (len > 1) {
    // Part ONE
    Wire.beginTransmission(AD5934_Address);
    Wire.write((byte) AD5934_Address_Pointer);
    Wire.write((byte) address);

    err = Wire.endTransmission();

    // Part TWO
    Wire.beginTransmission(AD5934_Address);
    Wire.write((byte) AD5934_Block_Read);
    Wire.write(len);

    // Part THREE
    Wire.requestFrom(AD5934_Address, len);
    StartHigh = Wire.read();
    StartMed = Wire.read();
    StartLow = Wire.read();
    err = Wire.endTransmission();
  }
return err;
}

For some reason, the Arduino tries to read the three bytes before Part TWO is executed.

I'm aware that I'm ending the I2C transmission after the requestFrom. The datasheet for AD5934 describes how to read a block of bytes on page 26. It does not show a STOP CONDITION before the end.

The oscilloscope shows

START 0001101 WRITE ACK 10110000 ACK 10000010 ACK STOP START 0001101 READ ACK 00000001 ACK 11000111 ACK 11111111 NACK STOP START 0001101 WRITE ACK 10100001 ACK 00000011 ACK STOP

Short: S 0x0D W A 0xB0 A 0x82 A P S 0x0D R A 0x01 0xC7 0xFF NA P S 0x0D W A 0xA1 A 0x03 A P

The highlighted part (requestFrom and three Wire.read()) should be at the end.

I've spent a long time trying to figure this out, any help would be very much appreciated.

PS. Working on a Sparkfun Pro Micro 5V

  • Is there a Wire.endTransmission(false) missing before Part THREE? – Mikael Patel Dec 6 '17 at 17:16
  • A Wire.requestFrom does the stop itself. You may not do a Wire.endTransmission after it. Part TWO needs the Wire.endTransmission as @MikaelPatel wrote. What might happen is this: the Wire.requestFrom reads data, and the Wire.endTransmission after or inside the Wire.requestFrom might execute what already is written in a buffer in Part TWO. It depends on the code of the Wire library and it should not be done like that. – Jot Dec 6 '17 at 17:45
1

I think you should re-see AD5934x datasheet.

To read data from AD5934, we have three ways:

  • read single byte
  • read block
  • using pointer command

If you want to read multi byte, you can refer to my way:

unsigned long GetRegisterValue(unsigned char regAddr, unsigned char len)
{
    unsigned long regValue = 0;
    unsigned char index;
    unsigned char wrData[2] = {0,0};
    unsigned char rdData[2] = {0,0};

    for (index = 0; index < len; index++)
    {
        wrData[0] = 0xB0; //assign pointer cmd
        wrData[1] = regAddr + index;
        I2C_Write(AD5934_ADDR, wrData, 2);
        rdData[0] = 0xff;
        I2C_Read(AD5934_ADDR, rdData, 1);
        regValue <<= 8;
        regValue += rdData[0];
    }

    return regValue;
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.