One wire keypad error with ESP32 WROOM

// Armuino --- Reading Membrane Keypad to Arduino with a Single Analog Wire  ---
// Video - https://www.youtube.com/watch?v=N39EXI_F8uA

#include "OnewireKeypad.h" // OneWireKeypad Library

char KEYS[] =   // Define keys' values of Keypad
{
	'1', '2', '3', 'A',
	'4', '5', '6', 'B',
	'7', '8', '9', 'C',
	'*', '0', '#', 'D'
};

/* Define Library :
OnewireKeypad <Print, #of buttons>
Keypad(Serial, Char values, #Rows, #Cols, Arduino Pin, Row_resistor, Columns_resistor) */
OnewireKeypad <Print, 16 > Keypad(Serial, KEYS, 4, 4, A0, 4700, 1000);

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

void loop()
{
	Keypad.SetHoldTime(100);  // Key held time in ms
	Keypad.SetDebounceTime(50); // Key Debounce time in ms
  
	if ((Keypad.Key_State() == 3))    // not pressed = 0, pressed = 1, released = 2,  held = 3
	{
		char keypress = Keypad.Getkey();  // put value of key pressed in variable 'keypress'
		// Serial.print("Keypad Key: ");
		Serial.print(keypress);  // Display value on Serial Monitor
		while ((Keypad.Key_State())) {} // Stay here while Key is held down
	}
}

With above code and diagram I tried it with UNO, MEGA and ESP32

It works well with UNO and MEGA but in case of ESP32 it displays wrong information like
For key D it shows 4
For key 4, 5 and 6 it shows 1
For 7 it shows 2
For 8 it shows A
For 9 it shows 3

Anything at anytime it is showing like that

Kindly help me in resolving such an issue
Thanks !!

It could still be trying to calculate the resistance based on 5 volts instead of 3.3 volts. There should be a way to change it to be 3.3v. It’s been awhile since I worked on that library.

So is it possible to directly apply 3.3v in place of 5v ?
Or needed variations in resistor value too ??

You can try it with just 3.3v and see if that works. I also wrote in a way to test the resistors based on the input voltage. It prints out a chart of values based on which resistors you use.

I just tried with 3.3v but same issue with different values for every key pressed.

Well, what about your chart of values ?
I mean how to go with your system !

There is a function called "setKeypadVoltage()", set it to 3.3. And to see the chart, there is a function called "showRange();". Call it inside void setup()

If it still doesn't work, i'll try it on my end. I too have a ESP32-WROOM-32D that I can test with, I just need to find my keypad.

I see
OK I need to go through these very new things firstly
Let me try with that and ll let you know.
Please let me know in case of any update . .

I declared
Keypad.SetKeypadVoltage(3.3);
under void setup

But not able to get scripting about showRange();

i'll test it on my end.

EDIT: I provided an example sketch with that library called Show Range, give it a try.

Yeah Please . . . . Thanks for your kind help !!

error msg is like

showRange();
^~~~~~~~~
_howmany

exit status 1

Compilation error: 'showRange' was not declared in this scope

There is another example sketch called OneWireKeypad_Final.ino, run that please.

Ok make sure the keypad voltage is 3.3, and swap out the 4.7k resistors for 2.2k (Red, Red, Red, Gold)

Range: 3.3V with 2.2k and 1K resistors

Volts: 3.30
0.82	1.10	1.65	3.30	
0.53	0.63	0.79	1.03	
0.39	0.45	0.52	0.61	
0.31	0.34	0.38	0.43	

Ideally you want each row to be lower than then next row. But the above should still work even though the 0.82 is lower than the start of the new row at 1.03. You just want enough as much space in between the values as possible, especially the lower values (0.31, 0.34, 0.38 & 0.43)

Didn't get Example sketch for ShowRange, where it is ? Please guide !!

Is it the one below ???

// Creator: Andrew Mascolo
//
//#include <Wire.h>
//#include <LiquidCrystal_I2C.h>
#include <OnewireKeypad.h>

char KEYS[] = {
  '1', '2', '3', 'A',
  '4', '5', '6', 'B',
  '7', '8', '9', 'C',
  '*', '0', '#', 'D'
};

//LiquidCrystal_I2C Lcd(0x20,20,4);
//OnewireKeypad <LiquidCrystal_I2C, 12> KP( Lcd, KEYS, 4, 3, A0, 4700, 1000 );

OnewireKeypad <Print, 16 > KP2(Serial, KEYS, 4, 4, A0, 4700, 1000 );

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

  //  Lcd.init();
  //  Lcd.backlight();

  // This method is set in the constructor with a default value of 5.0
  // You only need to include this method if your Arduino is not supplying 5v to
  // the keypad. ie. ~4.7v or even with 3.3v Arduino boards too.
  //KP.SetKeypadVoltage(5.0);
  KP2.SetKeypadVoltage(5.0);
}

void loop() {
  //  if( KP.Getkey() )
  //  {
  //    Lcd.clear();
  //    Lcd.home();
  //    Lcd.print( F( "KP: " ) );
  //    Lcd.setCursor(4,0);
  //    KP.LatchKey();
  //  }

  if ( char key = KP2.Getkey() ) {
    Serial << "Key: " << key << " State: ";
    switch (KP2.Key_State()) {
      case PRESSED:
        Serial.println("PRESSED");
        break;

      case RELEASED:
        Serial.println("RELEASED");
        break;

      case HELD:
        Serial.println("HOLDING");
        break;
    }
  }
}



Ya replaced with 2.2k resistor

Where to place this

Volts: 3.30
0.82	1.10	1.65	3.30	
0.53	0.63	0.79	1.03	
0.39	0.45	0.52	0.61	
0.31	0.34	0.38	0.43

That just shows you the tolerance between each button.

Did changing the resistors work?

No it's not working any of the way !!!

OnewireKeypad.h has 5volt and 10-bit (1023) throughout the code.
An ESP32 is 3.3volt-logic and has a 12-bit (4095) A/D.
Both have to be changed.
And then there is the poor linearity of the A/D of the ESP32.
An I/O expander could be a better solution.
Leo..

Given a reasonably linear ADC, the technique could be optimized using unique resistances for the divider chain as well. I'd play with it if it was of immediate interest, but for me it's not.

I run a single wire array of 22 buttons on a Nano, and have no fewer than 30 ADC counts between each button using a string of resistance/button pairs. But, it takes a bit of work to optimize. I may look at optimizing this keypad technique for another application, but it's down the road.

Why it is not working with ESP32 and ESP8266 modules only ??
It acts good enough with Arduino models