Hallo ihr da draußen,
ich habe mich in den letzten Tagen etwas mit dem Atmega8 und der C-
Programmierung beschäftigt. Bin also nicht so lange dabei!
Folgendes:
Ich habe 5 Taster und 5 LEDs. Jede LED wird von einem Taster ein und
wieder ausgeschaltet. Dabei wird die LED beim Einschalten langsam hoch
gedimmt. Das hochdimmen erfolgt über SoftPWM und wird in einer ISR
realisiert.
Hardware:
Atmega8 auf einem MyAVR- Board.
Habe die Taster am PORTD und die LEDs am PORTC angeschlossen.
NUN zum Problem:
das Programm funktioniert soweit... nur wenn ich die LEDs an den PortB
hänge, dann bleiben diese nicht an... sie gehen nach loslassen des
Tasters wieder aus... das Phenomen habe ich am PORTC nicht. Nach
loslassen des Tasters bleiben die LEDs auch an....
Frage => ist an dem PORTB etwas was ich nicht berücksichtige ??
Der Code ist nur für eine LED... den Rest habe ich
übersichtlichkeitshalber ausgeblendet.
Danke im Voraus!!!
Gruß
Rafael
eine Variable die 'unsigned char' ist, kann nicht unbegrenzt hochzählen.
Irgendwann ist der Wert 255 erreicht, dann erfolgt beim nächsten
Increment ein Überlauf und der Wert wird wieder zu 0.
Du hast da ein bischen viele Variablen in deinem Programm. Damit jagst
du dich nur selbst ins Boxhorn.
Du brauchst:
genau eine Variable für den PWM-Counter
genau eine Variable für jede Led.
Am Port B ist programmtechnisch nichts besonderes. Er verhält sich wie
jeder andere Port auch.
1
volatileunsignedcharled1Brightness;
2
volatileunsignedcharled2Brightness=64;
3
4
ISR(TIMER0_OVF_vect)
5
{
6
staticunsignedcharpwmCounter;
7
8
pwmCounter++;// gewollter Überlauf nach 255
9
10
if(pwmCounter<=led1Brightness&&led1Brightness!=0)
11
PORTB|=(1<<PB0);
12
else
13
PORTB&=~(1<<PB0);
14
15
if(pwmCounter<=led2Brightness&&led2Brightness!=0)
16
PORTB|=(1<<PB1);
17
else
18
PORTB&=~(1<<PB1);
19
}
Die Helligkeit steuerst du ausschliesslich über die Variable
'led1Brightness'. Willst du die LED abschalten, dann weisst du der
Variablen einfach eine 0 zu und gut ists. Mit deinen diversen Lauf und
Stopp Variablen schiesst du dir nur selber ins Knie, weil du den
Überblick verlierst, wie welche Variable wann stehen muss, damit was
passiert. Variablen sind gut. Aber zu viele Variablen auf ein Problem
werfen ist auch nicht das Gelbe vom Ei.
Ich hab dir doch schon mal gezeigt, wie man so eine Tastenauswertung
inklusive Dimmung macht. Warum benutzt du das denn nicht? Alles was du
brauchst, das ist eine weitere Variable, die als Vorgabevariable
fungiert. In die schreibst du den Helligkeitswert, auf den die LED
hindimmen soll. Von diesem Vorgabewert ausgehend wird dann genau diese
'led1Brightness' aus verändert. Willst du die LED auf einen Schlag auf
einen Wert setzen (wie zb 0) dann schreibst du den neuen Wert dann eben
nicht nur in diesen Vorgabewert sondern zusätzlich auch nach
led1Brightness
1
if(Tastegedrücktundhochdimmen)
2
led1Vorgabe=255;// nur dimmen
3
4
if(Tastegedrücktundausschalten)
5
{
6
led1Vorgabe=0;// dimmen auf 0
7
led1Brightness=0;// aber die LED auch gleich auf 0 setzen
8
// -> effektiv wird hier also nicht gedimmt, sondern
9
// die LED geht sofort aus.
10
}
11
12
// hochdimmen notwendig?
13
if(led1Brightness<led1Vorgabe)
14
led1Brightness++;
15
16
// runterdimmen notwendig?
17
// da in diesem Programm nicht runter gedimmt wird
Hallo Karl Heinz,
danke für deine schnelle Antwort!:) und für die Hilfe!!!!
Ja ich gebe zu, dass ich zu viele Variablen in dem Code habe. Ist mein
erstes Programm :)
Es fällt mir noch ein wenig schwer auf den Punkt genau zu denken und dem
entsprechend die Programme zu schreiben. Man verrennt sich oft und
schnell in seinen eingenen Gedanken.... und dann wirds immer
komplizierter!
Die Kunst hierbei denke ich ist es so einfach wie möglich aber effektiv
zu programmieren... das werde ich noch viel üben müssen!
Ich werde mir deine Nachricht zu Brust nehmen und alles ausprobieren!
Karl H. schrieb:> ISR (TIMER0_OVF_vect)> {> static unsigned char pwmCounter;>> pwmCounter++; // gewollter Überlauf nach 255>> if( pwmCounter <= led1Brightness && led1Brightness != 0 )> PORTB |= ( 1 << PB0 );> else> PORTB &= ~( 1 << PB0 );> }
Eine Frage dazu noch :
Soll die Zeile:
if( pwmCounter <= led1Brightness && led1Brightness != 0 )
nicht so heißen
if( pwmCounter <= led1Brightness && led1Vorgabe != 0 )?
Danke!!!!!
Gruß
Rafael
Hallo noch einmal,
Rafael S. schrieb:> Soll die Zeile:> if( pwmCounter <= led1Brightness && led1Brightness != 0 )> nicht so heißen> if( pwmCounter <= led1Brightness && led1Vorgabe != 0 )?
Ich denke diese Frage hat sich erübrigt!
Es hat gerade "klick" gemacht!!! :)
Gruß
Rafel
Rafael S. schrieb:> Eine Frage dazu noch :>> Soll die Zeile:> if( pwmCounter <= led1Brightness && led1Brightness != 0 )> nicht so heißen> if( pwmCounter <= led1Brightness && led1Vorgabe != 0 )?
Nein.
An dieser Stelle geht es darum, wie hell die LED sein soll. Das hat
nichts mit irgendwelchen 'Vorgaben' oder dergleichen zu tun. Schmeiss
die Dinge nicht durcheinander. Das eine ist die Relaisierung einer
bestimmten Helligkeit unabhängig davon wo der Wert für die Helligkeit
her kommt. Das ist das, worum es bei der PWM geht. Das andere ist das
Dimmen - also das gezielte variieren dieser Helligkeit. 2
unterschiedliche Themenkreise.
Man könnte natürlich die ganze Dimmung hin zu einem Vorgabewert
ebenfalls in der Timer-ISR unterbringen. Trotzdem ist es vernünftig das
immer noch als eigenständigen Mechanismus anzusehen.
Guten Morgen Karl Heinz,
ich habe mir am Freitag noch dein Code zur Tastenbetätigung aus dem
anderen Thread angeschaut und habe aufgrund dessen eine einfache LED Ein
und Ausschaltung mit einem Taster realisieren wollen.
Beitrag "atmega8 led dimmen ohne PB1, PB2 (OC1A, OC1B)"
Leider klappt es nicht mit der Ausschaltung.
Taster0Vorher = taster0;
// Hauptschleife
while(1)
{
Taster0Jetzt = taster0;
if( Taster0Jetzt != Taster0Vorher )
{
Taster0Vorher = Taster0Jetzt;
if(!Taster0Jetzt)
{
LED0_ON;
} }
return 0;
}
Wir fragen also am Anfang ab, ob sich der Zustndand der Taste verändert
hat. Wenn ja.. sie ist also nun gedrückt worden Signalzustand des
Eingangs geht von "1" auf "0", dann wird "Taster0Vorher" auch eine "0"
zugewiesen. Ist der Taster immer noch gedrückt, also auf "0", dann wird
die LED eingeschaltet.
Wenn ich nun nach der Einschaltbedingung die Ausschaltbedingung
schreibe, dann wird die LED nie angehen, weil sie direkt wieder
ausgeschaltet wird.
if (Taster0Vorher == Taster0Vorher)
{
Taster0Vorher=1;
LED0_OFF;
}
Meine Frage ist... wie bekomme ich es hin, dass die LED anbleibt, aber
mit wiederholtem Tastetdruck wieder ausgeht ?
Sorry für diese Amateurfragen! Aber ich stehe da iwie auf dem Schlauch!
Danke im Voraus! :)
Gruß
Rafael
Stefan U. schrieb:> Suche mal den Artikel zum Thema "Tastenentprellung". Das steht, wie es> geht.
In PeDas 'Komfort' Routine gibt es dafür 'get_key_short' und
'get_key_long', welches zwischen kurzen und langen Tastendrücken
unterscheidet. Du kannst also das von anderen Geräten gewohnte Verhalten
bauen, das ein kurzer Tastendruck die LED an und ausschaltet, während
ein langer Tastenddruck die Dimmerfunktion steuert.
https://www.mikrocontroller.net/articles/Entprellung#Timer-Verfahren_.28nach_Peter_Dannegger.29
Zugegeben, die Routine erscheint beim ersten Anschauen komplizierter als
nötig, wenn sie aber einmal implementiert ist, läuft sie zuverlässig und
komfortabel.
Hallo zusammen,
Danke für die schnelle Antwort! :)
Stefan U. schrieb:> Suche mal den Artikel zum Thema "Tastenentprellung". Das steht,> wie es> geht.
Werde mich dem jetzt direkt annehmen!
Matthias S. schrieb:> Stefan U. schrieb:> In PeDas 'Komfort' Routine gibt es dafür 'get_key_short' und> 'get_key_long', welches zwischen kurzen und langen Tastendrücken> unterscheidet.
Ebenfalls danke füe die Anktwort!
Die Superroutine von PeDas kenne ich bereits, aber ich muss erstmal die
Basics verstehen :) Da steige ich noch nicht so gut durch!
Bin ja ein blutiger Anfänger :D
Gruß
Rafael
Rafael S. schrieb:> Die Superroutine von PeDas kenne ich bereits, aber ich muss erstmal die> Basics verstehen :) Da steige ich noch nicht so gut durch!> Bin ja ein blutiger Anfänger :D
Diese Tastenerkennung und Entprellung ist eine der wenigen Codestücke,
von denen ich jedem zugestehe, dass er sie einfach verwenden kann, ohne
zu verstehen wie er funktioniert.
Oder kannst du selbst eine performante Wurzel-Funktion schreiben?
Trotzdem würdest du ohne Hemmungen einen Phytagoras programmieren.
Rafael S. schrieb:> Wenn ich nun nach der Einschaltbedingung die Ausschaltbedingung> schreibe, dann wird die LED nie angehen, weil sie direkt wieder> ausgeschaltet wird.>> if (Taster0Vorher == Taster0Vorher)> {> Taster0Vorher=1;> LED0_OFF;> }>> Meine Frage ist... wie bekomme ich es hin, dass die LED anbleibt, aber> mit wiederholtem Tastetdruck wieder ausgeht ?
Du musst anfangen Dinge voneinander zu trennen!
Das eine ist die Erkennung einer Tastenbetätigung.
Punkt
Das andere ist, was diese Betätigung auslöst.
Punkt.
Das sind 2 verschiedene Dinge! Solange du nicht sicher genug bist,
solltest du die Dinge strikt voneinander trennen.
Du erkennst eine Tastenbetätigung (richtigerweise) so:
1
betaetigt=0;
2
Taster0Vorher=taster0;
3
4
// Hauptschleife
5
while(1)
6
{
7
Taster0Jetzt=taster0;
8
if(Taster0Jetzt!=Taster0Vorher){
9
Taster0Vorher=Taster0Jetzt;
10
betaetigt=1;
11
}
12
13
// die Variable 'betaetigt' sagt dir jetzt, ob es einen
14
// auszuwertenden Tastendruck gegeben hat oder nicht.
15
16
....
17
18
_delay_ms(10);
19
}
Das ist das eine. Jetzt wissen wir, ob eine Taste gedrückt wurde oder
nicht.
Das andere ist, was mit diesem Tastendruck geschehen soll. Er soll eine
LED schalten. D.h. wenn die LED nicht leuchtet, dann soll sie
eingeschaltet werden und wenn sie leuchtet dann soll sie ausgeschaltet
werden.
1
betaetigt=0;
2
Taster0Vorher=taster0;
3
4
// Hauptschleife
5
while(1)
6
{
7
Taster0Jetzt=taster0;
8
if(Taster0Jetzt!=Taster0Vorher){
9
Taster0Vorher=Taster0Jetzt;
10
betaetigt=1;
11
}
12
13
// die Variable 'betaetigt' sagt dir jetzt, ob es einen
14
// auszuwertenden Tastendruck gegeben hat oder nicht.
15
16
if(betaetigt){
17
betaetigt=0;
18
if(IS_LED_ON())
19
LED_OFF();
20
else
21
LED_ON();
22
}
23
24
delay_ms(10);
25
}
man sieht hier schon: das eine hat mit dem anderen im Grunde nichts zu
tun, ausser das die Umschaltung der LED durch die Taste ausgelöst wird.
Das Umschalten selbst ist aber recht unspezifisch von der Taste
abhängig. Das könnte genausogut bei einer Temperaturüber- bzw.
unterschreitung passieren, oder wenn eine Drehzahl zu hoch wird, oder
.... was auch immer. Irgendetwas triggert das Umschalten der LED (oder
eines Motors oder eines Relais). Abhängig ist der jeweils zu schaltende
Zustand (Ein oder Aus) von nichts anderem als von dem Zustand in dem die
LED (Motor, Relais, ...) jetzt gerade ist. Wenn der Zeitpunkt zur
Umschaltung da ist, dann wird einfach nachgesehen: wie steht es um die
LED (Motor, Relais, ...) jetzt gerade, welches ist der jetzige Zustand
und je nachdem wird in den jeweils anderen Zustand geschaltet.
Um zu wissen, wie die LED jetzt gerade steht, kannst du eine weitere
Variable benutzen, oder du siehst ganz einfach am entsprechenden Portpin
nach. Niemand sagt, dass man an einem Port-Ausgangspin nicht auch
nachsehen darf, wie der Ausgangspinn gerade steht
1
if(PORTC&(1<<PC1))// steht der Pin auf 1?
2
PORTC&=~(1<<PC1);// -> ja tut er. auf 0 schalten
3
else
4
PORTC|=(1<<PC1);// -> nein, tut er nicht. auf 1 schalten
Wenn du nur 1 Taste hast, dann kann man natürlich die Variable
'betaetigt' wieder los werden, zumal die davon abhängige OPeration jetzt
nicht so umfangreich ist.
1
betaetigt=0;
2
Taster0Vorher=taster0;
3
4
// Hauptschleife
5
while(1)
6
{
7
Taster0Jetzt=taster0;
8
if(Taster0Jetzt!=Taster0Vorher){
9
Taster0Vorher=Taster0Jetzt;
10
11
// Taste wurde betätigt, die LED PC0 in den anderen Zustand schalten
12
if(PORTC&(1<<PC0))
13
PORTC&=~(1<<PC0);
14
else
15
PORTC|=(1<<PC0);
16
}
17
18
_delay_ms(10);
19
}
Jeder Code ist aus 'Modulen' zusammengebaut. Diese können auch manchmal
ineinander geschachtelt sein, so wie in der letzten Version. Aber nichts
desto trotz finden sich auch hier wieder die 2 Teilaufgaben wieder: Das
eine ist die Erkennung eines Tastendrucks, die andere Teilaufgabe ist
das was dieser Tastendruck auslösen soll.
Karl H. schrieb:> Diese Tastenerkennung und Entprellung ist eine der wenigen Codestücke,> von denen ich jedem zugestehe, dass er sie einfach verwenden kann, ohne> zu verstehen wie er funktioniert.
Was dahinter steckt ist relativ simpel, aber bei der Lösung von PeDa ist
so viel optimiert worden, dass es wirklich schwierig wird noch
durchzublicken, vor allem für einen Anfänger.
Jan H. schrieb:> Karl H. schrieb:>> Diese Tastenerkennung und Entprellung ist eine der wenigen Codestücke,>> von denen ich jedem zugestehe, dass er sie einfach verwenden kann, ohne>> zu verstehen wie er funktioniert.>> Was dahinter steckt ist relativ simpel, aber bei der Lösung von PeDa ist> so viel optimiert worden, dass es wirklich schwierig wird noch> durchzublicken, vor allem für einen Anfänger.
Brauchst du mir nicht sagen :-)
Ich hab als ich den Code das erste mal gesehen habe, rund 40 Minuten
gebraucht um dahinter zu steigen, was jede Anweisung macht und warum sie
genau so und nicht anders formuliert ist. Und ich würde mich keinesfalls
als Anfänger bezeichnen. Diese 8 parallelen horizontalen Zähler sind
nicht so leicht zu durchschauen.
Ändert aber nichts daran, dass der Code einfach zu gut funktioniert um
ihn aus den falschen Gründen heraus nicht zu verwenden.
Karl H. schrieb:> Um zu wissen, wie die LED jetzt gerade steht, kannst du eine weitere> Variable benutzen,
Das wirst du zum Beispiel dann benutzen, wenn du am Portpin keinen
eindeutigen Zustand ablesen kannst. Du willst die LED ja vielleicht
dimmen und dann kannst du aufgrund der PWM vom aktuellen Zustand des
Portpins selber nichts ableiten. Der kann ja, je nachdem zu welchem
Zeitpunkt du innerhalb des PWM Zykluses nachsiehst, 0 oder 1 sein. Also
wirst du dir hier eine weitere Variable zu hilfe nehmen. Nennen wir sie
ganz einfach 'led1Zustand'. Wenn die Variable 1 ist, dann soll das
bedeuten, dass die LED leuchtet (auch wenn sie gerade erst hochdimmt)
und wenn sie 0 ist, dann soll das bedeuten, dass die LED auf jeden Fall
nicht leuchtet.
Also wirst du schreiben
1
Taster0Vorher=taster0;
2
3
// Hauptschleife
4
while(1)
5
{
6
Taster0Jetzt=taster0;
7
if(Taster0Jetzt!=Taster0Vorher){
8
Taster0Vorher=Taster0Jetzt;
9
10
if(led1Zustand==0){// war die LED aus?
11
led1Vorgabe=255;// hochdimmen starten
12
led1Zustand=1;// und vermerken, dass die LED jetzt leuchtet
13
}
14
else{// nein, die LED hat schon geleuchtet
15
led1Vorgabe=0;// dimmen auf 0
16
led1Brightness=0;// aber die LED auch gleich auf 0 setzen
17
led1Zustand=0;// und vermerken, dass die LED jetzt aus ist
18
}
19
}
20
21
.....
das wäre eine Möglichkeit. Eine andere wäre es, die Variable led1Vorgabe
gleich dafür mitzubenutzen. leuchtet die LED, dann hat die ja den Wert
255. Leuchtet sie nicht, dann hat sie den Wert 0.
1
Taster0Vorher=taster0;
2
3
// Hauptschleife
4
while(1)
5
{
6
Taster0Jetzt=taster0;
7
if(Taster0Jetzt!=Taster0Vorher){
8
Taster0Vorher=Taster0Jetzt;
9
10
if(led1Vorgabe==0){// war die LED aus?
11
led1Vorgabe=255;// hochdimmen starten
12
}
13
else{// nein, die LED hat schon geleuchtet
14
led1Vorgabe=0;// dimmen auf 0
15
led1Brightness=0;// aber die LED auch gleich auf 0 setzen
16
}
17
}
18
19
....
viele Wege führen nach Rom. Aber da wie dort ist der Knackpunkt die
Unterscheidung, dass die Erkennung eines Tastendrucks und das was dieser
beweirken soll, 2 voneinander getrennt zu sehende Dinge sind, die halt
nur 'zufällig' über die zu erzielende Logik miteinander in dem Sinne
verknüpft sind, dass das eine das andere auslöst.
Man kann das ganz gut daran erkennen, dass ich auch der "Beschreibung"
der Bedingungen
1
if( Taste gedrückt und hochdimmen )
2
led1Vorgabe = 255; // nur dimmen
3
4
if( Taste gedrückt und ausschalten )
5
{
6
led1Vorgabe = 0; // dimmen auf 0
7
led1Brightness = 0; // aber die LED auch gleich auf 0 setzen
8
// -> effektiv wird hier also nicht gedimmt, sondern
9
// die LED geht sofort aus.
10
}
den Teil 'Taste gedrückt' wie in der Mathematik als gemeinsamen Teil
beider Bedingungen 'herausheben' kann. Und genau das will ich ja sowieso
tun, weil es keinen Sinn macht, denselben Bedingungsteil 2 mal testen zu
müssen. Das ist nur eine Fleissaufgabe für nichts.
1
if( Taste gedrückt )
2
{
3
if( hochdimmen )
4
led1Vorgabe = 255; // nur dimmen
5
6
if( ausschalten )
7
{
8
led1Vorgabe = 0; // dimmen auf 0
9
led1Brightness = 0; // aber die LED auch gleich auf 0 setzen
10
// -> effektiv wird hier also nicht gedimmt, sondern
Karl H. schrieb:> Diese Tastenerkennung und Entprellung ist eine der wenigen Codestücke,> von denen ich jedem zugestehe, dass er sie einfach verwenden kann, ohne> zu verstehen wie er funktioniert.
Wenn man die Sache mit der Timer Initialisierung und den evtl.
differierenden Vektornamen der Timer Overflow ISR einmal auf den MC
angepasst hat, sehe ich das auch so. Diese beiden Punkte allerdings muss
jeder, der die Routine anwendet, implementieren und begreifen.
Hallo Karl Heinz,
wow... ich bin sprachlos! Tausend DANK für die HILFE!!! Du hast wirklich
alles sehr ausführlich beschrieben. Ich werde mich direkt heute Abend an
die Arbeit machen und mich damit ausgibig beschäftigen.
Wie du schon geschrieben hast man muss die Dinge gedanklich Trennen.
Erst schauen was der Taster macht und dann wenn "betätigt" schauen was
er auslöst! Klingt eigentlich einfach ... aber ertmal auf die Idee
kommen sich das genau so einfach zu machen. Das fällt mir noch nicht
sooo einfach! Aber ich denke mit der Zeit komme auch ich dahin... :)
Also! ...üben üben üben :)
Nochmals DANKE! ;)
Gruß
Rafael
Hi,
ich möchte ungern mit meinen Beiträgen hier euch allen vor allem dir
Karl Heinz auf den Senkel gehen. Ich komme mir schon selbst ein wenig
blöde vor!
Aber ich habe mir gestern Abend den Code vorgenommen und ein wenig
probiert....
Der Code den ich auf meinen Atmega8 gebrannt habe:
1
#define F_CPU 3686400
2
#include<avr/io.h>
3
#include<util/delay.h>
4
#include<stdbool.h>
5
#include<avr/interrupt.h>
6
7
#define LED0_ON PORTC |= (1<<PC0)
8
#define LED0_OFF PORTC &= ~(1<<PC0)
9
10
#define taster0 (PIND & (1<<PD0))
11
12
uint8_tTaster0Jetzt;
13
uint8_tTaster0Vorher;
14
15
intmain(void)
16
{
17
DDRC=0xff;// PORTC als Ausgang
18
DDRD=0x00;// PORTD als Eingänge
19
PORTD=0xff;// PullUps für PORTD
20
21
betaetigt=0;
22
Taster0Vorher=taster0;
23
24
// Hauptschleife
25
while(1)
26
{
27
Taster0Jetzt=taster0;
28
if(Taster0Jetzt!=Taster0Vorher){
29
Taster0Vorher=Taster0Jetzt;
30
betaetigt=1;
31
}
32
33
// die Variable 'betaetigt' sagt dir jetzt, ob es einen
34
// auszuwertenden Tastendruck gegeben hat oder nicht.
35
36
if(betaetigt){
37
betaetigt=0;
38
if(IS_LED_ON())
39
LED_OFF();
40
else
41
LED_ON();
42
}
43
44
delay_ms(10);
45
}
46
}
Fogende Feststellung: die LED geht solange AN, solange ich den Taster
drücke. Lasse ich den Taster los, geht sie AUS.
Ich interpretiere den Code fogendermaßen:
Das Programm wird auf den Kontroller wie oben aufgeführt gebrannt.
Taster0jetzt und Taster0Vorher sind beide HIGH "1".
Taste wird betätigt und betätigt gehalten => Taster0jetzt wird LOW.
Dadurch dass nun Taster0Jetzt != Taster0Vorher ist, läuft das Programm
durch die if- Schleife, Taster0Vorher wird LOW, in "betaetigt" wird eine
"1" geschrieben.
Somit wäre die Bedingung für die If- Schleife erfüllt, in der die LED
entweder ein- bzw ausgeschaltet wird. Je nach Zustand der LED.
In unserem Fall geht die LED erstmal an.
Nun folgendes.... ich lasse den Taster los.
In diesem Moment wird taster0jetzt HIGH und Taster0Vorher ist noch auf
LOW. Ergo... ich habe ein ungleich in der ersten IF- Schleife.
if( Taster0Jetzt != Taster0Vorher )
Jetzt wird taster0vorher HIGH und "betaetigt" ist immernoch "1".
Die Bedingung für die nächste if- Schleife ist gegeben und die LED geht
aus.
Somit kann die LED nie mit einem Tasterdruck ein und beim nächsten
wieder ausgeschaltet werden.
Was wird eigentlich aus der Variable "betaetigt"? Ihr wird beim ersten
Tastendruck die 1 zugewiesen und dann bleit sie für immer aus 1? Sie
müsste iwo wieder mit 0 beschrieben werden.?!?
Liege ich da gedanklich richtig ??
Wenn ich in der zweiten IF- Schleife noch zusätzlich den Taster abfrage,
dann funktioniert es. Die LED wird mit eimen Tasterdruck ein und mit dem
nächsten drücken wieder ausgeschaltet....
if( ! Taster0Vorher && betaetigt ) {
betaetigt = 0;
if( IS_LED_ON() )
LED_OFF();
else
LED_ON();
}
Was ist aber mit der Variablen "betaetigt" ??
Gruß
R
Rafael S. schrieb:> Ich interpretiere den Code fogendermaßen:> Das Programm wird auf den Kontroller wie oben aufgeführt gebrannt.> Taster0jetzt und Taster0Vorher sind beide HIGH "1".> Taste wird betätigt und betätigt gehalten => Taster0jetzt wird LOW.> Dadurch dass nun Taster0Jetzt != Taster0Vorher ist, läuft das Programm> durch die if- Schleife, Taster0Vorher wird LOW, in "betaetigt" wird eine> "1" geschrieben.> Somit wäre die Bedingung für die If- Schleife erfüllt, in der die LED> entweder ein- bzw ausgeschaltet wird. Je nach Zustand der LED.> In unserem Fall geht die LED erstmal an.> Nun folgendes.... ich lasse den Taster los.> In diesem Moment wird taster0jetzt HIGH und Taster0Vorher ist noch auf> LOW. Ergo... ich habe ein ungleich in der ersten IF- Schleife.>> if( Taster0Jetzt != Taster0Vorher )>> Jetzt wird taster0vorher HIGH und "betaetigt" ist immernoch "1".> Die Bedingung für die nächste if- Schleife ist gegeben und die LED geht> aus.
ABgesehen davon, dass ein if technisch gesehen keine Schleife ist, ist
die Analyse soweit richtig. Gratuliere!
> Somit kann die LED nie mit einem Tasterdruck ein und beim nächsten> wieder ausgeschaltet werden.
Doch. du musst dur nur überlegen, ob jeder Wechsel des Tastenzustands zu
einem betaetigt führen soll, oder nur dann wenn die Taste von 1 auf 0
wechselt (also niedergedrueckt wurde).
Das ist aber leicht festzustellen. Wenn die Taste jetzt auf 0 ist, dann
muss das ein Wechsel von 1 auf 0 gewesen sein. Das kann man testen und
nur dann betaetigt auf 1 setzen wenn genau das erfüllt ist. Den anderen
Wechsel (also das Loslassen der Taste) ignoriert man einfach. In deinem
Programm interessiert er schlicht und ergreifend nicht.
> Was wird eigentlich aus der Variable "betaetigt"? Ihr wird beim ersten> Tastendruck die 1 zugewiesen und dann bleit sie für immer aus 1? Sie> müsste iwo wieder mit 0 beschrieben werden.?!?
Wird die doch.
Hier
1
if(betaetigt){
2
betaetigt=0;
wird der Tastendruck bearbeitet, dann setzt du das Flag welches eine
niedergedrückte Taste vermerkt, wieder zurück auf 0.
Rafael S. schrieb:> Wenn ich in der zweiten IF- Schleife noch zusätzlich den Taster abfrage,> dann funktioniert es. Die LED wird mit eimen Tasterdruck ein und mit dem> nächsten drücken wieder ausgeschaltet....
Kannst du machen.
Aber denk an die Überlegung die Dinge zu trennen.
Du willst in deinem Programm das Niederdrücken einer Taste erkennen. Das
gehört logisch gesehen in den Themenkreis 'Erkennen einer gedrückten
Taste' und (in deinem Programm) nicht in den Themenkreis 'Was soll ein
Tastendruck bewirken'.
Es gibt natürlich auch Fälle, bei denen man explizit zwischen
Niederdrücken und Loslassen unterscheidet. Dann würde das in einem
gewissen Sinne zur Auswertung gehören. Den Fall hast du aber nicht. Dich
interessiert qquer durch dein Programm nur das Niederdrücken (was auch
der häufigere Fall ist). Also siedelst du diese Funktionalität im
Dunstkreis genau dieser Erkennung eines Tastendrucks an. Denn du willst
dich nicht in weiterer Folge mit diesem technischen Detail rumschlagen.
Wenn die Tastenerkennung nur dann 'Bescheid gibt', wenn sie ein
Niederdrücken registriert, dann bist du happy damit. Überhaupt wenn du
dann irgendwann einmal mehrere Tasten und je nach Kontext
unterschiedliche Codestellen zur Bearbeitung hast.
1
if(Taster0Jetzt!=Taster0Vorher){// irgendwas ist mit der Taste passiert
2
// nur was? Die Taste kann niedergedrueckt
3
// worden sein oder aber auch losgelassen
4
Taster0Vorher=Taster0Jetzt;
5
if(!Taster0Jetzt)// wenn es ein Niederdrücken war
6
betaetigt=1;// dann werten wir das als Betaetigung