Wio Terminal on-screen numeric keyboard with good Button Input routine

This code is a little numbers-only on-screen keyboard input for the Wio Terminal.
Run it and use the 5-way to move left or right to go to the desired digit.
Click the 5-way to select the digit, adding it to what you’ve already selected.
The 5-way Up will change modes to allow editing the value you have. In Edit mode, you can use the 5-way left to delete digits and 5-way down to go back to data-entry mode. If you delete all the digits, it will put you back to data-entry mode.
The Middle button causes the entered value to be returned.
The Left button causes the entered value to be discarded.
The button input is very responsive with no delay problems. If you hold a button down, it does not enter multiple characters. It only gets the button value when you let up on the button.

Scott

#include <TFT_eSPI.h> // Graphics and font library for ILI9341 driver chip
#include <SPI.h>

TFT_eSPI tft = TFT_eSPI();  // Invoke library
const int keyboardTop = 190;   // Maximum keyboardTop is 190

void setup(void) {
  pinMode(WIO_KEY_A, INPUT_PULLUP);
  pinMode(WIO_KEY_B, INPUT_PULLUP);
  pinMode(WIO_KEY_C, INPUT_PULLUP);
  pinMode(WIO_5S_UP, INPUT_PULLUP);
  pinMode(WIO_5S_DOWM, INPUT_PULLUP);
  pinMode(WIO_5S_LEFT, INPUT_PULLUP);
  pinMode(WIO_5S_RIGHT, INPUT_PULLUP);
  pinMode(WIO_5S_PRESS, INPUT_PULLUP);
  
  tft.init();
  tft.setRotation(3);
  tft.fillScreen(TFT_BLACK);
  String keyboardInput = getOnScreenKeyboardInput();
  tft.setTextColor(TFT_YELLOW, TFT_BLACK);
  tft.fillScreen(TFT_BLACK);
  tft.setCursor(0,0);
  tft.print(keyboardInput);
}
String waitForButtonPressed() {
  String buttonPressed = "";
  while (1) {
    if (digitalRead(WIO_KEY_A) == LOW) {
      buttonPressed = "RIGHT";
    }
    else if (digitalRead(WIO_KEY_B) == LOW) {
      buttonPressed = "MIDDLE";
    }
    else if (digitalRead(WIO_KEY_C) == LOW) {
      buttonPressed = "LEFT";
    }
    else if (digitalRead(WIO_5S_UP) == LOW) {
      buttonPressed = "5UP";
    }
    else if (digitalRead(WIO_5S_DOWM) == LOW) {
      buttonPressed = "5DOWN";
    }
    else if (digitalRead(WIO_5S_LEFT) == LOW) {
      buttonPressed = "5LEFT";
    }
    else if (digitalRead(WIO_5S_RIGHT) == LOW) {
      buttonPressed = "5RIGHT";
    }
    else if (digitalRead(WIO_5S_PRESS) == LOW) {
      buttonPressed = "5CLICK";
    } else if (buttonPressed != "") {
      return buttonPressed;
    }
    delay(20);
  }
}

String getOnScreenKeyboardInput() {
  int keySelected = 5;
  int priorSelected = 0;
  String valueEntered = "";
  String editingMode = "entering"; // or correcting
  String buttonPressed = "";
  drawOnScreenKeyboard();
  // highlight keySelected
  tft.setTextColor(TFT_RED, TFT_BLACK);
  tft.setCursor(7 + keySelected * 31, keyboardTop + 1, 6);
  tft.print(String(keySelected));
  while (buttonPressed != "MIDDLE" && buttonPressed != "LEFT") {
    if (buttonPressed == "5UP" && editingMode == "entering" && valueEntered != "") {
      // Switch mode to correcting
      editingMode = "correcting";
      tft.fillScreen(TFT_BLACK);
    } else if (buttonPressed == "5DOWN" && editingMode == "correcting") {
      // Switch mode to doing data entry.
      editingMode = "entering";
      tft.fillScreen(TFT_BLACK);
      drawOnScreenKeyboard();
    } else if (buttonPressed == "5LEFT") {
      if (editingMode == "correcting") {
        valueEntered.remove(valueEntered.length() - 1);
        if (valueEntered == "") {
          // Switch mode to doing data entry
          editingMode = "entering";
          tft.fillScreen(TFT_BLACK);
          drawOnScreenKeyboard();
        }
      } else {
        priorSelected = keySelected;
        if (keySelected == 0) {
          keySelected = 10;
        }
        keySelected = keySelected -1;
      }
    } else if (buttonPressed == "5RIGHT" && editingMode == "entering") {
      priorSelected = keySelected;
      if (keySelected == 9) {
        keySelected = -1;
      }
      keySelected = keySelected +1;
    } else if (buttonPressed == "5CLICK") {
      if (editingMode == "entering" && valueEntered.length() < 10) {
        valueEntered = valueEntered + String(keySelected);
      }
    }
    if (editingMode == "entering") {
      tft.setTextColor(TFT_WHITE, TFT_BLACK);  
      tft.setCursor(7 + priorSelected * 31, keyboardTop + 1, 6);
      tft.print(String(priorSelected));
    }
    tft.setTextSize(2);
    tft.setCursor(1,1,4);
    if (editingMode == "correcting") {
      tft.setTextColor(TFT_BLUE, TFT_BLACK);
    } else {
      tft.setTextColor(TFT_RED, TFT_BLACK);
    }
    tft.print(valueEntered);
    if (editingMode == "correcting") {
      tft.print("_   ");
    }
    tft.setTextSize(1);
    if (editingMode == "entering") {
      // highlight keySelected
      tft.setTextColor(TFT_RED, TFT_BLACK);
      tft.setCursor(7 + keySelected * 31, keyboardTop + 1, 6);
      tft.print(String(keySelected));
    }
    buttonPressed = waitForButtonPressed();
  }
  if (buttonPressed == "MIDDLE") {
    return valueEntered;
  }
  if (buttonPressed == "LEFT") {
    return "";
  }
}

void drawOnScreenKeyboard() {
  tft.drawLine(4, keyboardTop, 314, keyboardTop, TFT_GREEN); // TOP LINE
  tft.drawLine(4, keyboardTop + 49, 314, keyboardTop + 49, TFT_GREEN); // BOTTOM LINE
  for (int i = 4; i <= 319; i = i + 31){ 
    tft.drawLine(i, keyboardTop, i, keyboardTop + 49, TFT_GREEN); // VERTICAL LINES
  } // VERTICAL LINES
  
  tft.setTextColor(TFT_WHITE, TFT_BLACK);  
  for (int i=0; i <= 9; i++){
    tft.setCursor(7 + i * 31, keyboardTop + 1, 6);
    tft.print(String(i));
  }
}

void loop() {
  return;
}

@ansonhe97 Please help him

Hi @mischko

Sorry, i don’t quite get what your question is as this code is compiling fine and working on this end. Can you provide more details pls :smiley:

Thanks

There is no problem. I am making this available for use by others.

Scott

1 Like

Lol

I will download and look at this when my testing is done. I find on my testing that the 5 way button to be a little hard to press the correct action.

Dennis,
It’s very simple. I am thinking of using these little terminals to gather data in the field, in this case for recording electric meter readings in the RV park I live in.

I changed the button input code quite a bit from the demo code I found here.

Scott