Hallo
Ich verwende hier die bekannte Routine rc5.c mit der über normale
Fernbedienungen Werte in den ATmega eingelesen werden können.
Das Funktioniert eigentlich auch perfekt.
Mein Problem ist, das ich nicht weis wie ich es hinbekomme jeden
Tastendruck nur einmal auszulesen, egal wie lange ich die Taste drücke.
Hintergrund:
Ich möchte zunächst die Taste "PROGR" auf der Fernbedienung drücken
(Code 41) und erst danach eine dreistelige Zahl in eine Variable
eingeben, sagen wir der Einfachheit 111 (jeweils Code 1)
Leider bleibt es aber nicht bei einer Ziffer wenn ich die Taste einen
Moment zu lange gedrückt halte. Es ist vielleicht vergleichbar als wenn
eine Taste prellt.
Wie kann ich das hinbekommen, hat vielleicht jemand eine Idee?
Hier ein Teil des Codes wie ich es bisher habe. Ich habe der Einfacheit
mal nur den Check auf Taste "1" angegeben:
1
taste=0;
2
taste_nr=0;
3
wert=0;
4
5
//Main
6
while(1){
7
8
/* Gibt's was Neues an RC5? */
9
if(-1==rc5.flip){
10
//zur Zeit nichts zu tun
11
}
12
else
13
{
14
// Auswertung des Codes wenn Fernbedienung gedrückt
15
16
uint8_tcode=rc5.code;
17
uint8_taddr=rc5.addr;
18
19
20
//PROGR Taste gedrückt
21
if(code==41){
22
taste_nr=0;
23
wert=0;
24
taste=41;//merken das PROGR gedrückt war
25
}
26
27
// taste "1"
28
if((code==1)&&(taste==41)){
29
taste_nr++;
30
//erste Stelle Hunderter
31
if(taste_nr==1)wert=wert+100;
32
//zweite Stelle Zehner
33
if(taste_nr==2)wert=wert+10;
34
//dritte Stelle Einer
35
if(taste_nr==3)wert=wert+1;
36
}
37
38
39
//Wert auf Display ausgeben
40
itoa(wert,int_buffer,10);
41
set_cursor(1,2);
42
lcd_string("Wert: ");
43
lcd_string(int_buffer);
44
45
//Empfänger bleibt inaktiv, bis rc5.flip auf -1 gesetzt wird !
Michael H. schrieb:> Hallo>> Ich verwende hier die bekannte Routine rc5.c
Welcher Code soll das sein.
Gib doch mal einen Link oder hänge die Files als Attachment an.
* Einem Start-Bit, das immer logisch 1 ist und es dem Empfänger erlaubt,
2
die korrekte Verstärkung für die nachfolgenden Datenbits zu wählen.
3
* Einem Field-Bit, das verwendet wird, um zwischen einem unteren
4
Kommandobereich mit einem Wertebereich von 0 bis 63 und einem oberen
5
Kommandobereich mit einem Wertebereich von 64 bis 127 zu unterscheiden.
6
* Einem Steuerbit, das bei jedem Tastendruck auf der Fernbedienung seinen
7
Zustand wechselt. Damit kann zwischen dem permanenten gedrückt Halten
8
einer Taste und dem wiederholten Drücken und Loslassen unterschieden
9
werden.
letzters, das Steuerbit, ist genau der Dreh und Angelpunkt mit dem du
dein Problem lösen kannst. Leider kann ich dir nicht mehr helfen, da ich
nicht weiß, auf welche Routinen du dich eigentlich beziehst.
Eventuell könnte es das hier sein
1
/* Gibt's was Neues an RC5? */
2
if(-1==rc5.flip){
3
//zur Zeit nichts zu tun
4
}
aber dann müsste die Auswertung anders aussehen. Entscheidend ist nicht
ein spezifischer Wert, sondern dss sich dieses Bit im Vergleich zur
letzten gemeldeten Tasten verändert hat. Erst dann hast du die
Gewissheit, dass die Taste tatsächlich nieder gedrückt wurde und nicht
einfach nur der Benutzer auf der Taste eingeschlafen ist und der Sender
auf Autorepeat umgeschaltet hat und denselben Tastendruck wieder und
immer wieder sendet.
die Fernbedienung sendet den selben Code immer wieder, solange du die
Taste gedrückt hältst. Um zu unterscheiden, ob die selbe Taste zwei mal
gedrückt wurde oder ob sie lange gedrückt wird gibt es das sog.
Togglebit im RC5-Code. Das wechselt jedesmal den Pegel, wenn die Taste
neu gedrückt wird.
http://www.sprut.de/electronic/ir/rc5.htm#2
Wenn du also mehrmals hintereinander das selbe Zeichen empfängst und das
Togglebit hat immer den gleichen Wert, dann wird die Taste dauerhaft
gedrückt (d.h. Wiederholungen müssen ignoriert werden).
Wenn du mehrmals hintereinander das selbe Zeichen empfängst und das
Togglebit wechselt jedesmal den Zustand, dann wurde die Taste immer
wieder neu gedrückt (und die Wiederholungen des Zeichens dürfen nicht
ingoriert werden).
Hallo
Danke an alle für den Input!
Ich habe hier die rc5 Programmteile die ich verwende als Anhang
drangehängt. Ich glaube die waren von Peter Danneberger (?) und hier im
Forum.
Ich dachte wirklich ich hätte die Beschreibungen von Euch wie das mit
dem rc5.flip funktioniert verstanden und mir zu Verdeutlichung das
Programm so umgestrickt das ich erst einmal "sehen" kann wie sich der
Wert verändert.
Die Ausgabe auf dem Display ist aber anders als von mir erwartet:
Nach Programmstart wird erst einmal nichts auf dem Display angezeigt,
das ist ja soweit ok.
Wenn ich jetzt eine Taste auf der Fernbedienung drücke, bleibt sie immer
auf 1 oder 0 bis ich das Gerät ausschalte. Da ändert sich nichts mehr,
egal ob ich auf der Fernbedienung eine Taste kurz, lang oder garnicht
drücke.
So wollte ich das testen:
Ich denke ich hab´s jetzt. Der Code sieht zwar nicht schön aus,
aber vielleicht hat ja jemand die gleichen Probleme und kann
dann darauf aufbauen.
Danke noch mal für die Unterstützung!
Michael H. schrieb:> if ((flip_aktuell != -1) && (flip_aktuell == 0) && (flip_alt ==> flip_aktuell)){
Wenn flip_aktuell 0 sein MUSS (damit die Bedingung in ihrer Gesamtheit
überhaupt jemals wahr sein kann), dann ist damit automatisch klar, dass
flip_aktuell nichtg -1 sein kann. Denn es ist ja 0.
Selbiges für die restlichen Abfragen.
Es ist kein Verbrechen, wenn man if ineinander schachtelt.
Welche Fälle hast du?
Zuallerst mal un dam wichtigsten: unterscheiden sich die beiden?
Denn wenn sie es nicht tun, dann setzt du rc5.flip auf -1. Dieses auf -1
setzen soll verhindern, dass du denselben Code weiterhin auswertest. Es
ist quasi dein: hab ich schon bearbeitet
1
flip_aktuell=rc5.flip;
2
3
if(flip_aktuell!=-1)// gibt es überhaupt was zu tun
4
{
5
if(flip_aktuell!=flip_alt)// ist es ein neuer tastendruck
6
{
7
flip_alt=flip_aktuell;
8
rc5.flip=-1;
9
10
//Anzeigen welche Taste gedrückt wird
11
code=rc5.code;
12
itoa(code,int_buffer,10);
13
lcd_string(int_buffer);
14
}
15
}
von der Logik her müsste das völlig gleichwertig zu deinem sein. Nur
kürzer.
Es ist schon seltsam, wir sind wieder mal beim Entprellen. Das scheint
ein EWIGES Thema hier zu sein.
Eigentlich gibt fast jede Fernbedienung beim Drücken einer Taste eine
Salve von Codes aus, die dazu gedacht sind, bei eventuellem Fehlempfang
die Sache innerhalb von ca. 20 ms korrigieren zu können.
Deshalb:
Den Empfang von der Fernbedienung muß man softwareseitig entprellen,
indem man aus einer hinreichend großen zeitlichen Lücke zwischen den
Codes (oder aus einem echten Codewechsel) erkennt, daß die taste wieder
losgelassen wurde.
Im allereinfachsten Falle macht man es so, daß man nach Empfang eines
Codes genau diesen Code erstmal von jeglicher Weiterverarbeitung
ausschließt (falls er nochmal kommt), solange bis er mindestens 70..150
ms lang nicht wieder erscheint. Erst dann darf man ihn wieder
erlauben. Sowas ist am besten in dm System-Tick-Interrupt angesiedelt.
Das hohe C wäre natürlich, mit ner umschaltbaren Repetierzeit-Schwelle
zu arbeiten, aber zumeist braucht man diesen Komfort nicht wirklich.
W.S.
Karl Heinz Buchegger schrieb:> von der Logik her müsste das völlig gleichwertig zu deinem sein. Nur> kürzer.
Du hast natürlich Recht.
Ich bis nur seit 2 Tagen dabei im Code rumzuwurschteln nach dem Motto 2
Schritte vor und 3 zurück.
Bis ich vorhin alles weggeworfen habe und stur und ohne Abkürzung alle
Bedingungen zusammengefaßt habe die möglich sind.
Klar das der Code jetzt noch aufgeräumt und verkürzt werden muß. Ich bin
nur froh das es bis dahin funktioniert :)
W.S. schrieb:> Es ist schon seltsam, wir sind wieder mal beim Entprellen. Das scheint> ein EWIGES Thema hier zu sein.
Das "Entprellen" von Fernbedienungen hat nur entfernt mit dem Entprellen
von Tasten zu tun.
> Eigentlich gibt fast jede Fernbedienung beim Drücken einer Taste eine> Salve von Codes aus, die dazu gedacht sind, bei eventuellem Fehlempfang> die Sache innerhalb von ca. 20 ms korrigieren zu können.
Fast korrekt: Die meisten FBs machen eine Pause von ca. 40 bis 50 ms
zwischen den Frames - einige sogar noch etwas mehr. Siehe auch
http://www.mikrocontroller.net/articles/IRMP#Die_IR-Protokolle_im_Detail> Deshalb:> Den Empfang von der Fernbedienung muß man softwareseitig entprellen,> indem man aus einer hinreichend großen zeitlichen Lücke zwischen den> Codes (oder aus einem echten Codewechsel) erkennt, daß die taste wieder> losgelassen wurde.
Das wäre auf jeden Fall die sinnvollste Methode, denn die meisten
FB-Protokolle sehen ein Toggle-Bit als Hilfestellung (für genau den Fall
"langer/kurzer Tastendruck") gar nicht vor. Aber das Ignorieren von
Frames über einen gewissen zeitlichen Bereich ist nicht immer sinnvoll -
schon gar nicht das Warten auf das Loslassen der Taste. Beim Regeln
einer Lautstärke wärest Du mit dieser Methode jedenfalls ziemlich
gekniffen.
IRMP erkennt (protokollunabhängig) an den Pausen zwischen den
Frames, ob es sich um einen langen Tastendruck oder um mehrere kurze
Tastendrücke handelt und setzt ein entsprechenendes Repetition-Flag zur
Unterscheidung. Dies kann die Anwendung abfragen und selbst entscheiden:
Entweder "Entprellung" für z.B. eine numerische Taste 0-9 (d.h. der User
muss die Taste erst wieder loslassen, bevor er sie neu senden kann),
oder kontinuierliches Interpretieren - z.B. für Lautstärkeregelung oder
Faden von LEDs.
> Im allereinfachsten Falle macht man es so, daß man nach Empfang eines> Codes genau diesen Code erstmal von jeglicher Weiterverarbeitung> ausschließt (falls er nochmal kommt), solange bis er mindestens 70..150> ms lang nicht wieder erscheint.
Auch diese ganze Arbeit nimmt IRMP dem Programmierer vollkommen ab.
Er bekommt Protokoll, Geräteadresse, Kommando und (Repetition-)Flag -
fertig.
@TO: RC5 (und damit das Toggle-Bit) ist längst ausgestorben. Auch wenn
Peters RC5-Decoder schön klein und elegant ist, wäre eine Lektüre des
IRMP-Artikels zumindest sinnvoll. ;-)