AD7780: DOUT/RDY pin always high at a specific load

Hello everyone,

I am designing a weigh scale for a bee hive, using AD7780, using four load cells, 20kg each, 1mV/V, powered at 3.3V.

I ordered 2 samples and I etched a small evaluation circuit (schematics and layout attached), based on the CN0107 reference design. The part is powered with 3.3V, the AVDD and DVDD pins are decoupled using tantalum and ceramic capacitors, and the AVDD is powered through a low pass filter. The part is configured with 128 gain and 10Hz filter.

I tested with two individual load cells and the behavior is the same: above a specific load () the DOUT/RDY pin remains HIGH. If I reverse the sense wires and the force direction, the behavior is the same.

Vref is 3.3V. Gain is 128, so the maximum measurable voltage should be ~25mV. My multimeter, set on mV, indicated 0.09mV between AIN+ and AIN-. Referenced to GND, I measured 1.532  at AIN+ and AIN-. Excitation voltage is 3.281V and AVDD is 3.290 (the load cell is powered through the BPDSW pin). DVDD is 3.332V.

Filter an Gain pins are solidly connected to 3.3V and GND. All solder joints and wiring is intact. The load cell does not appear to be faulty (as measured with the multimeter set on Ohms)

As for the interface, the level is 3.3V, the clock frequency is 200KHz and the MCU waits for DOUT/RDY pin to go low before attempting anything. At no load, the status byte reads correctly: no conversion errors, gain and filter are as set by hardware, and the PAT bits are correct.

I also attached the interface code, in case there might be something wrong with it. It is written in Arduino IDE, targeted for the ESP8266. Also, at no load, the measured voltage was 12.84mV, so I think I am doing something wrong there.

What am I mistaking ?

Thank you,

Mihai V.

attachments.zip
Parents
  • Hello,

    I just figured it all out !

    The problem was in the code (I should stick to my hardware and leave the software for the experienced).

    Here is what happens: if the voltage seen by the ADC (AIN+ - AIN-) is greater than 0, conversion stops and DOUT/RDY remains high forever. In the previous post, at 5V tests, when I stated that I was reading almost full scale values  (such as 16777211) I had a reading error. I solved It.

    Back at 3.3V AVDD. As soon as AIN+ became greater than AIN- and the conversion result was greater than 8388607 (which is the correct value for 0 voltage differential) DOUT remained High.

    While checking the code (for the 1000th time) I noticed that I fed the 32 clock cycles to get the data, but the "for" loop responsible for that left the clock line low. After exiting the loop, I set the clock high.

    And it works now. I set 100mv positive differential voltage and I read 0.0994 mV.

    Jellenie, thank you for your advice and patience !

     I am posting the code, in case someone finds it useful. It implements bit-banging method instead of SPI and it is written for Arduino IDE, but the principle applies for any micro-controller.

     #define WEIGHT_DATA  12
     #define WEIGHT_CLK  14

    uint32_t readData();

    void setup() {
        Serial.begin(115200);
        Serial.println("## Serial ok.");
        pinMode(WEIGHT_CLK, OUTPUT);
        pinMode(WEIGHT_DATA, INPUT);
        pinMode(2, OUTPUT);
        digitalWrite(WEIGHT_CLK, LOW);

    }

    void loop() {
        while (digitalRead(WEIGHT_DATA))
            yield();
        Serial.println(readData());
    }

    uint32_t readData() {
        uint32_t aux = 0;
        digitalWrite(WEIGHT_CLK, LOW);
        delayMicroseconds(1);
        for (int i = 31; i>=0; i--) {
            digitalWrite(WEIGHT_CLK, HIGH);
            delayMicroseconds(1);
            if (digitalRead(WEIGHT_DATA) == 1) {
                aux|=(1<<i);
            }        
            delayMicroseconds(50);
            digitalWrite(WEIGHT_CLK, LOW);
            delayMicroseconds(50);
        }
        digitalWrite(WEIGHT_CLK, HIGH);
        if ((aux & 64)!=0)
            Serial.println("## Filter=10hz;");
        else
            Serial.println("## Filter=16hz;");

        if (aux & 32)
            Serial.println("## Conversion error.");

        if ((aux & 4)!=0)
            Serial.println("## Gain=1;");
        else
            Serial.println("## Gain=128;");

        if (((aux & 1)!=0) && ((aux & 2) == 0))
            Serial.println("## Serial transfer ok.");
        else
            Serial.println("## Serial transfer error.");
        Serial.println(aux, BIN);
        
        aux = aux >> 8;
     
        return aux;
    }

Reply
  • Hello,

    I just figured it all out !

    The problem was in the code (I should stick to my hardware and leave the software for the experienced).

    Here is what happens: if the voltage seen by the ADC (AIN+ - AIN-) is greater than 0, conversion stops and DOUT/RDY remains high forever. In the previous post, at 5V tests, when I stated that I was reading almost full scale values  (such as 16777211) I had a reading error. I solved It.

    Back at 3.3V AVDD. As soon as AIN+ became greater than AIN- and the conversion result was greater than 8388607 (which is the correct value for 0 voltage differential) DOUT remained High.

    While checking the code (for the 1000th time) I noticed that I fed the 32 clock cycles to get the data, but the "for" loop responsible for that left the clock line low. After exiting the loop, I set the clock high.

    And it works now. I set 100mv positive differential voltage and I read 0.0994 mV.

    Jellenie, thank you for your advice and patience !

     I am posting the code, in case someone finds it useful. It implements bit-banging method instead of SPI and it is written for Arduino IDE, but the principle applies for any micro-controller.

     #define WEIGHT_DATA  12
     #define WEIGHT_CLK  14

    uint32_t readData();

    void setup() {
        Serial.begin(115200);
        Serial.println("## Serial ok.");
        pinMode(WEIGHT_CLK, OUTPUT);
        pinMode(WEIGHT_DATA, INPUT);
        pinMode(2, OUTPUT);
        digitalWrite(WEIGHT_CLK, LOW);

    }

    void loop() {
        while (digitalRead(WEIGHT_DATA))
            yield();
        Serial.println(readData());
    }

    uint32_t readData() {
        uint32_t aux = 0;
        digitalWrite(WEIGHT_CLK, LOW);
        delayMicroseconds(1);
        for (int i = 31; i>=0; i--) {
            digitalWrite(WEIGHT_CLK, HIGH);
            delayMicroseconds(1);
            if (digitalRead(WEIGHT_DATA) == 1) {
                aux|=(1<<i);
            }        
            delayMicroseconds(50);
            digitalWrite(WEIGHT_CLK, LOW);
            delayMicroseconds(50);
        }
        digitalWrite(WEIGHT_CLK, HIGH);
        if ((aux & 64)!=0)
            Serial.println("## Filter=10hz;");
        else
            Serial.println("## Filter=16hz;");

        if (aux & 32)
            Serial.println("## Conversion error.");

        if ((aux & 4)!=0)
            Serial.println("## Gain=1;");
        else
            Serial.println("## Gain=128;");

        if (((aux & 1)!=0) && ((aux & 2) == 0))
            Serial.println("## Serial transfer ok.");
        else
            Serial.println("## Serial transfer error.");
        Serial.println(aux, BIN);
        
        aux = aux >> 8;
     
        return aux;
    }

Children
No Data