Electronic – Weird reading from NAU7802 ADC

adcamplifieri2cstrain-gage

I'm using an NAU7802 ADC which has a built in amplifier. I'm trying to use it to read a strain gauge but it keeps giving me weird readings.

Eventually I resorted to shorting the two differential inputs together so that it should read 0, however these are the readings I actually get (at 80 Hz, gain = 128):

ADC result

As you can see, most of the time the reading is correct, but every 0.4s or so it has a burst of nonsense.

I am pretty sure that my code is correct (I can't post it, sorry). Note that I am polling the device for DRDY (data ready) rather than interrupting on it. That shouldn't make a difference but I'm kind of at a loss as to what is causing this.

Does anyone have any suggestions? I've added capacitors to just about everywhere I can and put everything in a metal box so I don't think it is EMI.

I am going insane.

Update, it gets weirder

So I changed my code a bit so that it uses the DRDY interrupt, like this (I couldn't get I2C to work within the ISR for some reason, hence the boolean):

    // In setup()
    attachInterrupt(1, adcIsr, RISING);
}

volatile bool dataReady = false;

void adcIsr()
{
    dataReady = true;
}

loop()
{
    if (dataReady)
    {
        Serial.println(adc.readADC());
        dataReady = false;
    }
}

And now I get this graph. The magnitude of the triangles is independent of the gain!

mystery triangles

I seriously have no idea what is going on now. It seems like some kind of timing issue but the data sheet says whenever you read the ADC output it latches and gives you the last one.

Best Answer

Aha, I finally found the answer in this code!

The datasheet mentions a couple of "choppers" - ADC chopper and PGA chopper, but doesn't really say what they are and at least in the case of the ADC chopper there is only one value that isn't reserved (off). It turns out the non-reserved value isn't the default! If you turn off the ADC chopper it gets rid of the weird triangle wave. A small amplitude sine wave remains, but if you turn off the PGA chopper that goes too. Here is the relevant code (writeReg is the obvious implementation).

writeReg(OTP_B1, 0x30);
writeReg(PGA, PGA_OUTPUT_BUFFER_ENABLE | PGA_PGACHPDIS);

Stupid datasheet.