Mehrstellige Zahleneingabe

Hey,
ich habe mal wieder ein Problem…
Nur erstmal kurz zum Hintergrung: Für ein Projekt ist es wichtig mehrstellige Zahlen eingeben und abgleichen zu können. Alles was ich bisher versucht habe funktioniert eher nicht. Mein aktueller Ansatz sieht folgendermasen aus:

int taste1=50;
int taste2=50;

#include <Keypad.h>

const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
//define the cymbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = {53, 49, 45, 41}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {37, 33, 29, 25}; //connect to the column pinouts of the keypad


Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); 

void setup(){
  Serial.begin(90);
  pinMode(3,OUTPUT);
}


void test3(){
  if(taste1==1 && taste2==2){digitalWrite(3, HIGH);}
}

void test2(){
  char customKey = customKeypad.getKey();

    if (customKey){taste2=customKey;
    void test3();}
}  
void loop(){
  char customKey = customKeypad.getKey();

  if (customKey){taste1=customKey;
  void test2();}
}

Nur funktioniert er nicht. Hat irgendjemand von euch eine Idee, wie ich das Konzept so umsetzten kann oder wie ich es sonst versuchen könnte?

Vielen Dank schonmahl im Vorraus
Jo02ny

Und was meinst du mit "abgleichen" ?

Ich muss diese Zahl mit einem vorher eingegeben Wert vergleichen können um im Fall das eine der hinterlegten Kombinationen eingegeben wurde einen anderen Void aufzurufen

Du kannst höchstens Funktionen aufrufen. Void ist ein Datentyp, der "nichts" bedeutet.

Nimm ein Char-Array. Schreibe die eingelesenen customKey hintereinander da rein, bis das Abschlußzeichen kommt (z.B. #). Dann schließt Du das mit '\0' ab und kannst es mit anderen Zeichenketten vergleichen.

Gruß Tommy

Es gibt keine voids. Void ist ein Datentyp. Die Dinger heißen Funktionen

Du kannst die korrekten Codes in Arrays speichern. Dann liest du die eingebenden Ziffern in ein anderes Array ein und vergleichst die beiden mit memcmp().
Manche Leute zählen auch die Anzahl der eingegebenen Ziffern mit und vergleichen dann die aktuelle eingebene Taste mit dem nächsten Index im Array. Das halte ich aber für etwas komplizierter.

@Tommy56
Bitte nicht mit C Strings verwirren. Das ist hier völlig überflüssig. Man kann auch Arrays direkt vergleichen.
Man sollte zwar nicht verwendete Ziffern auf 0 setzten, damit man z.B. immer 4 Zeichen vergleichen kann, aber eine richtige Terminierung ist nicht nötig wenn man dann immer memcmp() mit 4 Bytes macht

Ich halte bei flexibler Länge eine vernünftige Terminierung vor allem in Hinblick auf Debugausgaben für sinnvoller.

Gruß Tommy

Geht eigentlich beides. Ist auch etwas Geschmackssache :slight_smile:
Es hängt auch davon ab ob man die Eingabe lieber als String sieht, oder als Integer Ziffern. Man könnte z.B. immer ‘0’ subtrahieren um auf 0-9 zu kommen. Das ist aber nur Kosmetik

Für mich sind das halt nicht unbedingt Strings, auch wenn bei Keypads die Tasten i.d.R. mit char belegt werden

Ohne Strings:

byte code1[4] = { '1', '5' };  //der Rest ist 0 da global 
byte code2[4] = { '1', '2', '3', '4' };

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  static byte index;
  static byte input[4];

  if (Serial.available())
  {
    char c = Serial.read();

    if (c == '#')
    {
      if (memcmp(input, code1, 4) == 0)
        Serial.println("Code 1");
      else if (memcmp(input, code2, 4) == 0)
        Serial.println("Code 2");
      else
        Serial.println("Falscher Code");
      
      Serial.println();
      memset(input, 0, 4);
      index = 0;
    }
    else
    {
      if (index < 4)
      {
        input[index++] = c;
        Serial.println(c);
      }
      else
      {
        Serial.println("Fehler bei Eingabe!\n");
        memset(input, 0, 4);
        index = 0;
      }
    }
  }

Achtung: wenn der Code 0000 ist, muss man nur # drücken und es ist korrekt. Das kann man abfangen, aber es geht hier nur um den grundlegenden Vergleich

Mit Strings:

const char code1[] = "15";
const char code2[] = "1234";

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  static byte index;
  static char input[5];

  if (Serial.available())
  {
    char c = Serial.read();

    if (c == '#')
    {
      input[index] = '\0';
      
      if (strcmp(input, code1) == 0)
        Serial.println("Code 1");
      else if (strcmp(input, code2) == 0)
        Serial.println("Code 2");
      else
        Serial.println("Falscher Code");
      
      Serial.println();
      index = 0;
    }
    else
    {
      if (index < 4)
      {
        input[index++] = c;
        Serial.println(c);
      }
      else
      {
        Serial.println("Fehler bei Eingabe!\n");
        index = 0;
      }
    }
  }
}

Klar geht beides. Ich benutze auch lieber das Wort Zeichenkette, um es von der Stringklasse abzugrenzen. Da man erfahrungsgemäß immer mal wieder Eingaben als Debugausgaben bracht, hat sich bei mir die Betrachtung als Zeichenkette als die praktischere erwiesen.
Wie Du aber schon schriebst - es ist Geschmackssache.

Gruß Tommy

Das ist nur das sekundäre Problem. Das Primäre ist es, dass ich die Eingabe des Testenfeldes überhaupt nicht in eine Variabel schreiben kann. Somit kann ich es auch nicht Vergleichen...

Jo02ny:
Das ist nur das sekundäre Problem. Das Primäre ist es, dass ich die Eingabe des Testenfeldes überhaupt nicht in eine Variabel schreiben kann. Somit kann ich es auch nicht Vergleichen...

Dann lass dir doch einfach mal im seriellen Monitor anzeigen, was bei jedem Tastendruck ausgegeben wird.
Darauf kannst du doch weiter aufbauen und vergleichen.
Das Ergebnis kannst dann in deine Variablen speichern und entsprechend weiter nutzen.

Korrigiere dazu aber deine Baudrate in "Serial.begin" auf den richtigen Wert.

Jo02ny:
Nur funktioniert er nicht.

Die Fehlerbeschreibung ist ausbaubar. :slight_smile:

leider ist dein Code recht wirr und du vermischt Datentypen.

"if (customKey)"
customKey enthält einen char. In der Klammer des if Befehls muss aber ein boolscher Wert stehen.
wenn, dann müsste es heissen: if (customKey == '1')

"taste1=customKey;"
damit weißt du einer Variablen taste1 (int) den Inhalt von customKey (char) zu.
char ist ein Zeichen, ein Buchstabe. int enthält eine Zahl.
Du könntest sowas probieren: if(customKey=='1') { taste1 = 1};
der Unterschied zwischen '1' und 1 ist dir klar? das erste ist ein Zeichen, also quasi alles, was man drucken kann, kann auch 'a' oder '?' oder '@' enthalten. Das zweite ist die Zahl 1. die Variable könnte aber 12 oder 6941 oder -27 enthalten.

Warum probierst du nicht einfach mal das Beispiel aus dem Keypad - Tutorial?

Jo02ny:
Das Primäre ist es, dass ich die Eingabe des Testenfeldes überhaupt nicht in eine Variabel schreiben kann.

In #6 gibt es eine Variable input, wo die Eingabe reingeschrieben wird.

Wenn Du lieber mit Zahlen vergleichen möchtest, kannst Du zur Wandlung von Zeichenkette nach Zahl atoi verwenden. Die Ideen von #6 übernommen für einen Vergleich von Zahlen:

const byte led = 13;
const uint16_t zahl1 = 50, zahl2 = 1234;

void setup() {
  Serial.begin(9600);
  Serial.println("Anfang");
  pinMode(led, OUTPUT);
}

void test1()
{
  digitalWrite(led, HIGH);
  Serial.println("Funktion 1");
}

void test2()
{
  digitalWrite(led, LOW);
  Serial.println("Funktion 2");
}

char getKey()
{
  char c = '\0';
  if (Serial.available())
  {
    c = Serial.read();
  }
  return c;
}

void loop()
{
  static byte index;
  static char input[6];

  char customKey = getKey(); // customKeypad.getKey();
  if (customKey)
  {
    Serial.print(customKey);
    if (customKey == '#')
    {
      input[index] = '\0';
      uint16_t zahl = atoi(input);
      Serial.print("\t");
      Serial.print(input);
      Serial.print("\t");
      Serial.println(zahl);
      index = 0;
      if (zahl == zahl1) test1();
      if (zahl == zahl2) test2();
    } else {
      if (index < sizeof(input) / sizeof(input[0]))
      {
        input[index++] = customKey;
      } else {
        Serial.println("\nFehler bei Eingabe!\n");
        index = 0;
      }
    }
  }
}