How to use dual function on Single push button of keypad

Hello, There !

In one of the my project, I am trying to use dual function ("+" and “-”) with single (+) button of 3x4 matrix keypad using Arduino Mega-2560 and print on LCD. Currently while combine the two codes of matrix keypad and dual function, unable to get correct results. can anyone suggest which changes required.

Dual function code

#include <LiquidCrystal.h>
#define sw 32 //5
#define GND 26 

bool buttonState ; 
byte tapCounter; 
bool flag1, flag2; 

LiquidCrystal lcd (38,37,36,35,34,33); 

void setup() 
{
  lcd.begin(16,2);
  pinMode(GND, OUTPUT); 
  pinMode(sw, INPUT_PULLUP); 
  lcd.setCursor(0,0); 
  lcd.print ("+"); 
}

void loop() {
  digitalWrite (GND, LOW);       
  int buttonState = digitalRead(sw);

  if (buttonState == 0 )   //when switch is pressed
  {
    tapCounter++; 
  }
  
    if (tapCounter == 1) 
    {
        lcd.clear();
        lcd.print ("-");
        tapCounter = tapCounter+1;    
    }
    
    else if (tapCounter == 3 ) 
    {
        lcd.clear();
        lcd.print ("+");
        tapCounter = 0; 
    }
}

Matrix Keypad code

#include <Keypad.h>
#include <LiquidCrystal.h>
#include <EEPROM.h>

const int ROW_NUM = 7; 
const int COLUMN_NUM = 3; 

char keys[ROW_NUM][COLUMN_NUM] = {
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'.', '0', '+'},
  {'E', 'N', 'T'}, //Enter button function
  {'B', 'A', 'C'}, //Back button function
  //{'.', 'P', 'P'}  //DP button function
};

byte pin_rows[ROW_NUM] = {29,30,31,32,43,44}; //,42  
byte pin_column[COLUMN_NUM] = {26,27,28}; 

LiquidCrystal lcd(38,37,36,35,34,33);
Keypad keypad = Keypad( makeKeymap(keys), pin_rows, pin_column, ROW_NUM, COLUMN_NUM );

String inputString;
float inputInt;
float data;
const int COUNT_ADDR = 0;

 /////
 bool buttonState ; 
byte tapCounter; 
bool flag1, flag2; 

void setup() {
  lcd.begin(16, 4);
  inputString.reserve(8); // maximum number of digit for a number is 10, change if needed
  
  EEPROM.get (COUNT_ADDR, data);
  lcd.setCursor(0,2);  //// EEPROM              
  lcd.print(data,4);
  lcd.setCursor(0,0); 
}

void loop() {
  char key = keypad.getKey(); 
  if (key) {
    lcd.print(key);
      inputString += key;               

  if (key == 'E') //digitalRead(43)== LOW
    {
      if (inputString.length() > 0) 
      {
        inputInt = inputString.toFloat(); 
        data = EEPROM.put(COUNT_ADDR, inputInt);
        inputString = "";
        lcd.setCursor(0,1);  //// Data In Variable               
        lcd.print(inputInt);
        lcd.setCursor(0,2);  //// EEPROM              
        lcd.print(data);
      }
    }
    
    else if (key == 'B') //digitalRead(44)== LOW //Clear function
    {
      lcd.setCursor(0,0);
      lcd.print("              ");
      lcd.setCursor(0,1);
      lcd.print("              "); //inputString line is only clear
      lcd.setCursor(0,0);
      inputString = "";           // clear input
    }

    else if (key == '+')
    {
     //digitalWrite (26, LOW);       
     int buttonState = digitalRead('+');
       if (buttonState == 0)   //when switch is pressed
          {
            tapCounter++; 
          }
       if (tapCounter == 1) 
          {lcd.clear();
           lcd.setCursor(0,0);
           lcd.print ("-");
           tapCounter = tapCounter+1;    
          } 
       else if (tapCounter == 3 ) 
          {lcd.clear();
           lcd.setCursor(0,0);
           lcd.print ("+");
           tapCounter = 0; 
          }
    }
  }
}

if (buttonState == 0 ) //when switch is pressed

the above code recognizes that the button is active, being held down, resulting in any action being repeated quickly, msecs.

presumably you want to recognize the transition from not active to active with some small delay (~10msec) to ignore contact bounce

consider

enum { Off = HIGH, On = LOW };

void
loop ()
{
    static byte butState = Off;
           byte but      = digitalRead (Button);

    if (butState != but)  {
        butState = but;

        if (On == but) 
            digitalWrite (LED, ! digitalRead (LED));

        delay (10);     // debounce
    }
}

That makes no sense. ‘+’ is not a pin number. You KNOW that the ‘+’ key has been pressed so there is no need to check a pin. Just go straight to incrementing the tapCounter.

Yes it can not work , i did many changes in code one of it i shared. do you have any idea to do dual function? or any reference link.

Did you do what I told you to do?!?

    else if (key == '+')
    {
     //digitalWrite (26, LOW);       
      tapCounter++; 

If I understand correctly do you mean something like, ‘short press’ = + and 'long press = - ’ ?

Based on the original code, they want to alternate between ‘+’ and ‘-’ on the single keypad key.

Aah.

Hi,
@design wants the + to be +/-

Tom… :grinning: :+1: :coffee: :australia:

@dougp yes, i want to do that

I am sure I do not understand.

This

@design wants the + to be +/-

(Nice, @TomGeorge !)

seems to recall the “change sign” button on a better calculator. As such, it is just a key to be handled like any other key.

The OP (original post in this case) seems to want one press for one function and a double press for another? That’s the only sense I can make of counting anything, tapCounter.

But there is nothing in the logic to listen and react that way. Also tapCount is only examined for 1 and 3, is that a typo?

And @design has agreed to the latest, which is yet ambiguous.

@design : use some more words or whatever and give a clear and concise description of the desired behavior. Perhaps knowing the context in which this experiment will be exploited would be useful.

I’m reminiscing about watching Al Gore explaining George Bush’s tax policy to George Bush. Sigh.

a7

tapCounter is initialized to 0. When the button is pressed, tapCounter is incremented. If tapCounter ==1 the character is displayed as ‘-’ and tapCounter is incremented to 2. If tapCounter == 3 the character is displayed as ‘+’ and tapCounter is set back to 0.

The result is that the button press alternately displays ‘-’ and ‘+’.

THX.

I didn’t notice yet any timing constraint, so I remain thinking that it’s just a button, every press means something in a current context and I guess this is just an ad-hoc local state machine kinda thing.

I also did not appreciate @johnwasser’s fix, which results in the desired behaviour.

I would have just rolled this “change sign” into the larger mechanism that is handling the buttons. As of now, there is no larger mechanism, presumably the OP was helping by providing a small program.

But clearly there will be a key stroke handler at some point, which should centralize all key handling w/o little helpers scattered about, some of which may take more than a moment (and caffeine, sry too early!) to understand.

I still find the OP’s statements to be ambiguous. I’ll try again later when, well, you know.

a7

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