WS2812-Matrix Interrupt

Guten Morgen programmers :slight_smile:

Folgendes: Also ich bin noch nicht so lange am Programmieren und dementsprechend ist auch mein Wissensstand in Sachen Arduino :slight_smile:

Ich habe eine RGB-LED Matrix (41 mal 9). Und da habe ich über eine Library von Adafruit einen Text über die Matrix laufen lassen.

Jetzt möchte ich aber das so machen, dass ich über einen Interrupt einen anderen Text durchlaufen lasse.
Ich habe aber keine Ahnung von Interrupt. Ich habe zwar im Buch nachgelesen, aber das hat noch nicht zum Erfolg geführt.
Kann mir da jemand weiterhelfen???

sketch_jan26a.ino (922 Bytes)

Wieso brauchst Du einen Interrupt?
Eine einfache digitalRead()-abfrage reicht nicht?
Grüße Uwe

Der Ausbilder möchte das mit Interrupt.
Das soll auch nicht nur ein Text durchlaufen, sondern auch mal ein Regenbogenmuster etc...
Ich verstehe einfach nicht, wie ich den Interrupt reinsetze.
Wo sollte ich denn das digitalRead() reinschreiben? Mit dem Interrupt würde ich sofort den anderen Text durchlaufen lassen können. Wenn ich das mit dem digitalRead () mache, dann muss ich doch erst warten bis der void loop bis dahin gekommen ist, wo ich digital reinschreibe, oder?

WS2812 + Interrupts auf AVR wird nichts, weil Interrupts beim LEDs Schreiben gesperrt sind.

Was heißt AVR? :confused:
kann ich also die datapin-Leitung gar nicht über einen Interrupt ansteuern?
Ich habe mir das so vorgestellt, dass ich einen Taster bei dem Interrupt-Pin anschließe und sobald der Taster betätigt ist, soll der nächste Text angezeigt werden.
In diesem Fall können dann nur 2 Möglichkeiten ausgewählt werden, weil es ja auch nur 2-Interrupt-Pins gibt, oder liege ich da falsch?

http://www.modellbau-wiki.de/wiki/AVR

Wie lautet die Aufgabe deines Ausbilders denn wörtlich?

kann ich also die datapin-Leitung gar nicht über einen Interrupt ansteuern?

Falsche Frage.

Ich habe mir das so vorgestellt, dass ich einen Taster bei dem Interrupt-Pin anschließe und sobald der Taster betätigt ist, soll der nächste Text angezeigt werden.

Auch wenn Interrupts an der Stelle unsinnig sind: Ja! Das geht.

weil es ja auch nur 2-Interrupt-Pins gibt,

z.B. beim UNO ist jeder Pin Interrupt fähig.
Siehe: "PinChangeInterrupt"

...einen Taster ... anschließe und sobald der Taster betätigt ist, soll der nächste Text angezeigt werden.
In diesem Fall können dann nur 2 Möglichkeiten ausgewählt werden,

Die Abfrage eines Tasters ohne Interruptnutzung ist möglich. -> Zustandsautomat (ohne Delays).

So kannst Du viele Texte/Programme auswählen - jeder Tastendruck schaltet ein Programm weiter.

Whandall:
AVR – Modellbau-Wiki

Wie lautet die Aufgabe deines Ausbilders denn wörtlich?

Er meint das ich den Text dort wiedergeben soll. Über einen Taster soll dann ein anderer Text durchlaufen. Beim nächsten Taster soll dann z.b. ein Regenbogen durchspielen.
Und er meinte ich werde dafür den "Interrupt" brauchen

Helmuth:
Die Abfrage eines Tasters ohne Interruptnutzung ist möglich. -> Zustandsautomat (ohne Delays).

So kannst Du viele Texte/Programme auswählen - jeder Tastendruck schaltet ein Programm weiter.

Also ist das so zu verstehen, das ich dann mit einem Taster das erste Programm schalte, bei der nächsten Betätigung das nächste usw. Geht es dann auch, dass ich zurückschalte auf das Programm was vorher war???

Und er meinte ich werde dafür den "Interrupt" brauchen.

Dann hat er entweder keine Ahnung, oder Ihr verwendet einen Arduino mit ARM Prozessor.

Um welchen Arduino geht es?

Also ist das so zu verstehen, das ich dann mit einem Taster das erste Programm schalte, bei der nächsten Betätigung das nächste usw. Geht es dann auch, dass ich zurückschalte auf das Programm was vorher war???

Du nimmst eine Zustandsvariable. In Abhängigkeit der Tastendrücke zählst Du diese hoch. Dann berechnest Du Animationen / Bilder in Abhängigkeit dieser Variable.

Z.B. wenn Programmnummer = 23, dann zeige Animation 23.

Mit einem Taster kannst Du nur weiterschalten, nicht zurück-. Dafür brauchst Du 2 Taster.
Oder Du wertest die Druckdauer aus - kurzer Klick = weiter, langer Klick = zurück. Klingt gut, nervt aber beim Gebrauch.

Dann hat er entweder keine Ahnung, oder Ihr verwendet einen Arduino mit ARM Prozessor.

Um welchen Arduino geht es?

Es geht um einen Arduino Uno

Du nimmst eine Zustandsvariable. In Abhängigkeit der Tastendrücke zählst Du diese hoch. Dann berechnest Du Animationen / Bilder in Abhängigkeit dieser Variable.

Z.B. wenn Programmnummer = 23, dann zeige Animation 23.

Mit einem Taster kannst Du nur weiterschalten, nicht zurück-. Dafür brauchst Du 2 Taster.
Oder Du wertest die Druckdauer aus - kurzer Klick = weiter, langer Klick = zurück.

Ja super, dass hört sich ja gar nicht so schwer an. Dann einfach eine for-Schleife (int i = 0; i == 1; i++);

So richtig???

Es geht um einen Arduino Uno

Dann vergiss die Interrupts.

Dann einfach eine for-Schleife (int i = 0; i == 1; i++);
So richtig???

Verstehe ich nicht.

Mal als Pseudocode:

loop() {

  Taster abfragen und pgmNR entsprechend verändern, wenn nötig

  in Abhängigkeit von pgmNR passende Animation aufrufen (switch-case)
}

Alle Animationen als einzelne und unabhängige Funktionen anlegen, keine Delays verwenden (siehe BlinkWithoutDelay)

Ja danke, ich glaube das hat mir geholfen.

Die Ansteuerung der WS2812 ist sehr zeitkritisch. Die Übertrgung der Signale muß auf 0,15µS genau erfolgen. Das erreicht man nur mit Assembler und abgeschaltenen Interrut. Deshalb kann kein Interrupt während der Ausgabe der Daten an die Matrix erfolgen. (wahrscheinlich weiß das Dein Lehrer nicht).
Dannach hast Du das Problem, daß Taster prellen, das heißt wenn die Kontakte schließen, prallen sie 2-3 ab und öffnen wieder. Das bedeutet, daß der Interrupt mehrmals aufgerufen wird (der µController ist sehr schnell). Das Prellen mußt Du durch Hardware verhindern sodaß bei einer Betätigung/loslassen des Tasters nur ein Wechsl erfolgt.

Als Beispiel:
Den 2. Text kannst Du einfach :

...
loop()
{
  if(digitalRead(taster)== HIGH)
    {
    Ausgabe 1.Text
    }
  else
    {
    Ausgabe 2. Text
    }
  }

Um mehr verschiedene Texte/animationen zu haben nimmst Du eine Variable und zählst sie hoch/runter. Als Beispiel suche "Arduino switch toggle"

und dann mit switch case unterscheidest Du die verschiedenen Animationen /Texte.

Das ist dann ein Zustandsautomat. Das ist ganz so wie Dein Stundenplan in der Schule Montag : Deutsch dann 2 Stunden Mathematik, usw. Du weißt je nach Wochentag Was Du zur Schule mitbringen mußt bzw in welchen Raum Du gehen mußt.

AVR ist die Produktfamilie von ATMEL, wo der ARmega328 drin ist. Microchip AVR – Wikipedia

Grüße Uwe

Hey Leute ihr seid super. Das ist ja richtig simple und ich zerbrich mir den Kopf. Jetzt lese ich mir mal noch beides durch, sowohl Switch case und arduino Switch toggle und dann sollte das klappen.

Herzlichen Dank!!! :slight_smile: :slight_smile: :slight_smile: :slight_smile:

Um mehr verschiedene Texte/animationen zu haben nimmst Du eine Variable und zählst sie hoch/runter. Als Beispiel suche "Arduino switch toggle"

und dann mit switch case unterscheidest Du die verschiedenen Animationen /Texte.

Also du meinst das so, oder?

Der Taster soll bei jeder Betätigung einmal hochzählen, oder? Und dann mit Switch case:

Switch (taster){



case 1:

text 1 läuft wenn taster den Wert 1 hat

case 2:

text 2 läuft wenn taster den Wert 2 hat


}

liege ich damit richtig?

Du hast break vergessen.

Ich mache gerade dies als Grundgerüst (enum ist nicht notwendig aber praktisch):

enum Zustaende {INIT, AUSWAHL, ERGEBNIS};
byte zustand = INIT;
...
  switch (zustand) {
    case INIT:
      // Initialisierung
      break;
    case AUSWAHL:
      // Manschaftsauswahl
      break;
    case ERGEBNIS:
      // Ergebnisanzeige
      break;
  }

p123:
Also du meinst das so, oder?

Der Taster soll bei jeder Betätigung einmal hochzählen, oder? Und dann mit Switch case:

Switch (taster){

case 1:

text 1 läuft wenn taster den Wert 1 hat

case 2:

text 2 läuft wenn taster den Wert 2 hat

}





liege ich damit richtig?

Geht auch wenn Du 0 und 1 nimmst (ergebnis von digitalRead())

aber ich meinte:

So erkennst Du daß der Taster das erste mal als dedrückt/losgelassen erkannt wurde und kannst so Deine Zustandsvariable hoch/ runterzählen.

das delay() sollte besser nach dem digitalRead() sein und 10 mS lang sein zum entprellen.

Grüße Uwe

Also ich habe den Sketch jetzt verändert.

Ich hatte gedacht, dass es so funktionieren müsste, tut es aber nicht:

const uint16_t colors[] = {
  matrix.Color(255, 200, 0), matrix.Color(255, 200, 0), matrix.Color(255, 200, 0)
};

const int buttonPin = 2;
int buttonState = 0; //Lesen des Tasters
int prgm = 0;


void setup() {
  matrix.begin();
  matrix.setTextWrap(false);
  matrix.setBrightness(140);
  matrix.setTextColor(colors[0]);

}

int x    = matrix.width();
int pass = 0;

pinMode(buttonPin, INPUT);



void loop() {

  buttonState = digitalRead(buttonPin); //Zustand Taster
  if (buttonState == HIGH) {
    prgm + 1;
  }
  switch (prgm) {
    case 1:
      matrix.fillScreen(0);
      matrix.setCursor(x, +1);
      matrix.print(F("Herzlich Willkommen im NAZHA"));
      if (--x < -165) {
        x = matrix.width();
        if (++pass >= 3) pass = 0;
        matrix.setTextColor(colors[pass]);
      }
      matrix.show();
      delay(100);
    case 2:
      matrix.fillScreen(0);
      matrix.setCursor(x, +1);
      matrix.print(F("Hallo Christian"));
      if (--x < -165) {
        x = matrix.width();
        if (++pass >= 3) pass = 0;
        matrix.setTextColor(colors[pass]);
      }
      matrix.show();
      delay(100);
  }
  if (prgm == 2);
    prgm == 0;
}

Wer kann mir weiterhellfen? Was ist falsch??

Übrigens kommt folgende Fehlermeldung:

sketch_jan26a:33: error: expected constructor, destructor, or type conversion before '(' token
expected constructor, destructor, or type conversion before '(' token