How to stop Single Analog Pin Keypad Matrix (Using Resistors) from receiving Interference from Livewire/other Sensors?

saw a tutorial on linking a keypad using one pin, utilising several resistors: One single analog pin keypad control using Arduino - Razib Shahadat

I have this keypad, a 16x2 LCD, a PIR motion detector, and a DHT11 temperature & humidity sensor attached. Furthermore, I have an additional 5V power supply connected to the breadboard for additional power, although I'm not sure if this is required?

All components work as expected in the current configuration when only loading their relevant Arduino template code, except for the keypad. The keypad worked initially when nothing else was connected, but now the resistance values fed to the serial seem to jump, particularly in the first column. I tried to add some resistance between the first input of the keypad matrix and the live wire, which dampens the fluctuations but does not remove them completely.

My actual setup is rather chaotic, hence I have created a Fritzing sketch to try to make it a bit easier to understand, although I realise that it is still rather chaotic. I am new to Fritzing and Arduino and am still figuring things out.

Here is the isolated code for the keypad, which I am using to find the output values (which, as mentioned, are varying unpredictably), although this was working previously, on a more simple setup:

// code adapted from: One single analog pin 4*4 Keypad Control by Arduino with Lcd display - YouTube
void setup() {
Serial.begin(9600); /* Define baud rate for serial communication */

void loop() {
  int keyIn;
  int keyVals [16] = {976, 450, 333, 244, 166, 138, 124, 109, 90, 81, 76, 70, 61, 57, 54, 51};
  char keys[16] = {'1','2','3','A','4','5','6','B','7','8','9','C','*','0','#','D'};
  int range = 1;

  keyIn = analogRead(A1);

  String temp = "";

  if (keyIn > 2)
    for(int i=0; i<=15; i++)
      // The values of the keys changed, that's why the following is commented out
      //if (keyIn >= keyVals[i]-range && keyIn <= keyVals[i]+range)
      //  temp = keys[i];

Lastly, I intend for this board to be my master. I then intend to connect a slave through I2C with a DC motor, a servo motor, and an RGB LED. Does this seem feasible?

Please assist if you can.

If you have any additional advice, that too would be highly appreciated - thank you in advance!

1 Like

What are you actually using for a 5 V Power supply? You will certainly need a proper regulated supply when you add motors; the regulation of the "breadboard" module is dubious.

Remove the connection between the contrast potentiometer and 5 V. You will find it much easier to adjust.

The code is incomplete and thus useless for determining problems. The use of a "String" is liable to cause problems.

1 Like

Is this a class project, I just responded to a very similar question with the same frizzy picture which is not much help. What you show will not work, there is no power, grounds are missing. Lowering the resistance value of the resistors will decrease the coupled noise.

You are powering the keypad from a power supply and reading the single pin on your Arduino. What I do not see is a ground between them.
Looks like that's a good problem to start with after you address the other replies.

1 Like

Minor details! :yawning_face:

It's the thought that counts, isn't it?

1 Like

How is that even possible ?
So I tested it in Tinkercad with 5k and 1k resistors:



No key pressed = 000 mV
1 = 5000 mV
2 = 2500
3 = 1667
A = 1250
4 = 833
5 = 714
6 = 625
B = 556
7 = 455
8 = 417
9 = 385
C = 357
* = 312
0 = 294
# = 278
D = 263

Between 'D' and '#' is only 15 mV. That is three ADC steps.

When I change the 5k resistors to 4k7, then the numbers are better.
The library is made for 4k7 resistors.

@csfitzgerald, your code will not work. Your range is only 1. I think that the switching points has to be calculated to be precisely in the middle.

That link uses a library:
That library searches for the nearest value. That is better.

However, having 16 keys in a matrix to a single analog input will cause trouble one way or the other.

1 Like

Can you please post a picture(s) of your project so we can see your component layout?

A proper schematic would help, as the connections are not labelled, especially to the keypad.

Where is your gnd connection between the UNO and the breadboard?

Do you have a DMM?

Thanks.. Tom... :smiley: :+1: :coffee: :australia:

1 Like

The example ShowRange.ino can be used find the best values for the resistors when that library is used.
To get the maximum distance, the 4k7 resistors should have a lower value than the 1k resistors. It is possible to get a distance of 62 mV. That is better than the 15 mV.

If the three resistors on the high side / rows are 1k and the four resistors at the low side / columns are 4k7, then the distance is 52mV and 59mV with 1k and 3k9.

I have added a Issue about the resistor values:

1 Like

You don't show power going to your Arduino so I am guessing it has a separate supply. You should power the Arduino and the keypad from the same power supply. If either of the supplies changes voltage under load, the mapping of key to analog input will change.

1 Like

In electronics Nope! Electrons do not understand thoughts.

First and foremost - my mind is blown at the amount and quality of responses that I have received. My sincerest gratitude to each and every one of you!

As a new user, I can only mention two users per post. Therefore, I'll just post everything together without names.

The power supply module is an MB102, with the following specs:

  • incoming voltage: 6,5 - 12V DC
  • outgoing voltage 3,3V / 5V
  • max. current: < 700 mA

Tthis is a uni project, yes.

I removed my string variable, and I will avoid strings from the rest of the code. I also removed the potentiometer connection. Thank you!

I removed the second power source - this drastically reduced the jumping! It seems the other issue was that the Arduino ground was not connected to the board! Thank you all for this advice!!!

I thought showing power to the Arduino was trivial, as it always needs a power supply connected to USB or power plug to work (I was not aware of the Vin pin, which I now am).

@johnwasser I think your answer to the two power supplies and the load jumps seems to make sense. I think this explains most theoretically what was wrong. Why would it jump in this case though, and not when only on one supply under differing load?

Using 4.7 kOhm resistors would give the maximum spacing and work better is good info. I will try to source them before my deadline! The code is outdated and incomplete, I was just using it to get new readings from the keys, the output values of which were now jumping. I realise that I should have cleaned the code that was not in use. I apologise - lesson learnt! Thank you for the link to the showRange.ino code. I was looking for something like this previously.

@everyone, after making all the changes that I could from your recommendations, the keypad outputs are stable now, differing within a range of only +-1. My only problem is with my 1st key [1], which still seems to jump between about three values within a range of approx. 40 units up and down. I can include all three values for the key, but it would just be nice to have a rigid solution. Adding a resistance between the live and the first connector of the keypad stops the jumping but then I end up with a bunch of duplicate values. Does anyone have a closing recommendation for this?

Thank you again to each and every one of you for your responses and your help!!!

Please post pictures of your setup so others can learn from this.

That is of course, complete nonsense!

As in the UNO itself, the regulator on the board has almost no heatsink, so it will overheat and (hopefully reversibly) shut down if more than a couple of hundred milliamps are drawn, particularly if supplies at anything approaching 12 V.

If you power it with an actual 5 V via the USB connector, it can supply up to the limit of the (USB power supply and) the protection device on the board (no protection device on the board you cite, so whatever the USB supply is limited) .

There is no such "rigid solution". :woozy_face:

I do not know what code you are using as you only posted a snippet, but you never code for specific values. Your array needs to contain the values halfway between the values you have calibrated for each key and you use those values for ">" or "<" comparisons.

Have you got a 0.1uF capacitor between the analog input and gnd?

Tom... :smiley: :+1: :coffee: :australia:

If one power supply is used for the Analog Reference (the 5V line on the Arduino) and a different power supply is used to power the voltage divider (5V from the breadboard supply) the output of the ADC will change if either of the supplies change. If the same supply is used for both, the supply can change without changing the output: both the reference voltage and the output of the voltage divider change the same amount.

Sorry for my delayed response. I have been overwhelmed.

@er_name_not_found the project is due tomorrow. It is in a mess at the moment, so it is difficult to understand what's going on from pictures. I will tidy it up and post pictures of the components and connections once it is finalised. :smile:

@Paul_B noted, thank you.

@TomGeorge I still need to try that. I will report back once I have done it. Thanks!

@johnwasser noted, thank you.