Forum: PC-Programmierung Realisierung Tastenabfrage PIC


von Hans M. (downbaesher)


Lesenswert?

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
von C. L. (calle)


Lesenswert?

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

von B. S. (bestucki)


Lesenswert?

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.

von Hans M. (downbaesher)


Lesenswert?

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 :(

von B. S. (bestucki)


Lesenswert?

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?

von Hans M. (downbaesher)


Lesenswert?

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.

von Nobi (Gast)


Lesenswert?

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

von Hans M. (downbaesher)


Lesenswert?

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?

von Peter D. (peda)


Lesenswert?

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

von Nobi (Gast)


Lesenswert?

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 ?-?

von Hans M. (downbaesher)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

OK.
Also ist dein Problem ein PC-Problem und ich verschieb den Thread mal 
entsprechend.

von Robert L. (lrlr)


Lesenswert?

>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

von Robert L. (lrlr)


Lesenswert?

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???

von Hans M. (downbaesher)


Lesenswert?

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!

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

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.

von Hans M. (downbaesher)


Lesenswert?

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)

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

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.

von Hans M. (downbaesher)


Lesenswert?

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
Noch kein Account? Hier anmelden.