1X4 matrix keypad to set 3 set of parameters for LED

I want to use 1X4 keypad to set 3 working parameters for LED string controlled by ATinny 85. For now I’m trying my code on Arduino mini. Keypad is attached to D2-D5 pins and LED is attached to pin 12. My objective is to set the following parameters:
frequency (4 values, each key represent one value, for example key 1 1000, key2 2000, key3 3000, key4 4000 ),
duty cycle (4 values),
run time 4 (values).
I need to force Arduino to read keypad 3 times to set all parameters. Run time In the sketch below has not been set. I tried to use “while” to force Arduino to read the keys. Only first “while” is working like it is supposed to and I can set cycle period. Second “while” does not do the job because the key has been already pressed and Arduino does not read keypad second time. Are there any means to use more than 1 "while" in the code?

#define Key1 3 // key 1 attached to pin 3
#define Key2 2 // key 2 attached to pin 2
#define Key3 5 // key 3 attached to pin 5
#define Key4 4 // key 4 attached to pin 4
float period; // cycle time
float power; // duty cycle
float ontime; // ontime  time LED is on
float rest;  // rest time LED is off
const int ledPin =  12;      // the number of the LED pin

void setup()
{
  pinMode(Key1, INPUT_PULLUP);
  pinMode(Key2, INPUT_PULLUP);
  pinMode(Key3, INPUT_PULLUP);
  pinMode(Key4, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);
}
void loop() {
  digitalWrite(ledPin, LOW);
  while (digitalRead(Key1) == HIGH && digitalRead(Key2) == HIGH && digitalRead(Key3) == HIGH && digitalRead(Key4) == HIGH) {};

  int key1a = digitalRead(Key1);
  int key2a = digitalRead(Key2);
  int key3a = digitalRead(Key3);
  int key4a = digitalRead(Key4);

  if (!key1a) {
    period = 1000;
  }
  if (!key2a) {
    period = 2000;
  }
  if (!key3a) {
    period = 3000;
  }
  if (!key4a) {
    period = 4000;
  }

  while (digitalRead(Key1) == HIGH && digitalRead(Key2) == HIGH && digitalRead(Key3) == HIGH && digitalRead(Key4) == HIGH) {};

  int key1b = digitalRead(Key1);
  int key2b = digitalRead(Key2);
  int key3b = digitalRead(Key3);
  int key4b = digitalRead(Key4  );

  if (!key1b) {
    power = 10;
  }
  if (!key2b) {
    power = 20;
  }
  if (!key3b) {
    power = 50;
  }
  if (!key4b) {
    power = 80;
  }

  ontime = period * power / 100;
  rest = period - ontime;

  digitalWrite(ledPin, HIGH);
  delay(ontime);
  digitalWrite(ledPin, LOW);
  delay(rest);
}

Hello

Think about how to do it without using blocking while loops, and also look at the example BlinkWithoutDelay

By the way, 1x4 is not a matrix. It might be considered a degenerate matrix in mathematics, but not in electronics. It would be called an array of keys.

What difference does it make?

Clear technical language helps people understand and help you. Also if you're searching for information or searching to purchase one, it will be a more fruitful search.

A lot of places sell it as a matrix keypad. https://bc-robotics.com/shop/membrane-1x4-keypad/

According to pinout 1 is row and 2-4 are columns so I would think it qualifies it as a matrix.

No, it's not even described as a matrix:
"Since this keypad has only one row of 4 outputs, no special code or libraries are required to add this to your project, simply treat this as 4 standard buttons. "

Well, while we’re here…

For this type of keypad you could use a resistive ladder style of switch ‘array’ on a single analog inout pin…

-unless more than one keypress is needed at a single time.

(I’m with @anon57585045 on this…
As described, they are just four inputs, no scanning rows/columns, or or x-y implied in the code requirements)

Here is an example using JC_Button library, no while loops or delays : t938882.ino - Wokwi Arduino and ESP32 Simulator

Code is different but the problem is the same.

The second while loop is working perfectly. It is supposed to wait for a key to be pressed. But if a key is already pressed, then it will not wait. That is what is happening. The problem is that, after the first button press is detected, your code is not waiting for that button to be released.

Sure. This is exactly what I said in my post.

So, would you like to re-phrase your original question? How about "how do I tell my code to wait until all keys have been released?"

For a lack of better definition my original question is how to enter multiple parameters using 1X4 keypad? I ended up using while statement because I really had no clue. Probably while is not a good idea.
I assumed that you meant to say 4 keys when you said all keys. I will never hit all 4 keys because i need to enter 3 parameters and there is a potential scenario that I would have to press the same key to enter all parameters, for example 1,1,1. In this case all keys will be never released. So I think the questions is how to make the program wait until 1x4 keypad is tapped 3 times? I wander if somehow I can use a counter?

Certainly you can use a counter, but you also need to decide how you’re going to handle the inputs…

As a -

  • 3-value entry (1…2…3),
  • a number (123), or
  • a char string (“123”)…
  • or to process each keypress on its own merits when it’s pressed
    (e.g. allows ‘clear’ or ‘backspace’ etc). 1…2…3… CLR, BKSP processed as separate key events.

It's very simple, I think. Just add this line in 2 places, after the keys have been read:

delay(20);
while (digitalRead(Key1) == LOW || digitalRead(Key2) == LOW || digitalRead(Key3) == LOW || digitalRead(Key4) == LOW) {};

The delay is to debounce the keys.

I was trying to do 3 value entry and the value for each key is defined in the code.
A number would be more flexible option but I have no idea how to do it.

It's very simple, I think. Just add this line in 2 places, after the keys have been read:

delay(20);
while (digitalRead(Key1) == LOW || digitalRead(Key2) == LOW || digitalRead(Key3) == LOW || digitalRead(Key4) == LOW) {};

The delay is to debounce the keys.

I need to press only 3 keys as I need to enter 3 parameters. In theory I can press a dummy key that will return no value to make sure that I press 4 keys but the problem will still remain for the cases when all 3 parameters are entered by pressing one key ( 111, 222, 333, 444 or two keys 112, 113.....).

Hi,
I'm confused, sorry.
You have 4 buttons, 3 buttons are used to enter 3 paramaters.
Button 1 enters parameter1, each press advances that parameter, how do you decrease the parameter?
Button 2 enters parameter2, each press advances that parameter, how do you decrease the parameter?
Button 3 enters parameter3, each press advances that parameter, how do you decrease the parameter?
What does the 4th button do?

What is the numerical range of these "parameters"?
What do the parameters represent?
Why ultimately an ATtiny85?

I fail to see anywhere in your code Serial.print statements to check your values?

Tom... :grinning: :+1: :coffee: :australia: