Button Keypad 4x4 module Assembled - dimaatmelodromru/techdoc GitHub Wiki

Button Keypad 4x4 module (Assembled)

The Button Keypad 4x4 module (Assembled) looks very much like the popular Matrix Membrane Keypad 16 Key (4x4) but actually it works in a very different way. On the Matrix Membrane Keypad 16 Key (4x4) the buttons form a 4x4 matrix and to connect this keyboard to the microcontroller you need to use 8 contacts, which is very wasteful for some projects. The Button Keypad 4x4 module (Assembled) has only 3 pins (VCC, GND, Out) and one analog input is enough to connect it to a microcontroller (e.g. Arduino).

img

How is that possible? Let's take a look at the schematics of this keyboard.

Schematics

img

Voltage is applied to pins 3 (VCC) and 2 (GND). Pressing one of the buttons SW1-SW16 forms a voltage divider at the output 1 (Out), and each button has its own unique voltage divider. For example, for the SW2 button - 1/10, for the SW10 button - 11/10. By connecting this contact to the analog input of the microcontroller, when the buttons are pressed, we will get different values by which we can identify the pressed button.

Connecting the Keypad to Arduino

Connect the Button Keypad 4x4 module (Assembled) to the Arduino board and write a sketch of the definition of the pressed key.

We will use the following components::

  • RobotDyn (Arduino) UNO – 1;

  • Button Keypad 4x4 module (Assembled) – 1;

  • Jumper wires – 3.

img

The approximate analog values for the keyboard buttons are printed on the back of the keyboard.

img

We connect the Arduino board to the computer. In the Arduino IDE, create a new sketch and enter the following code into it:

void setup() {
  // selial port initialization
  Serial.begin(9600);
}

void loop() {
 // get value of A1 analog input
 int valueA1=analogRead(A1);
 // output data to serial port
 Serial.println(valueA1);
 // pause
 delay(500);
}

Download the sketch to the Arduino board, open the serial port monitor and look at the values on the analog input when pressing the keyboard keys:

img

The measurement results (comparison of expected and real values at the analog input when pressing the keys) are presented in the table:

Button Expected Value Actual average Button Expected Value Actual average
SW1 1023 1023 SW9 512 517
SW2 930 934 SW10 487 492
SW3 850 859 SW11 465 470
SW4 790 796 SW12 445 450
SW5 680 686 SW13 410 412
SW6 640 645 SW14 330 333
SW7 600 607 SW15 277 278
SW8 570 574 SW16 238 240

It's important to notice that the value at the analog input takes a value of 0-1023 relative to the reference voltage. By default, this is the power supply voltage of the microcontroller. The reference voltage plays a major role in measuring the analog signal, because the maximum measured voltage and, in general, the possibility and accuracy of converting the obtained value 0-1023 to Volts depend on it. Let's study the following function - analogReference(mode), where mode is:

  • DEFAULT: the reference voltage is equal to the supply voltage of the MCU. Active by default;

  • INTERNAL: built-in 1.1V reference source for ATmega168 or ATmega328P and 2.56V on ATmega8;

  • INTERNAL1V1: built-in 1.1V reference source (only for Arduino Mega);

  • INTERNAL2V56: built-in reference source at 2.56V (only for Arduino Mega);

  • EXTERNAL: The reference voltage will be the voltage applied to the AREF pin.

The value 1023 of the analogRead() function will correspond to the selected reference voltage or a voltage higher than that, but not higher than 5.5V, which will burn the board. That is, with the DEFAULT mode, we can digitize the voltage from 0 to the supply voltage. If the supply voltage is 4.5 Volts, and we supply 4.5 V, we get the digitized value of 1023. If we supply 5 Volts, we again get 1023, because it's above the reference. This rule works further, the main thing is not to exceed 5.5 Volts.

As for accuracy: when powered by 5V and in DEFAULT mode, we get the accuracy of voltage measurement (5/1023 ~ 8 mV) - 8 millivolts. By setting INTERNAL, we can measure voltage from 0V to 1.1V with an accuracy of (1.1 / 1023 ~ 1.2 mV) - 1.2 millivolts. Very good, especially if you use a voltage divider.

As for the external voltage reference. A voltage of less than 0 V or higher than 5.5 V cannot be used as an external reference in the AREF pin. Also, when using EXTERNAL mode, you need to call analogReference(EXTERNAL) before calling the analogRead() function, otherwise you can damage the microcontroller.

Key detection code

Now, knowing the real values at the analog input, we will write a sketch defining the pressed key. Sketch Content:

void setup() {
 // serial port initialization
 Serial.begin(9600);
}

void loop() {
 // is any button pressed?
 int valueA1=get_button();
 if(valueA1>0) { // Ссли Π½Π°ΠΆΠ°Ρ‚ΠΈΠ΅
   Serial.print("Click button ");
   Serial.println(valueA1);
   delay(500);
 } 
}

// button detection
int get_button() {
 // get A1 analog input value
 int val=analogRead(A1);
 if(val>1000)
   return 1;
 else if(val>900)
   return 2;
 else if(val>820)
   return 3;
 else if(val>750)
   return 4;
 else if(val>660)
   return 5;
 else if(val>620)
   return 6;
 else if(val>585)
   return 7;
 else if(val>540)
   return 8;
 else if(val>500)
   return 9;
 else if(val>475)
   return 10;
 else if(val>455)
   return 11;
 else if(val>425)
   return 12;
 else if(val>370)
   return 13;
 else if(val>300)
   return 14;
 else if(val>260)
   return 15;
 else if(val>200)
   return 16;
 else
   return 0; 
}

Download the sketch to the Arduino board, open the serial port monitor and look at the values on the analog input when pressing the keyboard keys:

img

Note that a long press on the key (> 500 ms) leads to auto-repeat.

Calculator example

As an example of using the keyboard, let's create a mini-calculator project for arithmetic operations (addition, subtraction, multiplication, division) with two numbers on the Arduino board and the WH1602 display on the HD77480 controller.

Required Components

We will use the following components:

  • Arduino UNO board - 1;

  • Keyboard Button Keypad 4x4 module (Assembled) - 1;

  • Display WH1602 (in our case LCD Keypad shield) - 1;

  • Wires MM - 3.

Connection diagram

Connection diagram for a mini calculator on Arduino UNO, Button Keypad 4x4 module (Assembled) and LCD keypad shield:

img

Assignment of keyboard keys in the project according to the figure:

img

The sketch

Let's code the sketch.

All keystrokes of digits 0-9 and actions (+, -, /, *) are entered into the buffer and displayed. At the same time, we introduce restrictions:

  • start the input with numbers;

  • after entering an arithmetic action, the input of another action is blocked;

  • the button "=" (total) can be entered after the number;

  • the "backspace" key deletes the previous character.

Sketch Content:

// include the display library
\#include <LiquidCrystal.h>
// instantiation of an object
const int rs = 8, en = 9, d4 = 4, d5 = 5, d6 = 6, d7 = 7;
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
// variables
int pos=0;   // number of input characters
int buf[32];  // buffer storage array
int endkey=0; // 1 - digit, 2 - action 3 - result

// key map
// 1,2,3,+
// 4,5,6,-
// 7,8,9,/
// BS,0,=,*
int trans[]={0,
​       1,2,3,10,
​       4,5,6,11,
​       7,8,9,12,
​       14,0,15,13,
​      };
// key to symbol translation array
char sw[]={'0','1','2','3','4','5','6','7','8','9','+','-','/','*',' ','='};      

void setup() {
 // init the display
 lcd.begin(16,2);
 lcd.clear();
 // welcome message
 lcd.setCursor(3,0);
 lcd.print("Calculator");
 lcd.setCursor(2,1);
 lcd.print("Robotdyn.com");
 delay(3000);
 // clear the display
 lcd.clear();
 // show cursor
 lcd.cursor();
}

void loop() {
 // keypress?
 int valueA1=get_button();
 if(valueA1>0) { // if key pressed
   // process key value
   add_key(trans[valueA1]);
   delay(500);
 } 
} 

int get_button() {
 // read analog A1
 int val=analogRead(A1);
 if(val>1000)
   return 1;
 else if(val>900)
   return 2;
 else if(val>820)
   return 3;
 else if(val>750)
   return 4;
 else if(val>660)
   return 5;
 else if(val>620)
   return 6;
 else if(val>585)
   return 7;
 else if(val>540)
   return 8;
 else if(val>500)
   return 9;
 else if(val>475)
   return 10;
 else if(val>455)
   return 11;
 else if(val>425)
   return 12;
 else if(val>370)
   return 13;
 else if(val>300)
   return 14;
 else if(val>260)
   return 15;
 else if(val>200)
   return 16;
 else
   return 0;  
}

// add a key to buf[] array
void add_key(int key) {
  // 0-9
  if(key<10) {
   if(endkey==3) { // after summ entry
​           // clear and
​           // start over
​     startover();pos=0;
   }
   buf[pos]=key;tolcd(key);endkey=1;
  }
  // + - / *
  else if(key<14) {
​    if(endkey==1) {
​     buf[pos]=key;tolcd(key);endkey=2;
   }
  }
  // backspace
  else if(key==14) {
   pos=max(0,pos-1);tolcd(key);
   pos=pos-1;lcd.setCursor(pos%15,pos/15);
   if(pos==0)
​     endkey=0;
   else if(buf[pos-1]>=0 && buf[pos-1]<=9)
​     endkey=1;
   else
​     endkey=2; 
  }
  // = (result)
  else {
   if(endkey==1) { 
​    buf[pos]=key;tolcd(key);
​    itogo();
​    endkey=3;   
   } 
  }
}

// output to the display
void tolcd(int s) {
  // cursor position
  lcd.setCursor(pos%15,pos/15);
  lcd.print(sw[s]);
  pos=pos+1;
  }

// output the result
void itogo() {
  String number1="";
  String number2="";
  char d;
  int i;
  int summa;

  // get first value
  for(i=0;i<pos;i++) {
   if(buf[i]>=0 && buf[i]<=9)
​    number1+=sw[buf[i]];
   else
​    break; 
  }
  // action
  d=buf[i];
  // get second value
  for(i=i+1;i<pos;i++) {
   if(buf[i]>=0 && buf[i]<=9)
​     number2+=sw[buf[i]];
   else
​     break; 
  }
  switch(d) {
   // +
   case 10: summa=number1.toInt()+number2.toInt();
​     break;
   // -
   case 11: summa=number1.toInt()-number2.toInt();
​     break;
   // /
   case 12: summa=number1.toInt()/number2.toInt();
​     break;
   // *
   case 13: summa=number1.toInt()*number2.toInt();
​     break;
   default:
​     break;   
   }
  lcd.setCursor(pos%15,pos/15);
  lcd.print(summa);
}

// clear at new entry
void startover() {
  for(int i=0;i<=pos;i++) {
   buf[i]=0;
  }
  lcd.clear();
}

Download the sketch to the Arduino board, and start using the mini calculator.

img

⚠️ **GitHub.com Fallback** ⚠️