2 Befehle "gleichzeitig"

Hallo liebe Community,

Ich steuere im Moment mit meinen Arduino 1m NeoPixel an und will nun einen zweiten Meter unabhängig über einen anderen Port ansteuern. Das Programm was ich umgeändert habe funktioniert nur halb. Zwar werden beide angesteuert aber nicht gleichzeitig. Ich weiß, dass gleichzeitig beim Arduino nicht wirklich funktioniert, sondern nur schnelles hin und her springen jedoch hab ich keine Ahnung wie das funktioniert. :( " void loop() {

rainbowCycle(5), rainbowCycle2(5);

}" Könnt ihr mir helfen wie ich die beiden Befehle "gleichzeitig" laufen lassen kann ? Ich freue mich über jede Antwort :)

MFG Octarock

Einsteinli: Könnt ihr mir helfen wie ich die beiden Befehle "gleichzeitig" laufen lassen kann ?

Hallo, wenn Du strip1.show(); und strip2.show(); nacheinander laufen läßt und auf blockierende Programmierung wie delay() verzichtest.

Adafruit_NeoPixel strip = Adafruit_NeoPixel(100 , 6 , NEO_GRB + NEO_KHZ800); //1.Led Band
Adafruit_NeoPixel strip2 = Adafruit_NeoPixel(100 , 5 , NEO_GRB + NEO_KHZ800); //2.Led Band

void setup() {
// This is for Trinket 5V 16MHz, you can remove these three lines if you are not using a Trinket
#if defined (AVR_ATtiny85)
if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
#endif

strip.begin();
strip.show(); // Initialize all pixels to ‘off’

strip2.begin();
strip2.show(); // Initialize all pixels to ‘off’
}

void loop() {

rainbowCycle(5), rainbowCycle2(5); // sollen “gleichzeitig” angesteuert werden

}

void rainbowCycle2(uint8_t wait) {
uint16_t g, h;

for(h=0; h<256*1; h++) { // 5 cycles of all colors on wheel
for(g=0; g< strip.numPixels(); g++) {
strip2.setPixelColor(g, Wheel(((g * 256 / strip.numPixels()) + h) & 255));
}
strip2.show();
delay(wait); //wenn ich delay lösche läuft das Programm zu schnell
}
}

void rainbowCycle(uint8_t wait) {
uint16_t i, j;

for(j=0; j<256*1; j++) { // 5 cycles of all colors on wheel
for(i=0; i< strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
}
strip.show();
delay(wait);
}
}

uint32_t Wheel(byte WheelPos) {
WheelPos = 255 - WheelPos;
if(WheelPos < 85) {
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
}
if(WheelPos < 170) {
WheelPos -= 85;
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
WheelPos -= 170;
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

uint32_t Wheel2(byte WheelPos2) {
WheelPos2 = 255 - WheelPos2;
if(WheelPos2 < 85) {
return strip2.Color(255 - WheelPos2 * 3, 0, WheelPos2 * 3);
}
if(WheelPos2 < 170) {
WheelPos2 -= 85;
return strip2.Color(0, WheelPos2 * 3, 255 - WheelPos2 * 3);
}
WheelPos2 -= 170;
return strip2.Color(WheelPos2 * 3, 255 - WheelPos2 * 3, 0);
}

Ich weiß nicht ob das euch Hilft mein Problem zu verstehen (hoffe mal)

delay(wait); //wenn ich delay lösche läuft das Programm zu schnell

:o :o :o :o :o

Tipp: "Blink without Delay" lesen

wenn ich delay weg lasse, läft das Licht zu schnell durch und selbst wenn laufen die beiden Led-Bänder immer noch deutlich spürbar hintereinander

Einsteinli: rainbowCycle(5), rainbowCycle2(5);

}" Könnt ihr mir helfen wie ich die beiden Befehle "gleichzeitig" laufen lassen kann ?

Stecken vielleicht in der Funktion rainbowCycle() oder rainbowCycle2(), oder eventuell sogar in beiden Funktionen Aufrufe der blockierenden Funktion delay() mit drin?

Wenn auch nur eine der beiden Funktionen eine https://en.wikipedia.org/wiki/Busy_waiting OProgrammschleife enthält, kannst Du die Funktion in die Tonne treten und Dir eine neue Programmlogik überlegen, die die gewünschte Funktionalität OHNE delay() und OHNE blockierende Busy-Waiting-Programmschleifen realisiert.

Ja tut es :( Weiß vielleicht einer ein Programm das Funktioniert ?

Wäre euch sehr Dankbar :)

Einsteinli: Ja tut es :( Weiß vielleicht einer ein Programm das Funktioniert ?

Wäre euch sehr Dankbar :)

Du solltest einfach mal das delay durch die Funktion mit millis ersetzen. Das Beispiel "BlinkWithoutDelay" wurde dir schon genannt.

Einfach mal einlesen und rangehen. So schwer ist es nicht.

Einsteinli: Weiß vielleicht einer ein Programm das Funktioniert ?

Hotsystems hat ja schon das BlinkWithoutDelay-Beispiel genannt. Zu den Themen delay()-Vermeidung und „endlicher Automat“ habe ich mir außerdem mal das hier einfallen lassen. Vielleicht hilft das.

Gruß

Gregor

Ok Danke dann lese ich mal

PS: was ich nicht verstehe ist dass, wenn ich delay lösche es immer noch nicht "gleichzeitig" funktioniert

Einsteinli: Ok Danke dann lese ich mal

PS: was ich nicht verstehe ist dass, wenn ich delay lösche es immer noch nicht "gleichzeitig" funktioniert

Du hast es ja schon selbst geschrieben. Da es immer noch nacheinander abläuft. Damit es quasi gleichzeitig läuft, musst du die Funktionen komplett neu schreiben und die einzelnen Anweisungen direkt nacheinander zusammenbauen.

Einsteinli:
PS: was ich nicht verstehe ist dass, wenn ich delay lösche es immer noch nicht “gleichzeitig” funktioniert

Es passiert halt „de facto“ nicht gleichzeitig. Weil es ohne delay() zwischen zwei Schaltereien nur zu einer seeeehr kurzen Verzögerung kommt. Es sieht „gleichzeitig“ aus, ist es aber nicht wirklich.

Gruß

Gregor

es sieht aber keineswegs gleichzeitig aus

Einsteinli: es sieht aber keineswegs gleichzeitig aus

Hatte ich doch schon in Post #10 geschrieben. Es läuft immer nacheinander ab. Da dein verwendeter Sketch auch eine eigene Verzögerung (for-Schleife) hat, wird es nie gleichzeitig sein.

Du musst deinen Sketch umbauen und die entsprechenden Anweisungen unmittelbar nacheinander ausführen.

ich habe mich jetzt rein gelesen und ausprobiert habe aber nichts erreicht :frowning:
Ich habe das nicht das Problem mit delay sonder, dass die for Bedingung so lange dauert und ich habe nicht heraus gefunden wie ich zwei for Bedingungen verknüpfen kann.

Einsteinli:
ich habe mich jetzt rein gelesen und ausprobiert habe aber nichts erreicht :frowning:
Ich habe das nicht das Problem mit delay sonder, dass die for Bedingung so lange dauert und ich habe nicht heraus gefunden wie ich zwei for Bedingungen verknüpfen kann.

Dein Problem ist, dass Du in blockierenden Abläufen denkst, statt in Zeitabläufen.

Du möchtest ein quasi-paralleles Abarbeiten von Funktionen im kooperativen Muititasking, aber Deine blockierenden for-Schleifen sind nicht im geringsten kooperativ angelegt, sondern "blockierend.

Du brauchst für deine LED-Steuerung eine komplett neue und “kooperative” (nicht-blockierende) Programmlogik.

Es wird in deiner Variante jeder RainbowCycle für sich selbst einmal durchlaufen, bevor er zum nächsten wechselt… deswegen passiert da nichts “gleichzeitig”.
Habe das Beispiel nur in der void RainbowCycle mal etwas umgemodelt, so daß du zumindest einen Eindruck bekommst, wie du beide Strips Gleiches machen lässt (davon ausgehend, daß beide die gleiche Anzahl an LEDs haben)

void rainbowCycle(uint8_t wait) {
  uint16_t i, j;

  for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
    for(i=0; i< strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
      strip2.setPixelColor(i, Wheel(((i * 256 / strip2.numPixels()) + j) & 255));
    }
    strip.show();
    strip2.show();
    delay(wait);
  }
}

zumindest mal ein Anfang, hoffe ich :slight_smile:

Allerdings kommst du um die bisher erteilten Ratschläge nicht herum, wenn du beide LED-stripes unabhängig voneinander ansteuern möchtest.
So ist das jetzt einfach nur strip1 auf strip2 gespiegelt.

Danke diese Idee hatte ich auch vor kurzen :) Hast du vielleicht auch noch eine Idee für die vorher genannte komplett neue und "kooperative" (nicht-blockierende) Programmlogik Ich bin mir sicher ihr wisst da mehr als ich

Letztendlich kommst du nicht darum, dich genau in diese Thematik einzuarbeiten, wie es einige hier schon vorgeschlagen haben. Mit blink without delay solltest du auf jeden Fall anfangen.

Das dort genannte Blink-Beispiel könnte dann in deinem Neopixel-Programm zum Beispiel so Anwendung finden:

#include <Adafruit_NeoPixel.h>

#define PIN 6

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

unsigned long previousMillis = 0; // speichert wie viele Sekunden seit derletzten Änderung vergangen sind
unsigned long interval = 20;      // Interval zwischen zwei Änderungen in ms

int j=0;

void setup() {
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
}

void loop() {

  // diese Abfrage prüft, ob 'interval' millisekunden abgelaufen sind
  if (millis() - previousMillis > interval) {
    previousMillis = millis();      // aktuelle Zeit abspeichern
    rainbowCycle();
  }

  /*
  Rest vom Programm, der möglichst auch ohne "delay"s auskommen sollte
   */
}


// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle() {
  uint16_t i;
  j++;                          // nächste Farbe im Wheel
  if (j>255) { j=0; }
  for(i=0; i< strip.numPixels(); i++) {
    strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
  }
  strip.show();
}


// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if(WheelPos < 85) {
    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if(WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

Wenn du diesen Zusammenhang erkennst bist du schon einen großen Schritt weiter :slight_smile: