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