LCD Keypad Shield DFR0009 - testing code

Thought to share a snippet to get the ADC values out of this board: LCD Keypad Shield For Arduino | Buy in Australia | DFR0009 | DFRobot | Core Electronics

It saved me a fair bit of guesswork.

#include <LiquidCrystal.h>

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

const char* names[] = {"RIGHT", "UP", "DOWN", "LEFT", "SELECT"};

int lastBtn = -2;

// calibration data
int minVal[5];
int maxVal[5];
unsigned long count[5];

int readButtonsRaw() {
  int adc = analogRead(A0);

  if (adc > 1000) return -1; //no input. ADC = 1023
  if (adc < 50)   return 0; //right
  if (adc < 210)  return 1; //up
  if (adc < 415)  return 2; //down
  if (adc < 630)  return 3; //left
  if (adc < 825)  return 4; //far left (select or menu)

  return -1;
}

// optional fuzzy classification using learned midpoints
int classify(int adc) {
  for (int i = 0; i < 5; i++) {
    if (count[i] == 0) continue;

    int mid = (minVal[i] + maxVal[i]) / 2;
    if (i == 0 && adc < mid) return i;
  }

  // fallback original mapping
  if (adc < 50) return 0;
  if (adc < 210) return 1;
  if (adc < 415) return 2;
  if (adc < 630) return 3;
  if (adc < 825) return 4;

  return -1;
}

void setup() {
  lcd.begin(16, 2);
  lcd.clear();

  for (int i = 0; i < 5; i++) {
    minVal[i] = 1023;
    maxVal[i] = 0;
    count[i] = 0;
  }

  lcd.print("STARTUP .....");
  delay(1000);
  lcd.clear();
  lcd.print("CALIBRATING...");
  delay(1000);
  lcd.clear();
}

void loop() {
  int adc = analogRead(A0);
  int b = readButtonsRaw();

  // update calibration only when button is stable
  if (b >= 0) {
    if (adc < minVal[b]) minVal[b] = adc;
    if (adc > maxVal[b]) maxVal[b] = adc;
    count[b]++;
  }

  int c = classify(adc);

  // line 1
  lcd.setCursor(0, 0);
  lcd.print("ADC:");
  lcd.print(adc);
  lcd.print(" ");
  lcd.print(c >= 0 ? names[c] : "NONE ");
  lcd.print("   ");

  // line 2: show selected button stats
  if (b >= 0) {
    lcd.setCursor(0, 1);
    lcd.print(names[b]);
    lcd.print(" ");
    lcd.print(minVal[b]);
    lcd.print("-");
    lcd.print(maxVal[b]);
    lcd.print(" ");
    lcd.print(count[b]);
    lcd.print("   ");
  } else {
    lcd.setCursor(0, 1);
    lcd.print("NO INPUT        ");
  }

  delay(80);
}
1 Like

Thanks for sharing this, it’s always handy to have this kind of information on record.

1 Like

Apologies my code is so crappy. I forgot to prune out some of my testing bumf. Not to worry though, it will work perfectly regardless.