Hi, hab den Code zum entprellen von Tasten von Peter Danegger auf meinen Controller angepasst. Im Moment schaltet mir der Taster 0 die LED 0 ein und wieder aus. Nun möchte ich dies mit einer Taster-Matrix die über einen AD-Wandler eingelesen wird erweitern. Dabei soll erst einmal nur diese eine LED bei einem Wert zwischen 30 und 35 ein- und ausgeschaltet werden. Wo muss ich in dem Code ansetzen? Hatte schon ein paar Ansätze, aber die haben alle nicht funktioniert. Wäre super wenn mir da jemand helfen könnte. Gruß Björn
Ich hab deinen Code (noch) nicht angeguckt. Es müsste aber so laufen: AD-Wandler einlesen, Tasten decodieren, feststellen, ob sich seit dem letzten Lesevorgang etwas verändert hat. Wenn sich etwas verändert hat, den entsprechenden Entprellzähler zurücksetzen (Prellen). Hat sich nichts verändert, Entprellzähler weiterzählen. Falls Schwellwert überschritten wurde, entsprechend handeln.
Also der AD-Wandler ist eingelesen. Entprechender Wert steht in ADCH. Was meinst du mit Tasten decodieren?
>Was meinst du mit Tasten decodieren?
Du hast eine Tatatur-Matrix am ADC hängen, die für jeden Tastendruck
einen bestimmten Wert zurückliefert. Der Zusammenhang zwischen ADC-Wert
und gedrückter Taste muß decodiert werden.
Du kannst natürlich auch feststellen, ob sich der ADC-Wert seit der
letzten Messung verändert hat, und dann reagieren (decodieren und
entprellen...).
Gut, verstanden! Aber kann ich nicht den ADC-Wert einfach irgendwo in den Code von Peter einbauen und dann ne Abfrage machen, ob dieser zwischen 30-35 liegt? Im Moment will ich ja nur einen Taster benutzen, hab ja dann auch nur einen ADC-Wert.
Hmm. Theoretisch könnte man das machen. Peter's Code geht von zwei Prämisse aus: * Alle Taster hängen an einem Port und werden von dort gemeinsam als 1 Byte eingelesen. * Für jede Taste gibt es ein Bit, welches auf 0 geht, wenn die Taste gedrückt wird. Theoretisch könnte man das so umbauen, dass der Tastenzustand nicht von einem Port kommt sondern von einer globalen Variablen, bei der jedes Bit wieder einer Taste in der Matrix entspricht. Die Frage ist halt nur: hast du mehr als 8 Tasten, dann geht das nicht mehr, weil du ja bekanntlich in einem Byte nur 8 Bits unterbringst. Daher: Schrieb dir selber was. Du kannst ja die Grundidee von PeDa-s Code übernehmen. WM-Rahul war ja bereits so freundlich und hat dir die Grundidee nach der der Code funktioniert geschildert. Sooo schwer ist das auch wieder nicht. Und wenn ich mir das alles so anschaue, dann kannst du nicht genug Übung im Umsetzen von Ideen bekommen.
Gut, 8 Taster würden mir reichen. Also müsste ich das so umbauen, dass nicht der PINB( wie in Peters Code) den Tastenzustand angibt sondern eine Varialble z.B. "Taster". Betätige ich nun den ersten Taster meiner Matrix, schreibt der AD-Wandler mir einen Wert von 33, also zwischen 30-35 ins ADCH. Das ADCH vergleiche ich dann auf einen Wert zwischen 30-35, und wenn dies zutrifft setze ich das erste Bit meiner Variablen "Taster" auf null. So ungefähr?
So ungefähr. Klingt nicht so schlecht. Wenn dir der ADC einen anderen Wert liefert musst du das Bit natürlich wieder auf 1 setzen.
Hallo, ich noch mal. Also mit einer LED klappt das super. Nur sobald ich einen zweiten Wert dazu nehme und eine zweite LED schalten will, klappt das nicht. Kann vielleicht mal einer den Code überfliegen, ist bestimmt nur ne Kleinigkeit. Nur mitlerweile sehe ich schon gar nichts mehr, häng schon zu lange da vor. Danke
Hab den Fehler! Die Abfrage if((ADCH <=105) && (ADCH >= 110)) ist falsch. Muss natürlich if((ADCH <=110) && (ADCH >= 105)) heißen, bei einem Wert von 107.
Und noch mal ich. Kann man den folgenden Term nicht irgendwie vereinfachen: //erste LED if((ADCH <=35) && (ADCH >= 30)) taster &= ~(1 << 0); else taster |= (1 << 0); if( get_key_press( 1<<KEY0 )) LED_PORT ^= 1<<LED0; //zweite LED if((ADCH <=110) && (ADCH >= 105)) taster &= ~(1 << 1); else taster |= (1 << 1); if( get_key_press( 1<<KEY1 )) LED_PORT ^= 1<<LED1; //dritte LED if((ADCH <=207) && (ADCH >= 202)) taster &= ~(1 << 2); else taster |= (1 << 2); if( get_key_press( 1<<KEY2 )) LED_PORT ^= 1<<LED2; //vierte LED if((ADCH <=253) && (ADCH >= 248)) taster &= ~(1 << 3); else taster |= (1 << 3); if( get_key_press( 1<<KEY3 )) LED_PORT ^= 1<<LED3; Weil bei 8 LED's wird es dann ein bißchen viel. Hat einer ne Idee?
Hi Björn, mach doch eine Schleife in der Du z.B. ein zweidimensionales Array abfragst ;) z.B.: for(in i=0;i<8;i++) { if((ADCH <=wert[i][0]) && (ADCH >= wert[0][i])) taster &= ~(1 << 0); else taster |= (1 << 0); } Nur zum Bleistift ;) Bye, Markus
schreib mal bite auf, wie die Intervall-Werte aussehen. Vielleicht kann man das durch eine simple Schleife und etwas Gerechne erzeugen.
Schleife ist gut. Aber 2-d Array ist schlecht. Für sowas definiert man sich eine struct. Also: Was sind den die Variablen die eine Schaltstufe betreffen? Da sind MinimalWert, Maximalwert die den Taster identifizieren Weiters gehört da das zu setzende bzw. löschende Bit in taster Ausserdem das Bit das zu setzen bzw. zu löschen ist für die LED Wir haben also: struct Stufe { unsigned int ADCMin; unsigned int ADCMax; unsigned char TasterBit; unsigned char LedBit; } Damit definieren wir uns ein Array von solchen Stufen und initialisiern sie mit dem was wir wissen: struct Stufe[] Stufen = { { 30, 35, ( 1 << KEY0 ), ( 1 << LED0 ) }, { 105, 110, ( 1 << KEY1 ), ( 1 << LED1 ) }, { 202, 207, ( 1 << KEY2 ), ( 1 << LED2 ) }, { 248, 253, ( 1 << KEY3 ), ( 1 << LED3 ) } }; unsigned char NrStufen = sizeof( Stufen ) / sizeof( *Stufen ); Damit programmieren wir: for( i = 0; i < NrStufen; ++i ) { if( ADCH >= Stufen[i].ADCMin && ADCH <= Stufen[i].ADCMax ) taster &= ~ Stufen[i].TasterBit; else taster |= Stufen[i].TasterBit; if( get_key_press( Stufen[i].TasterBit ) ) LED_PORT ^= Stufen[i].LedBit; } Ich haben fertig.
Hi, erst einmal Danke für eure Tips! Versuch mich gerade mal an dem Code-Stück von Karl-Heinz. Respekt! Muss ich ja gestehen dass ich da selber nie drauf gekommen wäre. Da fehlt mir wohl noch ziemlich viel Übung. Aber ich bin ja dabei. Soweit ist der Code klar, nur der folgende Teil macht mir Probleme: struct Stufe[] Stufen = { { 30, 35, ( 1 << KEY0 ), ( 1 << LED0 ) }; { 105, 110, ( 1 << KEY1 ), ( 1 << LED1 ) }; { 202, 207, ( 1 << KEY2 ), ( 1 << LED2 ) }; { 248, 253, ( 1 << KEY3 ), ( 1 << LED3 ) }; }; Müsste doch eigenlich: struct Stufe Stufen[] = { { 30, 35, ( 1 << KEY0 ), ( 1 << LED0 ) }; { 105, 110, ( 1 << KEY1 ), ( 1 << LED1 ) }; { 202, 207, ( 1 << KEY2 ), ( 1 << LED2 ) }; { 248, 253, ( 1 << KEY3 ), ( 1 << LED3 ) }; }; heißen. Oder bin ich da auf dem Holzweg? Leider erzeugt beides bei mir einen Fehler. Kommt immer ...c:57: Fehler: Syntaxfehler vor »[«-Zeichen
Oh, dummer Fehler! Jetzt gehts, muss natürlich so heißen: struct Stufe Stufen[] = { { 30, 35, ( 1 << KEY0 ), ( 1 << LED0 ) }, { 105, 110, ( 1 << KEY1 ), ( 1 << LED1 ) }, { 202, 207, ( 1 << KEY2 ), ( 1 << LED2 ) }, { 248, 253, ( 1 << KEY3 ), ( 1 << LED3 ) } }; Danke und Gruß
Hi, der Code funktionier soweit einwandfrei! Nun will ich ne Kleinigkeit ändern. Nehmen wir mal das Codestück oben von Karl Heinz: Wir haben also: struct Stufe { unsigned int ADCMin; unsigned int ADCMax; unsigned char TasterBit; unsigned char LedBit; } Damit definieren wir uns ein Array von solchen Stufen und initialisiern sie mit dem was wir wissen: struct Stufe[] Stufen = { { 30, 35, ( 1 << KEY0 ), ( 1 << LED0 ) }, { 105, 110, ( 1 << KEY1 ), ( 1 << LED1 ) }, { 202, 207, ( 1 << KEY2 ), ( 1 << LED2 ) }, { 248, 253, ( 1 << KEY3 ), ( 1 << LED3 ) } }; unsigned char NrStufen = sizeof( Stufen ) / sizeof( *Stufen ); Damit programmieren wir: for( i = 0; i < NrStufen; ++i ) { if( ADCH >= Stufen[i].ADCMin && ADCH <= Stufen[i].ADCMax ) taster &= ~ Stufen[i].TasterBit; else taster |= Stufen[i].TasterBit; if( get_key_press( Stufen[i].TasterBit ) ) LED_PORT ^= Stufen[i].LedBit; } Hierbei wird ja bei drücken des entsprechenden Tasters eine LED eingeschaltet. Nun will ich bei einem Taster keine LED schalten, sondern was anderes machen. Ist doch aber bei der Form des Codes jetzt gar nicht mehr möglich, oder?
for( i = 0; i < NrStufen; ++i ) { if( ADCH >= Stufen[i].ADCMin && ADCH <= Stufen[i].ADCMax ) taster &= ~ Stufen[i].TasterBit; else taster |= Stufen[i].TasterBit; if( get_key_press( Stufen[i].TasterBit ) ) { LED_PORT ^= Stufen[i].LedBit; machnochwas(); machwasanderes(); } }
Hab es jetzt anders versucht. Klappt aber noch nicht wirklich... if(!(PIND & (1 << PIND3))) taster &= ~(1 << 0); else taster |= (1 << 0); Mit diesem Codestück will ich, wenn ein Lowpegel a PORTD, PIN3 anliegt, dass erste Bit der Variablen Taster löschen. Ist das so richtig?
Darf ich einen Vorschlag machen? Besorg dir AVR-Studio, installiere es und lass deine Programme unter Kontrolle des Simulators laufen. Der Simulator lässt dich auch auf seinen virtuellen Ports Werte einstellen. Damit kannst du wunderbar testen was denn in deinem Programm wirklich vor sich geht; welche if genommen werden, welche nicht; wie Ports ihre Werte verändern; welche Werte die Variablen haben etc. > if(!(PIND & (1 << PIND3))) > taster &= ~(1 << 0); > > else > taster |= (1 << 0); > > Mit diesem Codestück will ich, wenn ein Lowpegel a PORTD, PIN3 > anliegt, dass erste Bit der Variablen Taster löschen. Und was soll passieren, wenn kein Lowpegel anliegt? Im Moment wird dann das Bit wieder gesetzt.
Es soll so funktionieren wie hier: if((ADCH <=110) && (ADCH >= 105)) taster &= ~(1 << 1); else taster |= (1 << 1); if( get_key_press( 1<<KEY1 )) LED_PORT ^= 1<<LED1; Dort wird ja bei gültiger if-Anweisung die LED1 ein- und ausgeschaltet. Klappt einwandfrei. Das soll hierbei: if(!(PIND & (1 << PIND3))) taster &= ~(1 << 0); else taster |= (1 << 0); if( get_key_press( 1<<KEY0 )) LED_PORT ^= 1<<LED1; auch passieren, nur mit ner anderen if-Anweisung. Nur dabei klappt es nicht! Möchte das dort bei einem Tasterdruck, also einem kurzen Low-Pegel die LED eingeschaltet wird.
Mit nem anderen Pin z.B. PD2 klappt es. Kann es daran liegen, dass ich zusätzlich noch den INT1-Interrupt verwende, der an PD3 ausgelöst wird?
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.