1
\$\begingroup\$

I am using an AD7323 12bit+sign 4-channel ADC an on a custom Arduino shield. I drive it with 12V from a power supply and -12V created using an ICL7662 IC. VCC is 5V from the Arduino. The ADC is used to measure DC signals with a low sampling rate (sampling once every second or so).

The board layout looks like this enter image description here

and the AD7323 pinout is enter image description here

I am using ceramic smd capacitors and BAT43 diodes. Using the control register, I set Power Mode to Normal (0,0), Converter Mode Single-Ended (0,0), Coding 1 (straight-binary), internal reference 1, and sequencer mode disabled (0,0).

SPI is configured at 256000 speed and MODE2. I first write a the address to the control register, and then write 0 via SPI to receive the next conversion value, which gives me -FSR/2+1LSB = 0 and FSR/2-1LSB = 8191 as a value.

The relevant C++ code is

void AD7323::SetSamplingChannel(uint16_t channel) {
    uint16_t data = GetControlValue(true);
    data &= ~(3 << 10); //Clear channel bytes
    data |= channel << 10; // Push channel address
    uint16_t answer = WriteSPI(data);
}

uint16_t AD7323::ReadADC(uint16_t channel)
{
    SetSamplingChannel(channel);
    uint16_t answer = WriteSPI(0) & ~(57344); //Remove top 3 bits
    return answer; 
}
// Get the current value of for the control register
uint16_t AD7323::GetControlValue(bool Write) {

    uint16_t data = Write ? 32800 : 32; //Sets write bit and Coding
    data &= ~(3 << 8); //Mode 0,0
    data |= Mode << 8; //Set new mode
    data &= ~(1 << 4); //Ref 0
    data |= (RefEnabled ? 1 : 0) << 4; //Set ref
    data &= ~(3 << 6); //Power mode 0,0
    data |= PowerMode << 6; //Set power mode
    return data;
}   
uint16_t AD7323::WriteSPI(uint16_t DIN)
{
  SPI.beginTransaction(settings); //settings = SPISettings(256000, MSBFIRST, SPI_MODE2);
  digitalWrite(CSPin,LOW);
  uint16_t val = SPI.transfer16(DIN);
  digitalWrite(CSPin,HIGH);
  SPI.endTransaction();
  delay(1); //Just for testing purposes
  return val;
}

This basically works, however when I simply apply a given voltage and read the ADC value, I have a constant offset of 11-13 LSB (LSB=2.441 mV at -10->10V range).

I am wondering if I have done anything wrong on the layout of code side of things. I was a bit on the low side in terms of decoupling caps for the chip, but I don't understand how missing decoupling caps could cause a constant offset in the value read. Also, should this be taken care of by the internal 2.5V reference in the ADC?

Or is this just a thing that exists, so that I have to add a calibration function in the code?

Since I am out of ideas, I would be glad for any input. Let me know if you need more information.

\$\endgroup\$
  • \$\begingroup\$ How close to symmetrical are your supplies? \$\endgroup\$ – Spehro Pefhany May 4 '18 at 15:53
  • \$\begingroup\$ @SpehroPefhany I can't say for certain right off the top of my head. They are roughtly similar since the -12V is created from the 12V supply. I have checked it only quickly because I thought that it didn't matter much from how I understood the datasheet. But there may be a few dozen mV difference possibly. \$\endgroup\$ – Jens May 4 '18 at 15:58
  • 2
    \$\begingroup\$ Do you have a voltmeter or multimeter? We're in the realm of "is" rather than "should be" at this point. \$\endgroup\$ – Spehro Pefhany May 4 '18 at 16:19
  • \$\begingroup\$ @SpehroPefhany Of course, and I would measure it again right away. I unfortunately don't have the device to hand right now so I would need to get back to you with it. That's why I didn't state the precise values, sorry. \$\endgroup\$ – Jens May 4 '18 at 16:26
2
\$\begingroup\$

AD7323 (from data sheet): -

  • The offset error could be up to +9 LSB single ended or +10 LSB differential.
  • The gain error could be +/- 8 LSB single ended and +/-14 LSB differential
  • Integral and differential non-linearites could add another 2 LSB
  • The internal reference accuracy is +/- 5 mV in 2.5 volt
\$\endgroup\$
  • \$\begingroup\$ Wild guess: does the forward voltage of D1 and D2 play a role here as well? \$\endgroup\$ – Simon Richter May 4 '18 at 15:43
  • \$\begingroup\$ So basically this means I should expect the amounts of error I see and deal with it with a calibration function? Would these offsets be constant, e.g. chip dependent, or are they expected to change over time? \$\endgroup\$ – Jens May 4 '18 at 16:01
  • 2
    \$\begingroup\$ @Jens you need to closely read the data sheet to find that out and look at temperature sensitivity of these figures also. They will drift over time and if the DS doesn't give the detail you need either choose a better part or contact ADI. \$\endgroup\$ – Andy aka May 4 '18 at 16:09
  • 1
    \$\begingroup\$ @Jens - The numbers given provide worst-case limits. For the offset, for instance, it could be zero, or it could be 7, or it could be 9, and in all cases the ADC would operating within the specified limits. You have no way to know other than testing. You need to understand what these errors mean, and specify your choice of part accordingly. For instance, if you MUST have no more than 2 counts of error, you need a different chip. \$\endgroup\$ – WhatRoughBeast May 4 '18 at 16:47
  • \$\begingroup\$ Thanks for the advice. I will do some "real world testing" regarding temperature and time dependence of the calibration values. \$\endgroup\$ – Jens May 4 '18 at 16:56

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.