Any way to make resistor ladder more consistent?

I've tried different pushbuttons and different resistor values but I still get bad readings about 1-5% of the time. By bad readings I mean I press button 1 and it registers as button 2. I am debouncing the input. Any tips? I've been searching resistor ladders and multiple pins on analog pin. I can't get a mega and use individual pins for each button, I need this going over two wires.

Boy I hate fritzing drawings, poor substitute for a proper schematic drawing which is the best universal language for electrical circuits, and forces me to ask several questions.

I don't see a positive voltage source wired to the resistor ladder, just a ground wire and a wire for the input to analog pin A2? You stated (indirectly) that it works properly 95-99% of the time, but I don't think that is possible if you wired it actually as you drew it? The divider network will have to use three wires, +5vdc voltage source, ground, analog input pin to function properly.

You say you are 'debouncing' the input, but that term is more proper used with digital input pins, not analog input pins. I would have to see your sketch code to see if you are using an effective means to read the analog value.

If you are using the internal pullup resistor, I don't know how stable that is with respect to time and temperature.

What is the tolerance of your resistors? How are you compensating for that?

Send the values read on the analog input to the serial port and monitor it on your computer. Are the numbers stable when you press a button, or jumping around? Are they the numbers you expect?

retrolefty:
Boy I hate fritzing drawings, poor substitute for a proper schematic drawing which is the best universal language for electrical circuits, and forces me to ask several questions.

I don't see a positive voltage source wired to the resistor ladder, just a ground wire and a wire for the input to analog pin A2? You stated (indirectly) that it works properly 95-99% of the time, but I don't think that is possible if you wired it actually as you drew it?

You say you are 'debouncing' the input, but that term is more proper used with digital input pins, not analog input pins. I would have to see your sketch code to see if you are using an effective means to read the analog value.

It's wired as I drew it.

I'm using analogRead:

  int in=analogRead(2);
 
  if ((millis() - last) > btn_delay) {
   if (in>37 && in<43){
     if (buttonState==0){
       buttonState=1;
	   // blah
     }
   }
  } 
  // 7 other else-if statements
  
  else if (in>300 && buttonState){
    buttonState=0;
    last = millis();
  }

There really isn't much to it.

polymorph:
If you are using the internal pullup resistor, I don't know how stable that is with respect to time and temperature.

What is the tolerance of your resistors? How are you compensating for that?

Send the values read on the analog input to the serial port and monitor it on your computer. Are the numbers stable when you press a button, or jumping around? Are they the numbers you expect?

Yes I'm the using internal pullup resistor.

1%. Compensating by reading a ton of presses and seeing what the expected range should be.

Yes I'm using the monitor... that's how I'm seeing an incorrect button press being registered 1 to 5% of the time.

Again you need a +5vdc voltage source to drive the divider network. The 40K+ ohm internal pull-up is much too high a value for stable analog input readings.

You are using the serial monitor to see which button is registering, but what about the raw analogRead value?

With 8k out of a total of about 50k, you are only getting about 1V with no button pressed, correct? If you set it to use the internal 1.1V reference, it'll be more stable and you'll be using more of the resolution of the ADC. In any case, there should be a 0.1uF capacitor from Aref to ground, and from AVcc to ground.

Does the internal pullup even work on an analog input pin?

Yes

I also think the internal pullup is too "weak" (high resistance) for this use, plus you can only measure it indirectly.

I suggest using a known external pullup resistor, and try to make the total resistance of your ladder, including the pullup, no more than about 10~20K in total between +5V and GND. The ADC input needs a small but significant current flow to give a good reading.

If it is still noisy, I suggest adding a 0.1uF cap between the ADC pin and GND.

Paul

You can't use the internal pull-up resistors as they have extremely poorly
characterized values (they are not linear for instance). You must use
an external pull-up and disable the internals.

The internal pull-ups are guaranteed to be somewhere between 20k and 50k.
You cannot assume anything else - they are actually special FETs sized to have
a channel resistance of approximately the right value, hence are non-linear
and supply-voltage sensitive.

An actual resistor on a chip is a large unwieldy structure wasting lots of chip
area, and modern VLSI chip designers avoid them like the plague outside of precision
analog and RF design.

It's wired as I drew it.

Then it won't work reliably, ditch the internal resistor and use an external one. You can't have a reliable system with unknown variables.


Rob