Hallo zusammen, ich hab wieder mal eine Frage, diesmal betreffend C-Programmierung. -> Wie kann man auf das Loslassen einer Taste reagieren? (Eventuell auf eine ähnliche Art und Weise wie mit der Funktion kbhit(), mit der das Drücken der Taste festgestellt wird?) Ich bin bei meiner Recherche auf die Funktion "GetKeyboardState()" gestoßen, mit der man den Zustand aller Tasten "kopiert" und dann mit einem Feld auswertet. So wäre die Lösung meines Problems natürlich möglich, ich weiß allerdings nicht ob ich diese Funktion in C verwenden kann, oder ob dies ein C++ Ausdruck ist. Außerdem wären mir einfachere Lösungen recht, wenn es welche gibt. Vielen Dank im Voraus! Hans M.
:
Verschoben durch User
Hallo, Die Frage ist, wie ist der Signalzustand bei losgelassener Taste? Ich mache das konventionell und sinngemäß immer so (positive Flanke): // Flanke auslösen //------------------------------------------------------- if (TASTER == 1) // Signalabfrage auf 1 { if (FLANKENMERKER.0 == 0) // und kein Flankenmerker { FLANKENMERKER.0 = 1; // Flankenmerker setzen } } //------------------------------------------------------- if (FLANKENMERKER.0 == 1) // Wenn Flankenmerker gesetzt { if (TASTER == 0) // Signalabfrage auf 0 { FLANKENMERKER.0 = 0; // dann Flankenmerker löschen } } Den Flankenmerker nimmst Du dann, um weiters auszuführen, er ist nur 1 Zyklus aktiv! Evtl. kannst Du nach dieser Abfrage noch eine Entprellzeit einbauen, das Du nicht mehrere Flanken bekommst, wg. dem Kontaktprellen. Gruß Carsten
Ich mach das immer so: Die Taster werden alle paar ms (Timer und Interrupt) eingelesen, entprellt (Vergleich mit dem letzten und evt. vorletzten Zustand) und pro Taster je ein Flag gesetzt. Eine Flankenerkennung ist natürlich auch möglich, dabei vergleichst du den letzten Zustand mit dem aktuellen. Wurde eine Flanke detektiert, so wird ein Flag gesetzt. Dieses Flag sollte aber nicht in der Interrupt-Funktion, sondern im Hauptprogramm zurückgesetzt werden, da dann dein Programm evt. eine Flanke verpassen könnte. Ob es dafür eine fixfertige, allgemein brauchbare Funktion gibt weiss ich nicht, ich schreibe die meisten meiner Funktionen selbst.
Danke für eure Antworten, ich hab mich allerdings nicht genau genug ausgedrückt, die "Taste" soll eine Taste auf der PC-Tastatur sein ;) Zusätzlich hab ich jetzt die Anforderung, dass ich mehrere Tasten gleichzeitig behandeln soll :(
Programmierst du einen uC oder einen PC? Der Thread ist im uC-Forum und im Titel steht was von PIC. Hast du eine Tastatur an einen PIC angeschlossen?
Ich programmiere einen uC, in meinem Fall PIC. Dieser kommuniziert mit dem PC über eine RS232 und soll auf Tastendruck verschiedene Aktionen ausführen. Das Problem ist nicht, wie ich auf eine beliebige Taste der PC-Tastatur reagiere, sondern dass ich dies mit mehreren Tasten gleichzeitig kann (getch nimmt ja immer nur die letzte gedrückte, also nie mehrere gleichzeitig). Und außerdem möchte ich darauf reagieren können, wenn man die Taste mit dem Finger wieder loslässt.
Lieber Hans, Da du hier anscheinend Doch eher den PC programmierst, wenn auch zur Kommunikation mit nem PIC bist Du irgendwie im falschen Forum; Zudem kommuniziert eine PC-Tastatur mit dem PC ueber ein serielles interface, das jeweils einen keycode ueberträgt. Es kann hier nicht festgestellt werden, ob mehrere Tasten gleichzeitig gedrückt werden. Beim loslassen einer Taste wird kein Codes übertragen, kann also nicht detektiert werden. Der PC puffert die Tasten in einem Tastaturbuffer, woraus diese dann auch verspätet, aber nur sequentiell ausgelesen werden können. viele Grüße nobi
Ich glaube du verstehst nach wie vor etwas falsch, natürlich programmier ich am PC, spiel das Programm aber auf den PIC. Ich will den PIC programmieren und mach das auch ;) Danke jedenfalls für die Tastatur-Auskunft. Dann werd ich das Ganze so lösen, dass ich die Tasten im Programm zeitlich zurücksetze. Wenn ich mit der Funktion kbhit() programmiere, hab ich automatisch immer eine Art "Totzeit" von ca. 100 ms drin. Hängt das mit der Funktion zusammen, oder mit dem getch(), der darauf folgt? Kann getch() z.B. nur alle 100 ms ein Zeichen einlesen, auch wenn ich auf der Taste drauf bleibe? Oder fragt kbhit() nur alle 100 ms ab, ob etwas gedrückt wurde? Und ist meine Annahme mit 100 ms richtig oder liege ich daneben?
Hans M. schrieb: > Dieser kommuniziert mit dem PC über eine RS232 und soll auf Tastendruck > verschiedene Aktionen ausführen. Dann muß Dein PC-Programm für jede Taste (auch für Strg, Alt usw.) einen Drück- und einen Loslassen-Code übertragen. Ein normales Terminalprogramm macht das aber nicht. Und was der PIC nicht empfängt, kann er logischer Weise auch nicht auswerten. Du mußt also erstmal ein PC-Programm dafür schreiben. Erst dann kann der PIC diese Codes empfangen und auswerten. Peter
nochmal ne blöde frage, wenn Du den PIC programmieren willst, und hier die ganze Zeit fragen nach der Tastaturauslesung stellst, willst du dann die PC-Tastatur an den PIC anschliesen, oder vieleicht doch am PC? im übrigen gibt kbhit TRue zurück, wenn eine Taste gedrückt wurde ohne es auszulesen, getch wartet dagegen auf eine Eingabe. kbhit wartet nicht, sondern läuft einfach durch , getch dagegen läuft erst dann weiter, wenn es ein Zeichen aus dem Tastaturbuffer ausgelesen hat. Die Zykluszeit bei gedrückt gehaltener Taste hängt dabei von der Wiederholfrequenz der Tastatur ab, und diese ist in der Systemsteuerung Einstellbar. Aber Du willst ja kein Programm fuer den PC schreiben ?-?
Ok, ich werd dir das gesamte System vorstellen ;) Ich sitz am Laptop vorm Haus, an diesem hängt ein RS232-Funkmodul. Der PIC, den ich programmiere, ist auf einem ferngesteuerten Fahrzeug verbaut, welches ich dann steuern will. Die RS232-Funkstrecke ersetzt mir nur das Kabel, dass ich zwischen Laptop und Fahrzeug natürlich nicht haben will. Der RS232-Funkmodul-Empfänger am Fahrzeug teilt dem PIC am Fahrzeug mit, dass ich z. B. die Taste "W" gedrückt habe, der PIC erkennt anhand des ankommenden Zeichens "W", dass er das Signal für die Fahrtenregler (=Endstufe vor den Motoren) entsprechend verändern muss, und das Fahrzeug sich damit vorwärts bewegt. Wenn ich die Taste "W" jetzt loslasse, sollte der PIC das Signal natürlich wieder in Richtung Stillstand verändern. Der PIC dient sozusagen als Ersatz für den Empfänger einer richtigen Fernsteuerung, die jeder von handelsüblichen Fahrzeugen kennt. Das meinte ich, also ist die Zeit von ca. 100 ms, die ich festgestellt habe, die Zeit, die "getch" wartet, bis ein neues Zeichen kommt, und das kommt bei meiner eingestellten Wiederholrate dann ca. alle 100 ms. Dann werd ich mein Problem mit dem Loslassen der Taste so lösen, dass ich z. B. alle 150 ms meine Variable "Taste", in die der getch hineinschreibt, einfach zurücksetze und der PIC somit mit einer x-beliebigen anderen Taste nicht mehr die Aktion "vorwärts" ausführt.
OK. Also ist dein Problem ein PC-Problem und ich verschieb den Thread mal entsprechend.
>Zudem kommuniziert eine PC-Tastatur mit dem PC ueber ein serielles >interface, das jeweils einen keycode ueberträgt. Es kann hier nicht >festgestellt werden, ob mehrere Tasten gleichzeitig gedrückt werden. >Beim loslassen einer Taste wird kein Codes übertragen, kann also nicht >detektiert werden. (alles) kompletter Schmarren.. hier z.b. 26 gleichzeitig http://www.hardwareluxx.de/index.php/news/hardware/eingabegeraete/14306-26-tasten-anti-ghosting-microsoft-stellt-gaming-tastatur-sidewinder-x4-vor.html
wie das ganze am PC funktioniert, hängt jetzt mal vorallem davon ab, Was du machst? ein Windows Programm, oder Linux? DOS ? und warum schreibst du das PC Programm in C???
Ich schreib in C, benutze dann den CCS Compiler, und der daraus entstandene Assembler-Code wird in den PIC hinuntergeladen. Ich schreibe kein PC Programm! Ich nutze HyperTerminal zur Kommunikation über die RS232 mit dem PIC!
Dann aber gibt es gar kein getch, und dann gibt es auch keine von Dir ausgedachten Verzögerungszeiten -- sofern diese nicht durch die seriellen Funkmodule verursacht werden. Verhält sich der Kram denn genauso, wenn Du statt der Funkstrecke ein serielles Kabel verwendest? Ansonsten: Es heißt serielle Übertragung, weil da Daten nacheinander übertragen werden. Mehrere simultane Tastendrücke lassen sich damit nicht übertragen, schon gar nicht, wenn da ein normales Terminalprogramm verwendet wird.
Klar gibt es einen getch, läuft ja so wie es soll ;) Ich hab während dem Programmieren immer eine Kabelverbindung, keine Funkstrecke, funktioniert bisher so, wie ich es beschrieben habe. Mir geht's ja auch nicht um eine echtzeitfähige, exakt gleichzeitige Übertragung. Die Übertragung soll ja seriell sein, aber eben beide Tasten beinhalten. Stört mich ja nicht wenn die 2. gedrückte Taste (Hausnummer) 4 Nanosekunden später "ankommt". Vielleicht noch zur Veranschaulichung: Das Fahrzeug ist ein Kettenfahrzeug, das heißt 2 Motoren und 2 getrennte Steuersignale, jeweils für die Kette links und die Kette rechts. Mir wäre es bereits möglich, mit meiner aktuellen Lösung jede Kette einzeln mit 2 Tasten zu steuern - jede Kette getrennt vor und zurück. Das Kurvenfahren ist mit dieser Methode natürlich noch nicht optimal. Darum wollte ich zusätzlich eine Steuerung wie bei einem PC-Spiel programmieren (z. B. "W" und "A" gleichzeitig für eine Linkskurve während man am Gas bleibt)
Hans M. schrieb: > Klar gibt es einen getch, läuft ja so wie es soll ;) Dann ist das eine Empfangsroutine, die Zeichen von der seriellen Schnittstelle abholt. Eine Tastatur gibt es aus Sicht Deines µCs nicht. Hans M. schrieb: > Darum wollte ich zusätzlich eine Steuerung wie bei einem PC-Spiel > programmieren (z. B. "W" und "A" gleichzeitig für eine Linkskurve > während man am Gas bleibt) Das ist mit der Art, wie ein Terminal(-Programm) Tastendrücke überträgt, nicht umsetzbar. Das ginge nur, wenn Du statt des Terminalprogrammes Dein eigenes Programm auf dem PC laufen lässt, das die PC-Tastatur in Form der Scancodes abfragt und auch Tastenkombinationen zusammengefasst über die serielle Schnittstelle überträgt. Deine Zeitverzögerungsprobleme liegen jedenfalls auf der Seite Deines µCs; wie auch immer Dein getch() implementiert ist, und wie oft Du es aufrufst, da liegt ziemlich sicher das Problem. Der PC bzw. das darauf laufende Terminalprogramm sendet Tastendrücke annähernd sofort. Einschränkungen gibt es, wenn die verwendete Schnittstellenhardware einen Sende-FIFO verwendet, bzw. die Hardwarearchitektur der Schnittstelle gewisse Verzögerungen mit sich bringt, wie es bei USB-Seriell-Adaptern der Fall ist --- aber keine dieser Einschränkungen sollte Verzögerungen im Bereich von 100 msec liefern.
Rufus Τ. Firefly schrieb: > Dann ist das eine Empfangsroutine, die Zeichen von der seriellen > Schnittstelle abholt. Eine Tastatur gibt es aus Sicht Deines µCs nicht. Das kann sein, man definiert ja im Kopf des Programms auch die zu verwendende RS232. Rufus Τ. Firefly schrieb: > Das ist mit der Art, wie ein Terminal(-Programm) Tastendrücke überträgt, > nicht umsetzbar. > > Das ginge nur, wenn Du statt des Terminalprogrammes Dein eigenes > Programm auf dem PC laufen lässt, das die PC-Tastatur in Form der > Scancodes abfragt und auch Tastenkombinationen zusammengefasst über die > serielle Schnittstelle überträgt. Ok, schade, danke trotzdem, dann weiß ich jetzt wenigstens, dass es so nicht funktioniert. Rufus Τ. Firefly schrieb: > Deine Zeitverzögerungsprobleme liegen jedenfalls auf der Seite Deines > µCs; wie auch immer Dein getch() implementiert ist, und wie oft Du es > aufrufst, da liegt ziemlich sicher das Problem. Der PC bzw. das darauf > laufende Terminalprogramm sendet Tastendrücke annähernd sofort. > > Einschränkungen gibt es, wenn die verwendete Schnittstellenhardware > einen Sende-FIFO verwendet, bzw. die Hardwarearchitektur der > Schnittstelle gewisse Verzögerungen mit sich bringt, wie es bei > USB-Seriell-Adaptern der Fall ist --- aber keine dieser Einschränkungen > sollte Verzögerungen im Bereich von 100 msec liefern. Einen USB-RS232-Adapter verwende ich schon, aber wie auch immer, ist jetzt eh nicht mehr relevant. Vielen Dank für die Infos!
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.