Analog Read wrong readings

Hi all,
I had been testing my brand new mrk1010 with some basic codes, just to check if it was all ok.
When i tried to read (via serial) an analog signal coming from a potentiometer i found out that the minimum reading was not 0 but 2/3, then i connected gnd to the analog input to check and even in that case the value wasn't 0.

Do you have any idea?

Additional infos:

board connected via usb

Have you tried running SAMD_AnalogCorrection.

You can find it under examples sketches

I didn’t find that example, but after some research i found the following code. Is it the code you were talking about? More or less, i mean, because in the comments there ìs written “for arduino zero”.

If not, could you provide me the right code to use?

Thank you for your help!

/*
  This sketch easily and quickly finds the right ADC correction values for a particular Arduino ZERO board.
  The correction values that are found are only valid for the board where the sketch is executed.
  This example code is in the public domain.
  Written 6 May 2015 by Claudio Indellicati
*/

/*
  How to use this sketch
  
  1) Remove any connection cable, shield or jumper from your Arduino ZERO
  2) Connect pin A1 to the nearest GND pin using the shortest jumper possible
  3) Connect pin A2 to the 3.3V pin using the shortest jumper possible
  4) Connect the Arduino ZERO to your PC using a USB cable plugged in the USB programming port of the board
  5) Upload this sketch and leave the board powered on for at least one minute
  6) Open the Serial Monitor and press the reset button on the Arduino ZERO
  7) At the and of the procedure you can find logged
       - the offset and gain values for the board where the sketch has been just executed
       - the instruction line to copy/paste in the final sketch
*/

#include "SAMD_AnalogCorrection.h"

#define ADC_GND_PIN          A1
#define ADC_3V3_PIN          A2

#define ADC_READS_SHIFT      8
#define ADC_READS_COUNT      (1 << ADC_READS_SHIFT)

#define ADC_MIN_GAIN         0x0400
#define ADC_UNITY_GAIN       0x0800
#define ADC_MAX_GAIN         (0x1000 - 1)
#define ADC_RESOLUTION_BITS  12
#define ADC_RANGE            (1 << ADC_RESOLUTION_BITS)
#define ADC_TOP_VALUE        (ADC_RANGE - 1)

#define MAX_TOP_VALUE_READS  10

void setup()
{
  Serial.begin(9600);

  Serial.println("\r\nCalibrating ADC with factory values");

  analogReadResolution(ADC_RESOLUTION_BITS);

  Serial.println("\r\nReading GND and 3.3V ADC levels");
  Serial.print("   ");
  readGndLevel();
  Serial.print("   ");
  read3V3Level();

  int offsetCorrectionValue = 0;
  uint16_t gainCorrectionValue = ADC_UNITY_GAIN;
  
  Serial.print("\r\nOffset correction (@gain = ");
  Serial.print(gainCorrectionValue);
  Serial.println(" (unity gain))");

  // Set default correction values and enable correction
  analogReadCorrection(offsetCorrectionValue, gainCorrectionValue);

  for (int offset = 0; offset < (int)(ADC_OFFSETCORR_MASK >> 1); ++offset)
  {
    analogReadCorrection(offset, gainCorrectionValue);
    
    Serial.print("   Offset = ");
    Serial.print(offset);
    Serial.print(", ");

    if (readGndLevel() == 0)
    {
      offsetCorrectionValue = offset;
      break;
    }
  }

  Serial.println("\r\nGain correction");

  uint8_t topValueReadsCount = 0U;
  
  uint16_t minGain = 0U,
           maxGain = 0U;

  analogReadCorrection(offsetCorrectionValue, gainCorrectionValue);
  Serial.print("   Gain = ");
  Serial.print(gainCorrectionValue);
  Serial.print(", ");
  uint16_t highLevelRead = read3V3Level();
  
  if (highLevelRead < ADC_TOP_VALUE)
  {
    for (uint16_t gain = ADC_UNITY_GAIN + 1; gain <= ADC_MAX_GAIN; ++gain)
    {
      analogReadCorrection(offsetCorrectionValue, gain);

      Serial.print("   Gain = ");
      Serial.print(gain);
      Serial.print(", ");
      highLevelRead = read3V3Level();
      
      if (highLevelRead == ADC_TOP_VALUE)
      {
        if (minGain == 0U)
          minGain = gain;

        if (++topValueReadsCount >= MAX_TOP_VALUE_READS)
        {
          maxGain = minGain;
          break;
        }
        
        maxGain = gain;
      }

      if (highLevelRead > ADC_TOP_VALUE)
        break;
    }
  }
  else if (highLevelRead >= ADC_TOP_VALUE)
  {
    if (highLevelRead == ADC_TOP_VALUE)
      maxGain = ADC_UNITY_GAIN;

    for (uint16_t gain = ADC_UNITY_GAIN - 1; gain >= ADC_MIN_GAIN; --gain)
    {
      analogReadCorrection(offsetCorrectionValue, gain);

      Serial.print("   Gain = ");
      Serial.print(gain);
      Serial.print(", ");
      highLevelRead = read3V3Level();
      
      if (highLevelRead == ADC_TOP_VALUE)
      {
        if (maxGain == 0U)
          maxGain = gain;
        
        minGain = gain;
      }

      if (highLevelRead < ADC_TOP_VALUE)
        break;
    }
  }

  gainCorrectionValue = (minGain + maxGain) >> 1;

  analogReadCorrection(offsetCorrectionValue, gainCorrectionValue);

  Serial.println("\r\nReadings after corrections");
  Serial.print("   ");
  readGndLevel();
  Serial.print("   ");
  read3V3Level();

  Serial.println("\r\n==================");
  Serial.println("\r\nCorrection values:");
  Serial.print("   Offset = ");
  Serial.println(offsetCorrectionValue);
  Serial.print("   Gain = ");
  Serial.println(gainCorrectionValue);
  Serial.println("\r\nAdd the next line to your sketch:");
  Serial.print("   analogReadCorrection(");
  Serial.print(offsetCorrectionValue);
  Serial.print(", ");
  Serial.print(gainCorrectionValue);
  Serial.println(");");
  Serial.println("\r\n==================");
}

void loop()
{
}

uint16_t readGndLevel()
{
  uint32_t readAccumulator = 0;

  for (int i = 0; i < ADC_READS_COUNT; ++i)
    readAccumulator += analogRead(ADC_GND_PIN);

  uint16_t readValue = readAccumulator >> ADC_READS_SHIFT;
  
  Serial.print("ADC(GND) = ");
  Serial.println(readValue);

  return readValue;
}

uint16_t read3V3Level()
{
  uint32_t readAccumulator = 0;

  for (int i = 0; i < ADC_READS_COUNT; ++i)
    readAccumulator += analogRead(ADC_3V3_PIN);

  uint16_t readValue = readAccumulator >> ADC_READS_SHIFT;
  
  if (readValue < (ADC_RANGE >> 1))
    readValue += ADC_RANGE;

  Serial.print("ADC(3.3V) = ");
  Serial.println(readValue);

  return readValue;
}

Yes that is the one, it is listed under examples for the MKRWIFI1010.

However when I tried it, I didn't get any results in the serial monitor.

When I try to read the ADC values, using a 10K potmeter, my top readings are 1023, but the low readings fluctuate between 0 and 25.

Now I wonder if there is a bug in the ADC implementation

Erni:
However when I tried it, I didn't get any results in the serial monitor.

I did ( I started the serial monitor as soon as possible while i was connecting my board to my pc. If i try to open it after the board has been running for a while it won't show anything), these are my output:

ADC(GND) = 6
   Offset = 6, ADC(GND) = 5
   Offset = 7, ADC(GND) = 4
   Offset = 8, ADC(GND) = 3
   Offset = 9, ADC(GND) = 2
   Offset = 10, ADC(GND) = 2
   Offset = 11, ADC(GND) = 1
   Offset = 12, ADC(GND) = 0

Gain correction
   Gain = 2048, ADC(3.3V) = 4083
   Gain = 2049, ADC(3.3V) = 4084
   Gain = 2050, ADC(3.3V) = 4086
   Gain = 2051, ADC(3.3V) = 4088
   Gain = 2052, ADC(3.3V) = 4090
   Gain = 2053, ADC(3.3V) = 4092
   Gain = 2054, ADC(3.3V) = 4094
   Gain = 2055, ADC(3.3V) = 4095
   Gain = 2056, ADC(3.3V) = 4095
   Gain = 2057, ADC(3.3V) = 4095
   Gain = 2058, ADC(3.3V) = 4095
   Gain = 2059, ADC(3.3V) = 4095
   Gain = 2060, ADC(3.3V) = 4095
   Gain = 2061, ADC(3.3V) = 4095
   Gain = 2062, ADC(3.3V) = 4095
   Gain = 2063, ADC(3.3V) = 4095
   Gain = 2064, ADC(3.3V) = 4095

Readings after corrections
   ADC(GND) = 0
   ADC(3.3V) = 4095

==================

Correction values:
   Offset = 12
   Gain = 2055

Add the next line to your sketch:
   analogReadCorrection(12, 2055);

==================

Update: i tried to add the correction suggested ( analogReadCorrection(12, 2055); ) and now I can read 0 BUT the maximum value has become 1014... so, one problem was corrected and another problem has come out

Thanks for the tip, now i got it working, but my result are the same as yours or worse.
I get 0 for the low reading and 1003 for the high.

In my opinion that code doesn't work well with our mkr1010, anyway someone else may correct me about that.

Just to check if it is ok (i might not have understood correctly where to write the "correction line"), for my last test i used this code:

#include "SAMD_AnalogCorrection.h"
void setup() {
  // put your setup code here, to run once:

     Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  analogReadCorrection(12, 2055);
  int a = analogRead(A1);
  Serial.println(a);
}