The M5Stack CardKB is a full specification mini keyboard, with a built-in controller IC. It is supplied with a Grove connector and uses an I2C interface, plus the Wire library, to transfer keypress data to a connected Arduino-compatible microcontroller. Surprisingly, the entire keypad is the size of a credit card.
The CardKB module offers a convenient alternative to manual connection of a mini-keypad, for two key reasons – pardon the pun!
Firstly, consider the case of a manually connected 12- or 16-button keypad. This would require a separate digital I/O connection for each of the rows and columns, which is assumed here to be in addition to the standard range of general purpose inputs and outputs used with the plcLib library (X0–X3, AD0–AD1, Y0–Y3). Typical keypad connection arrangements are illustrated below.
Miniature keypads are arranged as 2-dimensional arrays of rows and columns. Pressing a key momentarily connects the associated row and column and this is detected by a program which scans the keypad many times per second. A 16-button keypad will have 4 rows and 4 columns, hence requiring 8 additional I/O lines, while a 12-button keypad will require an extra 7 I/O lines.
A second issue is the extra software complexity associated with scanning the keypad and detecting keypresses. However, in practice, the heavy-lifting is typically performed by a dedicated keypad library. The process of scanning the keypad is similar to the scan cycle of the plcLib library, so these should be mutually compatible, provided there are no hard-coded delays.
The CardKB unit has a dedicated ATMega8A microcontroller which performs all keyboard scanning operations and offers a simple I2C interface via a standard Grove connector. The device status may easily be read by using the Wire library. The following sketch reads the status of keys ‘1’ to ‘5’, and uses these to activate or de-activate LEDs connected to digital outputs Y0 to Y3.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
// Using a M5Stack CardKB keyboard as ‘digital input’ // with LED outputs x 4 // Hardware Connections // LEDs x 4 connected to outputs Y0-Y3 // M5Stack CardKB connected to Grove I2C port // Operation // Keys 1 and 2 turn Y0 on and off respectively via AUX0 // Key 3 turns Y1 alternately on and off via AUX1 // Key 4 turns Y2 alternatively on and off via AUX2 // Key 5 causes a 0.5 s fixed width pulse on Y3 via AUX3 // Setup Wire library and M5Keypad I2C address //$#include <Wire.h> //$#define KB_ADDR 0x5F // Auxiliary variables AUX0 = new Auxiliary(); AUX1 = new Auxiliary(); AUX2 = new Auxiliary(); AUX3 = new Auxiliary(); c = new Auxiliary(); // Holds current keypress: ‘1’ – ‘5’ used // Timer variable for fixed width pulse when key ‘5’ is pressed TIMER0 = new Timer(); function setup() { //$Wire.begin(); } function loop() { //$Wire.requestFrom(KB_ADDR,1); // Request 1 byte from M5Keypad //$if (Wire.available()) { // If data is available then //$ c = Wire.read(); // store the received data //$} // Two button toggle if (c == ‘1’) { // Press ‘1’ to enable AUX0 AUX0 = 1; } if (c == ‘2’) { // Press ‘2’ to disable AUX0 AUX0 = 0; } // Single button toggle if (c == ‘3’) { // Press ‘3’ to enable/disable AUX1 AUX1 = (~AUX1 & 1); } // Single button toggle if (c == ‘4’) { // Press ‘4’ to enable/disable AUX2 AUX2 = (~AUX2 & 1); } // Momentary activation of AUX3 when ‘5’ is pressed (Ternary operator) AUX3 = (c == ‘5’) ? 1 : 0; // Update LEDs connected to outputs Y0-Y3 din(AUX0); // Read auxiliary input AUX0 dout(Y0); // Send to output Y0 din(AUX1); // Read auxiliary input AUX1 dout(Y1); // Send to output Y1 din(AUX2); // Read auxiliary input AUX2 dout(Y2); // Send to output Y2 din(AUX3); // Read auxiliary input AUX3 timerPulse(TIMER0, 500); // 0.5 second fixed width pulse dout(Y3); // Send to output Y3 } |
Listing 1. Using a keyboard to control digital outputs (Source: Extras > M5StackCardKBDigitalOut).
The above sketch demonstrates three different approaches to using keyboard entry to control digital outputs.
- Buttons ‘1’ and ‘2’ enable or disable output Y0, respectively. Hence two keys are used to control a single digital output.
- Buttons ‘3’ and ‘4’ independently control outputs Y1 and Y2. Pressing a key either enables or disables the output, based on its previous state. Hence each key controls a dedicated digital output.
- Button ‘5’ uses a ternary operator to momentarily enable an associated auxiliary variable and this in turn triggers a 0.5 second fixed width pulse, via the timerPulse command.
Which approach is best will depend on the application. Hence it is assumed that the reader will adapt the supplied sketch, as required.
Final Thoughts
There are many potential uses of keyboard input in plcLib-based applications. One possibility is to use it as an alternative to dedicated digital inputs, as shown here – most likely for testing purposes. However, the ability to update auxiliary variables based on keyboard input means that virtually any application which can accept input from a variable can also be controlled from a keyboard. Hence the range of applications of keyboard input is mainly limited by the user’s imagination!