More than 50% ADC noise using Arduino MKR Zero

I am trying to use an Arduino MKR Zero to read out 4 voltages between 0-1V and send the values to a connected PC. I have connected the pins A0-A3 to 4 different BNC plugs, the ground pin of the BNCs and the ground pin of the Arduino are all connected to a metal housing. I am currently powering the Arduino via the USB port (I know this is not ideal for noise, but the noise seems far to big to be caused by this).

The code I am using on the Arduino:

void setup() {
  Serial.begin(9600);           //  setup serial
  analogReadResolution(12);
  analogReference(AR_INTERNAL1V0);
  pinMode(A0, INPUT);
  pinMode(A1, INPUT);
  pinMode(A2, INPUT);
  pinMode(A3, INPUT);
}

void loop() {
  int ch = atoi(Serial.readStringUntil('\n').c_str());
  
  switch (ch)
  {
    case 0:
      return;
    case 1:
      ch = A0;
      break;
    case 2:
      ch = A1;
      break;
    case 3:
      ch = A2;
      break;
    case 4:
      ch = A3;
      break;
  }
  
  float val = 0;
  
  // for (int i = 0; i < 5; ++i)
    val += analogRead(ch);
    
  // val /= 5;
  
  Serial.print(1.0 / 4096 * val, 4);
  Serial.print('\n');
}

To read out values, I send the channel I want to read (1-4) to the serial port of the Arduino, and get the result back. If I connect a photodiode to the first channel (connected to A0) and read out the voltage, I get 0.000V most of the time, with slight fluctuations around that (the photodiode is not illuminated, so the expected voltage is 0V). So far so good. However, there are also readouts of >0.5V (!), which is an error of 50% of the total ADC range. The strange thing is that this does not seem to happen all the time, sometimes I get consistent readings for a long time. Changing something (no idea what exactly triggers this), it goes back to the erratic behavior with huge spikes every few values.

What could be causing this? Am I doing something wrong on the code side? Is my wiring incorrect?

One thing I have tried is to read out the voltage reference via the AREF pin: I get a value of <50mV which I am not sure how to interpret (several places seem to suggest that when an internal reference is used, the AREF pin can be used to read out the ADC reference voltage)

Replace the photodiode with a 10K pot (wiper to A0, the other pins to ground & 3.3V. Obviously anything over 1.0V will read 4095, but do you get noise-free readings at settings below 1.0V?

Thanks for the suggestion! I have done some more testing, I have found the following:

  • When using a potentiometer as suggested, I get a stable voltage reading that can be tuned by adjusting the potentiometer
  • The VCC voltage output delivers a stable 3.33V when measured using a multimeter
  • Connecting the photodiode I want to use to the arduino still gives strange results.
    • The photodiode (Thorlabs DET100A/M, specs can be found here) is connected to the meaurement device with a 100Ohm resistor in parallel.
    • When measuring with only the multimeter, I get a fairly stable reading of 100mV (with any noise coming from fluctuations in incident power)
    • When measuring with only the Arduino, I get 100mV on average, but 150mV peak-to-peak
    • I see the same results when connecting both the Arduino and Multimeter in parallel, i.e. stable reading on the multimeter, fluctuating reading on the arduino

Is there something special about the photodiode as a voltage source that the Arduino can’t handle, but the multimeter can?

My guess is that it is something to do with the recommended input circuit independance of the Zero’s analog input vs. your circuit. Perhaps an op-amp buffer circuit will be required, like that shown in the sensor’s data sheet. I don’t know, it’s on the borders of my knowledge. But at least the pot showed that there is nothing wrong with the Zero’s inputs.

Not sure where you problem is, however low level signals are inherently noisy.

For example: the first half is what one might like, however the 2nd half is what you can get.

Noise

  1. I couldn’t make your link work.

  2. You mentioned the pot measurement was stable. Are the leads to the pot similar in length as the photo diode?

  3. I would put an 0.1µF capacitor at the analog input of the Arduino. However I wouldn’t add this capacitor now as there seems to be some basic issue and a capacitor would likely mask such an issue.

  4. for testing I would put a delay before reading the analog inputs. 100 ms would be large enough to discount any timing issues.

Sorry for the delayed response. I have finally found the time to try all of your suggestions, and I think I have also found the issue after some more testing. It turns out that the Arduino was in fact reporting the “correct” values: The signal from the photodiode is pulsed with 10MHz repetition rate. The multimeter is simply too slow to resolve this, and only shows the average value. Since this is the value I was after, I completely forgot to consider that the Arduino might be fast enough to resolve this. Adding a 100nF capacitor between the inputs and the ground seems to have fixed the issue by filtering out the high frequency stuff.

Thank you for your valuable suggestions!

1 Like

Hi, @Mathe172

Have you got the gnd of the BNC connected DIRECTLY to the GND of the Arduino?
Using the chassis as a method of connecting the two GNDs together is a bad idea as your reading will have noise from other currents flowing through or induced into the chassis.

Tom… :grinning: :+1: :coffee: :australia: