Measurement accuracy ADC of arduino zero

Hello,

there is already a blog of speeding up analogRead() on Arduino Zero.

But before I do that, I am interested in measurement accuracy. I made a few tests with a cheap board from Ebay and connected A0 directly to ground. (Refer to the attachment)

Running this code, the result plottet in Excel is in the next attachment.

unsigned int messArray[1000];

void setup() {
  delay(2000);
  SerialUSB.begin(0);
  delay(2000);

  analogReadResolution(12);

  for (int i = 0; i < 1000; i++) {
    messArray[i] = analogRead(A0);
  }
  for (int i = 0; i < 1000; i++) {
    SerialUSB.println(messArray[i]);
  }

}

Then I changed the reference to 1 V internal and made the same test.

analogReference(AR_INTERNAL1V0);

Now, the result doesn’t have that offset, but it is still noisy.

I also got a SPI display connected to the board and powered by the board. If I disconnect the display, the noise got somehow less. (next attachment)

But still I am not really satisfied and I am interested to know if anyone else has experience with this. Also I tested different supplies and connected a 9 V supply to the Vin pin and a USB-plug at the same time, causing one IC producing flames immediately. (next attachment) (The picture shows the IC before it was damaged.) Does anyone know what kind of IC this is?

So I can’t make further tests right now, but I ordered one of these boards from avandalen. They got the advantage of an own analog ground. Maybe that improves the measurement accuracy.

grounded.JPG

grounded_1V_reference.JPG

no_SPI-display.JPG

Burned_IC.JPG

Does anyone know what kind of IC this is?

The voltage regulator. It seems that your cheap clone doesn't have a power selection circuit so you must not power it twice. You're a lucky guy that your PC's USB port survived this.

The thing I can NEVER understand when this question about ADC's is asked

IS - WHY DO YOU EXPECT THE READING TO BE CONSTANT!

  1. What is that makes you think that your input is constant to less than 1 4000th, well, 1 in 4k for the 12 bit ADC of the Due

  2. On the Uno , for example with it's 10 bit ADC and using Vin (5v nominal) for example, you can expect the reading to jump by +/- 10 ie 1%.

This is simply due to the changes in power consumption when an instruction is executed. A 0.05V change in the voltage at at the Vcc pin of the processor chip will get you a 1% change in the ADC reading.

Add to the above a long list of things that can affect the input (including body heat, drafts vibrations and electromagnetic interference.

  1. With the internal voltage refs start by checking the data sheet for the chip and then head for the electronics and Physics text books

Mark

I want to keep this a serious post. It is not really helpful to recommend others to read electronics and physics text books.

But here is a helpful hint for you: Connect a 5 nF capacitor right on the analog input and don’t use A0 to A5 als digital output. I have done so on several projects with an Arduino Nano clone, what is basically the same as an Arduino Uno. It was even possible to double the sampling rate. (Division factor 64 in ADCSRA).

I have build for example a laboratory power supply using a laptop power supply. I have plotted an example of the ADC results. I made a short circuit on the output at approx. 5 ms. The output voltage drops down to zero and stays there also without noise. The other signals are the input voltage of the laptop power supply and a current measurement using a hall sensor SS495A. There is some swing of the signals, caused by the inductance of the current sense and the main capacitor.

Also I built a small electric car for my children to drive around. I used an Arduino Nano clone for the BLDC motor controller. It works with 16 kHz and powers the Moog motor with up to 40 A. The entire program repeats within 16 kHz, what means the program completes one time within 1000 clock strikes.

In such projects, the Arduino Nano is really running on its limit. That’s why I decided to take a deeper look on SAMD21 for a higher performance. So if you got a measurement with an Arduino Zero with A0 connected directly to ground, I really appreciate you to post it here.

Regarding the power selection circuit: I think it has one, but it was not working. I powered the clone from USB and measured 4,6 V on the Vin-pin. The voltage drop compared to 5 V from USB is likely to be caused from a schottky diode, that should protect the USB circuit.

Voltage_Drop.JPG

Well, now I bought a board from this Netherlands guy. There is a picture of the setup in 01. It seems here are not many people interested in the ADC accuracy. But anyway here are my results.

I used a 10 nF capacitor on the input in combination with a 1.2 V battery as a guaranteed noise free source. I used a voltage devider of two 325 Ohm resistors for the tests with the 1 V internal reference. In order to quantify the noise of the ADC, I calculated the standard deviation of 1000 samples.
First measurements using the Arduino functions showed a standard deviation of approx. 1.8, independent if the internal 1 V reference or default reference is used.

Because of the fact, that the ADC capacitor is charged to VDDANA, special care has to be taken to keep VDDANA constant. So I added an additional ceramic capacitor and an electrolyte 47 µF capacitor between 3.3 V supply and GND according to the datasheet. Refer to 02. This dropped the standard deviation from 1.8 to 1.7.

Next step was to add an additional electrolyte capacitor between VDDANA and GNDANA on the backside of the board. (Picture 03) But this didn’t bring further improvements of the standard deviation.

Now I looked for the required charging time of the ADC capacitor. I speeded up the ADC clock to 1.5 MHz (ADC->CTRLB.bit.PRESCALER =3) and made a variation of ADC->SAMPCTRL.bit.SAMPLEN. In order to be sure that the ADC capacitor is not pre-charged from the last measurement, ground was measured in between. Refer to picture 04 and 05 for the results. So if a low impedance source is used, ADC->SAMPCTRL.bit.SAMPLEN = 2 seems to be sufficient to charge the ADC capacitor. Also the standard deviation keeps stable for bigger values than 1 and is only a little bit higher at ADC->SAMPCTRL.bit.SAMPLEN = 0.

According to the datasheet, the signal to noise ratio is 5.5 dB higher if differential mode is used. I also found this in the results and continued with an investigation of the standard deviation with different ADC clock speeds and gain settings.
Constant values:
ADC->SAMPCTRL.bit.SAMPLEN = 0x02;
ADC->CTRLB.bit.DIFFMODE = 0x1;
1 V internal voltage reference

Both, the positive and negative input were tied to analog ground. Out came the result in 06. So the noise level reaches lowest values with the highest ADC clock speed. Bigger gain settings are probably only useful if the 8 bit mode is used.

The next step was to implement an external voltage reference. I used a REF3130 with 3 V output. The 3 V output is divided with two 1K resistors to 1.5 V. The 1.5 V are fed to pin 3 and 4 of the SAMD21G. (Picture 07). A 1µF ceramic capacitor is added on the backside at the entrance of the board to analog ground. Pin 3 is used as negative reference. So a voltage range from 0 to 3 V can be measured on the analog pins. For the further test, the analog pin (I used pin 8) was tied to 1.5 V also. The result is plotted in picture 08. Significant improvements are visible compared to picture 6. The standard deviation without gain drops down to 0.6 and no significant noise dependency of the clock speed is visible. An example of 1000 samples plotted, using gain=0 is shown picture 09. Mainly the last bit is toggling only.

For data acquisition purposes, probably the Arduino Due is better. According to the datasheet, the signal to noise ratio as well as the acquisition speed are significantly higher. But I like small boards like the one from avandalen.

02.JPG

04.JPG

05.JPG

06.JPG

08.JPG

09.JPG

pylon:
The voltage regulator. It seems that your cheap clone doesn't have a power selection circuit so you must not power it twice. You're a lucky guy that your PC's USB port survived this.

This is not a voltage regulator. It is a single port analog mux which is intended to control supplying power OUT of the USB port when the module is action as a USB host (USB OTG).