// https://forum.arduino.cc/t/i-need-help-for-lcd-ui/1372143
// bool debug = 0;
bool debug = 1; // Show pages, potentiometer index, page, row, character
uint8_t num[][8] = {
{0, 4, 10, 10, 10, 4, 0, 0}, // 0
{0, 4, 12, 4, 4, 14, 0, 0}, // 1
{0, 4, 10, 4, 8, 14, 0, 0}, // 2
{0, 12, 2, 4, 2, 12, 0, 0}, // 3
{0, 2, 6, 14, 2, 2, 0, 0}, // 4
{0, 14, 8, 12, 2, 12, 0, 0}, // 5
{0, 4, 8, 12, 10, 4, 0, 0} // 6
};
#include <LiquidCrystal_I2C.h>
#define I2C_ADDR 0x27
#define LCD_COLUMNS 20
#define LCD_LINES 4
LiquidCrystal_I2C lcd(I2C_ADDR, LCD_COLUMNS, LCD_LINES);
char alphabet[] = {"-abcdefghijklmnopqrstuvwxyz-"};
char cursor = 127; // arrow
char space = 32; // space
byte potentiometer = A0; // potentiometer reading
byte index, indexOld; // mapped potentiometer
byte cursorRowOld, cursorRow = 1; // step, page and cursor index
byte firstPage = 0, lastPage = 6, prevPage = 0, nextPage = 5;
int alphabetPage; // int allows -1 needed for "< 0"
int buttonPin = 2;
unsigned long timer, debounceTimeout = 100; // debounce timer
bool lastButtonRead, currentButtonState;
void setup() {
Serial.begin(115200);
pinMode(buttonPin, INPUT_PULLUP);
lcd.init();
lcd.clear();
lcd.backlight();
for (int i = 0; i < 8; i++) {
lcd.createChar(i, num[i]); // small numbers
}
if (debug) showPages();
welcome();
}
void loop() {
readButton(); // print character
readPotentiometer();
}
void readPotentiometer() {
index = map(analogRead(potentiometer), 0, 1023, 0, 5); // four rows plus "next" and "prev"
if ((index != indexOld)) { // if the potentiometer has changed...
indexOld = index; // store new index
// scroll within page
if (index > 0 && index < 5) { // ... and it is not 0 "prev" or 5 "next"
cursorRow = index;
lcd.setCursor(1, cursorRowOld - 1); // adjust row from 1234 to 0123
lcd.write(space); // erase old cursor with "space" overwrite
lcd.setCursor(1, cursorRow - 1);
lcd.write(cursor);
cursorRowOld = cursorRow; // update cursor location
}
// get previous page
if (index == 0) { // ... and it is 0 "prev"
alphabetPage--;
if (alphabetPage < firstPage)
alphabetPage = firstPage; // lower bound
printAlpha(alphabetPage, 0);
}
// get next page
if (index == 5) { // ... and it is 5 "next"
alphabetPage++;
if (alphabetPage > lastPage)
alphabetPage = lastPage; // upper bound
printAlpha(alphabetPage, 0);
}
indexOld = index; // store row value
if (debug) printReport();
}
}
void printAlpha(byte pag, byte col) {
for (byte row = 0; row < LCD_LINES; row++) {
lcd.setCursor(col, row);
lcd.print(alphabet[pag * LCD_LINES + row]);
}
}
void readButton() {
bool currentButtonRead = digitalRead(buttonPin); // read button pin
if (currentButtonRead != lastButtonRead) { // if button pin reading changes...
timer = millis(); // ...start a timer
lastButtonRead = currentButtonRead; // ... and store current state
}
if ((millis() - timer) > debounceTimeout) { // if button-read change was longer than debounceTimeout
if (currentButtonState == HIGH && lastButtonRead == LOW) { // ... and button-state NOT pressed while Button IS PRESSED
if ((alphabetPage * LCD_LINES + cursorRow - 1) > 0 // do not allow first or last "-"...
&& (alphabetPage * LCD_LINES + cursorRow - 1) < 27) // ...only select alphabet
Serial.print(alphabet[alphabetPage * LCD_LINES + cursorRow - 1]);
}
currentButtonState = currentButtonRead; // update button state
}
}
void welcome() {
lcd.setCursor(0, 0);
lcd.print(F("BUTTON to start."));
lcd.setCursor(0, 1);
lcd.print(F("<< previous row/page"));
lcd.setCursor(0, 2);
lcd.print(F(">> next row/page"));
lcd.setCursor(0, 3);
lcd.print(F("BUTTON to select."));
while (digitalRead(buttonPin));
lcd.clear();
lcd.setCursor(1, cursorRow); // set cursor to bottom row
printAlpha(0, 0); // show first page of letters, column 0
lcd.write(cursor); // place cursor at bottom
if (debug) printReport();
}
void showPages() {
Serial.println(F("Running in DEBUG mode (debug = 1). "));
lcd.setCursor(0, 0);
lcd.print(F("Pages"));
for (byte pag = 0; pag < 7; pag++) {
lcd.setCursor(pag * 2 + 6, 0);
lcd.write(pag); // print page number
printAlpha(pag, pag * 2 + 7); // place cursor to print page
}
lcd.setCursor(0, 2);
lcd.print(F("PRESS"));
lcd.setCursor(0, 3);
lcd.print(F("BUTTON"));
while (digitalRead(buttonPin));
lcd.clear();
}
void printReport() {
Serial.print(F(" pot:"));
Serial.print(index); // mapped potentiometer
Serial.print(F(" pag:"));
Serial.print(alphabetPage);
Serial.print(F(" row:"));
Serial.print(cursorRow);
// page 0 1 2 3 4 5 6
// ==================
// row0 - d h l p t x
// row1 a e i m q u y
// row2 b f j n r v z
// row3 c g k o s w -
Serial.print(F(" (pag * LCD_LINES + row) c:"));
Serial.println(alphabet[alphabetPage * LCD_LINES + cursorRow - 1]);
}