Go Down

Topic: Wieviel LEDs sind für ein Lauflicht möglich ? (Read 2531 times) previous topic - next topic

Doc_Arduino

Hallo,

aktuell verstehe ich nicht wo es gedanklich klemmt.
In #71 hast du meine Blockierung bestätigt.
In #72 findest du plötzlich die Blockierung nicht mehr
In #74 redest du plötzlich von #55 in der es gar kein case 2 gibt
Verstehe ich nur noch Bahnhof?

Das Fading kannste einbauen wenn du millis angewendet hast. Ansonsten erzeugst du noch mehr Kaos und baust dann später noch mehr um und siehst den Wald nicht mehr.

Notbremse. Vergiss erstmal den Sketch. Lege ihn beiseite. Befasse dich umgehend mit millis.
#54 war der Wink. Irgendwo war noch ein Link zum Nachtwächter verlinkt.
Lasse blockierfrei in langen Perioden eine LED blinken und gleichzeitig reagiert eine 2. LED auf Tasterdruck.
Erst wenn du das Schema verinnerlicht hast kannste am Sketch weitermachen.
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

Aceli

Moin

die Blockierung habe ich bestätigt im sinne von : jaa das hackt beim tasten drücken bis es von vorne los geht.

in #72 war ich auf der suche danach und konnte aber nicht finden woran es nun mal liegt ....

und #55 wurde mir ja der Millisekunden Sketch gezeigt und da hatte ich einfach versucht case 2 einzufügen... aber evtl falsch gemacht... dachte es wäre eine einfache Erweiterung

Doc_Arduino

#77
Apr 19, 2019, 06:13 pm Last Edit: Apr 19, 2019, 06:15 pm by Doc_Arduino
Hallo,

siehst du die Blockierung wirklich nicht?
delay(x) blockiert - das weißt du doch hoffentlich.
dieses delay kommt in deiner for Schleife 2x vor. Also sind wir schon bei 2x delay, was 2x30ms ist.
Die for Schleife wird 15x ausgeführt. Also sind wir bei 15 x 2 x 30ms = 900ms.

Letztes Bsp. blockierfreies switch case. Die Pausenzustände werden solange immer wieder angesprungen bis die Zeit abgelaufen ist. Während dessen landet der Programmablauf immer wieder in der loop und kann dort andere Dinge tun. Wie zum Bsp. den heartbeat abarbeiten.

Code: [Select]
const byte pin_Taster2 = 2;
const byte pin_LED12 = 12;
const byte pin_LED13 = 13;
const unsigned int BLINKPAUSE = 1000;
unsigned long zeitmerker;
          
enum state {EIN, PAUSE_EIN, AUS, PAUSE_AUS, NICHTS};
state zustand = NICHTS;

void setup() {
  pinMode(pin_Taster2, INPUT_PULLUP);
  pinMode(pin_LED12, OUTPUT);
  pinMode(pin_LED13, OUTPUT);
}

void loop() {
  
  steuerung();

  heartbeat(pin_LED12, 500);

}


void steuerung ()
{
  switch (zustand) {
    case NICHTS:
                if (update_Taster2() ) {
                  zustand = EIN;
                }
                break;

    case EIN:
                digitalWrite(pin_LED13, HIGH);
                zeitmerker = millis();
                zustand = PAUSE_EIN;
                break;

    case PAUSE_EIN:
                if ( millis() - zeitmerker > BLINKPAUSE) {
                  zustand = AUS;
                }
                break;

    case AUS:
                digitalWrite(pin_LED13, LOW);
                zeitmerker = millis();
                zustand = PAUSE_AUS;
                break;

    case PAUSE_AUS:
                if ( millis() - zeitmerker > BLINKPAUSE) {
                  zustand = NICHTS;
                }
                break;
                            
    default: zustand = AUS;
             break;
  }

}


bool update_Taster2()
{
  static unsigned long last_ms = 0;
  static bool state = false;

  if (millis() - last_ms > 40) {
    last_ms = millis();
    state = !(digitalRead(pin_Taster2));
  }
  return state;
}


void heartbeat (const byte led, unsigned int interval)           // Kontrolle ob Sketch blockiert
{
  static unsigned long last_ms = 0;
  static bool state = LOW;
  
  unsigned long ms = millis();
  
  if (ms - last_ms >= interval) {
    last_ms = ms;
    state = !state;
    digitalWrite(led, state);
  }
}


Dann musst du dir noch eine Funktion schreiben die von 0 bis 15 zählt und dabei immer den zustand erneut EIN schaltet. Die Zählfunktion muss natürlich blockierfrei sein. Es verbietet sich for. Sonst blockiert heartbeat. Wenn du das hast, kannste das Wissen auf deinen Sketch anwenden.

Das mit millis können nur Bsp. sein. Du musst den Ablauf verstehen. Was machst du mit deiner Armbanduhr. Dann kannst du das in allen Varianten anwenden.
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

Aceli

#78
Apr 19, 2019, 07:00 pm Last Edit: Apr 19, 2019, 07:01 pm by Aceli
Gut.

also muss ich wohl erstmal alles beiseite legen... und lesen und verstehen....

Doch nicht so einfach wie ich dachte.

Wenn ich Drehschalter nehme... muss das ganze ja auch anders aufgebaut werden, richtig?!

Doc_Arduino

Hallo,

ob Taster oder Drehschalter ist völlig egal. Auch beim Drehschalter möchtest du das dein Programm unverzögert reagiert. Auch der Drehschalter muss ständig eingelesen werden können. Genau wie der/die Taster. Wenn du unmittelbare Reaktionen auf Ereignisse erwartest musst du dafür sorgen das der Programmablauf nicht blockiert wird.

Guck dir heartbeat an. Was macht das Teil während den 500ms?
Die Frage beantwortest du dir selbst.
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

agmue

also muss ich wohl erstmal alles beiseite legen... und lesen und verstehen....
Ja, das würde Dich weiterbringen.

Wenn ich Drehschalter nehme... muss das ganze ja auch anders aufgebaut werden, richtig?!
Ich erlaube mir eine andere Sichtweise als Doc_Arduino. Ein Drehschalter rastet an der eingestellten Stelle und kann solange auf den µC warten, bis der vor lauter delays mal vorbeischaut, um die Pins zu lesen. Wenn es Dich nicht stört, daß eine Reaktion auf eine neue Stellung des Drehschalters eine Weile dauern kann, dann kannst Du diese Variante anstreben.

Wenn also die Gefahr besteht, Du kloppst den Arduino in die Tonne, weil Dir der Spaß vergeht, dann nimm lieber den Drehschalter und delays. Nach den Partys mit LED-Beleuchtung kannst Du mit einem zweiten Arduino millis versuchen.

 :smiley-twist:  :smiley-twist:  :smiley-twist:

In der Sonne des Tages liegend  8)  kam mir folgende Idee: Da es mir selbst erst über Umwege gelang, den Sinn von millis() zu verstehen, mache ich Dir mal den Vorschlag, ein eigenes delay zu kreieren. Bei mir heißt die Funktion verzoegerung() und enthält alle zeitkritischen Dinge wie die Tastenabfrage. Selbstverständlich wird die Verzögerung mittels millis() realisiert. Überall in Deinem Programm, wo delay(x) steht, ersetzt Du das durch verzoegerung(x). Das sieht dann so aus:

Code: [Select]

#include <Adafruit_NeoPixel.h>
#define N_LEDS 15
#define PIN     6

Adafruit_NeoPixel strip = Adafruit_NeoPixel(N_LEDS, PIN, NEO_GRB + NEO_KHZ800);

const byte tasterPin = 7;
int lichtmodus = 0;
bool aktTasterStatus, altTasterStatus;
const byte potPin = A0;
uint32_t intervall;
int pos = 0, dir = 1; // Position, direction of "eye"

#define INTER_FLASH_DELAY 30
#define INTER_FLASH_COUNT 10

void setup() {
  strip.begin();
  pinMode (tasterPin, INPUT_PULLUP);
  Serial.begin(9600);
  Serial.println(F("Anfang"));
  intervall = analogRead(potPin);
  Serial.print(F("Intervall: "));  //gibt Text/Variablen auf der Seriellen aus
  Serial.println(intervall);
}

void setFarbe (const byte n, byte r, byte g, byte b)
{
  for (byte i = 0; i < n; i++)
  {
    strip.setPixelColor(i, strip.Color(r, g, b));
  }
}

void verzoegerung(uint32_t zeit)
{
  uint32_t entprellMillis = 0, vorhin = millis();
  while (1)
  {
    uint32_t jetzt = millis();
    altTasterStatus = aktTasterStatus;
    aktTasterStatus = digitalRead(tasterPin);

    if ((aktTasterStatus != altTasterStatus) && (jetzt - entprellMillis >= 30))
    {
      entprellMillis = jetzt;
      if (!aktTasterStatus)
      {
        lichtmodus++;
        Serial.print(F("Neuer Lichtmodus: "));
        Serial.println(lichtmodus);
        break;
      }
    }

    if (jetzt - vorhin >= zeit)
    {
      break;
    }
  }
}

void loop()
{
  verzoegerung(0);  // damit die Tasten immer abgefragt werden
  switch (lichtmodus)
  {
    case 0:
      intervall = analogRead(potPin);
      Serial.print(F("Intervall: "));  //gibt Text/Variablen auf der Seriellen aus
      Serial.println(intervall);

      // Rather than being sneaky and erasing just the tail pixel,
      // it's easier to erase it all and draw a new one next time.
      for (uint16_t j = 0; j < N_LEDS; j++) strip.setPixelColor(j, 0);

      // Draw 5 pixels centered on pos.  setPixelColor() will clip any
      // pixels off the ends of the strip, we don't need to watch for that.
      strip.setPixelColor(pos - 1, 0x696969);
      strip.setPixelColor(pos    , 0xFFFFFF); // Center pixel is brightest
      strip.setPixelColor(pos + 1, 0x696969);
      strip.show();
      verzoegerung(intervall);

      // Bounce off ends of strip
      pos += dir;
      if (pos < 0) {
        pos = 1;
        dir = -dir;
      } else if (pos >= N_LEDS) {
        pos = N_LEDS - 2;
        dir = -dir;
      }
      break;
    case 1:
      for (uint16_t n = 0; n < N_LEDS; n++)
      {
        strip.setPixelColor(n, 138, 43, 226);
      }
      strip.show();
      break;
    case 2:
      for (byte n = 0; n < N_LEDS; n++)
      {
        setFarbe(N_LEDS, 0, 0, 255);     // alle blau
        strip.show();
        verzoegerung(INTER_FLASH_DELAY);
        setFarbe(N_LEDS, 0, 0, 0);       // alle aus
        strip.show();
        verzoegerung(INTER_FLASH_DELAY);
      }
      break;
    default:
      lichtmodus = 0;
      Serial.print(F("Neuer Lichtmodus: "));
      Serial.println(lichtmodus);
  }
}

Getestet mit UNO und 9 LEDs.
Wahnsinn und Verstand trennt nur eine dünne Wand. (Daniel Düsentrieb)

Aceli

Chapeau!

Recht herzlichen Dank. Es funktioniert tadellos. Habe heute mal die zweite LED leiste mit angeschlossen. auch das , ohne Probleme.

Ihr habt alle irgendwo recht. Einerseits sollte ich mich damit wirklich auseinander setzen und endlich mal verstehen, weil es ja auch nicht meine erste kleine Spielerei ist.

Aber warum auch immer , geht es noch nicht in mein Kopf.

Andererseits, weiß ich, wenn ich das nicht verstehe, wird das Projekt entweder so eingebaut mit Macken oder beiseite gelegt weil ich wirklich kein Bock mehr habe..... und das wäre für das Projekt , für mich und diesen Beitrag (weil er nicht vollendet wird) auch schade...

Ich danke dir wirklich.

Ich werde das anhand deines Sketches noch einige male durchlesen und versuchen zu verstehen und noch zu erweitern, hoffentlich richtig und sinnvoll.  Es soll ja auch nur noch Fade in Out folgen.

Ich wünsche euch ein schönes sonniges Wochenende...

agmue

Es soll ja auch nur noch Fade in Out folgen.
Das kann man sich doch bei LEDStrip Effect - Fade In and Fade Out Your own Color(s) abschauen. Bei jedem Tastendruck läuft der Effekt aber erst bis zum Ende - der Nachteil dieser Art der Programmierung - aber mittels des Merkers ohneVerzoegerung kann man es beschleunigen.

Code: [Select]
#include <Adafruit_NeoPixel.h>
#define N_LEDS 15
#define PIN     6

Adafruit_NeoPixel strip = Adafruit_NeoPixel(N_LEDS, PIN, NEO_GRB + NEO_KHZ800);

const byte tasterPin = 7;
int lichtmodus = 0;
bool aktTasterStatus, altTasterStatus, ohneVerzoegerung;
const byte potPin = A0;
uint32_t intervall;
int pos = 0, dir = 1; // Position, direction of "eye"

#define INTER_FLASH_DELAY 30
#define INTER_FLASH_COUNT 10
#define INTER_FADE_DELAY 10

void setup() {
  strip.begin();
  pinMode (tasterPin, INPUT_PULLUP);
  Serial.begin(9600);
  Serial.println(F("Anfang"));
  intervall = analogRead(potPin);
  Serial.print(F("Intervall: "));  //gibt Text/Variablen auf der Seriellen aus
  Serial.println(intervall);
}

void setFarbe (const byte n, byte r, byte g, byte b)
{
  for (byte i = 0; i < n; i++)
  {
    strip.setPixelColor(i, strip.Color(r, g, b));
  }
}

void verzoegerung(uint32_t zeit)
{
  if (ohneVerzoegerung) return;
  uint32_t entprellMillis = 0, vorhin = millis();
  while (1)
  {
    uint32_t jetzt = millis();
    altTasterStatus = aktTasterStatus;
    aktTasterStatus = digitalRead(tasterPin);

    if ((aktTasterStatus != altTasterStatus) && (jetzt - entprellMillis >= 30))
    {
      entprellMillis = jetzt;
      if (!aktTasterStatus)
      {
        lichtmodus++;
        ohneVerzoegerung = true;  // bei einem Wechsel des Lichtmodus möglichst schnell weiter
        Serial.print(F("Neuer Lichtmodus: "));
        Serial.println(lichtmodus);
        break;
      }
    }

    if (jetzt - vorhin >= zeit)
    {
      break;
    }
  }
}

void loop()
{
  ohneVerzoegerung = false;
  verzoegerung(0);  // damit die Tasten immer abgefragt werden
  switch (lichtmodus)
  {
    case 0:
      intervall = analogRead(potPin);
      Serial.print(F("Intervall: "));  //gibt Text/Variablen auf der Seriellen aus
      Serial.println(intervall);

      // Rather than being sneaky and erasing just the tail pixel,
      // it's easier to erase it all and draw a new one next time.
      for (uint16_t j = 0; j < N_LEDS; j++) strip.setPixelColor(j, 0);

      // Draw 5 pixels centered on pos.  setPixelColor() will clip any
      // pixels off the ends of the strip, we don't need to watch for that.
      strip.setPixelColor(pos - 1, 0x696969);
      strip.setPixelColor(pos    , 0xFFFFFF); // Center pixel is brightest
      strip.setPixelColor(pos + 1, 0x696969);
      if (!ohneVerzoegerung) strip.show();
      verzoegerung(intervall);

      // Bounce off ends of strip
      pos += dir;
      if (pos < 0) {
        pos = 1;
        dir = -dir;
      } else if (pos >= N_LEDS) {
        pos = N_LEDS - 2;
        dir = -dir;
      }
      break;
    case 1:
      for (uint16_t n = 0; n < N_LEDS; n++)
      {
        strip.setPixelColor(n, 138, 43, 226);
      }
      if (!ohneVerzoegerung) strip.show();
      break;
    case 2:
      for (byte n = 0; n < N_LEDS; n++)
      {
        setFarbe(N_LEDS, 0, 0, 255);     // alle blau
        if (!ohneVerzoegerung) strip.show();
        verzoegerung(INTER_FLASH_DELAY);
        setFarbe(N_LEDS, 0, 0, 0);       // alle aus
        if (!ohneVerzoegerung) strip.show();
        verzoegerung(INTER_FLASH_DELAY);
      }
      break;
    case 3:
      for (uint16_t n = 0; n < N_LEDS; n++) FadeInOut(n, 0xff, 0xff, 0xff);
      for (uint16_t n = 0; n < N_LEDS; n++) FadeInOut(n, 0xff, 0x00, 0x00);
      for (uint16_t n = 0; n < N_LEDS; n++) FadeInOut(n, 0x00, 0xff, 0x00);
      for (uint16_t n = 0; n < N_LEDS; n++) FadeInOut(n, 0x00, 0x00, 0xff);
      break;
    default:
      lichtmodus = 0;
      Serial.print(F("Neuer Lichtmodus: "));
      Serial.println(lichtmodus);
  }
}

void FadeInOut(uint16_t led, byte red, byte green, byte blue) {
  float r, g, b;

  for (int k = 0; k < 256; k = k + 1) {
    r = (k / 256.0) * red;
    g = (k / 256.0) * green;
    b = (k / 256.0) * blue;
    strip.setPixelColor(led, r, g, b);
    if (!ohneVerzoegerung) strip.show();
    verzoegerung(INTER_FADE_DELAY);
  }

  for (int k = 255; k >= 0; k = k - 2) {
    r = (k / 256.0) * red;
    g = (k / 256.0) * green;
    b = (k / 256.0) * blue;
    strip.setPixelColor(led, r, g, b);
    if (!ohneVerzoegerung) strip.show();
    verzoegerung(INTER_FADE_DELAY);
  }
}

Getestet mit UNO und 9 LEDs.

Die Fade-Geschwindigkeit könnte man natürlich noch variabel gestalten.
Wahnsinn und Verstand trennt nur eine dünne Wand. (Daniel Düsentrieb)

Aceli

#83
Apr 20, 2019, 05:35 pm Last Edit: Apr 20, 2019, 05:39 pm by Aceli
Jez hast du mir das vorweg genommen :) aber danke.

Möchtest du dass das hier ein ende hat !? ;)

Ich werd das nachher mal testen. aber sollte wohl klappen....


jetzt kommen allerdings wieder neue gedanken auf.... ich hab ja noch einige IR fernbedienungen hier :)

anstatt des Tasters evtl eine Fernbedienung!?  Nachteil, der empfänger kann ja nicht irgendwo versteckt verbaut werden .....mh

aber das werde ich mir nächstes mal anschauen...  mit tastern auslesen und einbinden.

postmaster-ino

Hi

IR-Fernbedienung und WS2812B sind ein etwas mühseliges Thema.
In der Zeit, Die die WS2812B angesteuert werden, sind Interrupts abgeschaltet - in der Zeit wird auch keine IR-Fernbedienung erkannt oder gar mitgelesen (die serielle Schnittstelle würde ja den Puffer auch im Hintergrund füllen) - klappt hier aber nicht, da das Timing äußerst schwierig ist.

Du wirst also die IR-Fernbedienung nur selten 'verstehen' - und wenn man 10x drücken muß, bevor 'das Gelump' reagiert ... Freude sieht anders aus.

Heißt aber nicht, daß Das unmöglich wäre, aber wesentlich einfacher ist's mit LEDs, Die eine eigene Takt und Data-Leitung haben (aka APA102) - dort kann der Interrupt für die serielle Schnittstelle an bleiben, weshalb hier die Signale immer verstanden werden.

MfG
anscheinend ist Es nicht erwünscht, einen Foren-internen Link als 'Homepage' einzubinden, damit JEDER nur einen Klick von combie's Liste zum Thema State-Maschine entfernt ist.
... dann eben nicht ...

Aceli

Moin,

ok vielen Dank , also dann der zweite Grund, warum das keine gute idee ist....

Dann werd ich mal weiter überlegen, was außer dem Taster, noch eine Möglichkeit wäre. oder dem besagten Drehschalter.

agmue

Möchtest du dass das hier ein ende hat !? ;)
Ich möchte, daß Du selbst neue Animationen einbauen kannst.

Dann werd ich mal weiter überlegen, was außer dem Taster, noch eine Möglichkeit wäre. oder dem besagten Drehschalter.
Ein Drehschalter zeigt mechanisch die eingestellte Aniumation an, ein Taster benötigt dazu eine Anzeige. Möglich wäre eine 8x8 Led Matrix mit MAX7219.
Wahnsinn und Verstand trennt nur eine dünne Wand. (Daniel Düsentrieb)

Aceli

Tja . Ob ich eine grafische Anzeige benötige ..... denke n normaler Drehschalter würde da doch reichen

Aceli

tja so schön das ganze war und ich jetzt schön weiter testen wollte,.... aber nein... habe eben dummerweise wegen einem anderen Projekt meine Nano gegrillt..... hat mal kurz gequalmt und das wars.. nun heisst es warten und gleich mal n neuen bestellen.

Aceli

Kommando zurück, ich hab noch einen zweiten Nano in meiner Wühltasche gefunden, was n gluck.

beim Fade lädt er aber nach und nach eine LED aufhellen und abdunkeln. nicht alle zusammen.

in dem Video funktionieren ja alle parallel. muss ich mal durchschauen ob ich das finde.... aber danke

Go Up