www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Lauflicht mit Taster


Autor: Chriss (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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!

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Chriss (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Michael G. (linuxgeek) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Chriss (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Michael H* (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.:
PORTD = 1; /* damit ich bei 0 anfange */
void ich_werde_bei_tastendruck_aufgerufen(void)
{
   static unsigned char aktuelle_led;
   aktuelle_led++;
   if(aktuelle_led > 3)   aktuelle_led = 0;
   PORTD = 1 << aktuelle_led; /* if wäre hier grausam */
   wartefunktion(200ms); /* ich bin nötig */
}

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-Tu... 
abwärts

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
KeyStateOld = KeyStateNew
KeyStateNew = [einlesen vom Port]

IF (KeyStateOld==1) & (KeyStateNew==0)
    {
    // Tastenzustand hat sich von "nicht gedrückt"
    // zu "gedrückt" geändert

    k++
    IF (k==4) 
        {
        k = 0
        }

    [LED Nr. k einschalten, alle anderen aus]
    }

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

Autor: Michael G. (linuxgeek) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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 ;)

Autor: Chriss (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Michael H* (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Chriss (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
oh sry ich habe deine links garnicht gesehn... werde ich mir jetzt mal 
angucken

Autor: Chriss (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Michael H* (Gast)
Datum:

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

Autor: Chriss (Gast)
Datum:

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

Autor: Michael H* (Gast)
Datum:

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

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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).

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.