Keypad+Lcd hilfe!!!

Guten Tag,

ich versuche mit einem 4x4 Tastenfeld eine Tastatur zu emuieren (ähnlich wie bei den sehr alten Handys)
z.b. taste "1" einmal drücken kommt eine "1" zwei mal kommt eine "A" ..usw
dabei gibt das Arduino Mega die geschriebene Wörter auf einem Lcd aus.

Das Problem ist dass es nach eine gewisse Zeit keine Buchstaben mehr ausgibt sondern direkt die Nummern.

im Anhang ist das Code mit einem Bild von dem Problem

Ich danke euch im voraus für Lösungen bzw. Empfehlungen

mfg Zakoo

#include <Keypad.h>
#include <LiquidCrystal.h>
//Hier wird die größe des Keypads definiert


const byte COLS = 4; //3 Spalten

const byte ROWS = 4; //4 Zeilen

//Die Ziffern/Zeichen:

char hexaKeys[ROWS][COLS] = {

  {'1' , '2' , '3' , 'A'},
  {'4' , '5' , '6' , 'B'},
  {'7' , '8' , '9' , 'C'},
  {'*' , '0' , '#' , 'D'}
};

char Charakters[16][4] = {
  { '1'  ,   'A'   ,   'B'   ,   'C'   },       //1
  { '2'  ,   'D'   ,   'E'   ,   'F'   },       //2
  { '3'  ,   'G'   ,   'H'   ,   'I'   },       //3
  { '.'  ,   '.'   ,   '.'   ,   '.'   },       //A   remove the last latter
  { '4'  ,   'J'   ,   'K'   ,   'L'   },       //4
  { '5'  ,   'M'   ,   'N'   ,   'O'   },       //5
  { '6'  ,   'P'   ,   'Q'   ,   'R'   },       //6
  { '.'  ,   '.'   ,   '.'   ,   '.'   },       //B   clear the lcd
  { '7'  ,   'S'   ,   'T'   ,   'U'   },       //7
  { '8'  ,   'V'   ,   'W'   ,   'X'   },       //8
  { '9'  ,   'Y'   ,   'Z'   ,   '.'   },       //9
  { '.'  ,   '.'   ,   '.'   ,   '.'   },       //C   clear the actual lcd row
  { '*'  ,   '\''  ,   '.'   ,   '-'   },       //*
  { '0'  ,   ' '   ,   ':'   ,   ')'   },       //0
  { '.'  ,   '.'   ,   '.'   ,   '.'   },       //#
  { '.'  ,   '.'   ,   '.'   ,   '.'   }        //D   changes the lcd row
};

byte colPins[COLS] = {5 , 4 , 3 , 2 }; //Definition der Pins für die 3 Spalten

byte rowPins[ROWS] = { 10 , 9 , 8 , 7 };//Definition der Pins für die 4 Zeilen

char pressedKey; //pressedKey entspricht in Zukunft den gedrückten Tasten

Keypad myKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); //Das Keypad kann absofort mit myKeypad angesprochen werden
LiquidCrystal lcd(40, 41, 30, 31, 32, 33);

byte c = 0;
byte r = 0;

String WritenWord = "";
String Temp = "";
String TopString = "";
String BottomString = "";

byte LcdRow = 0;

byte PressedKeyRow = -1;
byte PressedKeyCol = -1;
byte LastPressedKeyRow = -1;
byte LastPressedKeyCol = -1;

char NewLetter = '.';

unsigned int counter = 0;

unsigned int LastTime;
unsigned int Offset = 500;

bool test = false;





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

  Serial.begin(9600);

}

void loop() {

  writeWord();
}

/*



*/
void writeWord() {

  if (checkKey()) {

    while ((LastTime + Offset) > millis()) {
      test = checkKey();
    //   Serial.print((LastTime + Offset));
    Serial.println("WL");
   //  Serial.println(millis());
    }
    Serial.println("OUT");
    LastPressedKeyRow = -1;
    LastPressedKeyCol = -1;
     counter = 0;
    if (hexaKeys[PressedKeyRow][PressedKeyCol] == 'A') {
      WritenWord = Temp;
      lcd.setCursor(0, LcdRow);
      lcd.print(WritenWord);
    } else if (hexaKeys[PressedKeyRow][PressedKeyCol] == 'B') {
      
    } else if (hexaKeys[PressedKeyRow][PressedKeyCol] == 'C') {

    } else if (hexaKeys[PressedKeyRow][PressedKeyCol] == 'D') {

    } else if (hexaKeys[PressedKeyRow][PressedKeyCol] == '#') {

    } else {
      WritenWord += NewLetter;
      lcd.setCursor(0, LcdRow);
      lcd.print(WritenWord);
      /******************************************************************************/
   // Serial.print("writen Word is : ");
   //Serial.println(WritenWord);
    }

  }
}
/*



*/
bool checkKey() {
  pressedKey = myKeypad.getKey(); //pressedKey entspricht der gedrückten Taste
  
  if (pressedKey) {
    LastTime = millis();
    for (r = 0 ; r < ROWS ; r++) {
      for (c = 0 ; c < COLS ; c++) {

        if (pressedKey == hexaKeys[r][c]) {
          PressedKeyRow = r;
          PressedKeyCol = c;
          if (PressedKeyRow == LastPressedKeyRow && PressedKeyCol == LastPressedKeyCol) {
            counter ++;
        //    Serial.println(counter);
          } else {
            counter = 0;
            LastPressedKeyRow = PressedKeyRow;
            LastPressedKeyCol = PressedKeyCol;
          }
          updetLCD();
          return true;
        }
      }
    }
  }
  return false;
}
/*




*/

void updetLCD() {

  if (hexaKeys[PressedKeyRow][PressedKeyCol] == 'A') {
    counter = 0;
    deletLastLetter();
  } else if (hexaKeys[PressedKeyRow][PressedKeyCol] == 'B') {
    counter = 0;
    clearLcd();
  } else if (hexaKeys[PressedKeyRow][PressedKeyCol] == 'C') {
    counter = 0;
   clearActualRow();
  } else if (hexaKeys[PressedKeyRow][PressedKeyCol] == 'D') {
    counter = 0;
    changLcdRow();
  } else if (hexaKeys[PressedKeyRow][PressedKeyCol] == '#') {
    counter = 0;
    scrollLcd();
  } else {
    NewLetter = Charakters[PressedKeyRow * 4 + PressedKeyCol][counter % 4];
    Temp = WritenWord + NewLetter ;
    lcd.setCursor(0, LcdRow);
    lcd.print(Temp);
  }
    LastTime = millis();
}

Keysfunction:

void deletLastLetter() {
  if (WritenWord.length() > 0) {
    Temp = WritenWord;
    Temp.remove(Temp.length() - 1);
    lcd.clear();
    if (LcdRow > 0) {
      lcd.setCursor(0, 0);
      lcd.print(TopString);
    } else {
      lcd.setCursor(0, 1);
      lcd.print(BottomString);
    }
    lcd.setCursor(0, LcdRow);
    lcd.print(Temp);
  }
}


void clearLcd() {
  WritenWord = "";
  TopString = "";
  BottomString = "";
  LcdRow = 0;
  lcd.clear();
}


void clearActualRow() {
  WritenWord = "";
  lcd.clear();
  if (LcdRow > 0) {
    lcd.setCursor(0, 0);
    lcd.print(TopString);
    lcd.setCursor(0, 1);
  } else {
    lcd.setCursor(0, 1);
    lcd.print(BottomString);
    lcd.setCursor(0, 0);
  }
}



void changLcdRow() {
  if (LcdRow > 0) {
    LcdRow = 0;
    BottomString = WritenWord;
    WritenWord = TopString;
    lcd.setCursor(WritenWord.length(), LcdRow);
  } else {
    LcdRow = 1;
    TopString = WritenWord;
    WritenWord = BottomString;
    lcd.setCursor(WritenWord.length(), LcdRow);
  }
}

void scrollLcd() {
  for (int positionCounter = 0; positionCounter < 13; positionCounter++) {
    lcd.scrollDisplayLeft();
    delay(200);
  }
  for (int positionCounter = 0; positionCounter < 29 ; positionCounter++) {
    lcd.scrollDisplayRight();
    delay(200);
  }
  for (int positionCounter = 0; positionCounter < 16; positionCounter++) {
    lcd.scrollDisplayLeft();
    delay(200);
  }
}

KeyPad_with_Lib.ino (4.54 KB)

KeysFunction.ino (1.38 KB)

Es wäre sinnvoller, die Sketche direkt im Forum einzutragen. Stelle sie dazu in Codetags (</>-Button oben links im Forumseditor).

Wenn es nach einigen Betätigungen nicht mehr funktioniert, sieht das nach einem Speicherproblem aus.
Du benutzt die Klasse String, die kann auf dem Arduino den Speicher fragmentieren und dann geht nichts mehr oder nicht mehr richtig.
Die Benutzung von Chararrays wäre günstiger.

Gruß Tommy

Du solltest wie üblich, deinen Sketch hier in Code-Tags direkt posten.
Dann können auch die mobilen User helfen.
Verwende dazu die Schaltfläche </> oben links im Editorfenster.

Hallo,

Ich füg mal die Codes in Code Tags ein </>, damit bekommst Du mehr Hilfe...
Ich habs mal gemacht, aber das pdf konventiere ich nicht.

Keys with lib:

void deletLastLetter() {
  if (WritenWord.length() > 0) {
    Temp = WritenWord;
    Temp.remove(Temp.length() - 1);
    lcd.clear();
    if (LcdRow > 0) {
      lcd.setCursor(0, 0);
      lcd.print(TopString);
    } else {
      lcd.setCursor(0, 1);
      lcd.print(BottomString);
    }
    lcd.setCursor(0, LcdRow);
    lcd.print(Temp);
  }
}


void clearLcd() {
  WritenWord = "";
  TopString = "";
  BottomString = "";
  LcdRow = 0;
  lcd.clear();
}


void clearActualRow() {
  WritenWord = "";
  lcd.clear();
  if (LcdRow > 0) {
    lcd.setCursor(0, 0);
    lcd.print(TopString);
    lcd.setCursor(0, 1);
  } else {
    lcd.setCursor(0, 1);
    lcd.print(BottomString);
    lcd.setCursor(0, 0);
  }
}



void changLcdRow() {
  if (LcdRow > 0) {
    LcdRow = 0;
    BottomString = WritenWord;
    WritenWord = TopString;
    lcd.setCursor(WritenWord.length(), LcdRow);
  } else {
    LcdRow = 1;
    TopString = WritenWord;
    WritenWord = BottomString;
    lcd.setCursor(WritenWord.length(), LcdRow);
  }
}

void scrollLcd() {
  for (int positionCounter = 0; positionCounter < 13; positionCounter++) {
    lcd.scrollDisplayLeft();
    delay(200);
  }
  for (int positionCounter = 0; positionCounter < 29 ; positionCounter++) {
    lcd.scrollDisplayRight();
    delay(200);
  }
  for (int positionCounter = 0; positionCounter < 16; positionCounter++) {
    lcd.scrollDisplayLeft();
    delay(200);
  }
}

KeysFunctions:

#include <Keypad.h>
#include <LiquidCrystal.h>
//Hier wird die größe des Keypads definiert


const byte COLS = 4; //3 Spalten

const byte ROWS = 4; //4 Zeilen

//Die Ziffern/Zeichen:

char hexaKeys[ROWS][COLS] = {

  {'1' , '2' , '3' , 'A'},
  {'4' , '5' , '6' , 'B'},
  {'7' , '8' , '9' , 'C'},
  {'*' , '0' , '#' , 'D'}
};

char Charakters[16][4] = {
  { '1'  ,   'A'   ,   'B'   ,   'C'   },       //1
  { '2'  ,   'D'   ,   'E'   ,   'F'   },       //2
  { '3'  ,   'G'   ,   'H'   ,   'I'   },       //3
  { '.'  ,   '.'   ,   '.'   ,   '.'   },       //A   remove the last latter
  { '4'  ,   'J'   ,   'K'   ,   'L'   },       //4
  { '5'  ,   'M'   ,   'N'   ,   'O'   },       //5
  { '6'  ,   'P'   ,   'Q'   ,   'R'   },       //6
  { '.'  ,   '.'   ,   '.'   ,   '.'   },       //B   clear the lcd
  { '7'  ,   'S'   ,   'T'   ,   'U'   },       //7
  { '8'  ,   'V'   ,   'W'   ,   'X'   },       //8
  { '9'  ,   'Y'   ,   'Z'   ,   '.'   },       //9
  { '.'  ,   '.'   ,   '.'   ,   '.'   },       //C   clear the actual lcd row
  { '*'  ,   '\''  ,   '.'   ,   '-'   },       //*
  { '0'  ,   ' '   ,   ':'   ,   ')'   },       //0
  { '.'  ,   '.'   ,   '.'   ,   '.'   },       //#
  { '.'  ,   '.'   ,   '.'   ,   '.'   }        //D   changes the lcd row
};

byte colPins[COLS] = {5 , 4 , 3 , 2 }; //Definition der Pins für die 3 Spalten

byte rowPins[ROWS] = { 10 , 9 , 8 , 7 };//Definition der Pins für die 4 Zeilen

char pressedKey; //pressedKey entspricht in Zukunft den gedrückten Tasten

Keypad myKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); //Das Keypad kann absofort mit myKeypad angesprochen werden
LiquidCrystal lcd(40, 41, 30, 31, 32, 33);

byte c = 0;
byte r = 0;

String WritenWord = "";
String Temp = "";
String TopString = "";
String BottomString = "";

byte LcdRow = 0;

byte PressedKeyRow = -1;
byte PressedKeyCol = -1;
byte LastPressedKeyRow = -1;
byte LastPressedKeyCol = -1;

char NewLetter = '.';

unsigned int counter = 0;

unsigned int LastTime;
unsigned int Offset = 500;

bool test = false;





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

  Serial.begin(9600);

}

void loop() {

  writeWord();
}

/*



*/
void writeWord() {

  if (checkKey()) {

    while ((LastTime + Offset) > millis()) {
      test = checkKey();
    //   Serial.print((LastTime + Offset));
    Serial.println("WL");
   //  Serial.println(millis());
    }
    Serial.println("OUT");
    LastPressedKeyRow = -1;
    LastPressedKeyCol = -1;
     counter = 0;
    if (hexaKeys[PressedKeyRow][PressedKeyCol] == 'A') {
      WritenWord = Temp;
      lcd.setCursor(0, LcdRow);
      lcd.print(WritenWord);
    } else if (hexaKeys[PressedKeyRow][PressedKeyCol] == 'B') {
      
    } else if (hexaKeys[PressedKeyRow][PressedKeyCol] == 'C') {

    } else if (hexaKeys[PressedKeyRow][PressedKeyCol] == 'D') {

    } else if (hexaKeys[PressedKeyRow][PressedKeyCol] == '#') {

    } else {
      WritenWord += NewLetter;
      lcd.setCursor(0, LcdRow);
      lcd.print(WritenWord);
      /******************************************************************************/
   // Serial.print("writen Word is : ");
   //Serial.println(WritenWord);
    }

  }
}
/*



*/
bool checkKey() {
  pressedKey = myKeypad.getKey(); //pressedKey entspricht der gedrückten Taste
  
  if (pressedKey) {
    LastTime = millis();
    for (r = 0 ; r < ROWS ; r++) {
      for (c = 0 ; c < COLS ; c++) {

        if (pressedKey == hexaKeys[r][c]) {
          PressedKeyRow = r;
          PressedKeyCol = c;
          if (PressedKeyRow == LastPressedKeyRow && PressedKeyCol == LastPressedKeyCol) {
            counter ++;
        //    Serial.println(counter);
          } else {
            counter = 0;
            LastPressedKeyRow = PressedKeyRow;
            LastPressedKeyCol = PressedKeyCol;
          }
          updetLCD();
          return true;
        }
      }
    }
  }
  return false;
}
/*




*/

void updetLCD() {

  if (hexaKeys[PressedKeyRow][PressedKeyCol] == 'A') {
    counter = 0;
    deletLastLetter();
  } else if (hexaKeys[PressedKeyRow][PressedKeyCol] == 'B') {
    counter = 0;
    clearLcd();
  } else if (hexaKeys[PressedKeyRow][PressedKeyCol] == 'C') {
    counter = 0;
   clearActualRow();
  } else if (hexaKeys[PressedKeyRow][PressedKeyCol] == 'D') {
    counter = 0;
    changLcdRow();
  } else if (hexaKeys[PressedKeyRow][PressedKeyCol] == '#') {
    counter = 0;
    scrollLcd();
  } else {
    NewLetter = Charakters[PressedKeyRow * 4 + PressedKeyCol][counter % 4];
    Temp = WritenWord + NewLetter ;
    lcd.setCursor(0, LcdRow);
    lcd.print(Temp);
  }
    LastTime = millis();
}

Schau mal:

byte colPins[COLS] = {5 , 4 , 3 , 2 }; //Definition der Pins für die 3 Spalten <- eigentlich sind es hier 4 Spalten

byte rowPins[ROWS] = { 10 , 9 , 8 , 7 };//Definition der Pins für die 4 Zeilen

Diese Pins stimmen nicht mit dem Bild überein. Außerdem haben diese Keypads keine gemeinsame Masse. Ich sehe das ein Pin des Keypad auf GND liegt.

Bei einem 4x4 Keypad hast Du 4 Pins für die rows und 4 Pins für die cols. Eine Reihe muss auf LOW geschalten werden, dann kannst Du jeden einzelnen Pin (Taster) abfragen und dann machst Du das mit der nächsten Reihe.

Grüße,
Donny

Danke Leute ich habe es verbessert

@Tomy56 ich werde es mit chararrays versuchen

@dony ich habe wegen der Pins noch mal geprüft und sie passen
es muss kein Reihe auf LOW geschaltet sein weil das die Bib <KeyPad.h> alles regelt

Hi

Genau DAS macht die Lib - Sie schaltet eine Reihe auf GND und prüft an den Zeilen-Pins, ob Da ebenfalls GND anliegt.
Das passiert mit jeder Reihe und jeder Zeile - aber dafür nutzen wir ja eine Lib, daß wir nicht immer Alles selber bauen müssen!

MfG

Hallo,

Das die lib das regelt wenn eine Spalte oder Reihe permanent auf GND geschalten ist bezweifel ich aber ich lasse mich gerne eines besseren belehren.
edit: schaut wahrscheinlich nur auf dem Foto so aus...

Grüße,
Donny

dony:
Das die lib das regelt wenn eine Spalte oder Reihe permanent auf GND geschalten ist bezweifel ich aber ich lasse mich gerne eines besseren belehren.
edit: schaut wahrscheinlich nur auf dem Foto so aus...

Ja, genau. Das Foto ist da leider sehr undeutlich.
GND wird da sicher nicht angeschlossen sein.

Hi Leute

ich hab neu Bilder hinzugefügt aber ich weis nicht ob man das direkt im Text posten kann


so etwa
(Bild.jpg aus dem ersten Beitrag)