Analog input stability

Hello! I don't know if it's a topic about this open already.
I was wondering how can i get rid of this variation of the analog input as you can see in the serial print bellow for this simple code for instance. Is it something physical (small variations of the V) or software, maybe something to do with the Voltage in my opinion..
Anyway what are your sugestions?

/*
  ReadAnalogVoltage

  Reads an analog input on pin 0, converts it to voltage, and prints the result to the Serial Monitor.
  Graphical representation is available using Serial Plotter (Tools > Serial Plotter menu).
  Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.

  This example code is in the public domain.

  http://www.arduino.cc/en/Tutorial/ReadAnalogVoltage
*/

// the setup routine runs once when you press reset:
void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
}

// the loop routine runs over and over again forever:
void loop() {
  // read the input on analog pin 0:
  int sensorValue = analogRead(A0);
  // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
  float voltage = sensorValue * (5.0 / 1023.0);
  // print out the value you read:
  Serial.println(voltage);
}

Serial print:

983
983
983
984
983
983
984
983
983

I suggest to read the "How to use this forum" post and follow the directions.

Describe your project and explain the problem, giving examples.

Post a wiring diagram (not Fritzing).

Post the code, using code tags.

That list of 983 and the occasional 984 is not stable enough for you? Why?

wvmarle:
That list of 983 and the occasional 984 is not stable enough for you? Why?

I need to output some wavetable through a external dac and the frequency varies because of this

Then start averaging your results. Do a rolling average of the last 10-20 readings or so, but be aware that your reaction time goes down accordingly.

When averaging, you still have variations, only moved by a decimal place and/or slower.

What resolution do you need.
If you need less than 10-bit, you could add hysteresis.
Try this (untested) 8-bit output sketch.
Leo..

// converts the position of a 10k lin(B) pot to a byte (0-255)
// pot connected to A0, 5volt and ground

int rawValue; // raw reading
int oldValue; // for deadband
byte Byte; // final byte
byte oldByte; // for printing

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

void loop() {
  // rawValue = analogRead(A0); // dummy read, if needed
  rawValue = analogRead(A0); // read pot
  if (rawValue < (oldValue - 2) || rawValue > (oldValue + 2)) { // add some deadband
    oldValue = rawValue; // update value
    Byte = oldValue >> 2; // convert 10-bit to 8-bit
    if (oldByte != Byte) { // only print if value changes
      Serial.print("Byte is: ");
      Serial.println(Byte);
      oldByte = Byte; // update value
    }
  }
}

Edit:
I also wrote a 0-100% (101 values) version.

I need this for 12 bit res, for the digital encoder the readings are stable, but when analog in is on ±1,2 variations appearing
This is the part:

#include <Encoder.h>
Encoder enc2(3, 4);

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

void loop(){
float frqA;
const int threshold = 200; //
int analogValue = analogRead(A0);
 
if (analogValue > threshold) {
  frqA = map(analogRead(A0), 0, 4095, 0, 4092);
  } 
  else 
  {
  int val1 = enc2.read(); //freqA of Wavetable **0 -> 2^32
  if(val1 <= 0) { // constrain for below 0
  enc2.write(0); // constrain the encoder object
  }
     else if(val1 >= 1000){
     enc2.write(1000); 
     }
     frqA = constrain(val1,0.1,1000.00)*4.092; // (=1x..hz..) 
  }

  Serial.print(" freqA:");
  Serial.print(frqA);
}

What do you think?

vincentiu:
What do you think?

I think two things after reading that message:

  1. for 12-bit you need an external ADC as the Arduino's ADC offers only 10 bits resolution (the ATmega processor based ones, that is - some more exotic flavours of Arduino may offer 12-bit or higher resolution).
  2. that code's indentation is such a mess I can't read it easily. Please fix that first, it's a simple button press (ctrl-T).

4093 stable values from a common analogue pot?
Sounds like a challenge.
Leo..

wvmarle:
I think two things after reading that message:

  1. for 12-bit you need an external ADC as the Arduino's ADC offers only 10 bits resolution (the ATmega processor based ones, that is - some more exotic flavours of Arduino may offer 12-bit or higher resolution).
  2. that code's indentation is such a mess I can't read it easily. Please fix that first, it's a simple button press (ctrl-T).
  1. It's tennsy 3.2 so it has this resolution
  2. now it's better?

Wawa:
4093 stable values from a common analogue pot?
Sounds like a challenge.
Leo..

it can be higher then this, you recommend even numbers, right?

vincentiu:

  1. It's tennsy 3.2 so it has this resolution

Why didn't you tell it's a Teensy before?

  1. now it's better?

I think you forgot to post your updated code.

it can be higher then this, you recommend even numbers, right?

We normally recommend powers of 2 as that's how computers work, so 4092.
But 4092 distinct values from a regular pot? Not much chance to get that perfectly stable. Vibrations from you touching the table may be enough to jump a few points up and down. The higher the resolution of your ADC, the more noise you will see.

wvmarle:
We normally recommend powers of 2 as that's how computers work, so 4092.

How is this 4092 more connected to powers of two than 4093?

Because computers are better at numbers than I am.

Make that 4096 then.

But :astonished: OP asked for this

frqA = map(analogRead(A0), 0, 4095, 0, 4092);

Leo..

That is just too weird a request so it must have popped right out of the realm of possibilities of "what an OP could actually want" making me completely miss the whole request.

I'm sure the double dead of A0 doesn't help

int analogValue = analogRead(A0);  // <=========== First read
if (analogValue > threshold) {
  frqA = map(analogRead(A0), 0, 4095, 0, 4092); // <=========== Second read
  } 
  else

@OP: I suggest you change
frqA = map(analogRead(A0), 0, 4095, 0, 4092);

to

frqA = map(analogValue, 0, 4095, 0, 4092);

for two reasons:

  1. analogRead is slow and blocking. So it is best to minimize their use.
  2. the value may change on a second read. The original premise of the thread was questioning analog read stibility