Hilfe zu Taster

Hallo Leute,

ich bin ganz neu im Thema und benötige Hilfe.
Vielleicht kann jemand mal über meinen sketch schauen und mir sagen, warum es so nicht funktioniert.
Ich würde gerne mehrere Lichtmodi eines WS2812 Stripes mit einem Taster durchwechseln.
Beim kompilieren kommt kein Fehler, aber es leuchtet nichts.

#include <FastLED.h>
const int tasterPin = 11;     // Taster an Pin 11 angeschlossen
const int LED_PIN = 7;       // LED signal an Pin 7
const int NUM_LEDS = 8;      // Anzahl LED
CRGB leds[NUM_LEDS];
unsigned long previousMillis = 0;
const long interval = 500;  
int StartValue = 0;
int lichtmodus = 0;          // Variable für die verschiedenen festgelegten Farben
int tasterStatus = LOW;      // Variable zu speichern des Tasterstatus
void setup()
{
  pinMode(tasterPin, INPUT);      // Setzt den TasterPin als Eingang
  FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS);
}
void loop()
{
  // Abfrage ob der Taster gedrückt ist
  tasterStatus = digitalRead(tasterPin);

  // Wenn Taster gedrückt ist...
  if (tasterStatus == HIGH)
  {
    lichtmodus++;     // Lichtmodus +1
    delay(300);       // 300ms warten
  }

  //+++++++++++++++ LEUCHTPROGRAMME +++++++++++++++++

  // Modus 0 = Licht aus
  if (lichtmodus == 0)
  {
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= interval && StartValue <= NUM_LEDS) {
      previousMillis = currentMillis;
      leds[StartValue] = CRGB::Black;
      StartValue++;
      FastLED.show();
    }

    // Modus 1 = Blau
    else if (lichtmodus == 1)
    {
      unsigned long currentMillis = millis();
      if (currentMillis - previousMillis >= interval && StartValue <= NUM_LEDS) {
        previousMillis = currentMillis;
        leds[StartValue] = CRGB::Red;
        StartValue++;
        FastLED.show();
      }

      // Modus 2 = Rot
      else if (lichtmodus == 2)
      {
        unsigned long currentMillis = millis();
        if (currentMillis - previousMillis >= interval && StartValue <= NUM_LEDS) {
          previousMillis = currentMillis;
          leds[StartValue] = CRGB::Blue;
          StartValue++;
          FastLED.show();
        }

        // Modus 3 = Grün
        else if (lichtmodus == 3)
        {
          unsigned long currentMillis = millis();
          if (currentMillis - previousMillis >= interval && StartValue <= NUM_LEDS) {
            previousMillis = currentMillis;
            leds[StartValue] = CRGB::Green;
            StartValue++;
            FastLED.show();
          }

          // Modus 4 = Lila
          else if (lichtmodus == 4)
          {
            unsigned long currentMillis = millis();
            if (currentMillis - previousMillis >= interval && StartValue <= NUM_LEDS) {
              previousMillis = currentMillis;
              leds[StartValue] = CRGB::Yellow;
              StartValue++;
              FastLED.show();
            }

            // Modus 5 = Weiß
            else if (lichtmodus == 5)
            {
              unsigned long currentMillis = millis();
              if (currentMillis - previousMillis >= interval && StartValue <= NUM_LEDS) {
                previousMillis = currentMillis;
                leds[StartValue] = CRGB(random(0, 255), random(0, 255), random(0, 255));
                StartValue++;
                FastLED.show();
              }

              // Anzahl der Leutmodi auf 6 begrenzen. (0 bis 5)
              else
              {
                lichtmodus = 0;
              }
            }
          }
        }
      }
    }
  }
}

Was fehlt noch:
Welcher Mikrokontroller?
Wie ist der Schalter beschaltet, wie der Neopixel, Stromquellen? --> Schaltbild
Echtfoto von deinem Aufbau, nicht "so wie in diesem Link", sondern wirklich das was du gemacht hast.

Und vieleicht Serielle Ausgabe aktivieren und im Code ergänzen was der Code macht.

Auf alle Fälle solltest du deine Klammersetzungen kontrollieren.
so aus dem Bauch raus müssen deine
else if (lichtmodus == 1)
auf gleicher Höhe stehen nachdem man strg-t gedrückt hat...

das Foto kann ich liefern.

Die Klammern sind nach strg-t genauso gesetzt wie oben.

Was genau ist denn der Fehler ?
Es leuchtet nichts ist nicht sehr präzise.
Was passiert wenn du den Taster drückst ?
Auf deinem Bild ist schlecht etwas zu erkennen.
Wie hast du den Taster angeschlossen ?

Hi

Die ELSE IF müssen alle auf gleicher Ebene stehen.
Du hast momentan den Fehler, daß das ELSE IF nicht auf die erste IF greift, sondern auf die IF in der IF.
Und Das bei jeder weiteren IF - somit werden Diese frühestens ausgeführt, wenn Dein lichtmodus 0 ist UND 1 ist UND 2 ist ....
Die ELSE IF sind eine Zeile zu früh - davor muß noch eine schließende Klammer, daß der davor liegende IF-Block abgeschlossen ist (Der NICHTS mit den lichtmodus zu tun hat)

MfG

akku3d:
Die Klammern sind nach strg-t genauso gesetzt wie oben.

Strg-T ist kein Allheilmittel gegen mangelhaft formatierten Code. Entscheide Dich, ob Du öffnende Klammern direkt nach dem Befehl setzt oder in die nächste Zeile und mach' das einheitlich. Auch mit Leerzeilen kann man Code lesbar(er) gestalten. Meinem Geschmack nach sollte es vor setup() und loop() jeweils eine Leerzeile geben.

Und anstatt Pin-Nummern als int zu deklarieren, solltest Du byte nehmen. Das spart jedes mal 1 Byte. Wenigstens benutzt Du const.

Gruß

Gregor

PS: Wenn Du Arduino-Blut geleckt hast und Lust auf weitere mehr oder weniger simple Basteleien hast: Vielleicht findest Du bei meinen Textereien etwas.

Hi

Also:
Packe VOR jedes ELSE IF eine schließende Klammer.
Drücke erneut STRG+T
Lösche alle Klammern, Die nun am Ende des Sketch ganz links untereinander stehen - bis auf die Erste, Die musst Du behalten.

MfG

OT

gregorss:
Und anstatt Pin-Nummern als int zu deklarieren, solltest Du byte nehmen. Das spart jedes mal 1 Byte. Wenigstens benutzt Du const.

Mit solchen Begründungen wäre ich ungeprüft ganz vorsichtig. Du hast das aber in den letzten Wochen öfters geschrieben, daher mal contra:
Der Kompiler ist nämlich ziemlich geschickt, sodass sich das wenig auf den RAM auswirkt. Der optimiert das weg.
Natürlich soll der TO const setzen was const ist, die richtigen Variablentypen auch verwenden, aber im konkreten Fall kümmert sich der Kompiler darum dass sich der RAM bedarf nicht ändert.

Hier ein Demo, kompiliert in verschiedenen Varianten für den Uno.
Solange du nicht an der Optimierung drehst, nimmt sich das nichts.

/*
  Blink without Delay
  http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
*/

//#pragma GCC optimize "O0"           // Kompiler Optimierungen deaktiveren

//const int ledPin =  LED_BUILTIN;    // Programmspeicher 860/ RAM 15          1054/15
const byte ledPin =  LED_BUILTIN;     // Programmspeicher 860/ RAM 15          1054/15
//#define ledPin   LED_BUILTIN        // Programmspeicher 860/ RAM 15          1054/15
//int ledPin =  LED_BUILTIN;          // Programmspeicher 860/ RAM 15          1070/17
//byte ledPin =  LED_BUILTIN;         // Programmspeicher 860/ RAM 15          1062/17

int ledState = LOW;             // ledState used to set the LED
unsigned long previousMillis = 0;        // will store last time LED was updated
const long interval = 1000;           // interval at which to blink (milliseconds)

void setup() {
  pinMode(ledPin, OUTPUT);  // set the digital pin as output:
}

void loop() {
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }
    digitalWrite(ledPin, ledState);
  }
}

Bei dieser Art Taster sind manchmal die Beinchen sehr kurz, so dass sie gar nicht mit dem Steckbrett Kontakt haben. Auch musst du die richtigen beiden nehmen, falls er 4 Anschlüsse hat. Am besten mit dem Multimeter nachmessen.

noiasca:
Der Kompiler ist nämlich ziemlich geschickt, sodass sich das wenig auf den RAM auswirkt. Der optimiert das weg.
Natürlich soll der TO const setzen was const ist, die richtigen Variablentypen auch verwenden, aber im konkreten Fall kümmert sich der Kompiler darum dass sich der RAM bedarf nicht ändert.

Okay, vielleicht bügelt der Compiler so etwas weg. Unabhängig davon finde ich aber, dass man immer darauf achten sollte, welchen Typ für welche Art Daten man verwendet.

Wie dem auch sei, für Pin-Nummern kann man auch gut #define-Zeilen nehmen. Dann braucht so etwas überhaupt kein RAM.

Gruß

Gregor

Und auch mal auf Fragen und Bemerkungen reagieren.

Wie dem auch sei, für Pin-Nummern kann man auch gut #define-Zeilen nehmen. Dann braucht so etwas überhaupt kein RAM.

#define led 13
// Steinzeit

const byte led = 13;
// ist schon ok.

const byte led {13};
// ist besser

constexpr byte led {13};
// die konsequenteste Variante

Das gilt natürlich nur für 8 Bit µC

Bei 16/32/64 Bit µC ist wohl int das Mittel der Wahl

Nicht nur die "konsequenteste Variante" kann man problemlos so

constexpr int led {13};
verwenden.

Selbst auf 8 Bit µC wird das dann zur Kompilezeit passend konvertiert/optimiert.
Es sind keinerlei Laufzeitnachteile zu erwarten, solange die Pins das "readonly" Attribut tragen..

Hallo akku,

das mit der if-Anweisungen hat postmaster-ino ja schon festgestellt...
Ich bevorzuge übrigens auch, wie gregorss vorschlägt, die öffnende geschweifte Klammer in der nächsten Zeile. Da sieht man gleich wenn was falsch ist. Du kannst, für die Übersicht, auch die if-Anweisung als Kommentar hinter die schließende geschweifte Klammer machen. Aber jeder wie es ihm beliebt....

Mir fiel auch auf, dass die Variable "StartValue" zwar hochgezählt, aber nie zurückgesetzt wird.
So wurden alle LEDs auf Black gesetzt und weiter wäre nichts passiert.

Außerden wurde der Wert von StartValue auf <= NUM_LEDS abgefragt. Sollte nur auf < abgefragt werden. Bei 3 LEDs ist der Index des Arrays 0, 1 und 2, nicht aber 3.

FastLED.show() sollte nach dem Setzen aller LEDs aufgerufen werden. Deshalb eine for-Schleife (siehe unten).

Bei der Tasterabfrage wäre eine Flankenauswertung besser als delay(300).

Hier mal etwas Code (ungetestet) als Vorschlag:

unsigned long currentMillis = millis();

if(( currentMillis - previousMillis) >= interval )
{
   if (lichtmodus == 0)
   {
      for( int i = 0; i < NUM_LEDS; i++ )
         leds[i] = CRGB::Black;
   }
   
   // Modus 1 = Blau
   else if (lichtmodus == 1)
   {
      for( int i = 0; i < NUM_LEDS; i++ )
         leds[i] = CRGB::Blue;
   }
	.
	.
	.

   FastLED.show();
   previousMillis = currentMillis;
}

Leute, ich habe für mich festgestellt, dass ich zwar genau weiß, was der Arduino machen soll.
Aber ohne längere Einarbeitung werde ich das nicht hinbekommen.
Nur irgendwelche code Fetzen aus dem Internet zusammensuchen und hoffen, dass es damit klappt, ist nicht der Weg, den ich einschlagen will. Wenn ich mich damit weiter auseinandersetze, will ich auch verstehen, was ich da tue. Es reizt mich, hier neues zu lernen. Aber irgendwie fehlt mir auch die Zeit, es richtig zu machen.
Gäbe es auch irgendwo einen Service, der kleine Sketches als Dienstleistung gegen einen schmalen Taler erstellt?

Frage doch mal Studenten einer Uni in deiner Nähe.

Hi

@akku3d

Leute, ich habe für mich festgestellt, dass ich zwar genau weiß, was der Arduino machen soll.
Aber ohne längere Einarbeitung werde ich das nicht hinbekommen.

Also ist das Umsetzen einer Hand voll Klammern - sogar nach Anleitung - gleichzusetzen mit höherer Mathematik?

Ok, muß ich so hinnehmen.

MfG

Edit @gregross
Quote hinzugefügt

akku3d:
Nur irgendwelche code Fetzen aus dem Internet zusammensuchen und hoffen, dass es damit klappt, ist nicht der Weg, den ich einschlagen will. Wenn ich mich damit weiter auseinandersetze, will ich auch verstehen, was ich da tue. Es reizt mich, hier neues zu lernen. Aber irgendwie fehlt mir auch die Zeit, es richtig zu machen.
Gäbe es auch irgendwo einen Service, der kleine Sketches als Dienstleistung gegen einen schmalen Taler erstellt?

Gute Einstellung!

Ja, es braucht einige Zeit, bis man „Arduino kann“. Aber es lohnt sich sehr! Wenn Du für den Einstieg ein paar kleine Häppchen brauchst, ist vielleicht bei meinem Zeug etwas dabei.

Was kleine Sketches angeht: Frag' einfach hier. Das kostet zumindest erst mal nichts. Und kleine Sketches werden hier hin und wieder auch mal gestrickt. Dann kostet's immer noch nichts :slight_smile: Ansonsten: Wenn Du Schüler oder Studenten kennst, dann sag' denen, dass sie sich umhören sollen. Wenn deutlich wird, dass Dich die Thematik tatsächlich interessiert, wird Dir bestimmt meistens freundlich geholfen.

Gruß

Gregor

postmaster-ino:
Also ist das Umsetzen einer Hand voll Klammern - sogar nach Anleitung - gleichzusetzen mit höherer Mathematik?

Wo liest Du das heraus? Ich habe gerade mal schnell quergelesen und nichts gefunden.

Gruß

Gregor

akku3d:
Gäbe es auch irgendwo einen Service, der kleine Sketches als Dienstleistung gegen einen schmalen Taler erstellt?

Dafür gibt es hier im Forum (englischsprachiger Teil) zum Beispiel die "Sektion" Gigs and Collaborations

Es sind nur ein paar Kleinigkeiten zu ändern, dann läuft es:

#include <FastLED.h>
const int tasterPin = 11;     // Taster an Pin 11 angeschlossen
const int LED_PIN = 7;       // LED signal an Pin 7
const int NUM_LEDS = 8;      // Anzahl LED
CRGB leds[NUM_LEDS];
unsigned long previousMillis = 0;
const long interval = 500;
byte ledPos = 0;
byte lichtmodus = 1;          // Variable für die verschiedenen festgelegten Farben
bool tasterStatus = LOW;      // Variable zu speichern des Tasterstatus

void setup()
{
  pinMode(tasterPin, INPUT_PULLUP);      // aktiv LOW wegen PullUp-Widerstand
  FastLED.addLeds<WS2812, LED_PIN, RGB>(leds, NUM_LEDS);  // "RGB" ggf. an Deine LEDs anpassen
  FastLED.show();                        // Löscht die LEDs
}
void loop()
{
  // Abfrage ob der Taster gedrückt ist
  tasterStatus = digitalRead(tasterPin);

  // Wenn Taster gedrückt ist...
  if (tasterStatus == LOW)
  {
    lichtmodus++;     // Lichtmodus +1
    ledPos = 0;       // zurück auf die erste LED-Position
    delay(300);       // 300ms warten
  }

  //+++++++++++++++ LEUCHTPROGRAMME +++++++++++++++++

  // Modus 0 = Licht aus
  if (lichtmodus == 0)
  {
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= interval && ledPos <= NUM_LEDS) {
      previousMillis = currentMillis;
      leds[ledPos] = CRGB::Black;
      ledPos++;
      FastLED.show();
    }
  }
  // Modus 1 = Blau
  else if (lichtmodus == 1)
  {
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= interval && ledPos <= NUM_LEDS) {
      previousMillis = currentMillis;
      leds[ledPos] = CRGB::Blue;
      ledPos++;
      FastLED.show();
    }
  }
  // Modus 2 = Rot
  else if (lichtmodus == 2)
  {
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= interval && ledPos <= NUM_LEDS) {
      previousMillis = currentMillis;
      leds[ledPos] = CRGB::Red;
      ledPos++;
      FastLED.show();
    }
  }
  // Modus 3 = Grün
  else if (lichtmodus == 3)
  {
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= interval && ledPos <= NUM_LEDS) {
      previousMillis = currentMillis;
      leds[ledPos] = CRGB::Green;
      ledPos++;
      FastLED.show();
    }
  }
  // Modus 4 = Lila
  else if (lichtmodus == 4)
  {
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= interval && ledPos <= NUM_LEDS) {
      previousMillis = currentMillis;
      leds[ledPos] = CRGB::BlueViolet;
      ledPos++;
      FastLED.show();
    }
  }
  // Modus 5 = Zufall
  else if (lichtmodus == 5)
  {
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= interval && ledPos <= NUM_LEDS) {
      previousMillis = currentMillis;
      leds[ledPos] = CRGB(random(0, 255), random(0, 255), random(0, 255));
      ledPos++;
      FastLED.show();
    }
  }
  // Anzahl der Leutmodi auf 6 begrenzen. (0 bis 5)
  else
  {
    lichtmodus = 0;
  }
}

Helfe, wenn Dir geholfen wurde ;D