Hallo Forum, ich versuche mich gerade ein bisschen in Elektronik und Mikrocontroller einzuarbeiten. Leider sind meine Vorkenntnisse hier sehr beschränkt - aber der Wille zum Lernen ist da. Momentan versuche ich ein Tastenfeld auszulese welches aus eine alten Tape-Deck stammt. Es hat 8 Tasten. Angeordnet ist das in einer 2 x 4 Matrix. Ich hab das jetzt mal so definiert, dass es 2 Reihen mit jeweils 4 Spalten sind. In der ersten Reihe ist jeweils eine Diode nach dem Schalter die den Strom von der Reihe in die Spalte fliessen lässt. Bei der zweiten Reihe ist nur eine Diode drin. Auslesen will ich das ganze mit einem Raspberry. Mir ist der Algorithmus dafür aber nicht klar. Mein Verständniss ist: Ich definiere die Pins der Reihe als OUTPUT und setze sie auf HIGH (3,3 Volt). Die Spalten setzte ich als INPUT mit einem Pull-Down-Widerstand. Wenn ich nun eine Taste drücke, dann sollte doch der entsprechende Pin der Spalte auf HIGH gehen, oder? Dann hab ich zumindest schon mal die Spalte gefunden in welcher die Taste liegt. Wie bekomm ich aber nun die Reihe raus? Aus den Beispielen die ich im Netz finde werde ich nicht schlau. Vielen Dank schon mal, Jürgen
Die Reihe hast du doch selbst definiert: Die Reihe, an der du 3.3 V anlegst.
Hallo, momentan leg ich an alle Reihen gleichzeitig die 3.3 Volt an. Wenn ich dich richtig verstehe, sollte ich jeweils nur an einer die Spannung anlegen. Dann die Spalten auslesen und dann Reihe wieder auf NULL und die nächste Reihe auf HIGH? Ist das echt so einfach.....? Jürgen
Jürgen P. schrieb: > Ist das echt so einfach.....? Mal Dir auf, was passiert, wenn man es so macht, und Du hast Chancen, es zu verstehen.
Jürgen P. schrieb: > Mein Verständniss ist: > Ich definiere die Pins der Reihe als OUTPUT und setze sie auf HIGH (3,3 > Volt). Das geht nicht statisch. Bei einer Matrix muss man in kurzen Abständen (Millisekunden) eine Reihe Hi setzen und die Splaten abfragen, dann die nächste Reihe usw. Georg
Vielen Dank, das hilft mir schon mal sehr weiter. Wenn ich aber eine library wie z.B. die hier einsetzen will https://github.com/jperkin/node-rpio Dort gibt es eine Methode "Poll" die anscheinend auf fallende, steigende oder beide Flanken reagiert. Dann wäre mein Verständniss, dass ich mir selbst das umschalten der Reihen sparen, oder? Aber ich muss mir das echt mal selber malen und probieren. Jürgen
Jürgen P. schrieb: > Dann wäre mein Verständniss, dass ich mir selbst das umschalten der > Reihen sparen, oder? Das geht bei einer Matrix eben nicht, aus Prinzip. Pollen geht nur bei ständig angesteuerten Pins, also in deinem Fall nur mit 1 Spalte, und sowieso ist Pollen i.A. die schlechteste aller möglichen Lösungen. Es gibt noch viel zu lernen. Georg
Kommt drauf an, was man unter Pollen versteht. Hier würde ich zuerst SEG1 auf low setzen (SEG2 auf high) und die ersten 4 Tasten abfragen (Wahlweise Q401 für die REC Led durchsteuern), dann SEG1 auf high und SEG2 auf low für den zweiten Satz à 4 Tasten (Q401 macht dann die Repeat LED). Wenn SEG1 low ist, steuert der Transistor ausserhalb des Auszuges die Play LED an.
:
Bearbeitet durch User
Hallo, danke für die Antworten: @Georg: Ja, ich weiss. Pollen ist nicht so der Brüller. Ich würde auch lieber was mit Interrupts machen, aber da hab ich für den Raspi nichts gefiunden. Und ja..."es gibt noch viel zu lernen". Aber irgendwie muss man anfangen. Warum geht das bei einer Matrox nicht? @Matthias: Das ist dann aber auch Polling, oder? Wie gesagt hatte ich die library rpio so verstanden, dass die selber pollt (oder was auch immer) und mir dann sagt, wann eine Leitung auf Lo geht. Dann kann ich das mit der CallBack Funktion abfangen. Jürgen
Jürgen P. schrieb: > @Georg: Ja, ich weiss. Pollen ist nicht so der Brüller. Ich würde auch > lieber was mit Interrupts machen, aber da hab ich für den Raspi nichts > gefiunden. > Und ja..."es gibt noch viel zu lernen". Aber irgendwie muss man > anfangen. Dann lerne es auch richtig. Pollen ist immer noch DIE Methode um Tasten sicher und nach Plan auszuwerten. Tasten und Interrupts machen immer Probleme wenn dann noch andere Ints dazukommen.
ps ich beziehe mich auf den Flankeninterrupt an den Pins, der unnötig Probleme macht. Nicht auf Timerinterrupts die zum Pollen benutzt werden.
Stephan schrieb: > Dann lerne es auch richtig. Pollen ist immer noch DIE Methode um Tasten > sicher und nach Plan auszuwerten. Aber nicht irgendwo wild herumpollen, sondern aus einem Timer-Interrupt.
Nop schrieb: > Aber nicht irgendwo wild herumpollen, sondern aus einem Timer-Interrupt. So mache ich das auch - ich habe hier eine Tastenmatrix in einem 4-Kanal Recorder von Fostex, der auch noch reichlich LEDs und eine 4-stellige 7-Segment Anzeige an den Tasten hat. Der Timer Interrupt schiebt die aktive Spalte eins weiter und fragt dann die Tasten ab, die in ein Array passend zur Spaltennummer gespeichert werden. Gleichzeitig wird aus dem zur Spaltennummer passenden LED Array das Datum auf die LED Treiber geschrieben. Ende der ISR. Beim nächsten Aufruf gehts weiter mit der nächsten Spalte. Das ganze läuft mit etwa 400Hz auf einem alten Mega8, der drei Latches antreibt, weil er einfach zu wenig Pins hat. Der Befehlsinterpreter liest die Tastenarrays und setzt sowohl die Steuerleitungen des Recorders als auch die LED Arrays - die ganze Logik des 4-Kanal Recorders ist ein recht langes switch-case Konstrukt.
Stephan schrieb: > Nicht auf Timerinterrupts die zum Pollen benutzt werden. Nop schrieb: > Aber nicht irgendwo wild herumpollen, sondern aus einem Timer-Interrupt. EBEN - was ich angesprochen habe, ist Pollen im Hauptprogramm, möglichst noch mit Delay-Aufrufen. Das Abfragen im Time Interrupt läuft für mich nicht unter der Bezeichnung Pollen. Den Unterschied sehe ich darin, ob in einer Programmschleife auf eine Änderung am Input gewartet wird - einfach aber extrem ineffektiv. Georg
georg schrieb: > Den Unterschied sehe ich darin, ob > in einer Programmschleife auf eine Änderung am Input gewartet wird - > einfach aber extrem ineffektiv. Vor allem wird das schnell schwierig, wenn die Hauptroutine mehr machen soll als nur I/Os zu setzen. Jede Aktivität muß dann von der Delay-Zeit abgezogen werden, das wird schnell unübersichtlich. So hingegen macht man im Timer-Interrupt das Debouncing, schiebt erkannte Tastendrücke in einen Ringbuffer und wertet diesen dann im Hauptprogramm aus.
Jürgen P. schrieb: > Ich definiere die Pins der Reihe als OUTPUT und setze sie auf HIGH (3,3 > Volt). > Die Spalten setzte ich als INPUT mit einem Pull-Down-Widerstand. > Wenn ich nun eine Taste drücke, dann sollte doch der entsprechende Pin > der Spalte auf HIGH gehen, oder falschrum. Die Dioden erlauben nur, dass eine gedrückte Taste eine der 4 Leitungen auf Masse (low) zieht. Man muss also die 4 Leitungen auf INPUT mit pull up stellen. Die 2 Reihen auf OUTPUT, beide high. Dann eine Reihe auf low und gucken ob eine (oder mehrere) der 4 Inputs auf low gezogen wird, diese Tasten sind dann gedrückt. Dann diesen Reihenausgang wieder auf high und den anderen auf low und gucken welche (ob überhaupt einer) der 4 Eingänge auf low gezogen wird. Das sind dann die 4 Tasten der anderen Reihe. Die LEDs werden durch high am jeweiligen Ausgang der beiden oberen Leitungen mit Vorwiderstand jeweils aktiviert in der Zeit in der man eine Reihe ausliest bzw. den low Pegel des Ausgangs strhe lässt bis man die nächste Reihe einlesen will, eigentlich wären 4 LEDs möglich (2x2).
Nop schrieb: > schiebt > erkannte Tastendrücke in einen Ringbuffer Ringbuffer muss nicht unbedingt die beste Lösung sein. Hier z.B. will man evtl. den gleichzeitigen Druck von REC und PLAY auswerten, um die Kiste auf Aufnahme zu schalten - oder PLAY und FF, um eine 'Skip' Funktion zu starten. Deswegen nutze ich in meinem Recorder Projekt die Arrays.
:
Bearbeitet durch User
MaWin schrieb: > Die Dioden erlauben nur, dass eine gedrückte Taste eine der 4 Leitungen auf Masse (low) zieht. Darüber sollten wir noch einmal sprechen!
Nop schrieb: > Stephan schrieb: > >> Dann lerne es auch richtig. Pollen ist immer noch DIE Methode um Tasten >> sicher und nach Plan auszuwerten. > > Aber nicht irgendwo wild herumpollen, sondern aus einem Timer-Interrupt. Deswegen schrieb ich ja dort "nach Plan".
Stephan schrieb: >> Aber nicht irgendwo wild herumpollen, sondern aus einem Timer-Interrupt. > > Deswegen schrieb ich ja dort "nach Plan". die Alternative wäre "planloses" herum pollen?
Abend zusammen, also Leute, ich wollte hier keinen Streit unter euch stiften. Alle mal wieder ruhig werden..... Ok, also wenn ich das nun richtog deute, dann ist das mit den Interupts auf ne Flanke nix. Timer-Interrupts wären besser. Also such ich nun eine Library die mir erlaubt, z.b. alle x msec eine Funktion aufzurufen die dann das macht, was MaWin vorgeschlagen hat. Es sein denn, Manfred ("darüber sollten wir nochmal sprechen") hat einen anderen Vorshclag. Bin grade noch am Zeichnen (von Hand) und werde dann mal mit Buntstiften einzeichnen, wo denn die Ströme fliesen und überlegen, was HIGH und was LOW ist.
Manfred schrieb: > Darüber sollten wir noch einmal sprechen! Vergiss das, verwirrt nur. Es ist schon so, wenn man eine Spalte auf low legt, antwortet eine gedrückte Taste auf den 4 Zeilenleitungen auch mit low (am besten hat man auf den Zeilen Pullups). Je nachdem, ob man SEG1 oder SEG2 auf low legt, kann man die rechte Gruppe Tasten (Repeat, Rec, Pause, Autospace) oder die linke (Stop, Fwd, Rew, Play) abfragen.
Jürgen P. schrieb: > Es sein denn, Manfred ("darüber sollten wir nochmal sprechen") hat einen > anderen Vorshclag Wenn, dann würde der nicht funktionieren. Jürgen P. schrieb: > Also such ich nun eine Library die mir erlaubt, z.b. alle x msec eine > Funktion aufzurufen Die Funktion ist so primitiv, die kann man auch ohne library-Shield, das Problem ist die Eingangspinzuordnung, hier D0 bis D3 benutzt.
1 | byte seg; |
2 | byte key; |
3 | byte keypressed() // call every 10ms |
4 | {
|
5 | key&=0x0F<<(seg<<2)); |
6 | digitalWrite(SEG1,seg); |
7 | seg=!seg; |
8 | digitalWrite(SEG2,seg); |
9 | key|=((!PORTD&0x0F)<<(seg<<2)); |
10 | return key; |
11 | }
|
Rausfinden wie's funktioniert left as an exercise to the reader.
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.