C LED-Reihe in Drehrichtung eines Encoders "laufen" lassen

Sarsch

Neues Mitglied
23. Apr. 2014
2
0
0
Sprachen
Schönen guten Tag.

Ich arbeite zur Zeit an meiner Thesis und komme einfach auf keine Lösung meines Problems. Kurzer Überblick:
Ein Teil der Arbeit handelt davon mittels eines Encoders (Drehgebers), eine Menüwahl durchzuführen. Zur besseren Visualisierung habe ich neben dem Encoder 3 LEDs angebracht, die als Statusanzeige dienen und einem die Menühführung erleichtern sollen. Programmiert wird das ganze auf einem Arduino Uno. Die Syntax ist etwas anders aber in großen Teilen der AVR Programmierung in C# sehr ähnlich.

In der Grafik, die hoffentlich eingefügt wurde, ist der Aufbau zu sehen. Rechts der Encoder und links daneben die 3 Status LEDs.

Prototype Box.png

Das Auslesen des Encoders funktioniert in beide Richtungen einwandfrei. Ich habe also immer den aktuellen Wert aus der Drehbewegung des Encoders zur Verfügung.

Nun zu meinem Problem. Ich möchte die LEDs in Drehrichtung des Encoders "mit laufen" lassen. D.h. wenn ich nach oben drehe, soll fortlaufend die nächste LED angehen. Es ist immer nur eine LED gleichzeitig eingeschalten!! Wenn ich nach unten drehe, dasselbe in die Abwärtsrichtung. Leuchtet beispielsweise die oberste LED und ich drehe weiterhin aufwärts, so soll das ganze von neuem beginnen und die unterste aufleuchten. In die entgegengesetzte Richtung dasselbe Spielchen.

Was ich nicht hin bekomme ist eine Abfrage zu schreiben, die mir anhand des aktuellen Wertes des Encoders sagt, dass in die positive bzw. negative Richtung gedreht wurde und anhand dessen die passende LED einschaltet.
Was ich bis jetzt habe ist:

void loop() //das Programm ist zunächst nur für 2 LEDs, da ich mir bis zur Lösung den Schreibaufwand sparen wollte
{
if(drehgeber > drehgeber_alt) //diese IF-Abfrage funktioniert und ist erst einmal nur für die positive Drehrichtung
{ //für die negative Drehrichtung sieht das wohl sehr ähnlich aus bis auf das Größer-Gleich-Zeichen
drehgeber_alt = drehgeber;
if(digitalRead(10) == HIGH && digitalRead(11) //die anderen beiden machen in der Konstellation natürlich keinen Sinn :p
{

digitalWrite(11,HIGH);
digitalWrite(10,LOW);

}
if(digitalRead(11) == HIGH) //was sich hier einstellt ist, dass die LED an Pin 10 dauerhaft an ist, was wie gesagt logisch ist, da die 2 IF-Abfragen
{ //Käse sind

digitalWrite(10,HIGH);
digitalWrite(11,LOW);
}
}


}

Für jeden hilfreichen Tipp wäre ich sehr dankbar.

Mit besten Grüßen
 
hey, also irgendwie fehlen mir da noch ein paar Infos oder ich habs noch nicht 100% ig verstanden ... du hast ein Poti / Incrementalgeber oder irgendwas von dem du Werte von (0 bis irgendwas bekommst) ?!

Dann willst du wenn der Positiv wird einfach die Led in die Eine Richtung laufen lassen und wenn Negativ in die Andere Richtung ?!? dann bist du ja auf dem Richtigen weg. Da ich keinen Schaltplan habe nehme ich einfach mal an, dass die LEDs auf PortA liegen PA0, PA1, PA3 Hier mal ein schnell schuss, bin grad leider nicht daheim zum es Testen, müsst aber laufen (is nur in pn++ getippt).

(Natürlich solltest das ganze dann noch in eine schöne Funktion verpacken)
Code:
 habs im Anhang als c file angehängt, da es irgendwie nicht hier reingepasst hatte ...
oder habe ich dich falsch verstanden ? das ganze macht halt nun wenn der Encoder wert größer wird 001 010 100 001 ... bzw wenns kleiner wird 001 100 010 001 ... ev. is n tippfehler drin wie gesagt, konnts nicht über nen compiler lassen.

Gruß, Manuel

Anhang anzeigen lauflicht.c
 
Hi Manu und danke für deine Antwort.
Die Aufgabenstellung hast du schon richtig aufgenommen. Die LEDs spiegeln die Drehung des Encoders wieder.
Ich bin mittlerweile auf eine Lösung gekommen. Passiert mir oft, wenn ich einfach die Problemstellung laut ausspreche bzw. ausführlich hinschreibe :)
Ich habe das ganze mit einer IF-Abfrage für die Drehrichtung, einer Variable für die zugehörige LED und einer switch-case-Anweisung gemacht:
Meine LEDs liegen auf den Pins 10,11 und 12. Pin 10 ist am Anfang des Programms auf High gesetzt und x mit 0 initialisiert. Die Variable x steht dabei einfach nur für die derzeit aktive LED. x = 0 entspricht Pin 10. x = 1 entspricht Pin 11. x = 2 entspricht Pin 12.

Code:
void loop()
{       
 
  if(drehgeber > drehgeber_alt) 
    {     
      
       switch(x){
    
  case 0:  digitalWrite(11,HIGH);
           digitalWrite(10,LOW);
           x = 1;
           break;
   case 1: digitalWrite(12,HIGH);
           digitalWrite(11,LOW);
           x = 2;
           break;
           
   case 2: digitalWrite(10,HIGH);
           digitalWrite(12,LOW);
           x = 0;
           break;
   default: 
          break;
             }
             drehgeber_alt = drehgeber;
        }
        
   
    if(drehgeber < drehgeber_alt) 
    {     
      
       switch(x){
    
  case 0:  digitalWrite(12,HIGH);
           digitalWrite(10,LOW);
           x = 2;
           break;
   case 1: digitalWrite(10,HIGH);
           digitalWrite(11,LOW);
           x = 0;
           break;
           
   case 2: digitalWrite(11,HIGH);
           digitalWrite(12,LOW);
           x = 1;
           break;
   default: 
          break;
             }
             drehgeber_alt = drehgeber;
        }
    
}

Es funktioniert ganz gut hat nur nen seltsamen Bug, dass bei jedem 4ten Schritt in dieselbe Drehrichtung der Zähler hängt und danach wie gewohnt weiter geht. Heißt, die ersten 3 gehen problemlos und der 4te wird verschluckt. Ab dem 5ten läufts wieder 3 weitere Schritte bis es beim 8ten hängen bleibt usw. Hat eventuell was mit meinem Interrupt zu tun in dem der Encoder eingelesen wird. Ich versuche das noch zu fixen.
Habe deinen Code kurz durchgesehen und denke, dass das auch ne gute Variante ist. Du gehst alle Fälle durch und weist ganz am Ende deinem Register das Ergebnis zu. Dafür müsste ich beim Arduino auf die Bit-Ebene runter, was aber kein Problem ist. Werde das mal bei Gelegenheit durchspielen.

Mit besten Grüßen
 
hey

also je nachdem wie du "dregeber" beschreibst, kann es so etwas problematisch werden :).
also ich würde dir empfehlen deine zweite if in ein else if zu Wandeln.
Bzw auch sicher stellen, dass der drehgeber nur bei einem durchlauf eben beschrieben wird (wie gesagt weiß nicht woher der Wert kommt .. wenn der aus nem IRS kommt wäre das sonst arg kritisch).

Mit deinem jeden 4ten verstehe ich nicht, wenn ich es so lese sollte es passen..

deine Möglichkeit geht natürlichauch =) ist halt aufwendiger wenn du mehrere hast, aber bei sowenig geht das natürlich auch =).


Gruß,
 
Moin :)

Wenn die Arduino IDE dem der "AVR GCC" ähnelt, dann wird es bestimmt auch den "switch case" geben.
Das könnte vill. deine Aufgabe mit den LED´s erheblich vereinfachen.

Lies dir mal den Syntax dazu durch.


:)
 
Moin :)

Wenn die Arduino IDE dem der "AVR GCC" ähnelt, dann wird es bestimmt auch den "switch case" geben.
Das könnte vill. deine Aufgabe mit den LED´s erheblich vereinfachen.

Lies dir mal den Syntax dazu durch.


:)


Ich habe gerade gesehen, dass du ja schon mit "switch / case" arbeitest.
Wo ist jetzt dein Problem ?
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)