HILFE: Arduino wird immer langsamer je mehr LED´s im Neopixel Strip

Servus Leute,

Ich bin nicht der beste Programmierer, aber soweit habe ich das was ich wollte schon hinbekommen.

Zur Erklärung:

Ich habe einen 4m langen Neopixel Stripe, am Anfang und am Ende einen Bewegungsmelder.
Wenn man "rein"geht geht der strip von rechts aus an
Wenn man “raus” geht geht der strip von links aus an.
Ebenso die aus Sequenz.
Und nen schalter der dann ein lichtspiel demo auslöst. ( im Moment entfernt)

Habe noch 2 Potis mit eingebaut die die Helligkeit und Licht an Zeit regulieren.

Auf dem Breadboard funktionierte alles super, da waren 60 Neopixel angeschlossen.

In der Ganzen Variante sind es dann 240

Und hier das Problem: Sobald ich die Led Zahl höher stelle wird das ganze Werk sau langsam.

Ich denke mal das der Code den ich da zusammen gepfriemelt habe einige schwerwiegende Fehler hat.

Kann mir da wer helfen ???

Hier mein Code:

////////////////////////////////////////////////////////////////////////////////////
//   LED Rohrlampe mit 2x Bewegungsmelder
//
//   Ver. 2.0
//   9/2019
//   by OBI
//
//   Bew. reingehen =PIN 5
//   Bew. rausgehen =PIN 4
//   Demo Buttton   =PIN 7 (High für Demo)
//   Neopixel       =PIN 3
//   Poti Helligkeit=PIN 0
//   Poti Zeit      =PIN 5
////////////////////////////////////////////////////////////////////////////////////

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif

// Wichtige sachen zum ändern ////////////////////////////////////////////////
//#define DELAYVAL2     3000    // Licht an Zeit    "über Poti jetzt"
#define NUM_LEDS      240        // Neopixel LED´s
//#define BRIGHTNESS    10      // Helligkeit Pixel "über poti jetzt"
/////////////////////////////////////////////////////////////////////////////
#define DELAYVAL  10 // Time (in milliseconds) to pause between pixels
#define DATA_PIN  3 // LED PIN
//#define LED_TYPE    WS2811
//#define COLOR_ORDER GRB
#if defined(FASTLED_VERSION) && (FASTLED_VERSION < 3001000)
#warning "Requires FastLED 3.1 or later; check github for latest code."
#endif

Adafruit_NeoPixel pixels(NUM_LEDS, DATA_PIN, NEO_GRB + NEO_KHZ800);
//CRGB leds[NUM_LEDS];
boolean __ardublockDigitalRead(int pinNumber)

{
 pinMode(pinNumber, INPUT);
 return digitalRead(pinNumber);
}


void __ardublockDigitalWrite(int pinNumber, boolean status)
{
 pinMode(pinNumber, OUTPUT);
 digitalWrite(pinNumber, status);
}

void lichtspiel();
void rein();
void reinaus();
void raus();
void rausaus();


void setup()
{
 //  Serial.begin(9600);
pixels.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
pixels.show();  // Initialize all pixels to 'off'


}





 
void loop()

{

 while ( __ardublockDigitalRead(7) )
 {
   lichtspiel();
 }
 if (__ardublockDigitalRead(5))
 {
   rein();
 }
 else
 {
   reinaus();
 }
 if (__ardublockDigitalRead(4))
 {
   raus();
 }
 else
 {
   rausaus();
 }
}

void rein()
{
 int val = analogRead(0);
 val = map(val, 0, 1050, 0, 255); // Helligkeit Neopixel
 int val2 = analogRead(5);
 val2 = map(val2, 0, 1050, 5000, 30000); //AN Zeit Neopixel
 
   for(int i=NUM_LEDS; i>-1; i--) { // For each pixel...
   pixels.setPixelColor(i, pixels.Color( val,val,val )); 
   pixels.show();   // Send the updated pixel colors to the hardware.   
   delay(DELAYVAL); // Pause before next pass through loop
}
delay(val2);
}
void reinaus()
{

   for(int i=0; i<NUM_LEDS; i++) { // For each pixel...
   pixels.setPixelColor(i, pixels.Color(0, 0, 0));
   pixels.show();   // Send the updated pixel colors to the hardware.
   delay(DELAYVAL); // Pause before next pass through loop
}
}
void lichtspiel()
{
}
void raus()
{
 int val = analogRead(0);
 val = map(val, 0, 1050, 0, 255); // Helligkeit Neopixel
 int val2 = analogRead(5);
 val2 = map(val2, 0, 1050, 5000, 30000); //AN Zeit Neopixel
 
   for(int i=0; i<NUM_LEDS; i++) { // For each pixel...
   pixels.setPixelColor(i, pixels.Color(val,val,val));
   pixels.show();   // Send the updated pixel colors to the hardware.
   delay(DELAYVAL); // Pause before next pass through loop
}
delay(val2);
}
void rausaus()
{
 for(int i=NUM_LEDS; i>0; i--) { // For each pixel...

   pixels.setPixelColor(i, pixels.Color(0, 0, 0));
   pixels.show();   // Send the updated pixel colors to the hardware.
   delay(DELAYVAL); // Pause before next pass through loop
}
}

Setze deinen Sketch in Code-Tags, dann kann dieser von allen besser gelesen werden, auch die mobilen User unter uns.
Das kannst du auch nachträglich machen. Verwende dazu die Schaltfläche </> oben links im Editorfenster.

du shiftest jeden Pixel einzeln raus, machst dann noch ein separates show und ein ein delay.
Da wundert es mich gar nicht, dass umso mehr Pixel da sind, desto länger es auch dauert.

Ah, danke, die schaltfläche habe ich nicht gefunden.

Ja ich habe nicht wirklich die Ahnung vom Programmieren, viel strg-c -v :slight_smile:

Ich dacht mir schon sowas das das zu kompliziert geschrieben ist, dafür das das nur 3 verschieden modis macht.

Ich habe das grundgerüst mit ardublock begonnen, und dann nach und nach funktionen eingefügt bis es das gemacht hat was ich wollte.

Ich dachte nachdem ich das hier geschafft habe : Arduino controlled "Ghost" phone - YouTube
bekomme ich das licht ding auch hin.

Hi

Das .show() sendet die Daten an ALLE Pixel - also erst NACH der FOR-Schleife, wenn Du alle Pixel neu gesetzt hast, solltest Du die neuen Daten an den Stripe senden - nicht schon zwischendrin.

Wobei - da Du die einzelnen Funktionen blockierend benutzt, also z.B. beim AUS-schalten die LEDs einzeln auf Null setzt, show(), delay, was wundert Dich, daß 260x warten länger dauert, als 60x warten?

MfG

Ja irgendwie logisch wie du das erklärst,

das ist das resultat aus strg-c strg-v :slight_smile:

Ich habe wie schon gesagt aus vielen beispielen was zusammen geschnitzt.
Ich denke irgendwie anders als es der arduino braucht :slight_smile:

wenn ich also strip.show nur 1x am schluss einbaue bringt das was?

Hi

Das .show() sendet die Daten an den Stripe - vorher wird der ganze Kram nur intern im Arduino in einem Array gespeichert.
Auch das .clear() leert nur das Array und hat keinerlei Auswirkungen auf die LEDs selber.

Das .show() kostet Zeit - deshalb nur, wenn die Daten für den Stripe 'fertig' sind.
Bei langsam nacheinander aus gehen ... jo, Da eben nach jeder LED ein .show() - sonst siehst Du Das ja nicht (allerdings ist der Stripe ja auch 'fertig', wenn diese eine LED abgeschaltet wurde - somit passt das .shoe() wieder)

MfG

obi81:
wenn ich also strip.show nur 1x am schluss einbaue bringt das was?

Wenn Du ein Lauflicht machen möchtest, eher nicht. Aber Du könntest DELAYVAL verkleinern.

:o :o

hui, ich merk schon, mir fehlt da noch einiges an wissen :slight_smile:

irgendwie hab ich aber schon den verdacht, das das mit dem Lauflicht und meinen mehreren Aktionen sich beißt.
weil nur durch einen befehl den stripe so anlaufen lassen klappt ja,

Wie muss das dann ca. aussehen, wenn ich durch mehrere Auslöser ( wie z.b. meine Bew. melder) das lauflicht anlaufen lassen will für eine bestimmte zeit?

Das sich sich die bewegungserkennung gegenseitig blockiert würde mich garnicht stören,

obi81:
hui, ich merk schon, mir fehlt da noch einiges an wissen :slight_smile:

Das kannst Du Dir aneignen, bedarf nur der Geduld und Ausdauer.

obi81:
Ich habe einen 4m langen Neopixel Stripe, am Anfang und am Ende einen Bewegungsmelder.
Wenn man "rein"geht geht der strip von rechts aus an

Tippe ich da richtig auf Treppenbeleuchtung? Auf der Treppe möchte niemand im Dunkeln stehen oder laufen, das ist sicherheitsrelevant.

obi81:
Das sich sich die bewegungserkennung gegenseitig blockiert würde mich garnicht stören,

Der Erste, der sich ein Bein bricht, wird das anders sehen. Und wenn Du dann den teuren Gips aus dem Krankenhaus bezahlen mußt, vermutlich auch. Ich möchte Dich daher auf Deine Verantwortung hinweisen!

obi81:
irgendwie hab ich aber schon den verdacht, das das mit dem Lauflicht und meinen mehreren Aktionen sich beißt.

Schleifen mit for und delay sind blockierend, was in diesem Zusammenhang möglichst vermieden werden sollte. Leider ist auch pixels.show() blockierend, was sich bei NeoPixeln aber nicht vermeiden läßt, washalb ich lieber APA102 verwende. Außerdem sind APA102 ca. um den Faktor 10 schneller. Wenn Du also die NeoPixel so wie ich für die Bar - ich hätte eine fertige Animation - verwenden könntest, würde ich Dir einen Umstieg auf APA102 nahelegen.

Zeiten solltest Du also unbedingt mit millis messen.

Es ist problemlos möglich, zwei Lauflichter - ich denke an eine Treppe - von oben und von unten auslösen zu lassen. Man kann mehrere Schichten an Animationen übereinander legen.

Mit t kannst Du Dein Programm gut leserlich formatieren lassen, habe ich mal so gemacht.

Ein paar Details zu Deinem Programm:

//   Bew. reingehen =PIN 5
//   Bew. rausgehen =PIN 4
...
__ardublockDigitalRead(5)
...
__ardublockDigitalRead(4)

Da kann man schöne Konstanten draus machen:

 const byte Bew_reingehen = 5;  // Bewegungsmelder reingehen
  const byte Bew_rausgehen = 4;  // Bewegungsmelder rausgehen
...
__ardublockDigitalRead(Bew_reingehen)
...
__ardublockDigitalRead(Bew_rausgehen)

Besser lesbar, oder?

#ifdef __AVR__
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif

Welchen Arduino verwendest Du? Wenn es kein Trinket ist, kann das raus.

#if defined(FASTLED_VERSION) && (FASTLED_VERSION < 3001000)
#warning "Requires FastLED 3.1 or later; check github for latest code."
#endif

Da Du FastLED nicht verwendest, kann das raus. Wobei es noch eine Überlegung wäre, auf FastLED umzusteigen.

Noch ein paar Links zum Anregungen holen:
Unterstützung bei Treppenbeleuchung
Unterstützung bei Treppenbeleuchung
NEO Pixel - Treppenlauflicht
Treppenbeleuchtung mit 2 PIR Sensoren und FastLED

@ agmue

danke für die vielen Tipps.
Das muss ich mir in ruhe mal antun, ich bin mehr der handwerkliche Bastler.
So in die tiefen der Programmierung einzusteigen bin ich n bissl faul :wink:

Ja nein, keine Treppenhausbeleuchtung, sondern nur im Flur eine effekt Lampe, der Strip ist in einem rohr was an der Decke hängt. Hat nen schlitz oben drin und leuchtet so zur Decke.

Keine Gefahr des hinunterfallen :slight_smile:

Bewegungsmelder sollten sich ja gegenseitig sperren, da sonst wenn man "rein"geht der "raus" einen ja auch erwischt, ich hab das unelegant gelöst mit meinen vermurksten code. :o

APA102 habe ich noch nie gehört

ja die fast LED geschichte sind von dem punkt "LICHTSPIEL" was angehen soll wenn man pin 7 auf HIGH macht. (ist das DEMO von der FAST LED libary)
Die habe ich zum Testen raus geschmissen.(nicht alles anscheinend :-))

hab mein altes Projekt heute mal neu verfilmt :slight_smile:

obi81:
Keine Gefahr des hinunterfallen :slight_smile:

Gut, dann soll es nur schön aussehen :slight_smile:

obi81:
APA102 habe ich noch nie gehört

Adafruit nennt sie auch DotStar, haben Takt und Daten getrennt. Ich betreibe sie beispielsweise an Hardware-SPI vom Nano oder ProMini, etwas schneller noch am Teensy 3.2. Man schafft dadurch schnellere Animationen.

Servus Leute, also das Projekt schläft gerade,

Aber was anderes macht mir Kopfzerbrechen

Eine kleine Hintergrundbeleuchtung meiner Garderobe mit einem Bewegungsmelder angesteuert.
Wenn Bewegung erkannt wird → Licht andimmen und eine Anzeige per Zufall wackeln lassen und dessen Hintergrundbeleuchtung flackern lassen.
Funktioniert soweit, nur möchte ich den Bewegungsmelder nachtriggern.
Das bekomm ich nicht hin.

Ich hab das etwas pfuschig gelöst,…

Meine Idee hier wäre nachtriggern bei erneuter Bewegung, und irgendwie ein Flackern mit einzubauen :slight_smile:

/ -----------------------------GARDEROBEN LAMPE -------------------------------------------
// -----------------------------------------------------------------------------------------
// --- Led´s andimmen, Anzeige per Zufall ansteuern ----------------------------------------
// 8-2019
// Quellen:
// https://www.kreativekiste.de/images/arduino-projekte/feuer-simulation/arduino-kerzenlicht-pwm-led-simulations-code.txt
// https://funduino.de/nr-4-pulsierende-led

boolean __ardublockDigitalRead(int pinNumber)
{
  pinMode(pinNumber, INPUT);
  return digitalRead(pinNumber);
}

  bool _ABVAR_1_Bewegung;
int led = 3;                      // LED Streifen
int wert = 120;                   // Helligkeit LED Streifen
int zeiger = 10;                  // Analog Anzeige
int back = 11;                    // Hintergrundbeleuchtung Anzeige
int pir = 4;                      // Bewegungsmelder
int val = 0;                      // variable LED Helligkeit
int delayval = 0;                 // variable LED Wartezeit
int i = 0;
int _ABVAR_1_a;
int _ABVAR_2_a;
int _ABVAR_3_a;

void setup()
{
  pinMode(led, OUTPUT);
  pinMode(zeiger, OUTPUT);
  pinMode(back, OUTPUT);
  pinMode(pir, INPUT);
  randomSeed(0);                // Zufallszahlengenerator
   _ABVAR_1_Bewegung = false;
}

void loop()
{
    _ABVAR_1_Bewegung = digitalRead(pir);
      if (_ABVAR_1_Bewegung)

  
{
  // 1te Aktion Starten--------------------------------------------------------
  for (_ABVAR_1_a=1; _ABVAR_1_a<= ( 1 ); ++_ABVAR_1_a )
    {
      
// fade in from min to max in increments of 5 points:
  for (int fadeValue = 0 ; fadeValue <= 255; fadeValue += 5) {
    // sets the value (range from 0 to 255):
    analogWrite(led, fadeValue);
    analogWrite(back,fadeValue);
    // wait for 30 milliseconds to see the dimming effect
    delay(30);
      }
    }
   
    // Zweite aktion 30 mal wiederholen) --------------------------------------------------------
    for (_ABVAR_2_a=1; _ABVAR_2_a<= ( 30 ); ++_ABVAR_2_a )
    {

// Zufalls Hintergrundbeleuchtung -----------------------------------------------------------------------
val = random(180,255);       // Zufallszahl zwischen 125 und 255. 0 = LED aus, 255 = LED maximale Helligkeit.
  analogWrite(back, val);    // Setzt das PWM Signal auf die Zufallszahl 
  delayval = random(50,150);   // Zufallszahl zwischen 200 und 500. 100 = schnell, 800 = langsam.
  delay(delayval);  


  
// Zufallsanzeige Zeiger -----------------------------------------------------------------------
val = random(1,50);       // Zufallszahl zwischen 1 und 68MAX. 0 = LED aus, 255 = LED maximale Helligkeit.
  analogWrite(zeiger, val);    // Setzt das PWM Signal auf die Zufallszahl 
  delayval = random(200,800);   // Zufallszahl zwischen 200 und 500. 100 = schnell, 800 = langsam.
  delay(delayval);             // Setze die Wartezeit auf die Zufallszahl 


    }
      for (_ABVAR_3_a=1; _ABVAR_3_a<= ( 1 ); ++_ABVAR_3_a )
      {

  // fade out from max to min in increments of 5 points:
  for (int fadeValue = 255 ; fadeValue >= 0; fadeValue -= 5) {
    // sets the value (range from 0 to 255):
    analogWrite(led, fadeValue);
    // wait for 30 milliseconds to see the dimming effect
    delay(30);
  }

        
  }
      
  }
  else
  {
analogWrite(zeiger, 0);
analogWrite(back, 0);
//analogWrite(led, 0);
  }
}

Drücke in der IDE mal +T und formatiere den Code lesbar. So wie er ist, wird sich den kaum einer antun.
Ansonsten einfach bei Bewegung den Startzeitpunkt nachführen. Das geht natürlich nur ohne delay.

Gruß Tommy

obi81:
Aber was anderes macht mir Kopfzerbrechen
.....

Und warum machst du da keinen neuen Thread auf ?
So wird doch alles vermischt.

Aber schau mal hier, das könnte für dich passen. Mit "nachtriggern" aber ohne geflacker, das macht mich huschig. :wink:
Dafür aber mit "hoch und runterdimmen".

Stimmt eigentlich mit dem eigenen Thread, dachte weils auch um ein Bewegungsmelder Thema ging :slight_smile:

Ja Merci, das hilft mir weiter mit nachtriggern.

Das mit Flackern stell ich mir vor wenn es ausdimmt das es so ein bischen rumzuckt, aber das muss ich erst probieren wie das aussieht :wink: