Anbei erstmal mein Quelltext den ich bisher erstellt habe mit dem myAVR Workpad Plus in Verbindung mit dem myAVRMK2 Board . Daran angeschlossen haben ich eine Tastaturmatrix : Betrieben wird das ganze mit einem ATMega8 . main () // Hauptprogramm, startet bei Power ON und Reset { DDRD = 0b10000000; PORTD = 0b00000000; DDRB = 0b000011; PORTB = 0b111100; DDRC = 0xFF; while (true) { switch(PINB & 0b111100) { case 0b111000 : DDRD = 0b00000000; PORTD = 0b10000000; DDRB = 0b111100; PORTB = 0b000011; switch(PINB & 0b000011) { case 0b000001 : DDRD = 0b10000000; PORTD = 0b00000000; DDRB = 0b000011; PORTB = 0b111100; PORTC = 0b100000; waitMs(200); //3 break; case 0b000010 : DDRD = 0b10000000; PORTD = 0b00000000; DDRB = 0b000011; PORTB = 0b111100; PORTC = 0b010000; waitMs(200); //2 break; default : DDRD = 0b10000000; PORTD = 0b00000000; DDRB = 0b000011; PORTB = 0b111100; PORTC = 0b001000; waitMs(200); // 1 break; } break; case 0b110100 : DDRD = 0b00000000; PORTD = 0b10000000; DDRB = 0b111100; PORTB = 0b000011; switch(PINB & 0b000011) { case 0b000001 : DDRD = 0b10000000; PORTD = 0b00000000; DDRB = 0b000011; PORTB = 0b111100; PORTC = 0b100000; waitMs(200); // 6 break; case 0b000010 : DDRD = 0b10000000; PORTD = 0b00000000; DDRB = 0b000011; PORTB = 0b111100; PORTC = 0b010000; waitMs(200); // 5 break; default : DDRD = 0b10000000; PORTD = 0b00000000; DDRB = 0b000011; PORTB = 0b111100; PORTC = 0b001000; waitMs(200); // 4 break; } break; case 0b101100 : DDRD = 0b00000000; PORTD = 0b10000000; DDRB = 0b111100; PORTB = 0b000011; switch(PINB & 0b000011) { case 0b000001 : DDRD = 0b10000000; PORTD = 0b00000000; DDRB = 0b000011; PORTB = 0b111100; PORTC = 0b100000; waitMs(200); // 9 break; case 0b000010 : DDRD = 0b10000000; PORTD = 0b00000000; DDRB = 0b000011; PORTB = 0b111100; PORTC = 0b010000; waitMs(200); // 8 break; default : DDRD = 0b10000000; PORTD = 0b00000000; DDRB = 0b000011; PORTB = 0b111100; PORTC = 0b001000; waitMs(200); // 7 break; } break; case 0b011100 : DDRD = 0b00000000; PORTD = 0b10000000; DDRB = 0b111100; PORTB = 0b000011; switch(PINB & 0b000011) { case 0b000001 : DDRD = 0b10000000; PORTD = 0b00000000; DDRB = 0b000011; PORTB = 0b111100; PORTC = 0b100000; waitMs(200); // # break; case 0b000010 : DDRD = 0b10000000; PORTD = 0b00000000; DDRB = 0b000011; PORTB = 0b111100; PORTC = 0b010000; waitMs(200); // 0 break; default : DDRD = 0b10000000; PORTD = 0b00000000; DDRB = 0b000011; PORTB = 0b111100; PORTC = 0b001000; waitMs(200); // * break; } break; default : PORTC = 0x00; break; } } } Leider bin ich noch recht unerfahren im Programmieren von Mikrocontrollern . Der Quelltext kann bereits genau unterscheiden welche Taste genau gedrückt wird auch wenn ich denke das ich das ziemlich umständlich umgesetzt habe . Soweit so gut allerdings kommt mir keine Idee wie ich jetzt einen Code einprogrammieren könnte der nach richtiger Eingabe beispielsweise eine LED schaltet . Vielleicht kann mir hier jemand mal einen Ansatz bzw ein Stichwort geben wie ich das umsetzten könnte . Lieben Dank schonmal und Gruß
du speicherst die Werte (ich nehme mal Zahlen von 0-9 an) in einer Variable. Dabei kannst du die Zahlen entweder verschieben oder mit einem Faktor multiplizieren: z.B. Wert = 0; Taste 2 gedrückt -> Wert *= 10; //"verschoben" um 10, hier egal, da 0 -> Wert += 2; // Wert ist 2 Taste 4 gedrückt -> Wert * 10; -> Wert += 4; //Wert ist jetzt 24 Taste bestätigen -> if Wert == Code -> Piepen
Andre schrieb: > Anbei erstmal mein Quelltext den ich bisher erstellt habe mit dem myAVR > Workpad Plus in Verbindung mit dem myAVRMK2 Board . > Daran angeschlossen haben ich eine Tastaturmatrix : Wie ist die angeschlossen (Schaltplan) Der Code schreit förmlich danach mit ein paar Schleifen und sonstigen Sachen drastisch vereinfacht zu werden. > Soweit so gut allerdings kommt mir keine Idee wie ich jetzt einen Code > einprogrammieren könnte der nach richtiger Eingabe beispielsweise eine > LED schaltet . Warte noch. Sieh erst mal zu, dass die Matrixabfrage einfacher wird Letztenendes willst du bei einer Funktion landen, die dir sagt welche Taste gedrückt ist. Das ist dein erstes Zwischenziel. Aber der jetzige Code ist mit seinen vielen Port Zugriffen und Binärkonstanten soweit undurchschaubar, dass sich diese Funktion nicht wirkich aufdrängt. Der Code agiert so ähnlich wie in einer Analogie jemand der nicht Multiplizeren kann und 3 * 4 bestimmt indem er 3 + 3 + 3 + 3 ausrechnet. Nicht wirklich falsch aber deutlich zu kompliziert.
Ich habe mal etwas überlegt allerdings fällt mir einfach nichts anderes ein . Am besten wären natürlich Befehle bzw Abfragen die direkt aus der Binärkombination der Matrix erkennt welche Taste genau gedrückt ist . Ich wollte ja zb auch einen Lernmodus einbauen mit dem ich dann einen neuen Code einprogrammieren kann . Ich brächte da echt Hilfe von euch zumindest ein Stichwort womit ich es umsetzen kann . Ich wurschtel mich dann irgendwie durch wenn ich die grobe Richtung kenne . Kann man sowas nicht am besten mit Interrups realisieren ? . So würden die Tastenabfragen nicht in der ständig wiederholenden Programmschleife liegen .
Andre schrieb: > Kann man sowas nicht am besten mit Interrups realisieren ? . Ja. Aber erst mal eins nach dem anderen. Also: Wie ist die Matrix verschaltet?
Also die Spalten liegen jeweils an PIN 1..3 und die Zeilen an 4..7 . Daher habe ich quasi in den case Abfragen erst ausgelesen welche Zeile gedrückt wurde und innerhalb dessen dann welche Spalte genau damit ich am Ende die Zuordnung für exakt eine Zahl bekomme .
Ich bin jetzt soweit das ich mir Gedanken mache wie ich den Code den nun wirklich "vergleichen" kann . Ich habe zwar schon mit Rechnungen versucht aber z.B. wenn ich 1234 nehme und es rückwärts eingebe wird es auch als richtig erkannt . Wie könnte man sowas denn umsetzen ? Die Lösung von "Flo" habe ich nicht ganz verstanden bzw wenn ich sie richtig verstanden habe komme ich zum selben Problem . Es darf einfach nur ein einziger Code auch richtig sein . Habe es mal mit Strings versucht da denn der Code an sich verglichen wird bin dann aber daran gescheitert das ich mein tmpCode = "0" nicht ausführen konnte weil irgendwas mit char und const char nicht passt ?!. Wäre für jede Idee dankbar
Andre schrieb: > Wie könnte man sowas denn umsetzen ? Du könntest zb so etwas machen: Du hast eine Funktion, die dir einen Tastendruck liefert. Das ist schon mal einer der wichtigen Punkte: Wird eine Taste gedrückt, dann liefert dir die Funktion den Code für diese Taste nur ein einziges mal. OK. Ich gehe davon aus, dass du so etwas hast. Vergiss auch erst mal die Werte, die auf den Tasten stehen. Jede Taste hat einen Code, nur der ist wichtig (damit man die Ziffern von den restlichen Tasten unterscheiden kann) Die Frage lautet daher: Dein Benutzer drückt nacheinander Tasten. Wie kannst du feststellen, dass zb die letzten 4 Tastendrücke genau einer vorgegebenen Sequenz entsprechen? In der Fragestellung ist in einem gewissen Umfang auch schon die Lösung enthalten. 'die letzten 4 Tastendrücke' Die wird man sich zwischenspeichern müssen. Bei jedem Tastendruck wird die älteste entfernt, dafür kommt die neu gedrückte Taste dazu. Und dann schaut man einfach, ob die 4 Tastendrücke der vorgegebenen Sequenz entsprechen. Wenn ja: Bingo Lösungsansatz 1: Du hast ein Array von 4 Werten. Nennen wir es
1 | unsigned char Input[4]; |
Input[0] sei dabei der 'älteste' Tastendruck (ausgedrückt als der dieser Taste zugeordnete Code). Input[3] sie die zuletzt gedrückte. Drückt der Benutzer eine Taste, dann wird sie 'hinten im Array angehängt'. Dies geschieht, indem der älteste Tastendruck verworfen wird, alle anderen um 1 Stelle im Array nach vorne rutschen und der neue Tastendruck an die Position Input[3] kommt
1 | for( i = 1; i < 4; ++i ) |
2 | Input[i-1] = Input[i]; |
3 | Input[3] = neuer_Tasten_Code; |
Dann hat man natürlich noch ein 2-tes Array, in dem die korrekte Tastenkombination drinnensteht
1 | unsigned char Code[4] = { 1, 8, 5, 3 }; |
und nachdem die neu gedrückte Taste im Input Array gelandet ist, vergleicht man einfach, ob alle Stellen in Input damit mit Code übereinstimmen. Das macht man in einer Schleife indem man jeweils korrespondierende Arrayelemente miteinander vergeleicht. Ausgansgpunkt ist die Annahme: der Code ist korrekt und sobald man ein Pärchen gefunden hat, welches nicht übereinstimmt revidiert man diese Annahme: der eingegebene Code ist nicht korrekt. Nach der Schleife prüft man einfach, ob die ursprüngliche Annahme gehalten hat oder nicht.
1 | for( i = 1; i < 4; ++i ) |
2 | Input[i-1] = Input[i]; |
3 | Input[3] = neuer_Tasten_Code; |
4 | |
5 | korrekt = TRUE; |
6 | for( i = 0; i < 4; ++i ) { |
7 | if( Input[i] != Code[i] ) |
8 | korrekt = FALSE; |
9 | }
|
10 | |
11 | if( korrekt ) |
12 | öffne_Tür |
Das ist eine Möglichkeit. Eine andere sieht so aus, das man sich die bisher eingegebenen Tasten nicht merkt, sondern nur wieviele Stellen bisher korrekt waren. Kommt ein neuer Tastendruck der stimmt (mit dem Code vergleichen), dann hat man wieder eine korrekte Taste mehr. Stimmen sie nicht überein, dann wird die Anzahl der korrekten Tasten wieder auf 0 gesetzt
1 | unsigned char bisher_korrekt; |
2 | ...
|
3 | |
4 | while( 1 ) { |
5 | |
6 | ....
|
7 | |
8 | if( neuer_Tasten_Code == Code[ bisher_korrekt ] ) |
9 | bisher_korrekt++; |
10 | else
|
11 | bisher_korrekt = 0; |
12 | |
13 | if( bisher_korrekt == 4 ) |
14 | öffne_Tür |
15 | |
16 | }
|
Die zweite Variante ist signifikant kürzer und auch ein wenig trickreicher als die erste. Hat man aber das Prinzip erst mal so einigermassen, ist sie aber denk ich auch nicht schwieriger als die erste.
Naja habe jetzt wieder das ganze über den Haufen geworfen . Die Abfrage der einzelnen Tasten ist immernoch totaler Mist . Zb dürfte die Taste ja auch nicht mehrfach gezählt werden wenn man sie länger hält . Den Abgleich vom Code habe ich insofern erstmal gelöst gehabt als das ich strcat bei Tastendruck immer ein Zeichen also z.B. eine 1,2 etc in einen Leerstring schreiben lassen habe . Am Ende wurde dann immer der String mit dem eingespeicherten String verglichen usw. Hat super geklappt aber wie gesagt diese Tastenmatrix macht mir doch zu schaffen weil man sie ja in erster Linie nichtmal direkt ansprechen kann . Gibt es nicht irgendeine Möglichkeit ausser zB. ADC die Tasten auf Anhieb zu erkennen .Bzw eine Funktion die nur die Taste annimmt wenn man sie auch wieder losgelassen hat würde ja meiner Meinung nach schon helfen .
Andre schrieb: > Naja habe jetzt wieder das ganze über den Haufen geworfen . > Die Abfrage der einzelnen Tasten ist immernoch totaler Mist . > Zb dürfte die Taste ja auch nicht mehrfach gezählt werden wenn man sie > länger hält . Richtig. Schau dir mal diesen Artikel an. Der stammt zwar aus dem Assembler Tutorial, die Gedankengänge sind aber hoffentlich gut genug beschrieben um die Ideen nachvollziehen zu können. http://www.mikrocontroller.net/articles/AVR-Tutorial:_Tasten Solange du dieses Teilproblem nicht zufriedenstellend gelöst hast, hat es keinen Sinn darauf aufbeuend weiterzuarbeiten.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.