6 buttons on (A0)

Hi

Next question:

With a ladder of resistors between 0 and 5 volt I got a nice, almost fixed, value with analogRead(A0).
With this value I want to make a 6 button array.
The attached PGN shows 4, but I have resistors in serial.

The values are 0, 171, 341, 512, 682 and 852

If 1 push for a short time a button say nr 1, i has to write digital 4 output high and stay high even when button is released.

If I press an other button say nr 2, it has to write to digital 4 output to low and digital 5 output to high.
This wil be for all attachted buttons (4 in this case)

I tried to make a loop with if , else, but no luck.

I Googled a lot but didn't find the way how to.

Any hint?

Peter

button.png

Please post your full sketch. If possible you should always post code directly in the forum thread as text using code tags (</> button on the toolbar). This will make it easy for anyone to look at it, which will increase the likelihood of you getting help. If the sketch is longer than the forum will allow then it's ok to add it as an attachment. Don't put your code in some external file service like dropbox, etc. We shouldn't need to go to an external website just to help you. I do feel it's reasonable to post a link to code hosted on GitHub or similar code hosting sites since that's an platform specifically designed for this sort of thing

Please always do a Tools > Auto Format on your code before posting it. This will make it easier for you to spot bugs and make it easier for us to read. If you're using the Arduino Web Editor then you will not have access to this useful tool. I recommend using the standard Arduino IDE instead.

When your code requires a library that's not included with the Arduino IDE please post a link(using the chain links icon on the toolbar to make it clickable) to where you downloaded that library from or if you installed it using Library Manger(Sketch > Include Library > Manage Libraries) then say so and state the full name of the library.

The standard way ( >40 years) to do this is with a R-2R ladder.

see Resistor ladder - Wikipedia.

It allows you to detect any combination of buttons.

You don't need to do any sums for this - just look at the bits of the a/d result.

How you then use this info to do other things is problem B

I'd use 1% resistors. Or you can buy accurate R-2R resistor networks quite cheaply.

Allan

Do you need to press 2 or more buttons at any one time and expect the system to determine which combination of buttons was pressed ? Or are you expecting only a single button to be pressed any any one time ? The first case requires much more care with the selection of resistor values.

In the loop(), print the value of analogRead( A0 ) to the serial console, and see what values you see when you press the buttons.

Use the StateChange example as a starting point. (I think it's under 01Digital.) That will show you how to detect when a button is first pressed.

It uses a digital input. It seems like you already know enough to read the analog input to determine which button IS pressed.

allanhurst:
The standard way ( >40 years) to do this is with a R-2R ladder.

see Resistor ladder - Wikipedia.

It allows you to detect any combination of buttons.

You don't need to do any sums for this - just look at the bits of the a/d result.

How you then use this info to do other things is problem B

I'd use 1% resistors. Or you can buy accurate R-2R resistor networks quite cheaply.

Allan

Hi Allen

The value's of readAnalogA0 are 0, 171, 341, 512, 682 and 852.
Using 6 resistors of 500 Ohm in serie between 0 and 5V + a pull up 100K to the +

Perhaps I wasn't clear :slight_smile:

Its as you called, problem B.
Don't know how to start :slight_smile:

The buttons are only pressed once and just one at the time.

Peter

A general structure like the enclosed might do the trick.

int test_vals [] = {0, 171, 341, 512, 682 , 852, 1023};
int but_val;
byte but_no, i;
int but_pin = A0;



void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:

  but_val = analogRead(but_pin);
  but_val = 0;
  for (i = 0; i < sizeof(test_vals) - 1; i++) {
    if ((but_val >= test_vals[i]) && ( but_val <= test_vals[i + 1])) {
      but_no = i;
    }
  }
  switch (but_no) {
    case : 0 {
      }
      break;
    case : 1 {
      }
      break;
    case : 2 {
      }
      break;
    case : 3 {
      }
      break;
    case : 4 {
      }
      break;
    case : 5 {
      }
      break;

    default :  {
      }
      break;
  }

}

Allan

Hi Allen

Will try this and looks good.

Just a typo:
Change => case : 1 { ===> to case 1 : {

What will be the tolerance in the analogRead value before its open a next case (button selection?)

Thanks!

Peter

It would be better to split the test vals evenly about the actual measurements - like this

int comp_vals [] = {0,   171, 341, 512, 682 , 852, 1023};
int test_vals [] = {0, 85, 235, 426, 587 ,777 , 937 , 1023};

This allows quite large (+/- >50) errors in the measurement.

Allan

allanhurst:
The standard way ( >40 years) to do this is with a R-2R ladder.

see Resistor ladder - Wikipedia.

It allows you to detect any combination of buttons.

You don't need to do any sums for this - just look at the bits of the a/d result.

How you then use this info to do other things is problem B

I'd use 1% resistors. Or you can buy accurate R-2R resistor networks quite cheaply.

Allan

Hi,
It seems that the OP just wants to use the analog input to detect one in between six buttons. May be the method is not the most elegant, but it should work (for low distances and not many buttons, at least).
The R-2R ladder you mention is to convert a binary number to an analog value; for the problem the OP poses, it gives exactly the same output that he/she has up to now (one button pressed at a time).
The OP is having trouble with the code, no with the hardware; let he/she solve the software problem in peace ...
Regards.

Isn't it easier with map and switch case.
Untested example for 6 buttons and 7 resistors plus a 1Meg bleed resistor.
Leo..

const byte ladder = A0;
byte threshold = 10;
int rawValue;
byte buttonNumber;

void setup() {
}

void loop() {
  if (analogRead(ladder) > threshold) { // if a button is pressed
    delay(50); // wait for bounce ?
    rawValue = analogRead(ladder); // read
    buttonNumber = map(rawValue, 0, 1023, 0, 7);
    // 'all reset' could go here
    switch (buttonNumber) {
      case 0:
        // do someting with the first button
        break;
      case 1:
        // second button thing
        break;
      case 2:
        // etc
        break;
    }
  }
}

Hi Leo,

Your part of code works.

How can I add a default start up status?
E.g. like button 1 is activated by default and its code at case 1:

Peter

Put whatever was in case 1 into a function by itself. Now you can call that function from setup() too.

If there is a default action which must continue while looping then there must be some variable which remembers that action is ongoing. Set that variable in its opening declaration or in setup()

bool blinkTheLED = true;

void loop(){
  if(blinkTheLED) {
    ....

dummyload:
The buttons are only pressed once and just one at the time.

Unless you have some system in place to make it physically impossible to press more than one at a time, or the same one again, your code must allow for this to happen, so you must have a way to detect this (and then gracefully ignore it - an improperly chosen resistor ladder can cause things like 2+3 to look like just 1).