Hallo Leute, ich versuche grade drei Tasten die ich an einem ADC pin eines Tiny 85 angehägt habe zu entprellen. (Tastenwert) wird duch eine ADKanallesenfunktion bestimmt und liegt zwischen 0 und 5 zuerst habe ich die 3 Zustände in einer funktion definiert uint8_t Tastenabfrage(void){ uint8_t Taste; Taste = 0; if (Tastenwert > 4) Taste=1; //Werte grösser als 4, schalter mit einem KOhm wurde gedrückt else if (Tastenwert > 2) Taste=10;//Werte grösser als 2, schalter mit 10 KOhm wurde gedrückt else if (Tastenwert > 1) Taste=33;//Werte grösser als 1, schalter mit 33 KOhm wurde gedrückt else Taste = 0; return Taste; } danach habe ich versucht die Tasten so zu entprellen sodass ein Tastendruck was ein Wert zwischen 0 und 5 erbit nicht erkannt wird, er wird erst dann erkannt wenn der Wert zweimal rauskommt, und dann wird 10 ms gewartet und letzendlich werden Taste als definiert. Das Prozessflag definiert mehrere Zustände. Für Jeden Zustand wird ein Bit reserviert in einem 8 Bit. Ich habe das folgende Code geschrieben. void TastenEntprellung(){ if((Tastenabfrage()==1)||(Tastenabfrage()==10)||(Tastenabfrage()==33)){ // wenn nur einmal gedrückt (KeineTaste) Anreiz=KeineTaste; if(Tastenabfrage()==1){// zweimal erkannt TasteEins _delay_ms(10); Anreiz=TasteEins; Prozessflag|= Benutzeroberflaeche; } if(Tastenabfrage()==10){// zweimal erkannt TasteZwei _delay_ms(10); Anreiz=TasteZwei; Prozessflag|=Benutzeroberflaeche; } if(Tastenabfrage()==33){// zweimal erkannt TasteDrei _delay_ms(10); Anreiz=TasteDrei; Prozessflag|=Benutzeroberflaeche; } } } Kann mir jemand sagen ob es richtig ist und ob es Verbesserungsvorschläge gibt. Mein bessten Dank
henry wrote: > danach habe ich versucht die Tasten so zu entprellen sodass ein > Tastendruck was ein Wert zwischen 0 und 5 erbit nicht erkannt wird, > er wird erst dann erkannt wenn der Wert zweimal rauskommt, Bis zur 2. Abfrage schätze ich mal 10µs Programmlaufzeit, das ist keine Entprellung. > und dann > wird 10 ms gewartet Wozu? Hier mal ein funktionierendes Beispiel: Beitrag "Tastenmatrix auslesen über nur 2 Leitungen" Peter
hmmm na ein bissl mehr ist es schon, allein weil der Adc länger braucht Beispiel ADC Takt = 250 kHz 13 Takte Wandlungzeit = ~19.230 khZ Abtastung. (~50µS) Das dann noch durch Anzahl der Kanäle teilen. Bei 8 wären es dann schon 400µS. Wohlgemerkt ohne Software
Ulli Vex wrote:
> hmmm na ein bissl mehr ist es schon, allein weil der Adc länger braucht
Nur fragt die Funktion nicht den ADC ab, sondern die globale Variable
"Tastenwert".
Es wird also nirgendwo auf ein neues ADC-Ergebnis gewartet und daher
auch nicht entprellt.
Peter
Danke erstmal, //Bis zur 2. Abfrage schätze ich mal 10µs Programmlaufzeit, das ist keine Entprellung. die Abfragen wollte ich nur zur Bestätigung haben, die eigentliche Entprellung wollte ich dann haben in dem ms wartet deswegen // _delay_ms(10); Das Beispiel von peda habe ich mir angeschaut, nun gibts es paar unterschiede. Ich habe drei Widerstände genommen mit unterschiedlichen Werten (1k, 10k, 33k) die an einem anderen Widerstand angehängt sind (10k), und die funktionieren über die Spannungsteilerregel. Ich will die Tasten abfragen nur wenn ein Taste gedrückt ist, das heisst ich habe 3 Fälle, und ich glaube da bracuhe ich nicht eine Tabelle und ein Schwellwert wie im Beispiel von peda. deswegen wollte ich es so einfach wie möglich entprellen. wäre dankbar für weitere Hilfe und Verbesserungsvorschläge. henry
Hi, frage an peda, könntest du vielleicht dein code kommentieren, viele Sachen habe ich nicht so wirklich verstanden, und glaube andere gehts genauso. Ich bedanke mich
henry wrote: > frage an peda, könntest du vielleicht dein code kommentieren, viele > Sachen habe ich nicht so wirklich verstanden Es ist schwer, zu wissen, was der andere nicht wissen könnte. Durch die Tastenmatrix werden unterschiedlich viele Widerstände eingeschaltet, 0k-1k-2k-3k, nächste Reihe 3,9k-4,9k-5,9k usw. Diese bilden dann mit dem Widerstand gegen VCC einen Spannungsteiler. Per Macro werden dann die Spannungen je Taste ausgerechnet und in der Tabelle die Werte zwischen 2 Tasten eingetragen. Die ADC-Werte werden im Timerinterrupt alle 10ms ausgelesen und damit verglichen. Danach gehts weiter mit meiner Standardentprellroutine, d.h. wird 4* hintereinander die gleiche Taste erkannt, wird sie gespeichert. Da es 12 Tasten sind, arbeitet die Entprellroutine mit 16Bit. Peter
Hi Peter, danke für die Erklärung, soweit habe ich verstanden wie du es berechnen willst, durch schwellenwert, der eine 0 bei Unterschreiten ausgibt und ein 1 beim Überschreiten. Nun versuche ich dann mittels dein Code, ein ähnliches für meinen Fall zu schreiben. Habe nur paar fragen die ich nicht verstanden habe. #define THRESHOLD(n) (u16)((ADCVAL(n)+ADCVAL(n+1))/2) wieso steht (u16) davor und hier static inline u16 key_no( u8 adcval ) { u16 num = 0x1000; prog_uint8_t * thr = THRESHOLDS;//nimmt hier * thr die Werte vom THRESHOLDS ??? while( adcval < pgm_read_byte( thr )){ thr++; num >>= 1; } return num & ~0x1000; } dabei hänge ich mein Code nur leider bekomme ich eine Fehlermeldung bezuglich des Arrays die lautet: expected ')' bevor token '}'
henry wrote: > wieso steht (u16) davor Die Macros enthalten float-Werte. Um nicht versehentlich die float-Library einzubinden, wird das Ergebnis nach 16Bit int gecastet. > dabei hänge ich mein Code nur leider bekomme ich eine Fehlermeldung > bezuglich des Arrays > die lautet: expected ')' bevor token '}' Dann poste bitte einen compilierbaren Code (mit allen verwendeten Macros), sonst kann man den Fehler ja nicht sehen. Und nenne den Code nicht *.txt sondern *.c! Peter
hi, das Problem ist behoben, ich hatte nur ein Klammer vergessen :-) passiert mir ständig. //prog_uint8_t * thr = THRESHOLDS;//nimmt hier * thr (Zeiger)die Werte vom THRESHOLDS ??? das war meine zweite Frage Danke nochmal
Hallo Leute, ich versuche es immer noch mit der Erkennung der Tasten über ADC, leider komme ich zu keinem Erfolg. das folgende Code habe ich nach dem Prinzip von peda geschrieben, aber wenn ich es auf meinem MC lade führt es zu keinem Erfolg. Bitte um Fehleranalyse, danke im voraus
Ich habe nochmal versucht einbischen umzuändern und kamm zu paar Efolge, aber paar Fehler sind aufgetreten und verstehe bis jetzt nicht warum. Ich habe die Werte, die die Funktion ADkanallesen ausgibt bzw die adcwerte berechnet. (erste Taste --> 1,22V --> 235) (zweite Taste --> 2,62V --> 506) (dritte Taste --> 4,75V --> 918) und die berechnete Schwellwerte sind (712,370,118) Wenn ich jetzt auf die erste Taste drücke bekomme ich das gewunschte Zeichen "A" siehe Anhang. Wenn ich auf die zweite drucke (wollte ich das Zeichen "B" bekommen)aber ich bekomme wieder "A". auf die Dritte bekomme ich "C" (will das es dann auf LCD bleibt) aber nach kurzer Zeit zeigt sich "A" wieder zurück
Du hast die Tasten ja umgekehrt angeschlossen (gegen VCC). Dann mußt Du auch den Vergleich und die Tabelle umgekehrt machen. Peter
Hi peda, ich habe s versucht wie du es beschriben hast. --------------------------------- typedef unsigned char u8; typedef unsigned short u16; volatile uint16_t adcwert; //ADCWERT WIRD AUS DER FUNKTION LeseADkanal berechnet prog_uint16_t SCHWELLWERTE[] = {370,712,970};// berechnete Schwellwerte static inline u8 taste_no( u8 adcwert ) { adcwert = LeseADkanal(3); u16 num = 0x08; // DA NUR DREI FÄLLE SIND 0b00001000 prog_uint16_t * thr = SCHWELLWERTE; while(adcwert > pgm_read_byte(thr)){ thr++; num >>= 1; } return num & ~0x08; } -------------------------------- Bekomme ich aber nur ein "C" Zeichen wenn ich auf die Taste (dritte Taste --> 4,75V --> 918) Drücke Ich habe auch die Werte des Arrays mehrmals geändert, und u16 num = 0x08 ---> u16 num = 0x01 num >>= 1; ---> num <<= 1; hat auch nix gebracht? Weiss nicht woran es liegen kann :( henry
henry wrote: > Ich habe die Werte, die die Funktion ADkanallesen ausgibt bzw die > adcwerte berechnet. > (erste Taste --> 1,22V --> 235) > (zweite Taste --> 2,62V --> 506) > (dritte Taste --> 4,75V --> 918) > > und die berechnete Schwellwerte sind (712,370,118) Wenns nicht funktioniert, dann zeige doch erstmal die gemessenen Werte auf dem LCD an. Vielleicht hast Du ja einen Rechenfehler oder einen Schaltungsfehler. Peter
P.S.: Du solltest mal versuchen, nicht nur planlos rumzuprobieren, sondern überlegt zu debuggen. Also wenn was nicht geht, das Problem in einzelne Abschnitte zerlegen und diese für sich kontrollieren. Z.B. ob der ADC überhaupt das richtige macht. Oder statt des ADC über die UART oder über nen Timer im Sekundentakt verschiedene ADC-Werte zu simulieren (der Auswertefunktion übergeben). Usw. Peter P.S.: Du hast da noch einige Variablen und Funktionen 16Bittig, was bei 3 Tasten nicht nötig ist. Das ist aber nicht der Fehler, würde nur SRAM und Flash einsparen.
Hallo zusammen, ich habe eine Frage bezüglich dem Code "Tastenmatrix auslesen über nur 2 Leitungen" von Peter Dannegger. Und zwar im Teil an der Interrupt Routine ISR(TIMER0_OVF0_vect ) { static u16 ct0, ct1; u16 i; TCNT0 = (u16)(256 - XTAL 1024 100); // 100Hz (10ms) i = key_state ^ key_no( ADCH ); // key changed ? ct0 = ~( ct0 & i ); // reset or count ct0 ct1 = ct0 ^ (ct1 & i); // reset or count ct1 i &= ct0 & ct1; // count until roll over ? key_state ^= i; // then toggle debounced state key_press |= key_state & i; // 0->1: key press detect } Hier wird ein Interrupt jede 10 ms ausgelöst??? und wie lange dann dauert diese 4*mal abfrage? findet sie in diesen 10 ms statt?? Danke im Voraus
S-E, O wrote: > Hier wird ein Interrupt jede 10 ms ausgelöst??? > und wie lange dann dauert diese 4*mal abfrage? findet sie in diesen 10 > ms statt?? Natürlich 40ms. Eine Entprellung durch Mehrfachabtastung funktioniert nur dann, wenn sie in gleichen Zeitabständen erfolgt. Hier wird allerdings weniger das Prellen unterdrückt, sondern Störeinstreuungen auf die AD-Wandlung. Peter
Nun was ich nicht verstehe, das es jede 10ms ein Interrupt ausgelöst wird was eine abfrage von 40ms beinhaltet. Nehmen wir an ich wurde ein Event bei 40ms beschreiben, in dem ich ein Counter reinschreibe was mir bei Counter==4 --> 40ms ein Interrupt auslöst. würde das dann funktionieren? ich frage weil ich deine Funktion zur Nutze nehmen will aber will auch in der Interrupt Routine noch eine Funktion beschreiben. Danke S-E, O
S-E, O wrote: > Nun was ich nicht verstehe, das es jede 10ms ein Interrupt ausgelöst > wird was eine abfrage von 40ms beinhaltet. Nehmen wir an ich wurde ein > Event bei 40ms beschreiben, in dem ich ein Counter reinschreibe was mir > bei Counter==4 --> 40ms ein Interrupt auslöst. Du kannst in einem Timerinterrupt generell viele verschiedene Sachen machen, er ist durch das Entprellen nicht "verbraucht". Peter
Hi, ich habe solange versucht bis ich endlich es geschafft habe durch die Entprellfunktion ein laufendes Code zu realisieren. wenn ich Taste 1,2 oder 3 drücke bekomme ich was. jetzt habe ich diese Funktion zur nutze genommen, nur leider geht sie jetzt nicht mehr. wenn ich auf die erste oder dritte Taste drücke bekomme ich den selben Ergebnis, und auf die zweite reagiert es überhaupt nicht. bin jetzt die ganze Zeit am debuggen, weiss nicht wieso es jetzt nicht funktioniert. die berechneten Schwellenwerte haben einwandfrei funktioniert. s.a
Was macht LeseADkanal (Code)? Nimm dochmal 3 LEDs und laß Dir die 3 TastenStatus-Bits anzeigen. Dann nimm die 3 LEDs und laß sie mit TastenErkennung togglen. LCDs sind zum Debuggen schlecht, da sie viel zu träge sind. Außerdem könnte die Ausgabezeit den Ablauf stören, insbesondere wenn man Display-Clear benutzt. Peter
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.