Spikes in the First Set of Measurements ADC Arduino DUE

Hello people,

Pardon my english, currently i'm having some trouble with my ADC that I can't figure out.

I build and wrote a code to measure the voltage in a vessel. I recently made some changes and the ADC is strangely behaving. My acquisition makes 208 differential voltage measurements. Each module of the equipment works perfectly injecting a sinusoidal wave. The problem is that in the first set of measurements appears spikes that were not supposed to be there. However, in the second cycle, the measurements works perfectly. I have tried to increase the delay between measurements and no good. The input of the ADC is buffered with a low-pass of 1k resistor and cap 47 pF. There are a lot of cables, jumpers, I confess, more that I'd like. So help is needed and appreciated.

If you guys need more information, I will inform.

Every cable or jumper connected to this 12-bit ADC behaves like a small antenna. One possible workaround would be to oversample and average to suppress most of the noise.

There is a recent thread on the same subject:

https://forum.arduino.cc/index.php?topic=587953.msg3999215#msg3999215

And some example sketches to get ADC conversions (reply #3):

https://forum.arduino.cc/index.php?topic=587953.msg4000260#msg4000260

BTW, this ADC has a fully differential feature.

Post your code (between code tags).

const int injPins[4] = {42, 44, 46, 48}; // S-pins to Arduino pins: S0, S1, S2, S3; 
const int gndPins[4] = {43, 45, 47, 49}; // S-pins to Arduino pins: S0, S1, S2, S3; 
const int msr1Pins[4] = {28, 30, 32, 34}; // S-pins to Arduino pins: S0, S1, S2, S3; 
const int msr2Pins[4] = {29, 31, 33, 35}; // S-pins to Arduino pins: S0, S1, S2, S3; 
int E1 = 40;
int E2 = 41;
int E3 = 26;
int E4 = 27;
int nelet = 16;
int flag;

void setup(void)
{
 analogReadResolution(12);
 Serial.begin(9600); 
for (int i=0; i<4; i++)
 {
 pinMode(injPins[i],OUTPUT);
pinMode(gndPins[i],OUTPUT);
 pinMode(msr1Pins[i],OUTPUT);
 pinMode(msr2Pins[i],OUTPUT);
 }
}
void loop(void)
{
 int16_t ad0;

int cont = 0;
for (int i=0; i<nelet; i++)
{
ground(i);
if (i+1==nelet)
 {
 injection(0);
 flag = 1;
 }
else
 {
 injection(i+1); 
 }
for (int j=0; j<nelet; j++) {
 if (i==0 && j==0)
 
{
 Serial.println("Meas");
 
}
 if (j==i
-1 || j==i || j==i+1)
 
{
 continue;
 
}
 if (i==0 && j==nelet
-1)
 
{
 continue;
 
}
 if (flag == 1)
 
{
 flag = 0;
 continue;
 
}
 measure1(j);
 if (j+1==nelet)
 
{
 measure2(0);
 
}
 else
{
 measure2(j+1);
 }
 digitalWrite(E1, 0);
 digitalWrite(E2, 0);
 digitalWrite(E3, 0);
 digitalWrite(E4, 0);
 ad0 = analogRead(A0);
 delay(60);
 sprintf(str, "A%dB", ad0);
 Serial.println(str); //%dN%dO%dP%dQ
 digitalWrite(E1, 1);
 digitalWrite(E2, 1);
 digitalWrite(E3, 1);
 digitalWrite(E4, 1);
 }
} 
}
// The selectMuxPin function sets the S0, S1, and S2 pins to select the give pin
void ground(byte pin)
{
 if (pin > 15) return; // Exit if pin is out of scope
 for (int i=0; i<4; i++)
 {
if (pin & (1<<i))
 digitalWrite(injPins[i], HIGH);
 else
 digitalWrite(injPins[i], LOW);
 }
}
// The selectMuxPin function sets the S0, S1, and S2 pins to select the give pin
void injection(byte pin)
{
 if (pin > 15) return; // Exit if pin is out of scope
 for (int i=0; i<4; i++)
 {
 if (pin & (1<<i))
 digitalWrite(gndPins[i], HIGH);
 else
 digitalWrite(gndPins[i], LOW);
 }
}
// The selectMuxPin function sets the S0, S1, and S2 pins to select the give pin
void measure1(byte pin)
{
 if (pin > 15) return; // Exit if pin is out of scope
 for (int i=0; i<4; i++)
 {
 if (pin & (1<<i))
digitalWrite(msr1Pins[i], HIGH);
 else
 digitalWrite(msr1Pins[i], LOW);
 }
}
void measure2(byte pin)
{
 if (pin > 15) return;
 for (int i=0; i<4; i++)
 {
 if (pin & (1<<i))
 digitalWrite(msr2Pins[i], HIGH);
 else
 digitalWrite(msr2Pins[i], LOW);
 }
}

The code cycles through 208 measurements. Although I know there is some noise in the measurements, the second cycle appears as It should be. The first cycle, that begins soon after the serial com opens, appears these spikes. Another thing I notice is that when I only measure the analog signal from another arduino, the signal appears normal.

As a matter of fact, the oversampling would take too much time. The measurement needs to be the fastest as possible. Although it states that the delay is 60 ms, the actual delay is 5 ms, which is before the adc register the value btw. The delay is needed because of the settling time of the analog system. The oversampling would increase more the time than use the second cycle of measurements. The aim is to eliminate the spikes of the system for the first cycle of measurements to be good.

This spikes are like a transient behavior, it shows up in the first, let's say, 100 measurements and then fades away. It all happens just after the reset when opening the serial com.

How do you power your board ?

Currently by USB.

Powering the board thru the USB cable when you are doing ADC conversions is a bad choice because the USB power line is very unstable. Power your board with a 9V battery pack thru the jack (the USB cable will be used only to output results on the Serial Monitor).

I attached some pictures to explain better.

The ideal case is the signal in the shape of 'U', with the peaks with the same level.
It is expected some noise in the signal, so the perfect shape will not be obtained.

The first picture is the first loop of the signal input into the ADC.
The second picture is the second loop.
As it is clear there are some spikes in the signal in the first loop, the second figure is satisfactory.
To better understanding, the x-axis is the number of measurement. The total number of measurements are 208 in one loop.

I tried to power with an external supply, but got the same trend.

spike.png

no-spike.png

What is the frequency of the input sin wave you are trying to read ?

The signal is a 20 kHz sinewave that passes through an inamp, then the RMS-to-DC converter, and finally through a buffer with a low-pass of 1k resistor and cap 47 pF and the ADC.

For a 20 KHz input signal, the sampling frequency should be (much) greater than 40 KHz (T = 25 us).