Go Down

Topic: Probleme mit Programmcode für Türschloßprojekt (Read 2 times) previous topic - next topic

circuit99

Mach dir als erstes ein Struktogramm/PAP und überleg wie dein Programm funktionieren soll. Wenn du das geschafft hast kannst du dir über die Programmierung Gedanken machen. Das ist dann eine rein technische Frage. Dabei solltest du die Konventionen von C kennen und beachten. Ließ ein Tutorial und beschäftige dich nochmal damit was Datentypen sind. Dann überlegst du, ob du unbedingt mit char arbeiten möchtest, oder ob du einfach byte bzw. int Variablen benutzt. Mit letzteren kann man rechnen und Bitopperationen durchführen. Dann könnte man seinen code auch so einlesen:

myKey = myOwnKeyPad.readKey();   // Abfragen des gedrückten Tasters
if (myKey != X){                            // X ist eine Zahl die kommt, wenn keine Taste gedrückt wurde
Eingabe = Eingabe*10+myKey;
}

michael_x

Quote
... was Datentypen sind. Dann überlegst du, ob du unbedingt mit char arbeiten möchtest, oder ob du einfach byte bzw. int Variablen benutzt. Mit letzteren kann man rechnen und Bitopperationen durchführen


circuit99 hat Recht, nur oben erwähnter Satz ist evtl. missverständlich.
byte und char ist fast dasselbe, bis auf das Vorzeichen.  Du meinst sicher den Unterschied zwischen

#define KEY_0   '0'    // 0x30
#define KEY_0   0     // 0x00

Beides kann sowohl in byte wie auch in char Variablen verwendet werden.

Ersteres kann gleich angezeigt werden, das zweite ist leichter zum Rechnen. Der Unterschied ist aber minimal ( '0' dazuaddieren bzw. abziehen, oder auch bitweise ein/ausblenden)

int brauchst du nur für mehrstellige codes ( long wenns über 4 Stellen sein können ). Ein 8 bit Arduino arbeitet lieber mit bytes.



Quote
#define KEY_star 'stern'
#define KEY_hash 'raute'


ist sehr verwirrend. Schade, dass der Compiler das überhaupt zulässt.

#define KEY_star '*'    // ist übrigens kleiner als '0'
oder
#define KEY_star 10  // oder irgendein Wert > 9

Muss in jedem Fall bei der Berechnung abgefangen werden ( was z.Zt. fehlt und zu Tobias' "Reise nach Jerusalem" führt )


Tobias93

Es gibt 2 Punkte die ich nicht verstehe / bzw. nicht hinbekomme.
1. Wie funktioniert das Einlesen. Wie speichere ich am besten die Eingabe ab, damit ich mit ihr dann auch weiter rechnen und arbeiten kann? Besonders im Bezug auf die Zeichen * und #

2. Wie kann ich das Einlesen der Codes für die einzelnen Ebenen anpassen. Das heißt das er in der Startebene wo er auffordert den Code einzulesen, soll er ja nur bei Eingabe = CODE den Code akzeptieren. Gibt man z.B. #100 ein soll man in die Menüebene kommen. Alle anderen Eingaben werden als falsch erkannt. Ist man nun in der Menüebene und soll auch wider für irgendwelche Funktionen was eingeben soll er ja nun wider etwas einlesen, allerdings das nicht mit den Parametern aus der Startebene vergleichen. Das macht er aktuell. Gibt man z.B. 1000 für Code ändern ein zeigt er an CODE verweigert, das was er aber nur in der Startebene machen soll.

Ich finde zu den beiden Punkten keine Lösung bzw. bekomme es nicht hin.
Ich wäre dankbar für Lösungsvorschläge.
Gruß
Tobias93
Nobody is perfect but - impossible is nothing

Arduinokiller

Hallo,
ich kämpfe mich gerade durch ein ähnliche Problem (siehe String abfragen ?). In meinem Sketch habe dann auch 'atoi' ausprobiert, es wurde mir hier dann der Wert 35 (ascii für #) bzw. 42 (ascii für *) ausgegeben, also "421000" für "*1000", allerdings hat mich das ganze nicht richtig weitergebracht. :smiley-sad-blue:

michael_x

Versuchen wir mal, es einfach zu machen ;)

Mit jedem Tastendruck liefert readKey() ein Zeichen zurück und hat sich schon um Prellen und kurze/lange Tastendrücke gekümmert, oder liefert bei Abfrage den Wert KEY_NOT_PRESSED, wenn kein neuer Tastendruck da war.  Das ist doch schon das Schwierigste.

Für mich das zweitschwierigste war:

#define KEY_star 'stern'

und tatsächlich, Kinder, wenn euch meine Erklärung verwirrt, oder es zu grausam ist, macht schnell die Augen zu

(ich hab meinen Arduino geopfert und es ausprobiert):

Code: [Select]
#define KEY_STAR 'stern' // kein Syntaxfehler, ist ja nur der Präprozessor
  byte testkey = KEY_STAR;  // kein Syntaxfehler
  static char teststring[]= "---";
  teststring[1] = testkey;
  Serial.println(teststring);  // erzeugt  "-n-"

Genauso erzeugt
#define KEY_hash 'raute' im Endeffekt ein 'e'

Das ist jetzt wohl nur Tobias' Problem.

wie Arduinokiller einmal einen Stern als 42 kriegen kann ist mir klar. Merkwürdig ist mir, wie er aber aus  "*10" eine "4210" (statt z.B. "424948" , weil eine '1' hat den ASCII-wert 49 (0x31)  genauso wie '*' den Wert 42 hat.


Tobias kann natürlich die Library anpassen, da hatten wir schon 2 Varianten, eine zum einfach Rechnen, eine zum einfach Anzeigen.
Ab jetzt nehm ich mal an, wir bleiben beim Einfach Anzeigen und die Stern-Taste würde als '*' im Display erscheinen, wenns ein 'n' ist wissen wir ja, warum. Rechnen (einen als Zahl agespeicherten CODE ermitteln und vergleichen) kann man mit '*' genauso schlecht wie mit 'n'.
Ihr könnt die Augen wieder aufmachen

Ein Sclüsselcode bestht also nur aus Ziffern, die # und * Tasten sind was besonderes. Was, das kann man sich frei wählen.
Für's einfache Verständnis lassen wir so wie es jetzt ist: Schlüsselcode sind 4 Ziffern, nicht mehr und nicht weniger.

Wir wollen ausser einer Code-Eingabe auch in einen Funktions-Menü-Modus springen:
Nehmen wir doch dazu das * Zeichen.
Dann definieren wir noch das # Zeichen als Anfang einer Code Eingabe, das hilft auch, wenn man sich vertippt hat.
Bei variabel langen Schlüsseln brauchen wir noch ein Ende-Zeichen ( zB. den Stern ) aber lassen wir das erstmal.
Code: [Select]

#define EINGABE 0
#define MENU 1
byte mode = EINGABE;  // Voreinstellung

byte stelle = 0;
unsigned int CODE = 9367;
unsigned int Eingabe = 0; // gleich als Zahl umgerechnet

void loop(){
  char myKey = myOwnKeyPad.readKey();                    // Abfragen des gedrückten Tasters
  if (myKey != KEY_NOT_PRESSED){                         // Abfragen ob irgendein Taster gedrückt ist
     lcd.print(myKey);                                      // Taste im LCD anzeigen
     if ( mode == EINGABE)
       switch (myKey)  {
       case KEY_STAR:
         mode = MENU;
         break;
      case KEY_HASH:
         delay(200); // damit man das # Zeichen noch kurz sieht
         stelle = 0;    // alles auf Anfang
         Eingabe = 0;
         lcd.clear(); // ...
         break;
      default:  // alle anderen Tasten
         Eingabe = Eingabe*10 + myKey-'0' ;  // setzt voraus, dass diese
         stelle++;
         if ( stelle == 4) {
           if (Eingabe == CODE) {
               // usw. ( richtiger Code )
           } else {
               // falscher Code
           }
         }
         break;
     } // Ende switch
     else {   // Menu - Zweig
         if ( myKey == ...
         // wie kommen wir wieder zur Code - eingabe ???
     }
  }
}


Go Up