Neopixel und PIR Senor in einer loop

Hallo, ich arbeite gerade an einer Solarlampe.
Diese beinhaltet einen Ring aus Neopixel, die in der Nacht durchgehend im Rainbow Modus leuchten.
Jedoch möchte ich mittels dreier PIR Sensoren, welche rund um die Lampe verteilt sind, gleichzeitig 3 LEDs einschalten.
Mein Problem ist, dass die “rainbow” funktion zu lange dauert und somit der PIR Sensor nicht reagiert.
Die Programme funktionieren einzeln super. Doch zusammen garnicht!
Ich habe das Ganze mal mittels attachInterrupt probiert und bei meinem Arduino Nano alle drei PIRs auf PIN 1 und 2 des Arduinos gelegt. Somit sollten sich beim Auslösen (RISING) des einen Interrupt PINS die LEDs einschalten und beim anderen Interrupt Pin (FALLING) wieder ausschalten.
Bekommt man das Ganze auch ohne Interrupts irgendwie hin oder könnt ihr mir weiterhelfen?
Danke schon mal im Voraus.
Hier unten findet ihr meinen Versuch mit Innterrupts
```
**//Automaisches Regenbogenlicht mit Bewegungsmelder für LEDs
#include <Adafruit_NeoPixel.h>

const int ledPin = 7;    // the number of the neopixel strip
const int numLeds = 16;

//Adafruit_NeoPixel pixels = Adafruit_NeoPixel(8, ledPin);
Adafruit_NeoPixel strip = Adafruit_NeoPixel(numLeds, ledPin, NEO_GRB + NEO_KHZ800);

const int LedPin1 = 8;              //Anschluss für die Lampe1 festlegen
const int LedPin2 = 9;              //Anschluss für die Lampe2 festlegen
const int LedPin3 = 10;              //Anschluss für die Lampe3 festlegen

int Arduino2 = 18;

int HelligkeitsPin = A0;      //Anschluss für den Abgriff des Spannungsteilers aus Vorwiderstand Rv und Fotowiderstand LDR
int Helligkeitswert = 0;      //Variable, die einen der Helligkeit entsprechenden Digitalwert speichert

unsigned long StartTime = 0;  //Variable, die für die Berechnung der Leuchtdauer der Lampe verwendet wird

#define interrupt_pin 3    // interrupt pin
#define interrupt_pinn 2    // interrupt pin

void setup() {
 
  Serial.begin(9600);
  strip.begin();
  strip.setBrightness(80); // 1/3 brightness

pinMode(LedPin1, OUTPUT);
  pinMode(LedPin2, OUTPUT);
  pinMode(LedPin3, OUTPUT);

pinMode(HelligkeitsPin, INPUT);  //Anschluss des Spannungsteiler-Abgriffes wird als Eingang gesetzt

pinMode(Arduino2, OUTPUT);

pinMode(interrupt_pin, INPUT);
  pinMode(interrupt_pinn, INPUT);
}

void loop() {
 
  attachInterrupt(digitalPinToInterrupt(interrupt_pin), einschalten, RISING);
  attachInterrupt(digitalPinToInterrupt(interrupt_pinn), ausschalten, FALLING);

rainbow(200);
  delay(90);

Helligkeitswert=analogRead(HelligkeitsPin);
  if (Helligkeitswert>15 ) {  //Wenn der Helligkeitswert 15 überschreitet,…
  digitalWrite(Arduino2,HIGH);                  //wird auf Arduino 2 umgeschaltet…
                           
  } 
}

void einschalten() {  //3 LEDs werden eingeschaltet

digitalWrite(LedPin1, HIGH);
  digitalWrite(LedPin2, HIGH);
  digitalWrite(LedPin3, HIGH);

}
void ausschalten() {  //3 LEDs werden ausgeschaltet
 
  digitalWrite(LedPin1, LOW);
  digitalWrite(LedPin2, LOW);
  digitalWrite(LedPin3, LOW);
}

void rainbow(uint8_t wait) {

uint16_t i, j;

for (j = 0; j < 256; j++) {
    for (i = 0; i < strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel((i * 1 + j) & 255));
    }
    strip.show();
    delay(wait);

}
}

// 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) {
  if (WheelPos < 85) {
    return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  }
  else if (WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  else {
    WheelPos -= 170;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
}**
```

Wieso schreibst Du fett bzw doppelfett?

Die Ws 2812B schalten bei der Übertragung die Interrupts ab wenn ich mich recht erinnere.

matthias1235:
Mein Problem ist, dass die "rainbow" funktion zu lange dauert und somit der PIR Sensor nicht reagiert.

Die Programme funktionieren einzeln super. Doch zusammen garnicht!

Bekommt man das Ganze auch ohne Interrupts irgendwie hin.

Indem Du keine delay() verwendest sondern die Zeiten mittels millis() bestimmst.

Grüße Uwe

Leider habe ich mit den "Neopixel" zu wenig Erfahrung, vermute aber, wenn du in deine Rainbow-Funktion mehrere Abfragen der Sensoren einbaust, könnte es funktionieren.

Edit:
Fetttschrift gilt als schreien und ist damit unhöflich.

Vielen Dank erstmal für eure Hilfe :slight_smile:

Habe den Sketch jetzt mal umgeschrieben. Das mit den PIRs funktioniert super wenn ich das delay(wait) rausnehme. Allerdings blinken die Neopixel dann wie wild…

Wie kann ich dieses delay(wait) bei der void rainbow am besten ersetzen?

//Automatisches Regenbogenlicht mit Bewegungsmelder für LEDs
#include <Adafruit_NeoPixel.h>

const int ledPin = 7;     // the number of the neopixel strip
const int numLeds = 16;


//Adafruit_NeoPixel pixels = Adafruit_NeoPixel(8, ledPin);
Adafruit_NeoPixel strip = Adafruit_NeoPixel(numLeds, ledPin, NEO_GRB + NEO_KHZ800);

int LedPin1 = 8;              //Anschluss für die Lampe1 festlegen
int LedPin2 = 9;              //Anschluss für die Lampe2 festlegen
int LedPin3 = 10;              //Anschluss für die Lampe3 festlegen
int BewegungsPin1 = 3;         //Anschluss für den Steuerungsausgang des Bewegungsmelders1 festlegen
int BewegungsPin2 = 4;         //Anschluss für den Steuerungsausgang des Bewegungsmelders2 festlegen
int BewegungsPin3 = 6;         //Anschluss für den Steuerungsausgang des Bewegungsmelders3 festlegen
int Bewegung1 = 0;             //Variable, die den Zustand des Bewegungsmelders1 speichert (0=keine Bewegung, 1=Bewegung)
int Bewegung2 = 0;             //Variable, die den Zustand des Bewegungsmelders2 speichert (0=keine Bewegung, 1=Bewegung)
int Bewegung3 = 0;             //Variable, die den Zustand des Bewegungsmelders3 speichert (0=keine Bewegung, 1=Bewegung)
int Arduino2 = 18;
int HelligkeitsPin = A0;      //Anschluss für den Abgriff des Spannungsteilers aus Vorwiderstand Rv und Fotowiderstand LDR
int Helligkeitswert = 0;      //Variable, die einen der Helligkeit entsprechenden Digitalwert speichert
unsigned long StartTime = 0;  //Variable, die für die Berechnung der Leuchtdauer der Lampe verwendet wird




void setup() {
  
  Serial.begin(9600);
  strip.begin();
  strip.setBrightness(80); // 1/3 brightness

   pinMode(LedPin1, OUTPUT);
  pinMode(LedPin2, OUTPUT);
  pinMode(LedPin3, OUTPUT);
  pinMode(BewegungsPin1, INPUT);     //Anschluss der Steuerleitung des Bewegungsmelders wird als Eingang gesetzt
  pinMode(BewegungsPin2, INPUT);
  pinMode(BewegungsPin3, INPUT);
  pinMode(HelligkeitsPin, INPUT);   //Anschluss des Spannungsteiler-Abgriffes wird als Eingang gesetzt
  pinMode(Arduino2, OUTPUT);
  
}



void loop() {
  
  Helligkeitswert=analogRead(HelligkeitsPin);   //analogen Helligkeitswert einlesen (wird im µController in Digitalwert umgewandelt
  Bewegung1=digitalRead(BewegungsPin1);           //Zustand des Bewegungsmelders1 auslesen
  Bewegung2=digitalRead(BewegungsPin2);           //Zustand des Bewegungsmelders2 auslesen
  Bewegung3=digitalRead(BewegungsPin3);           //Zustand des Bewegungsmelders3 auslesen
  
 if ((Bewegung1== HIGH or Bewegung2 == HIGH or Bewegung3 == HIGH)  ) {   //Wenn Bewegung1 vorliegt und der Helligkeitswert 700 überschreitet,...&& Helligkeitswert<15
    digitalWrite(LedPin1,HIGH);                  //wird die Lampe eingeschaltet...
    digitalWrite(LedPin2,HIGH);
    digitalWrite(LedPin3,HIGH);
    StartTime=millis();                         //und die aktuelle Zeit (Zeit ab Programmstart in Millisekunden) wird abgespeichert
   }
  else if (millis()-StartTime>5000){            //ansonsten, wenn 5000 Millisekunden Differenz überschritten sind,...
    digitalWrite(LedPin1,LOW);                   //wird die Lampe ausgeschaltet
    digitalWrite(LedPin2,LOW);  
    digitalWrite(LedPin3,LOW);                   
    
    }
  rainbow(200);
 

 
   
}

void rainbow(uint8_t wait) {

  uint16_t i, j;

  for (j = 0; j < 256; j++) {
    for (i = 0; i < strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel((i * 1 + j) & 255));
    }
    strip.show();
    delay(wait);

  }
}


// 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) {
  if (WheelPos < 85) {
    return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  }
  else if (WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  else {
    WheelPos -= 170;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
}

Schau Dir BlinkWithoutDelay in den Beispielen Deiner IDE an und verstehe es.

Gruß Tommy

oder auch

Grüße Uwe

Danke, habe mir eure links nochmal durchgelesen. Bekomme das delay aber einfach nicht zum laufen.

void rainbow(uint8_t wait) {

  uint16_t i, j;

  for (j = 0; j < 256; j++) {
    for (i = 0; i < strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel((i * 1 + j) & 255));
    }
    strip.show();
   delay(wait);
 
}

Das delay muss ganz raus.
Vom kurz Durchlesen kannst Du es wohl noch nicht verstehen.
Dann experimentierem mit dem Beispiel rum, bis Du es verstehst.

Gruß Tommy

Hab es jetzt ohne delays hinbekommen, Danke.

Prima, geht doch.
Das Verständnis von millis() wirst Du immer wieder brauchen.

Gruß Tommy

Hi

Was mir beim Drüberfliegen aufgefallen ist:
Du hast DREI PIR-Sensoren auf ZWEI Arduino-Pins gelegt?
Die mir vorliegenden PIR-Platinchen haben eine Push-Pull-Ausgangsstufe, treiben also aktiv HIGH und LOW, je nach Schaltzustand.
DAS scheint bei Dir nicht gegeben zu sein, weil sonst MINDESTENS EINER der Sensoren zerstört sein müsste, sobald die zusammen geschalteten Sensoren unterschiedliche Pegel generieren.

Meine sind die 'ganz Billigen' vom FC, Platine mit 4 Kondensatoren 'als Füße', zwei Einstell-Rädchen.

MfG