PIR timing and setting value

Hi
This is related to another topic on this forum but has more to do with the coding. Not sure if I'm crossposting now or breaking any forum rules?

The code I have works fine when I 'simulate' a 1 or 0 value with a switch and other IF-statements pick up on that. I want to get a 1 or 0 from when the PIR goes HIGH (motion is detected). The problem there is that it goed HIGH and LOW constantly or doesn't see motion at all. So the 1 and 0 are allover the place. I tried to set another int to 1 after the first motion is detected and use a millis of 10 seconds before it's put back to 0, unless the motion is still there. If in those 10 seconds any motion is detected, the millis are reset again to 10 seconds etc, until there is no more motion and the value goes to 0 after 10 - motion free- seconds.

So far the theorie and a lot of trying but I cannot get it to work, at least not as a replacement for the button (which I used because the PIR was in the mail).

The code I used is:

  if (PIRval == HIGH) {            // check if the input is HIGH
PIR = 1;
        if (pirStatus == LOW) {
            Serial.println("Motion detected!");
            pirStatus = HIGH;
    }
  } else {
PIR=0;
        if (pirStatus == HIGH){
      // we have just turned of
      Serial.println("Motion ended!");
      //millis
        if (currentTime - resetPir >= PIRinterval) {        // wachten tot grace tijd voorbij is
      pirStatus = LOW;  
            resetPir = currentTime;}
      
    }
  }

What I try to accomplish is to get a stable PIR=x, just like flipping a button on and off. I know I'm doing something wrong but can't seem to find it :confused:

Thanks in advance for any pointers!

Your code is incomplete

#define FASTLED_INTERNAL                // irritante waarschuwing uitzetten van fastled
#include "FastLED.h"                    // fastled lib laden

/*
 * BEKNOPTE UITLEG NUMMER ZEVEN EN LEDSTRIPS (LEDS2).
 * Gebruik wordt gemaakt van WS2812 programmeerbare ledstrips. Dit zijn de 5v versies, 3 pins waarvan 1 datapin.
 * De LDR meet constant op intervals 2 waarden en neemt een gemiddelde. Als gemiddelde hoger is dan de LDRtrigger
 * dan wordt een dimStatus op 1 gezet: verlichting mag gedimd aan. Het nummer heeft een eigen gemiddelde en zal
 * daardoor eerder aanspringen. Als dimStatus=1 dan gaan de PIR metingen er ook toe doen.
 * 
 * De PIR zet PIRstatus HIGH of Low. Zodra het HIGH gaat, gaat de PIRval óók HIGH. Vervolgens gaat het licht x-minuten
 * aan. Als de PIRstatus LOW is, dus geen beweging meer, dan verloopt de tijd gewoon en gaat de PIRstatus weer naar LOW, 
 * en dus licht uit. Gaat de PIR wéér HIGH terwijl die tijd nog niet is verlopen, dan reset de tijd dat het aan moet 
 * blijven weer naar maximum, etc.
 * 
 * Als het licht gedimd aan is en de PIR gaat HIGH (dus detectie) dan gaat het licht van de basiskleur naar wit en vol
 * vermogen (fade up) en blijft aan zolang de PIRstatus HIGH is. Wanneer er geen beweging meer is gaat het naar de
 * basiskleur én dimming terug.
 * 
 * Het nummer 7 heeft een eigen strip en controller deel (LEDS1). Deze kunnen eerder aan gaan door de deelwaarde aan te
 * passen in :nummerGemiddeld = (metingA+metingB)/1.25;. Afhankelijk van de status van e 3-weg schakelelaar wordt er 1
 * van de drie effecten gekozen. Grotere switch of array? Meer effecten :)
 */

// +++ Code voor nummer 7 +++
#define LED_PIN_ZEVEN     7             // led pin voor nummer 7 output
#define NUM_LEDS_ZEVEN    30            // aantal leds in keten
CRGB leds1[NUM_LEDS_ZEVEN];             // fastled library aanpreken en aantal LEDs voor calculatie
int nummerGemiddeld = 0;                // is gelijk aan dimStatus maar wordt voor de zeven gebruikt, kan ie eerder aan
int nummerStatus = 0;                   // hebben we de LDR trigger bereikt?
int effect = 2;                         // welk effect moet er draaien
int RPin = 5;                           // rechter pin van on/off/on switch
int LPin = 3;                           // linker pin van on/off/on switch (middelste is GND)

// +++ Code voor andere strips +++
#define LED_PIN_ACHT     8              // led pin voor andere strips output
#define NUM_LEDS_ACHT    30             // aantal leds in keten
CRGB leds2[NUM_LEDS_ACHT];              // fastled library aanpreken en aantal LEDs voor calculatie
int dimMin = 20;                       // hoeveel licht wanneer er geen beweging is 30
int dimMax = 250;                       // maximale verlichting bij beweging 250
int dimval;
int dimStatus = 0;                      // Uit = 0, gedimd aan is 1, maximaal aan is 2
int Rgb = 100;
int rGb = 20;
int rgB = 143;

// +++ Maar voor alle strips is geldig:
#define COLOR_ORDER RGB                 // kleurvolgorde GRB
#define CHIPSET     NEOPIXEL            // WS2812
#define FRAMES_PER_SECOND 60            // controleren op flikkeren....
bool gReverseDirection = false;         // looprichting eventueel omdraaien mocht dat nodig zijn...

// +++ sensor +++
int PIRpin = 10;                        // PIR 10
int PIRstatus = 0 ;                    // standaard geen detectie, dus uit
int PIRval = 0;                         // de staat van de pir sensor bewaren
int LDRpin = A0;                        // LDR A0
int LDRtrigger  = 2 ;                  // wanneer moet LDR iets regelen (is ANDERS dan de dimMin!)
int metingA = 0;                        // eerste meeting LDR, deze lager dan B zetten ivm opstart loop!!
int metingB = 0;                        // tweede meeting LDR
int meting = 1;                         // 1 = A, 2 = B waarde intellen
int gemiddeld = 0;                      // wat is de huidige gemiddelde waarde
const unsigned long LDRinterval = 5000; // tijd tussen de meting van LDR
const unsigned long PIRinterval = 5000; // tijd dat licht aan moet blijven na beweging detectie
unsigned long resetTime = 0;            // interval reset
unsigned long resetPir = 0;             // interval reset


int FadeUp = 0;                         // checken of we een faduup hebben gedaan, doen we maar 1 keer
int Pir = 0;                            // wat is de status van de Pir? 0 is inactief, 1 is actief
int MaxStatus =0;


void setup() {
  // put your setup code here, to run once:
pinMode(PIRpin, INPUT);                 // PIR input sensor
pinMode(LDRpin, INPUT);                 // LDR input sensor
pinMode(2, INPUT_PULLUP); //***tjdelijk ush button****
pinMode(3, INPUT_PULLUP); //***tjdelijk ush button****
pinMode(RPin, INPUT_PULLUP);            // rechter positie schakelaar
pinMode(LPin, INPUT_PULLUP);            // linker positie schakelaar

FastLED.addLeds<CHIPSET,LED_PIN_ZEVEN>(leds1,NUM_LEDS_ZEVEN);    // fastled laden voor strip zeven
FastLED.addLeds<CHIPSET,LED_PIN_ACHT>(leds2,NUM_LEDS_ACHT);     // fastled laden voor strip acht

// Serial.begin(115200);                      // kan uit
}



int buttonState = LOW;

void loop() {
//LDR meten
float lightlevel = analogRead(LDRpin); //licht level max is 1023
//Serial.println(lightlevel);

  

//  buttonState = digitalRead(2);
   // check if the pushbutton is pressed. If it is, the buttonState is LOW:
/*  if (buttonState == LOW) {
        dimStatus=0;
  } 
  if (buttonState == HIGH) {
        dimStatus=1;
  } 
*/


//pir button
  buttonState = digitalRead(3);
   // check if the pushbutton is pressed. If it is, the buttonState is LOW:
  if (buttonState == LOW) {
        Pir = 0; FadeUp=0;
  } 
  if (buttonState == HIGH) {
        Pir = 1;
          }

          
 /*  LDR SENSOR
  *  Via millis een interval intellen en wederkerend waardes invullen op metingA en metingB. Het gemiddelde hiervan wordt de trigger
  *  voor de verlichting. Deze doet continue meten (met interval) zodat het licht aan of uit mag). Deinterval staat nu op 5000ms,
  *  dus 5 seconden. Maar misschien moet dat 5 minuten o.i.d. worden zodat een donkere wolk of heldere koplampen geen trigger zijn.
  */
unsigned long currentTime = millis();                                     
if (currentTime - resetTime >= LDRinterval && meting == 1) {                           // 5 intervalseconde meting
      metingA=lightlevel;meting=2;                                                            // HIER KOMT INPUT WAARDE VAN LDR
      resetTime = currentTime;                                                         // reset timer
      //Serial.print("meting a: ");Serial.println(metingA);
      }
if (currentTime - resetTime >= LDRinterval && meting == 2) {                           // 5 intervalseconde meting
      metingB=lightlevel;meting=1;                                                            // HIER KOMT INPUT WAARDE VAN LDR
      resetTime = currentTime;                                                         // reset timer
      //Serial.print("meting b: ");Serial.println(metingB);
      //Serial.print("Gemiddeld: ");Serial.println(gemiddeld); 
          }

//gemiddelde nemen
gemiddeld = (metingA+metingB)/2;                                            // gemiddelde uitrekenen en naar int verplaatsen 
if(gemiddeld <= LDRtrigger){   dimStatus = 1;}else{dimStatus=0;}
nummerGemiddeld = (metingA+metingB)/1.25;                                      // gemiddelde uitrekenen voor de zeven, gaat eerder aan! 
//if(nummerGemiddeld <= LDRtrigger){ nummerStatus = 1;}else{nummerStatus=0;} // ok, hij mag aan
//Serial.println(nummerStatus);





/*  PIR SENSOR DIT DEEL ACTIVEREN!
 *  Wanneer de PIR HIGH gaat dan de status naar HIGH. Ook wanneer de PIR weer LOW is kan de status nog een poos HIGH blijven,
 *  soort van grace-time. Wanneer er na ntijd geen HIGH status van de PIR is mag de STATUS naar LOW. Maar dit doen we ALLEEN
 *  wanneer de LDR heeft toegestaan dat het donker genoeg is! Dus dimStatus moet 1 zijn!
 */
 
if(dimStatus == 1){                                    // Mag er gemeten worden, LDR regelt dit
   if (PIRval == HIGH) {            // check if the input is HIGH
Pir = 1;
        if (PIRstatus == LOW) {
            Serial.println("Motion detected!");
            PIRstatus = HIGH;
    }
  } else {
Pir=0;
        if (PIRstatus == HIGH){
      // we have just turned of
      Serial.println("Motion ended!");
      //millis
        if (currentTime - resetPir >= PIRinterval) {        // wachten tot grace tijd voorbij is
      PIRstatus = LOW;  
            resetPir = currentTime;}
      
    }
  }
}




/*    
 *     De aansturing van de langere ledstrips gebeurt hier. De diverse statussen van sensor en modus bepalen wat er gebeurt.
 */

// DimStatus is 0 dus er mag nog niets gedaan worden
if(dimStatus == 0) { AllesUit();}

// nummerStatus is 0 dus ook geen nummer zeven verlichten
//if(nummerStatus == 0) { NummerUit();}


// licht mag gedimt aan -> status is dan 1
if(dimStatus == 1 && FadeUp == 0){  DimStart();}


// er is beweging, dus fade up
if(dimStatus == 1 && FadeUp == 0 && Pir ==1){
  StartFadeUp();
}


// na de fadeup aanblijven op max vermogen
if(dimStatus == 1 && FadeUp == 1){
  MaxLed();
}

if(dimStatus == 1  && MaxStatus==1 && Pir ==0){
  StartFadeDown();

}

/*
 * Code voor het huisnummer 7. Hier diverse effecten specificeren maar kunnen ook het huisnummer eerder aan
 * laten gaan dan de strip... als we daarvoor een andere waarde gebruiken dan dimStatus. Gebruiken we dezelfde
 * dan gaat het nummer gelijktijdig aan met de rest van de strip.
 */




/* De 3-way switch uitlezen. Als links en rechts uit zijn dan moet midden actief worden.
 */
if (!digitalRead(RPin)) //test rechter positie
  {    
//een effect
  }
  else if (!digitalRead(LPin)) //test linker positie
  {    
    //een effect  
    }
  else  {    //een effect
  } 

if(nummerStatus == 0) { NummerUit();}

if(effect ==1 &&nummerStatus ==1)
  {meteorRain(0xff,0xff,0xff,10, 64, true, 30);}
  else if 
  (effect ==2 &&nummerStatus ==1)
  {RunningLights(0xff,0xff,0xff, 50);}
  else if
  (effect ==3 &&nummerStatus ==1)
  {Fire(20,70,65);} //cooling / sparking en delay




}
/*


 
}//einde loop




/*
 * Onderstaande loops worden aangeroepen bij de diverse lichtstadia van de lange strip
 * 
 */

void AllesUit(){
       fill_solid( leds2, NUM_LEDS_ACHT, CRGB(0,0,0));FastLED.show();
       } // Einde allesuit

void DimStart(){
       for(int i = 0; i < NUM_LEDS_ACHT; i++ ) 
       {leds2[i].setRGB(200,10, 50);} // basiskleur
       FastLED.setBrightness(dimMin);  // dimwaarde
       FastLED.show();
       } // einde dimstart

void StartFadeUp(){
       for( int colorStep=0; colorStep<256; colorStep++ ) {
       int r = colorStep;  // Redness starts at zero and goes up to full
       int b = colorStep;  // Blue starts at full and goes down to zero
       int g = colorStep;  // No green needed to go from blue to red
       for(int x = 0; x < NUM_LEDS_ACHT; x++){leds2[x] = CRGB(r,g,b);}
       for(int z = dimMin; z < dimMax; z++){FastLED.setBrightness(z);}
              delay(5);

       FastLED.show();
       FadeUp=1; // fadeup is gedaan dus niet herhalen
       }
       } // einde StartFadeUp

void MaxLed(){
       for(int i = 0; i < NUM_LEDS_ACHT; i++ ) 
       {leds2[i].setRGB(250,250,250);}
       FastLED.setBrightness(250);   
       FastLED.show();
       MaxStatus=1;
       } // einde maxled

void StartFadeDown(){
       for(int i = 0; i < NUM_LEDS_ACHT; i++ ) // alle leds
       {leds2[i].setRGB(250,0, 0);} // basiskleur
        FastLED.setBrightness(dimMin);
        FastLED.show();
        delay(1000);
       MaxStatus=0; // fadedown is gedaan dus niet herhalen
      // }
       } // einde StartFadeUp

void NummerUit(){
       fill_solid( leds1, NUM_LEDS_ZEVEN, CRGB(0,0,0));FastLED.show();
       nummerStatus =0;
       } // Einde allesuit
       











/*
 * Extra lib voor LED aansturing: NIET VERWIJDEREN!
 */
 void showStrip() {
 #ifdef ADAFRUIT_NEOPIXEL_H
   // NeoPixel
   strip.show();
 #endif
 #ifndef ADAFRUIT_NEOPIXEL_H
   // FastLED
 //  FastLED.setBrightness(250);
   FastLED.show();
 #endif
}

void setPixel(int Pixel, byte red, byte green, byte blue) {
 #ifdef ADAFRUIT_NEOPIXEL_H
   // NeoPixel
   strip.setPixelColor(Pixel, strip.Color(red, green, blue));
 #endif
 #ifndef ADAFRUIT_NEOPIXEL_H
   // FastLED
   leds1[Pixel].r = red;
   leds1[Pixel].g = green;
   leds1[Pixel].b = blue;
 #endif
}

void setAll(byte red, byte green, byte blue) {
  for(int i = 0; i < NUM_LEDS_ZEVEN; i++ ) {
    setPixel(i, red, green, blue);
  }
  showStrip();
}


/*
 * Onderstaande loops zijn voor het lichteffect in de 'zeven'
 * 
 */

/*
 * effect 1
 */
 void meteorRain(byte red, byte green, byte blue, byte meteorSize, byte meteorTrailDecay, boolean meteorRandomDecay, int SpeedDelay) {  
  setAll(0,0,0);
 //FastLED.setBrightness(250 );
  for(int i = 0; i < NUM_LEDS_ZEVEN+NUM_LEDS_ZEVEN; i++) {
   
   
    // fade brightness all LEDs one step
    for(int j=0; j<NUM_LEDS_ZEVEN; j++) {
      if( (!meteorRandomDecay) || (random(10)>5) ) {
        fadeToBlack(j, meteorTrailDecay );        
      }
    }
   
    // draw meteor
    for(int j = 0; j < meteorSize; j++) {
      if( ( i-j <NUM_LEDS_ZEVEN) && (i-j>=0) ) {
        setPixel(i-j, red, green, blue);
      }
    }
   
    showStrip();
    delay(SpeedDelay);
  }
}

void fadeToBlack(int ledNo, byte fadeValue) {
 #ifdef ADAFRUIT_NEOPIXEL_H
    // NeoPixel
    uint32_t oldColor;
    uint8_t r, g, b;
    int value;
   
    oldColor = strip.getPixelColor(ledNo);
    r = (oldColor & 0x00ff0000UL) >> 16;
    g = (oldColor & 0x0000ff00UL) >> 8;
    b = (oldColor & 0x000000ffUL);

    r=(r<=10)? 0 : (int) r-(r*fadeValue/256);
    g=(g<=10)? 0 : (int) g-(g*fadeValue/256);
    b=(b<=10)? 0 : (int) b-(b*fadeValue/256);
   
    strip.setPixelColor(ledNo, r,g,b);
 #endif
 #ifndef ADAFRUIT_NEOPIXEL_H
   // FastLED
   leds1[ledNo].fadeToBlackBy( fadeValue );
 #endif  
}








/*
 * effect 2
 */
void RunningLights(byte red, byte green, byte blue, int WaveDelay) {
  int Position=0;
 
  for(int j=0; j<NUM_LEDS_ZEVEN*2; j++)
  {
      Position++; // = 0; //Position + Rate;
      for(int i=0; i<NUM_LEDS_ZEVEN; i++) {
        // sine wave, 3 offset waves make a rainbow!
        //float level = sin(i+Position) * 127 + 128;
        //setPixel(i,level,0,0);
        //float level = sin(i+Position) * 127 + 128;
        setPixel(i,((sin(i+Position) * 127 + 128)/255)*red,
                   ((sin(i+Position) * 127 + 128)/255)*green,
                   ((sin(i+Position) * 127 + 128)/255)*blue);
      }
     
      showStrip();
      delay(WaveDelay);
  }
}






 /*
  * effect 3 vuurrrrrr
  */
  void Fire(int Cooling, int Sparking, int SpeedDelay) {
  static byte heat[NUM_LEDS_ZEVEN];
  int cooldown;

 
  // Step 1.  Cool down every cell a little
  for( int i = 0; i < NUM_LEDS_ZEVEN; i++) {
    cooldown = random(0, ((Cooling * 10) / NUM_LEDS_ZEVEN) + 2);
   
    if(cooldown>heat[i]) {
      heat[i]=0;
    } else {
      heat[i]=heat[i]-cooldown;
    }
  }
 
  // Step 2.  Heat from each cell drifts 'up' and diffuses a little
  for( int k= NUM_LEDS_ZEVEN - 1; k >= 2; k--) {
    heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2]) / 3;
  }
   
  // Step 3.  Randomly ignite new 'sparks' near the bottom
  if( random(255) < Sparking ) {
    int y = random(7);
    heat[y] = heat[y] + random(160,255);
    //heat[y] = random(160,255);
  }

  // Step 4.  Convert heat to LED colors
  for( int j = 0; j < NUM_LEDS_ZEVEN; j++) {
    setPixelHeatColor(j, heat[j] );
  }

  showStrip();
  delay(SpeedDelay);
}

void setPixelHeatColor (int Pixel, byte temperature) {
  // Scale 'heat' down from 0-255 to 0-191
  byte t192 = round((temperature/255.0)*191);
 
  // calculate ramp up from
  byte heatramp = t192 & 0x3F; // 0..63
  heatramp <<= 2; // scale up to 0..252
 
  // figure out which third of the spectrum we're in:
  if( t192 > 0x80) {                     // hottest
    setPixel(Pixel, 255, 255, heatramp);
  } else if( t192 > 0x40 ) {             // middle
    setPixel(Pixel, 255, heatramp, 0);
  } else {                               // coolest
    setPixel(Pixel, heatramp, 0, 0);
  }
  }

Where in your code, do you read the status of PIRpin?

You can refer to the below code to set the delay time in the code without using the delay() function

/*
 * Created by ArduinoGetStarted.com
 *
 * This example code is in the public domain
 *
 * Tutorial page: https://arduinogetstarted.com/tutorials/arduino-motion-sensor
 */

const int PIN_TO_SENSOR = 2;   // the pin that OUTPUT pin of sensor is connected to
int pinStateCurrent   = LOW; // current state of pin
int pinStatePrevious  = LOW; // previous state of pin
const unsigned long DELAY_TIME_MS = 30000; // 30000 miliseconds ~ 30 seconds
bool delayEnabled = false;
unsigned long delayStartTime;

void setup() {
  Serial.begin(9600);            // initialize serial
  pinMode(PIN_TO_SENSOR, INPUT); // set arduino pin to input mode to read value from OUTPUT pin of sensor
}

void loop() {
  pinStatePrevious = pinStateCurrent; // store state
  pinStateCurrent = digitalRead(PIN_TO_SENSOR);   // read new state

  if (pinStatePrevious == LOW && pinStateCurrent == HIGH) {   // pin state change: LOW -> HIGH
    Serial.println("Motion detected!");
    Serial.println("Turning on / activating");
    delayEnabled = false; // disable delay
    // TODO: turn on alarm, light or activate a device ... here
  }
  else
  if (pinStatePrevious == HIGH && pinStateCurrent == LOW) {   // pin state change: HIGH -> LOW
    Serial.println("Motion stopped!");
    delayEnabled = true; // enable delay
    delayStartTime = millis(); // set start time
  }

  if (delayEnabled == true && (millis() - delayStartTime) >= DELAY_TIME_MS) {
    Serial.println("Turning off / deactivating");
    delayEnabled = false; // disable delay
    // TODO: turn off alarm, light or deactivate a device ... here
  }
}

Further more, you can put the pumper in the right position to disable the "repeated trigger". It looks like below:

For more detail, see Arduino Motion sensor tutorial

Thank you very much!

This will help me out bigtime!

I had the pots set like you had but I'm missing the jumper pins on my board, there are only the solder pads. I have connected them now like you showed me.

Thanks again!