Capacitor to keep analog input from floating?

My analog inputs are floating around. They float around about 2% (a floating value of 5 of 255) Could soldering in a cap on each input help? See attached PDF of schematic. The photo shows the board as built, without the capacitors.

Garage Parking Light Pro Mini.pdf (83.2 KB)

//***********************************************************************

//DEFINE I/O TAGS AND PINS
const int trigPin=PIN5;
const int echoPin=PIN6;
const int stopLight=PIN2;
const int driveLight_1=PIN3;
const int driveLight_2=PIN4;
const int DL_1_Low_Pot=A0;
const int DL_1_High_Pot=A1;
const int DL_2_Low_Pot=A2;
const int DL_2_High_Pot=A3;
const int stopLight_Pot=A6;

//***********************************************************************

//SET INTERNAL TAGS AND VALUES
float duration, distance;
int stopSetPoint = 0; //stop light on less than this distance
int driveLight_2_LOW = 0; //drive light 2 on greater than this distance
int driveLight_2_HIGH = 0; //drive light 2 on less than this distance
int driveLight_1_LOW = 0; //drive light 1 on greater than this distance
int driveLight_1_HIGH = 0; //drive light 1 on less than this distance
int driveLight_1_lowValue = 0; //placeholder value for analog input
int driveLight_1_highValue = 0; //placeholder value for analog input
int driveLight_2_lowValue = 0; //placeholder value for analog input
int driveLight_2_highValue = 0; //placeholder value for analog input
int stopLight_Value = 0; //placeholder value for analog input

//***********************************************************************

//LCD SETUP
#define OLED_RESET  15  // Pin 15 -RESET digital signal
ArducamSSD1306 display(OLED_RESET); // FOR I2C

//***********************************************************************

//FUNTIONS SETUP
void callUltraSonic(int num);
void callStopLight(int num);
void calldriveLight_1(int num);
void calldriveLight_2(int num);
void call_analogValueScans(int num);
void call_OLED_Print(int num);
  

//***********************************************************************

void setup() {
  Serial.begin (9600);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(stopLight, OUTPUT);
  pinMode(driveLight_1, OUTPUT);
  pinMode(driveLight_2, OUTPUT);

  // initialize OLED with I2C addr 0x3C
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  Wire.begin();

}
//***********************************************************************
void loop() {
callUltraSonic(1);
callStopLight(2);
calldriveLight_1(3);
calldriveLight_2(4);
call_analogValueScans(5);
call_OLED_Print(6);
}

//***********************************************************************
void callUltraSonic(int num) {
 // Write a pulse to the HC-SR04 Trigger Pin
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  // Measure the response from the HC-SR04 Echo Pin
  duration = pulseIn(echoPin, HIGH);
  // Determine distance from duration
  // Use 343 metres per second as speed of sound
  distance = (duration / 2) * 0.0343;
  // Serial Print "out of range"
  Serial.print("Distance = ");
  if (distance >= 400 || distance <= 2){
      Serial.println("Out of range");
      }
// Serial Print "distance in cm"
  else {
    Serial.print(distance);
    Serial.println(" cm");
    delay(100);
    } 
}
//***********************************************************************
void callStopLight(int num) {
//Serial Print "STOP"
//Turn stop light on HIGH if less than setpoint
//Else turn stop light off LOW
  if (distance < stopSetPoint){
    digitalWrite(stopLight, HIGH);
    Serial.print(" STOP ");
    } 
    else {
      digitalWrite(stopLight, LOW);
    }
}
//***********************************************************************
void calldriveLight_1(int num){
  if (distance > driveLight_1_LOW && distance < driveLight_1_HIGH) {
      digitalWrite(driveLight_1, HIGH);
  }
  else {
    digitalWrite(driveLight_1, LOW);
  }
}
//***********************************************************************
void calldriveLight_2(int num){
  if (distance > driveLight_2_LOW && distance < driveLight_2_HIGH) {
      digitalWrite(driveLight_2, HIGH);
  }
  else {
    digitalWrite(driveLight_2, LOW);
  }
}
//***********************************************************************
void call_analogValueScans(int num){
  //*******
  //DRIVE LIGHT 1 LOW VALUE FROM POT
  driveLight_1_lowValue = analogRead(DL_1_Low_Pot);
  driveLight_1_LOW = map(driveLight_1_lowValue, 0, 1023, 0, 255);
  Serial.print("DL1Low = ");
  Serial.print(driveLight_1_LOW);
  //*******
  //DRIVE LIGHT 1 HIGH VALUE FROM POT
  driveLight_1_highValue = analogRead(DL_1_High_Pot);
  driveLight_1_HIGH = map(driveLight_1_highValue, 0, 1023, 0, 255);
  Serial.print("DL1High = ");
  Serial.print(driveLight_1_HIGH);
  //******
  //DRIVE LIGHT 2 LOW VALUE FROM POT
  driveLight_2_lowValue = analogRead(DL_2_Low_Pot);
  driveLight_2_LOW = map(driveLight_2_lowValue, 0, 1023, 0, 255);
  Serial.print("DL2Low = ");
  Serial.print(driveLight_2_LOW);
  //******
  //DRIVE LIGHT 2 HIGH VALUE FROM POT
  driveLight_2_highValue = analogRead(DL_2_High_Pot);
  driveLight_2_HIGH = map(driveLight_2_highValue, 0, 1023, 0, 255);
  Serial.print("DL2High = ");
  Serial.print(driveLight_2_HIGH);
  //******
  //STOP LIGHT VALUE FROM POT
  stopLight_Value = analogRead(stopLight_Pot);
  stopSetPoint = map(stopLight_Value, 0, 1023, 0, 255);
  Serial.print("StopLight = ");
  Serial.print(stopSetPoint);
}
//***********************************************************************
//OLED DISPLAY
void call_OLED_Print(int num){

  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  //Drive Light 1 Low/High 
    display.setCursor(0,3);
  display.print("DL1L = ");
  display.print(driveLight_1_LOW);
    display.setCursor(67,3);
  display.print("DL1H = ");
  display.print(driveLight_1_HIGH);
  //Drive Light 2 Low/High
    display.setCursor(0,20);
  display.print("DL2L = ");
  display.print(driveLight_2_LOW);
    display.setCursor(67,20);
  display.print("DL2H = ");
  display.print(driveLight_2_HIGH);
  //Stop Setpoint
    display.setCursor(0,40);
  display.print("STOP = ");
  display.print(stopSetPoint);
  display.display();
  //Live Sensor Read
    display.setCursor(0,50);
  display.print("LIVE = ");
  display.print(distance);
  display.display();
}

Schematics should have component values.

The ADC requires the source impedance to be less than 10K Ohms. If it is higher than that, a 10 to 100 nF cap from the analog input to ground can help with the resultant noise.

Noted.

The pots are 10K. So an output value of 10 (would be 10cm of 255cm) the impedance would be quite low - if I understand this correctly.

I can try and squeeze some caps in there if I don't have any other clues. I'm not sure what else to try.

keep signal wires short and twisted with GND wire. capacitor of 0.1µF is additional help. especially when wiper is worn out. but even then value variing ±1.

1 Like

Good choice. The ADC value should not be "floating", if connections are good, although some small variation is expected.

Note: after switching between ADC channels, many people find it helpful to make two successive readings, discarding the first.

1 Like

Then also a cap over the entire pot can help against noise on the Vcc connection.

I put an oscilloscope on an analog input pin at X10 to find a pk-pk of 1.56mv. Each step of the ADC is 4.8mv (I think), so the noise from the VCC rail shouldn't be the issue (...I think).

While outputting the raw data to an LCD, it floats around a lot, but I feel it should be stable. I found a piece of code that can smooth the data by averaging, I just don't understand why it needs it.

X10 = 15.6mV, see your screenshot. That's about 3 ADC steps. Or 30 if you did not set the scope to scale for the X10 probe.

The probe was set to X10. That makes the 15.6mV, 1.56mV?

In X10 mode the probe divides the voltage by 10. You have to tell the scope about that setting or multiply the shown X1 values by 10.

Check whether the Vcc 5V are shown as 5V or 0.5V DC by your scope.

Ok. I'll tinker some more with it. If the pk-pk really is 15.6mV, that explains everything.

Do your pots actually go to zero at the end of their movement? Not all do. Check with a meter.

"requires" is a bit strong. The datasheet says (section 29.3.2.4.3):

Since the Arduino Every does not operate at the full speed possible, and the ADC is initialized to run at about 1/10th of its maximum documented clock rate, I suspect that you can get away with source impedances much greater than 10k.

(IIRC, It's PICs that have a stronger 10k requirement.)

If your potentiometers are powered with the 5V from the DC/DC converters and your Arduino board uses its own 5V as reference, then you have a design flaw.

Search for the word "ratiometric".

Treat the potentiometers as sensitive sensors.
Use a GND wire from the Arduino board for the potentiometers. Do not connect that to anything else. Not even to power a led.
Use a 5V wire from the Arduino board for the potentiometers. Do not connect that to anything else.
If you add 100nF capacitors to the analog signals, then use that same GND wire from the Arduino board that is used for the potentiometers. Do not use an other GND.
You don't have to add the 100nF capacitors, taking the average of a number of samples in software will do almost the same.
You can also add a low-pass filter in software.

Do you have a flat ribbon connector with SDA next to SCL ? That's not good. How long is that cable ? It should be less than 10 cm.

Typical 0.1" ribbon cable connectors have two rows, with the second row usable to separate the first row signals by GND lanes.

2% fluctuation of ADC readings seems reasonable. A significant proportion of this could be as in this similar problem here.

VCC comes from the output of a buck converter and is connected to the analog voltage supply pin (AVDD) of the Nano Every's ATmega4809 without any special consideration for noise (filtering).

For comparison, the ATmega4809 Curiosity Nano uses an LC filter connected to AVDD.

I’m curious, is it me or…

In the photos it looks like there’s no connection to the 5th pin. In the sketch A1 is used.

This is aside from the noise problem that haunts the 4809.

1 Like

Well spotted :eye: You are right.
Pin A1 is not connected to one of the potentiometer.
The analog pins for the potentiometers (from right to left) are: A0, A2, A3, A6, A7.

I would put them in an array:

const int potPins[] = { A0, A2, A3, A6, A7 };

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.