Forum: Mikrocontroller und Digitale Elektronik Lauflicht mit Taster


von Chriss (Gast)


Angehängte Dateien:

Lesenswert?

Ich habe vier LED´s am PortD hängen und möchte nun damit ein "Lauflicht" 
bauen. Immer wenn ich den Taster drücke, soll die nächste LED angehen 
und die vorherige ausgehen. Also: am Anfang ist LED0 an. Wenn ich drücke 
soll sie ausgehen und dafür LED1 an. Wenn ich wieder drücke soll diese 
ausgehen und die nächste an. Bei der letzten soll das ganze wieder von 
vorne anfangen.
Kann man das ganze NUR mit IF-Funktionen lösen? ich weiß absolut nicht 
was ich schreiben soll. Im Anhang ist alles was ich hinbekommen habe... 
Hab halt absolut keine IDee wie ichs machen könnte.

Danke für jede Hilfe!

von Gast (Gast)


Lesenswert?

Bei den einzelnen Lampe() Funktionen brauchst du nicht jedes mal alle 
Pins schalten. Es reicht wenn du die aktuell leuchtende ausschaltest und 
die nächste einschaltest.
Also: 1x PORT |= (PIN) und 1x PORT &= ~(PIN2)
Die restlichen bleiben dabei auf Low.

von Chriss (Gast)


Lesenswert?

Das ist schon Absicht so, dass ich immer alle ausschalte ;)... vllt will 
ich irgendwann mal was ändern, dass z.b. nach der 3. schon die erste LED 
wieder angeht... Dann muss ich oben nicht alles umändern.
Kann man die IF funktionen nicht irgendwie Schachteln? ich weiß nur 
nicht wie ich sie schachteln soll, damit das rauskommt, was ich haben 
will.

von Michael G. (linuxgeek) Benutzerseite


Lesenswert?

Chriss wrote:
> Ich habe vier LED´s am PortD hängen und möchte nun damit ein "Lauflicht"
> bauen. Immer wenn ich den Taster drücke, soll die nächste LED angehen
> und die vorherige ausgehen. Also: am Anfang ist LED0 an. Wenn ich drücke
> soll sie ausgehen und dafür LED1 an. Wenn ich wieder drücke soll diese
> ausgehen und die nächste an. Bei der letzten soll das ganze wieder von
> vorne anfangen.

Hehe ich dachte Du hast das in Zwischenzeit am laufen? :D

von Chriss (Gast)


Lesenswert?

es geht sich hier um was ganz anderes ;) vorher wollt ichn interrupt der 
auch läuft. aber jetzt weiß ich nicht wie ich die dinger vernünftig 
schachteln soll. Also was gaaaanz anderes

von Michael H* (Gast)


Lesenswert?

Chriss wrote:
> Kann man das ganze NUR mit IF-Funktionen lösen? ich weiß absolut nicht
was für eine hausaufgabe ist denn das? die sind grundsätzlich alleine zu 
erledigen.

eine anständige lösung wäre z.b.:
1
PORTD = 1; /* damit ich bei 0 anfange */
2
void ich_werde_bei_tastendruck_aufgerufen(void)
3
{
4
   static unsigned char aktuelle_led;
5
   aktuelle_led++;
6
   if(aktuelle_led > 3)   aktuelle_led = 0;
7
   PORTD = 1 << aktuelle_led; /* if wäre hier grausam */
8
   wartefunktion(200ms); /* ich bin nötig */
9
}

nachtrag: dein code vermittelt auch das gefühl, dass du gar nicht so 
recht weißt, was du mit den befehlen eigentlich tust. das ganze &- und 
|-gefrickel mit einlesen und ausgeben...
ich empfehle Bitmanipulation und 
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Bitfelder 
abwärts

von Gast (Gast)


Lesenswert?

1
KeyStateOld = KeyStateNew
2
KeyStateNew = [einlesen vom Port]
3
4
IF (KeyStateOld==1) & (KeyStateNew==0)
5
    {
6
    // Tastenzustand hat sich von "nicht gedrückt"
7
    // zu "gedrückt" geändert
8
9
    k++
10
    IF (k==4) 
11
        {
12
        k = 0
13
        }
14
15
    [LED Nr. k einschalten, alle anderen aus]
16
    }

Diesen Pseudocode sinnvoll komplettieren und ca. 20 bis 100 mal pro 
Sekunde ausführen (bis in alle Ewigkeit).

von Michael G. (linuxgeek) Benutzerseite


Lesenswert?

Chriss wrote:
> es geht sich hier um was ganz anderes ;) vorher wollt ichn interrupt der
> auch läuft. aber jetzt weiß ich nicht wie ich die dinger vernünftig
> schachteln soll. Also was gaaaanz anderes

Hm joa aber das erste, was Du mal lernen solltest, ist Deinen Code 
anstaendig zu formatieren ;)

von Chriss (Gast)


Lesenswert?

ohje andauernt neue funktionen von denen ich keine ahnung habe... kann 
man die IF´s denn nicht irgendwie so zusammen puzzeln das das ganz 
klappt?

von Michael H* (Gast)


Lesenswert?

ja, aber warum sollte man?
was ist denn an den funktionen nicht verständlich? wird hier im tutorial 
und in den 2 links von mir doch alles erklärt.

von Chriss (Gast)


Lesenswert?

oh sry ich habe deine links garnicht gesehn... werde ich mir jetzt mal 
angucken

von Chriss (Gast)


Lesenswert?

Noch eine andere frage womit ich vllt schon ein stück weiter komme... 
mit dem programm, was ich geschrieben habe, geht die andere led nur so 
lange an, wie cih den taster drücke, wenn ich wieder loslasse springts 
wieder in die urposition... wie kann ich das ändern? also dass die leds 
so stehen bleiben?

von Michael H* (Gast)


Lesenswert?

versetz dich mal in die lage deines avrs und geh die befehle einzeln 
nacheinander durch. da sollte man recht schnell draufkommen.

von Chriss (Gast)


Lesenswert?

ich hebs jetzt mit einer schleife versucht, dass der befehl immer 
wiederholt wird. aber das klappt irgendwie nicht, dann leuchten alle 
leds

von Michael H* (Gast)


Lesenswert?

kleiner tipp: welche led geht denn an, wenn du wieder loslässt? und wo 
taucht die entsprechende zeile im code auf?

von Gast (Gast)


Lesenswert?

>ich hebs jetzt mit einer schleife versucht, dass der befehl immer
>wiederholt wird. aber das klappt irgendwie nicht, dann leuchten alle
>leds

Solange Du nicht verstanden hast, dass Du zur Lösung Deines Problems im 
Programm erkennen musst, wann sich der Tastenzustand von "nicht 
gedrückt" auf "gedrückt" ändert, wird das nix.

Um eine solche Änderung festzustellen musst Du a) den Taster zyklisch in 
einem kleinen Zeitintervall, z. B. alle 10 ms, abfragen, und b) Dir 
immer den vorherigen Tastenzustand merken. Das erlaubt Dir, den 
vorherigen mit dem aktuellen Zustand zu vergleichen. Bei "11", d. h. der 
vorherige Zustand ist "1" und der aktuelle auch "1", dann ist die Taste 
unverändert "up", bei "00" ist sie unverändert "down", bei "10" wurde 
sie gerade gedrückt, und bei "01" gerade losgelassen. Dich interessiert 
der Fall "10", darauf musst Du mit "IF" prüfen.  Tritt der 10-Fall ein, 
z. B. 7.28 Sekunden nach dem Start des Programms, schaltest Du die 
LED-Kette eins weiter, und in allen anderen drei Fällen tust Du nichts.

Nochmal: Nur mit der Information über den aktuellen Tastenzustand kannst 
Du dieses Problem nicht lösen, denn während die Taste "up" ist, kann 
jede LED eingeschaltet sein, und bei "down" genauso. Du brauchst 
mehr, nämlich die Information über die Änderung des Tastenzustands.

Das zyklische Abfragen kannst Du mit einer Delayschleife 
bewerkstelligen, oder (besser) über einen Timer.  Als Zeitintervall geht 
alles von ca. 5 ms bis 50 ms.  Wählst Du es noch größer, wirst Du 
zunehmend eine leichte Verzögerung zwischen dem Druck auf die Taste und 
dem Weiterschalten der LEDs spüren (ausprobieren!).

Gleich wird hier übrigens irgendein schlauer Mensch darauf hinweisen, 
dass man dieses Problem auch mit einem PinChange-Interrupt lösen kann. 
Stimmt. Aber man kann es eben auch ohne PC-Interrupt lösen, und das 
oft besser (Stichwort Entprellung).

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
Noch kein Account? Hier anmelden.