[Solved] Calculating values for AnalogButton

Hi, I want to know how to calculate the values for an AnalogButton keypad, I did a search, but I dont found anything about how to calculate this, I copied an already maked circuit, but I added two buttons because I need them, and this is what I have:

BUTTONS        VALUES     RESISTORS
btn 1          837-838    220
btn 2          737-738    390
btn 3          610-611    680
btn 4          ???-???    1.0K
btn 5          ???-???    1.5K
btn 6          318-319    2.2k
btn 7          178-179    4.7k
btn 8          91-92      10k

The circuit:

The Circuit:
 
         Analog pin 5
            |
Ground--1K--|--------|--------|-------|-------|-------|-------|-------|
            |        |        |       |       |       |       |       |
           btn1     btn2     btn3    btn4    btn5    btn6    btn7    btn8
            |        |        |       |       |       |       |       |
         220 Ohm  390 Ohm  680 Ohm   1.0K    1.5K    2.2K    4.7K    10K
            |--------|--------|-------|-------|-------|-------|-------|-- +5V

the code will be this

int j = 1; // integer used in scanning the array designating column number
//2-dimensional array for asigning the buttons and there high and low values
int Button[8][3] = {{1, 837, 838}, // button 1
                     {2, 737, 738}, // button 2
                     {3, 610, 611}, // button 3
                     {4, ??, ??}, // button 4
                     {5, ??, ??}, // button 5
                     {6, 318, 319}, // button 6
                     {7, 178, 179}, // button 7
                     {8, 91, 92}, // button 8

int analogpin = 5; // analog pin to read the buttons
int label = 0;  // for reporting the button label
int counter = 0; // how many times we have seen new value
long time = 0;  // the last time the output pin was sampled
int debounce_count = 50; // number of millis/samples to consider before declaring a debounced input
int current_state = 0;  // the debounced input value
int ButtonVal;

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

}

void loop()
{
   // If we have gone on to the next millisecond
  if (millis() != time)
  {
    // check analog pin for the button value and save it to ButtonVal
    ButtonVal = analogRead(analogpin);
    if(ButtonVal == current_state && counter >0)
    { 
      counter--;
    }
    if(ButtonVal != current_state)
    {
      counter++;
    }
    // If ButtonVal has shown the same value for long enough let's switch it
    if (counter >= debounce_count)
    {
      counter = 0;
      current_state = ButtonVal;
      //Checks which button or button combo has been pressed
      if (ButtonVal > 0)
      {
        ButtonCheck();
      }
    }
    time = millis();
  }
}

void ButtonCheck()
{
  // loop for scanning the button array.
  for(int i = 0; i <= 8; i++)
  {
    // checks the ButtonVal against the high and low vales in the array
    if(ButtonVal >= Button[i][j] && ButtonVal <= Button[i][j+1])
    {
      // stores the button number to a variable
      label = Button[i][0];
      Action();      
    }
  }
}

void Action()
{
  if(label == 1)
  {
    Serial.println("Button 1");
  }
  if(label == 2)
  {
    Serial.println("Button 2");
  }
  if(label == 3)
  { 
    Serial.println("Button 3");
  }
  if(label == 4)
  {
    Serial.println("Button 4");
  }
  if(label == 5)
  {
    Serial.println("Button 5");
  }
  if(label == 6)
  {
    Serial.println("Button 6");
  }
  if(label == 7)
  {
    Serial.println("Button 7");
  }
  if(label == 8)
  {
    Serial.println("Button 8");
  }
       
  //Serial.println("Button =:");
  //Serial.println(label);
  //delay(200);
  
  
}

But I need a total of 16 buttons, so duplicating this will be suficient right? I need to duplicate identifiers, like ‘‘j’’ to ‘‘k’’? And the AnalogPin to use ofcourse.

Im sorry if that questions are a bit noob, is the first time I do programming …

I want to know how to calculate the values for an AnalogButton keypad

You don't, normally. You build the circuit, and then use analogRead() to read the values when each switch is pressed. Use the average value that analogRead() reports.

so duplicating this will be suficient right? I need to duplicate identifiers, like ''j'' to ''k''? And the AnalogPin to use ofcourse.

Duplicating what? The code that determines which switch is pressed only needs to know the pin number. That same array (and all the indexes) can be used regardless of which analog pin is used. Or how many analog pins are used.

Thanks you Paul!

ok, so for the 2 circuits with 8 switch button each, having the 16 button, will work with this loop? (to know What I have to do twice)

void loop()
{
   // If we have gone on to the next millisecond
  if (millis() != time)
  {
    // check analog pin for the button value and save it
    ButtonA = analogRead(analogpin4);
    ButtonB = analogRead(analogpin5);
    if(ButtonA == current_state && counter >0)
    { 
      counter--;
    }
    if(ButtonB == current_state && counter >0)
    { 
      counter--;
    }
    if(ButtonA != current_state)
    {
      counter++;
    }
    if(ButtonB != current_state)
    {
      counter++;
    }
    // If ButtonX has shown the same value for long enough let's switch it
    if (counter >= debounce_count)
    {
      counter = 0;
      current_state = ButtonA;
      current_state = ButtonB;
      //Checks which button has been pressed
      if (ButtonA > 0)
      {
        ButtonCheck();
      }
      if (ButtonB > 0)
      {
        ButtonCheck();
      }
    }
    time = millis();
  }
}

here a small sketch that calculates the values. As the resistors are not exact the results may vary.

int R[] = { 
  220, 390, 680, 1000, 1500, 2200, 4700, 10000 };  // your resistors

void setup()
{
  Serial.begin(115200);
  Serial.println("start");

  Serial.println("R\tRtot\tVolt\tAnalog");

  for (int i=0; i< 8; i++)
  {
    long Rtotal = 1000 + R[i];
    float Voltage = (5.0 * 1000)/Rtotal;  // voltage in the middle
    long ana = Voltage * 1023/5;            // converted to analogRead

    Serial.print(R[i]);
    Serial.print("\t");
    Serial.print(Rtotal);
    Serial.print("\t");
    Serial.print(Voltage,2);
    Serial.print("\t");
    Serial.println(ana);
  }
}

void loop()
{}

ok, so for the 2 circuits with 8 switch button each, having the 16 button, will work with this loop?

No. You need two current_state variables (or an array) and two counter variables (or an array) and two debounce_count variables (or an array).

And, of course, we have no idea what ButtonCheck() does, but it seems likely that it should do the reading of the analog pin and should return which switch was pressed. But, that's just how I'd do it.

@robtillaart
Thanks you, I will do it later to see what it give me :slight_smile: (I have no time now)

@PaulS
So, I have to do the first code twice, with (for example) this: jA, jB, labelA, labelB, current_stateA, current_stateB, etc... ?
Thanks you again for your quick reply.

So, I have to do the first code twice, with (for example) this: jA, jB, labelA, labelB, current_stateA, current_stateB, etc... ?

What you need to do is post all of your code.

thats it, I have no more code, I will make a 16button keypad, nothing more, but I have to do it with no more than 4 wires, having 8 I can make a 4x4 Matrix, but where the keypad is, only a 4wires cable can be, (the 8wires cable is too big)

int j = 1; // integer used in scanning the array designating column number
//2-dimensional array for asigning the buttons and there high and low values
int Button[8][3] = {{1, 837, 838}, // button 1
                     {2, 737, 738}, // button 2
                     {3, 610, 611}, // button 3
                     {4, ??, ??}, // button 4
                     {5, ??, ??}, // button 5
                     {6, 318, 319}, // button 6
                     {7, 178, 179}, // button 7
                     {8, 91, 92}, // button 8

int analogpin = 5; // analog pin to read the buttons
int label = 0;  // for reporting the button label
int counter = 0; // how many times we have seen new value
long time = 0;  // the last time the output pin was sampled
int debounce_count = 50; // number of millis/samples to consider before declaring a debounced input
int current_state = 0;  // the debounced input value
int ButtonVal;

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

}

void loop()
{
   // If we have gone on to the next millisecond
  if (millis() != time)
  {
    // check analog pin for the button value and save it to ButtonVal
    ButtonVal = analogRead(analogpin);
    if(ButtonVal == current_state && counter >0)
    { 
      counter--;
    }
    if(ButtonVal != current_state)
    {
      counter++;
    }
    // If ButtonVal has shown the same value for long enough let's switch it
    if (counter >= debounce_count)
    {
      counter = 0;
      current_state = ButtonVal;
      //Checks which button or button combo has been pressed
      if (ButtonVal > 0)
      {
        ButtonCheck();
      }
    }
    time = millis();
  }
}

void ButtonCheck()
{
  // loop for scanning the button array.
  for(int i = 0; i <= 8; i++)
  {
    // checks the ButtonVal against the high and low vales in the array
    if(ButtonVal >= Button[i][j] && ButtonVal <= Button[i][j+1])
    {
      // stores the button number to a variable
      label = Button[i][0];
      Action();      
    }
  }
}

void Action()
{
  if(label == 1)
  {
    Serial.println("Button 1");
  }
  if(label == 2)
  {
    Serial.println("Button 2");
  }
  if(label == 3)
  { 
    Serial.println("Button 3");
  }
  if(label == 4)
  {
    Serial.println("Button 4");
  }
  if(label == 5)
  {
    Serial.println("Button 5");
  }
  if(label == 6)
  {
    Serial.println("Button 6");
  }
  if(label == 7)
  {
    Serial.println("Button 7");
  }
  if(label == 8)
  {
    Serial.println("Button 8");
  }
       
  //Serial.println("Button =:");
  //Serial.println(label);
  //delay(200);
  
  
}

The CheckButton() function should not be diddling with label. It should, instead, return a value. It should NOT call Action(). The function name implies that it is checking a button. It does not imply that it does anything in response to a switch press.

The CheckButton() function should take an argument - the pin number to read.

The Action() function should take an argument - the switch number that was pressed.

If you make these changes, I think you'll see how to go about using two sets of switches more easily.

I finished my panel button with all connected.
I tested all the buttons with analogread function, and all are working (the 16 buttons), and I changed all values to have the correctly one.

With that code, I have the first 8 buttons working fine

/*
The Circuit:
 
         Analog pin
            |
Ground--1K--|--------|--------|-------|-------|-------|-------|-------|
            |        |        |       |       |       |       |       |
           btn1     btn2     btn3    btn4    btn5    btn6    btn7    btn8
            |        |        |       |       |       |       |       |
         220 Ohm  390 Ohm  680 Ohm   1.0K    1.5K    2.2K    4.7K    10K
            |--------|--------|-------|-------|-------|-------|-------|-- +5V

*/
int j = 1; // integer used in scanning the array designating column number
//2-dimensional array for asigning the buttons and there high and low values
int Button[8][3] = {{1, 837, 842}, // button 1
                     {2, 733, 738}, // button 2
                     {3, 603, 608}, // button 3
                     {4, 508, 513}, // button 4
                     {5, 406, 411}, // button 5
                     {6, 318, 323}, // button 6
                     {7, 175, 180}, // button 7
                     {8, 87, 92}, // button 8
};
int analogpin = 1; // analog pin to read the buttons
int label = 0;  // for reporting the button label
int counter = 0; // how many times we have seen new value
long time = 0;  // the last time the output pin was sampled
int debounce_count = 50; // number of millis/samples to consider before declaring a debounced input
int current_state = 0;  // the debounced input value
int ButtonVal;

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

}

void loop()
{
   // If we have gone on to the next millisecond
  if (millis() != time)
  {
    // check analog pin for the button value and save it to ButtonVal
    ButtonVal = analogRead(analogpin);
    if(ButtonVal == current_state && counter >0)
    { 
      counter--;
    }
    if(ButtonVal != current_state)
    {
      counter++;
    }
    // If ButtonVal has shown the same value for long enough let's switch it
    if (counter >= debounce_count)
    {
      counter = 0;
      current_state = ButtonVal;
      //Checks which button or button combo has been pressed
      if (ButtonVal > 0)
      {
        ButtonCheck();
      }
    }
    time = millis();
  }
}

void ButtonCheck()
{
  // loop for scanning the button array.
  for(int i = 0; i <= 21; i++)
  {
    // checks the ButtonVal against the high and low vales in the array
    if(ButtonVal >= Button[i][j] && ButtonVal <= Button[i][j+1])
    {
      // stores the button number to a variable
      label = Button[i][0];
      Action();      
    }
  }
}

void Action()
{
  if(label == 1)
  {
    Serial.println("Button 1");
  }
  if(label == 2)
  {
    Serial.println("Button 2");
  }
  if(label == 3)
  { 
    Serial.println("Button 3");
  }
  if(label == 4)
  {
    Serial.println("Button 4");
  }
  if(label == 5)
  {
    Serial.println("Button 5");
  }
  if(label == 6)
  {
    Serial.println("Button 6");
  }
  if(label == 7)
  {
    Serial.println("Button 7");
  }
  if(label == 8)
  {
    Serial.println("Button 8");
  }   
       
  //Serial.println("Button =:");
  //Serial.println(label);
  //delay(200);
  
  
}

I cant understand what are you telling me PaulS, about that checkbutton and Action functions, but they are working, why I will change them?
Now I have to do that code twice, with diferent analogpin in order to make the others 8 buttons working.

why I will change them?

Because they are designed to work with one set of switches connected to one specific pin. If that's what you want, then you don't need to change anything. If not, then you do. I don't think that the way they work now IS what you want.

Well, I have the 16 buttons working fine, thats the code I used:

/*
The Circuit:
 
         Analog pin
            |
Ground--1K--|--------|--------|-------|-------|-------|-------|-------|
            |        |        |       |       |       |       |       |
           btn1     btn2     btn3    btn4    btn5    btn6    btn7    btn8
            |        |        |       |       |       |       |       |
         220 Ohm  390 Ohm  680 Ohm   1.0K    1.5K    2.2K    4.7K    10K
            |--------|--------|-------|-------|-------|-------|-------|-- +5V

*/
int j = 1;
int Button[8][3] = {{1, 837, 842}, // button 1
                     {2, 733, 738}, // button 2
                     {3, 603, 608}, // button 3
                     {4, 508, 513}, // button 4
                     {5, 406, 411}, // button 5
                     {6, 318, 323}, // button 6
                     {7, 175, 180}, // button 7
                     {8, 87, 92}, // button 8
};
int analogpin = 1; // analog pin to read the buttons
int label = 0;  // for reporting the button label
int counter = 0; // how many times we have seen new value
long time = 0;  // the last time the output pin was sampled
int debounce_count = 40; // number of millis/samples to consider before declaring a debounced input
int current_state = 0;  // the debounced input value
int ButtonVal;

int jB = 1;
int ButtonB[8][3] = {{1, 837, 842}, // button 1
                     {2, 733, 738}, // button 2
                     {3, 603, 608}, // button 3
                     {4, 508, 513}, // button 4
                     {5, 406, 411}, // button 5
                     {6, 318, 323}, // button 6
                     {7, 175, 180}, // button 7
                     {8, 87, 92}, // button 8
};
int analogpinB = 2; // analog pin to read the buttons
int labelB = 0;  // for reporting the button label
int counterB = 0; // how many times we have seen new value
long timeB = 0;  // the last time the output pin was sampled
int debounce_countB = 40; // number of millis/samples to consider before declaring a debounced input
int current_stateB = 0;  // the debounced input value
int ButtonValB;

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

void loop()
{
  if (millis() != time)
  {
    ButtonVal = analogRead(analogpin);
    if(ButtonVal == current_state && counter >0)
    { 
      counter--;
    }
    if(ButtonVal != current_state)
    {
      counter++;
    }
    if (counter >= debounce_count)
    {
      counter = 0;
      current_state = ButtonVal;
      if (ButtonVal > 0)
      {
        ButtonCheck();
      }
    }
    time = millis();
  }

  if (millis() != timeB)
  {
    ButtonValB = analogRead(analogpinB);
    if(ButtonValB == current_stateB && counterB >0)
    { 
      counterB--;
    }
    if(ButtonValB != current_stateB)
    {
      counterB++;
    }
    if (counterB >= debounce_countB)
    {
      counterB = 0;
      current_stateB = ButtonValB;
      if (ButtonValB > 0)
      {
        ButtonCheckB();
      }
    }
    timeB = millis();
  }

}

void ButtonCheck()
{
  for(int i = 0; i <= 8; i++)
  {
    if(ButtonVal >= Button[i][j] && ButtonVal <= Button[i][j+1])
    {
      label = Button[i][0];
      Action();      
    }
  }
}

void ButtonCheckB()
{
  for(int iB = 0; iB <= 8; iB++)
  {
    if(ButtonValB >= ButtonB[iB][jB] && ButtonValB <= ButtonB[iB][jB+1])
    {
      labelB = ButtonB[iB][0];
      ActionB();      
    }
  }
}

void Action()
{
  if(label == 1)
  {
    Keyboard.press('q');
    delay(25);
  }
  if(label == 2)
  {
    Keyboard.press('w');
    delay(25);
  }
  if(label == 3)
  { 
    Keyboard.press('a');
    delay(25);
  }
  if(label == 4)
  {
    Keyboard.press('s');
    delay(25);
  }
  if(label == 5)
  {
    Keyboard.press('z');
    delay(25);
  }
  if(label == 6)
  {
    Keyboard.press('y');
    delay(25);
  }
  if(label == 7)
  {
    Keyboard.press('e');
    delay(25);
  }
  if(label == 8)
  {
    Keyboard.press('r');
    delay(25);
  }  
  Keyboard.releaseAll();
  delay(25);
}

void ActionB()
{
  if(labelB == 1)
  {
    Keyboard.press('d');
    delay(25);
  }
  if(labelB == 2)
  {
    Keyboard.press('u');
    delay(25);
  }
  if(labelB == 3)
  { 
    Keyboard.press('c');
    delay(25);
  }
  if(labelB == 4)
  {
    Keyboard.press('j');
    delay(25);
  }
  if(labelB == 5)
  {
    Keyboard.press('g');
    delay(25);
  }
  if(labelB == 6)
  {
    Keyboard.press('h');
    delay(25);
  }
  if(labelB == 7)
  {
    Keyboard.press('b');
    delay(25);
  }
  if(labelB == 8)
  {
    Keyboard.press('n');
    delay(25);
  }  
  Keyboard.releaseAll();
  delay(25);
}